]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: fix corner case in TLBWR causing QEMU to hang
[mirror_qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
0a2672b7 31#include "sysemu/kvm.h"
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);
1613}
1614
1615static inline void generate_exception(DisasContext *ctx, int excp)
1616{
1617 save_cpu_state(ctx, 1);
1618 gen_helper_0e0i(raise_exception, excp);
1619}
1620
aaa9128a 1621/* Floating point register moves. */
7c979afd 1622static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1623{
7c979afd
LA
1624 if (ctx->hflags & MIPS_HFLAG_FRE) {
1625 generate_exception(ctx, EXCP_RI);
1626 }
ecc7b3aa 1627 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1628}
1629
7c979afd 1630static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1631{
7c979afd
LA
1632 TCGv_i64 t64;
1633 if (ctx->hflags & MIPS_HFLAG_FRE) {
1634 generate_exception(ctx, EXCP_RI);
1635 }
1636 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1637 tcg_gen_extu_i32_i64(t64, t);
1638 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1639 tcg_temp_free_i64(t64);
6d066274
AJ
1640}
1641
7f6613ce 1642static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1643{
7f6613ce 1644 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1645 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1646 } else {
7c979afd 1647 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1648 }
6d066274
AJ
1649}
1650
7f6613ce 1651static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1652{
7f6613ce
PJ
1653 if (ctx->hflags & MIPS_HFLAG_F64) {
1654 TCGv_i64 t64 = tcg_temp_new_i64();
1655 tcg_gen_extu_i32_i64(t64, t);
1656 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1657 tcg_temp_free_i64(t64);
1658 } else {
7c979afd 1659 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1660 }
aa0bf00b 1661}
6ea83fed 1662
d73ee8a2 1663static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1664{
f364515c 1665 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1666 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1667 } else {
d73ee8a2 1668 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1669 }
1670}
6ea83fed 1671
d73ee8a2 1672static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1673{
f364515c 1674 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1675 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1676 } else {
d73ee8a2
RH
1677 TCGv_i64 t0;
1678 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1679 t0 = tcg_temp_new_i64();
6d066274 1680 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1681 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1682 tcg_temp_free_i64(t0);
aa0bf00b
TS
1683 }
1684}
6ea83fed 1685
d94536f4 1686static inline int get_fp_bit (int cc)
a16336e4 1687{
d94536f4
AJ
1688 if (cc)
1689 return 24 + cc;
1690 else
1691 return 23;
a16336e4
TS
1692}
1693
48d38ca5 1694/* Addresses computation */
941694d0 1695static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1696{
941694d0 1697 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1698
1699#if defined(TARGET_MIPS64)
01f72885 1700 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1701 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1702 }
1703#endif
4ad40f36
FB
1704}
1705
31837be3
YK
1706/* Addresses computation (translation time) */
1707static target_long addr_add(DisasContext *ctx, target_long base,
1708 target_long offset)
1709{
1710 target_long sum = base + offset;
1711
1712#if defined(TARGET_MIPS64)
1713 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1714 sum = (int32_t)sum;
1715 }
1716#endif
1717 return sum;
1718}
1719
71f303cd 1720/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1721static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1722{
1723#if defined(TARGET_MIPS64)
71f303cd
RH
1724 tcg_gen_ext32s_i64(ret, arg);
1725#else
1726 tcg_gen_extrl_i64_i32(ret, arg);
1727#endif
1728}
1729
1730/* Sign-extract the high 32-bits to a target_long. */
1731static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1732{
1733#if defined(TARGET_MIPS64)
1734 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1735#else
71f303cd 1736 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1737#endif
1738}
1739
356265ae 1740static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1741{
fe253235 1742 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1743 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1744}
1745
356265ae 1746static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1747{
fe253235 1748 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1749 generate_exception_err(ctx, EXCP_CpU, 1);
1750}
1751
b8aa4598
TS
1752/* Verify that the processor is running with COP1X instructions enabled.
1753 This is associated with the nabla symbol in the MIPS32 and MIPS64
1754 opcode tables. */
1755
356265ae 1756static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1757{
1758 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1759 generate_exception(ctx, EXCP_RI);
1760}
1761
1762/* Verify that the processor is running with 64-bit floating-point
1763 operations enabled. */
1764
356265ae 1765static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1766{
b8aa4598 1767 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1768 generate_exception(ctx, EXCP_RI);
1769}
1770
1771/*
1772 * Verify if floating point register is valid; an operation is not defined
1773 * if bit 0 of any register specification is set and the FR bit in the
1774 * Status register equals zero, since the register numbers specify an
1775 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1776 * in the Status register equals one, both even and odd register numbers
1777 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1778 *
1779 * Multiple 64 bit wide registers can be checked by calling
1780 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1781 */
356265ae 1782static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1783{
fe253235 1784 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1785 generate_exception(ctx, EXCP_RI);
1786}
1787
853c3240
JL
1788/* Verify that the processor is running with DSP instructions enabled.
1789 This is enabled by CP0 Status register MX(24) bit.
1790 */
1791
1792static inline void check_dsp(DisasContext *ctx)
1793{
1794 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1795 if (ctx->insn_flags & ASE_DSP) {
1796 generate_exception(ctx, EXCP_DSPDIS);
1797 } else {
1798 generate_exception(ctx, EXCP_RI);
1799 }
853c3240
JL
1800 }
1801}
1802
1803static inline void check_dspr2(DisasContext *ctx)
1804{
1805 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1806 if (ctx->insn_flags & ASE_DSP) {
1807 generate_exception(ctx, EXCP_DSPDIS);
1808 } else {
1809 generate_exception(ctx, EXCP_RI);
1810 }
853c3240
JL
1811 }
1812}
1813
3a95e3a7 1814/* This code generates a "reserved instruction" exception if the
e189e748 1815 CPU does not support the instruction set corresponding to flags. */
d75c135e 1816static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1817{
d75c135e 1818 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1819 generate_exception(ctx, EXCP_RI);
d75c135e 1820 }
3a95e3a7
TS
1821}
1822
fecd2646
LA
1823/* This code generates a "reserved instruction" exception if the
1824 CPU has corresponding flag set which indicates that the instruction
1825 has been removed. */
1826static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1827{
1828 if (unlikely(ctx->insn_flags & flags)) {
1829 generate_exception(ctx, EXCP_RI);
1830 }
1831}
1832
e29c9628
YK
1833/* This code generates a "reserved instruction" exception if the
1834 CPU does not support 64-bit paired-single (PS) floating point data type */
1835static inline void check_ps(DisasContext *ctx)
1836{
1837 if (unlikely(!ctx->ps)) {
1838 generate_exception(ctx, EXCP_RI);
1839 }
1840 check_cp1_64bitmode(ctx);
1841}
1842
c7986fd6 1843#ifdef TARGET_MIPS64
e189e748
TS
1844/* This code generates a "reserved instruction" exception if 64-bit
1845 instructions are not enabled. */
356265ae 1846static inline void check_mips_64(DisasContext *ctx)
e189e748 1847{
fe253235 1848 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1849 generate_exception(ctx, EXCP_RI);
1850}
c7986fd6 1851#endif
e189e748 1852
5204ea79
LA
1853#ifndef CONFIG_USER_ONLY
1854static inline void check_mvh(DisasContext *ctx)
1855{
1856 if (unlikely(!ctx->mvh)) {
1857 generate_exception(ctx, EXCP_RI);
1858 }
1859}
1860#endif
1861
8153667c
NF
1862/* Define small wrappers for gen_load_fpr* so that we have a uniform
1863 calling interface for 32 and 64-bit FPRs. No sense in changing
1864 all callers for gen_load_fpr32 when we need the CTX parameter for
1865 this one use. */
7c979afd 1866#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1867#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1868#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1869static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1870 int ft, int fs, int cc) \
1871{ \
1872 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1873 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1874 switch (ifmt) { \
1875 case FMT_PS: \
e29c9628 1876 check_ps(ctx); \
8153667c
NF
1877 break; \
1878 case FMT_D: \
1879 if (abs) { \
1880 check_cop1x(ctx); \
1881 } \
1882 check_cp1_registers(ctx, fs | ft); \
1883 break; \
1884 case FMT_S: \
1885 if (abs) { \
1886 check_cop1x(ctx); \
1887 } \
1888 break; \
1889 } \
1890 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1891 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1892 switch (n) { \
895c2d04
BS
1893 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1894 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1895 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1896 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1897 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1898 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1899 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1900 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1901 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1902 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1903 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1904 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1905 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1906 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1907 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1908 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1909 default: abort(); \
1910 } \
1911 tcg_temp_free_i##bits (fp0); \
1912 tcg_temp_free_i##bits (fp1); \
1913}
1914
1915FOP_CONDS(, 0, d, FMT_D, 64)
1916FOP_CONDS(abs, 1, d, FMT_D, 64)
1917FOP_CONDS(, 0, s, FMT_S, 32)
1918FOP_CONDS(abs, 1, s, FMT_S, 32)
1919FOP_CONDS(, 0, ps, FMT_PS, 64)
1920FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1921#undef FOP_CONDS
3f493883
YK
1922
1923#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1924static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1925 int ft, int fs, int fd) \
1926{ \
1927 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1928 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1929 if (ifmt == FMT_D) { \
3f493883 1930 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1931 } \
1932 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1933 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1934 switch (n) { \
1935 case 0: \
1936 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1937 break; \
1938 case 1: \
1939 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1940 break; \
1941 case 2: \
1942 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1943 break; \
1944 case 3: \
1945 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 4: \
1948 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 5: \
1951 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 6: \
1954 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 7: \
1957 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 case 8: \
1960 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1961 break; \
1962 case 9: \
1963 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1964 break; \
1965 case 10: \
1966 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1967 break; \
1968 case 11: \
1969 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1970 break; \
1971 case 12: \
1972 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1973 break; \
1974 case 13: \
1975 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1976 break; \
1977 case 14: \
1978 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1979 break; \
1980 case 15: \
1981 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1982 break; \
1983 case 17: \
1984 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1985 break; \
1986 case 18: \
1987 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1988 break; \
1989 case 19: \
1990 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1991 break; \
1992 case 25: \
1993 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1994 break; \
1995 case 26: \
1996 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1997 break; \
1998 case 27: \
1999 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2000 break; \
2001 default: \
2002 abort(); \
2003 } \
2004 STORE; \
2005 tcg_temp_free_i ## bits (fp0); \
2006 tcg_temp_free_i ## bits (fp1); \
2007}
2008
2009FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2010FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2011#undef FOP_CONDNS
8153667c
NF
2012#undef gen_ldcmp_fpr32
2013#undef gen_ldcmp_fpr64
2014
958fb4a9 2015/* load/store instructions. */
e7139c44 2016#ifdef CONFIG_USER_ONLY
d9bea114 2017#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2018static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
2019{ \
2020 TCGv t0 = tcg_temp_new(); \
2021 tcg_gen_mov_tl(t0, arg1); \
2022 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2023 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2024 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2025 tcg_temp_free(t0); \
aaa9128a 2026}
e7139c44
AJ
2027#else
2028#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2029static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 2030{ \
895c2d04 2031 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
2032}
2033#endif
aaa9128a
TS
2034OP_LD_ATOMIC(ll,ld32s);
2035#if defined(TARGET_MIPS64)
2036OP_LD_ATOMIC(lld,ld64);
2037#endif
2038#undef OP_LD_ATOMIC
2039
590bc601
PB
2040#ifdef CONFIG_USER_ONLY
2041#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2042static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2043{ \
2044 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2045 TCGLabel *l1 = gen_new_label(); \
2046 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2047 \
2048 tcg_gen_andi_tl(t0, arg2, almask); \
2049 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2050 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2051 generate_exception(ctx, EXCP_AdES); \
2052 gen_set_label(l1); \
7db13fae 2053 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2054 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2055 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2056 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2057 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2058 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2059 gen_set_label(l2); \
2060 tcg_gen_movi_tl(t0, 0); \
2061 gen_store_gpr(t0, rt); \
2062 tcg_temp_free(t0); \
2063}
2064#else
2065#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2066static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2067{ \
2068 TCGv t0 = tcg_temp_new(); \
895c2d04 2069 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2070 gen_store_gpr(t0, rt); \
590bc601
PB
2071 tcg_temp_free(t0); \
2072}
2073#endif
590bc601 2074OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2075#if defined(TARGET_MIPS64)
590bc601 2076OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2077#endif
2078#undef OP_ST_ATOMIC
2079
662d7485
NF
2080static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2081 int base, int16_t offset)
2082{
2083 if (base == 0) {
2084 tcg_gen_movi_tl(addr, offset);
2085 } else if (offset == 0) {
2086 gen_load_gpr(addr, base);
2087 } else {
2088 tcg_gen_movi_tl(addr, offset);
2089 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2090 }
2091}
2092
364d4831
NF
2093static target_ulong pc_relative_pc (DisasContext *ctx)
2094{
2095 target_ulong pc = ctx->pc;
2096
2097 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2098 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2099
2100 pc -= branch_bytes;
2101 }
2102
2103 pc &= ~(target_ulong)3;
2104 return pc;
2105}
2106
5c13fdfd 2107/* Load */
d75c135e
AJ
2108static void gen_ld(DisasContext *ctx, uint32_t opc,
2109 int rt, int base, int16_t offset)
6af0bf9c 2110{
fc40787a 2111 TCGv t0, t1, t2;
afa88c3a 2112
d75c135e 2113 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2114 /* Loongson CPU uses a load to zero register for prefetch.
2115 We emulate it as a NOP. On other CPU we must perform the
2116 actual memory access. */
afa88c3a
AJ
2117 return;
2118 }
6af0bf9c 2119
afa88c3a 2120 t0 = tcg_temp_new();
662d7485 2121 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2122
6af0bf9c 2123 switch (opc) {
d26bc211 2124#if defined(TARGET_MIPS64)
6e473128 2125 case OPC_LWU:
be3a8c53
YK
2126 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2127 ctx->default_tcg_memop_mask);
78723684 2128 gen_store_gpr(t0, rt);
6e473128 2129 break;
6af0bf9c 2130 case OPC_LD:
be3a8c53
YK
2131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2132 ctx->default_tcg_memop_mask);
78723684 2133 gen_store_gpr(t0, rt);
6af0bf9c 2134 break;
7a387fff 2135 case OPC_LLD:
bf7910c6 2136 case R6_OPC_LLD:
b835e919 2137 save_cpu_state(ctx, 1);
5c13fdfd 2138 op_ld_lld(t0, t0, ctx);
78723684 2139 gen_store_gpr(t0, rt);
7a387fff 2140 break;
6af0bf9c 2141 case OPC_LDL:
3cee3050 2142 t1 = tcg_temp_new();
908680c6
AJ
2143 /* Do a byte access to possibly trigger a page
2144 fault with the unaligned address. */
2145 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2146 tcg_gen_andi_tl(t1, t0, 7);
2147#ifndef TARGET_WORDS_BIGENDIAN
2148 tcg_gen_xori_tl(t1, t1, 7);
2149#endif
2150 tcg_gen_shli_tl(t1, t1, 3);
2151 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2152 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a 2153 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2154 t2 = tcg_const_tl(-1);
2155 tcg_gen_shl_tl(t2, t2, t1);
78723684 2156 gen_load_gpr(t1, rt);
eb02cc3f 2157 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2158 tcg_temp_free(t2);
2159 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2160 tcg_temp_free(t1);
fc40787a 2161 gen_store_gpr(t0, rt);
6af0bf9c 2162 break;
6af0bf9c 2163 case OPC_LDR:
3cee3050 2164 t1 = tcg_temp_new();
908680c6
AJ
2165 /* Do a byte access to possibly trigger a page
2166 fault with the unaligned address. */
2167 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2168 tcg_gen_andi_tl(t1, t0, 7);
2169#ifdef TARGET_WORDS_BIGENDIAN
2170 tcg_gen_xori_tl(t1, t1, 7);
2171#endif
2172 tcg_gen_shli_tl(t1, t1, 3);
2173 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2174 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2175 tcg_gen_shr_tl(t0, t0, t1);
2176 tcg_gen_xori_tl(t1, t1, 63);
2177 t2 = tcg_const_tl(0xfffffffffffffffeull);
2178 tcg_gen_shl_tl(t2, t2, t1);
78723684 2179 gen_load_gpr(t1, rt);
fc40787a
AJ
2180 tcg_gen_and_tl(t1, t1, t2);
2181 tcg_temp_free(t2);
2182 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2183 tcg_temp_free(t1);
fc40787a 2184 gen_store_gpr(t0, rt);
6af0bf9c 2185 break;
364d4831 2186 case OPC_LDPC:
3cee3050 2187 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2188 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2189 tcg_temp_free(t1);
5f68f5ae 2190 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831
NF
2191 gen_store_gpr(t0, rt);
2192 break;
6af0bf9c 2193#endif
364d4831 2194 case OPC_LWPC:
3cee3050 2195 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2196 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2197 tcg_temp_free(t1);
5f68f5ae 2198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831
NF
2199 gen_store_gpr(t0, rt);
2200 break;
6af0bf9c 2201 case OPC_LW:
be3a8c53
YK
2202 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2203 ctx->default_tcg_memop_mask);
78723684 2204 gen_store_gpr(t0, rt);
6af0bf9c 2205 break;
6af0bf9c 2206 case OPC_LH:
be3a8c53
YK
2207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2208 ctx->default_tcg_memop_mask);
78723684 2209 gen_store_gpr(t0, rt);
6af0bf9c 2210 break;
6af0bf9c 2211 case OPC_LHU:
be3a8c53
YK
2212 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2213 ctx->default_tcg_memop_mask);
78723684 2214 gen_store_gpr(t0, rt);
6af0bf9c
FB
2215 break;
2216 case OPC_LB:
5f68f5ae 2217 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2218 gen_store_gpr(t0, rt);
6af0bf9c 2219 break;
6af0bf9c 2220 case OPC_LBU:
5f68f5ae 2221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2222 gen_store_gpr(t0, rt);
6af0bf9c
FB
2223 break;
2224 case OPC_LWL:
3cee3050 2225 t1 = tcg_temp_new();
908680c6
AJ
2226 /* Do a byte access to possibly trigger a page
2227 fault with the unaligned address. */
2228 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2229 tcg_gen_andi_tl(t1, t0, 3);
2230#ifndef TARGET_WORDS_BIGENDIAN
2231 tcg_gen_xori_tl(t1, t1, 3);
2232#endif
2233 tcg_gen_shli_tl(t1, t1, 3);
2234 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2235 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a 2236 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2237 t2 = tcg_const_tl(-1);
2238 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2239 gen_load_gpr(t1, rt);
eb02cc3f 2240 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2241 tcg_temp_free(t2);
2242 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2243 tcg_temp_free(t1);
fc40787a
AJ
2244 tcg_gen_ext32s_tl(t0, t0);
2245 gen_store_gpr(t0, rt);
6af0bf9c 2246 break;
6af0bf9c 2247 case OPC_LWR:
3cee3050 2248 t1 = tcg_temp_new();
908680c6
AJ
2249 /* Do a byte access to possibly trigger a page
2250 fault with the unaligned address. */
2251 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2252 tcg_gen_andi_tl(t1, t0, 3);
2253#ifdef TARGET_WORDS_BIGENDIAN
2254 tcg_gen_xori_tl(t1, t1, 3);
2255#endif
2256 tcg_gen_shli_tl(t1, t1, 3);
2257 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2258 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2259 tcg_gen_shr_tl(t0, t0, t1);
2260 tcg_gen_xori_tl(t1, t1, 31);
2261 t2 = tcg_const_tl(0xfffffffeull);
2262 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2263 gen_load_gpr(t1, rt);
fc40787a
AJ
2264 tcg_gen_and_tl(t1, t1, t2);
2265 tcg_temp_free(t2);
2266 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2267 tcg_temp_free(t1);
c728154b 2268 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2269 gen_store_gpr(t0, rt);
6af0bf9c 2270 break;
6af0bf9c 2271 case OPC_LL:
4368b29a 2272 case R6_OPC_LL:
e7139c44 2273 save_cpu_state(ctx, 1);
5c13fdfd 2274 op_ld_ll(t0, t0, ctx);
78723684 2275 gen_store_gpr(t0, rt);
6af0bf9c 2276 break;
d66c7132 2277 }
d66c7132 2278 tcg_temp_free(t0);
d66c7132
AJ
2279}
2280
5c13fdfd
AJ
2281/* Store */
2282static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2283 int base, int16_t offset)
2284{
5c13fdfd
AJ
2285 TCGv t0 = tcg_temp_new();
2286 TCGv t1 = tcg_temp_new();
2287
2288 gen_base_offset_addr(ctx, t0, base, offset);
2289 gen_load_gpr(t1, rt);
2290 switch (opc) {
2291#if defined(TARGET_MIPS64)
2292 case OPC_SD:
be3a8c53
YK
2293 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2294 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2295 break;
2296 case OPC_SDL:
2297 save_cpu_state(ctx, 1);
895c2d04 2298 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2299 break;
2300 case OPC_SDR:
2301 save_cpu_state(ctx, 1);
895c2d04 2302 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2303 break;
2304#endif
2305 case OPC_SW:
be3a8c53
YK
2306 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2307 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2308 break;
2309 case OPC_SH:
be3a8c53
YK
2310 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2311 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2312 break;
2313 case OPC_SB:
5f68f5ae 2314 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2315 break;
2316 case OPC_SWL:
2317 save_cpu_state(ctx, 1);
895c2d04 2318 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2319 break;
2320 case OPC_SWR:
2321 save_cpu_state(ctx, 1);
895c2d04 2322 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2323 break;
2324 }
5c13fdfd
AJ
2325 tcg_temp_free(t0);
2326 tcg_temp_free(t1);
2327}
2328
2329
d66c7132
AJ
2330/* Store conditional */
2331static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2332 int base, int16_t offset)
2333{
d66c7132
AJ
2334 TCGv t0, t1;
2335
2d2826b9 2336#ifdef CONFIG_USER_ONLY
d66c7132 2337 t0 = tcg_temp_local_new();
d66c7132 2338 t1 = tcg_temp_local_new();
2d2826b9
AJ
2339#else
2340 t0 = tcg_temp_new();
2341 t1 = tcg_temp_new();
2342#endif
2343 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2344 gen_load_gpr(t1, rt);
2345 switch (opc) {
2346#if defined(TARGET_MIPS64)
2347 case OPC_SCD:
bf7910c6 2348 case R6_OPC_SCD:
b835e919 2349 save_cpu_state(ctx, 1);
5c13fdfd 2350 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2351 break;
2352#endif
6af0bf9c 2353 case OPC_SC:
4368b29a 2354 case R6_OPC_SC:
e7139c44 2355 save_cpu_state(ctx, 1);
5c13fdfd 2356 op_st_sc(t1, t0, rt, ctx);
6af0bf9c 2357 break;
6af0bf9c 2358 }
78723684 2359 tcg_temp_free(t1);
d66c7132 2360 tcg_temp_free(t0);
6af0bf9c
FB
2361}
2362
6ea83fed 2363/* Load and store */
7a387fff 2364static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2365 int base, int16_t offset)
6ea83fed 2366{
4e2474d6 2367 TCGv t0 = tcg_temp_new();
6ea83fed 2368
662d7485 2369 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2370 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2371 memory access. */
6ea83fed
FB
2372 switch (opc) {
2373 case OPC_LWC1:
b6d96bed 2374 {
a7812ae4 2375 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2376 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2377 ctx->default_tcg_memop_mask);
7c979afd 2378 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2379 tcg_temp_free_i32(fp0);
b6d96bed 2380 }
6ea83fed
FB
2381 break;
2382 case OPC_SWC1:
b6d96bed 2383 {
a7812ae4 2384 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2385 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2386 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2387 ctx->default_tcg_memop_mask);
a7812ae4 2388 tcg_temp_free_i32(fp0);
b6d96bed 2389 }
6ea83fed
FB
2390 break;
2391 case OPC_LDC1:
b6d96bed 2392 {
a7812ae4 2393 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2394 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2395 ctx->default_tcg_memop_mask);
b6d96bed 2396 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2397 tcg_temp_free_i64(fp0);
b6d96bed 2398 }
6ea83fed
FB
2399 break;
2400 case OPC_SDC1:
b6d96bed 2401 {
a7812ae4 2402 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2403 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2404 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2405 ctx->default_tcg_memop_mask);
a7812ae4 2406 tcg_temp_free_i64(fp0);
b6d96bed 2407 }
6ea83fed
FB
2408 break;
2409 default:
9d68ac14 2410 MIPS_INVAL("flt_ldst");
e397ee33 2411 generate_exception(ctx, EXCP_RI);
78723684 2412 goto out;
6ea83fed 2413 }
78723684
TS
2414 out:
2415 tcg_temp_free(t0);
6ea83fed 2416}
6ea83fed 2417
5ab5c041
AJ
2418static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2419 int rs, int16_t imm)
26ebe468 2420{
5ab5c041 2421 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2422 check_cp1_enabled(ctx);
d9224450
MR
2423 switch (op) {
2424 case OPC_LDC1:
2425 case OPC_SDC1:
2426 check_insn(ctx, ISA_MIPS2);
2427 /* Fallthrough */
2428 default:
2429 gen_flt_ldst(ctx, op, rt, rs, imm);
2430 }
26ebe468
NF
2431 } else {
2432 generate_exception_err(ctx, EXCP_CpU, 1);
2433 }
2434}
2435
6af0bf9c 2436/* Arithmetic with immediate operand */
d75c135e
AJ
2437static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2438 int rt, int rs, int16_t imm)
6af0bf9c 2439{
324d9e32 2440 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2441
7a387fff 2442 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2443 /* If no destination, treat it as a NOP.
2444 For addi, we must generate the overflow exception when needed. */
324d9e32 2445 return;
6af0bf9c
FB
2446 }
2447 switch (opc) {
2448 case OPC_ADDI:
48d38ca5 2449 {
324d9e32
AJ
2450 TCGv t0 = tcg_temp_local_new();
2451 TCGv t1 = tcg_temp_new();
2452 TCGv t2 = tcg_temp_new();
42a268c2 2453 TCGLabel *l1 = gen_new_label();
48d38ca5 2454
324d9e32
AJ
2455 gen_load_gpr(t1, rs);
2456 tcg_gen_addi_tl(t0, t1, uimm);
2457 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2458
324d9e32
AJ
2459 tcg_gen_xori_tl(t1, t1, ~uimm);
2460 tcg_gen_xori_tl(t2, t0, uimm);
2461 tcg_gen_and_tl(t1, t1, t2);
2462 tcg_temp_free(t2);
2463 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2464 tcg_temp_free(t1);
48d38ca5
TS
2465 /* operands of same sign, result different sign */
2466 generate_exception(ctx, EXCP_OVERFLOW);
2467 gen_set_label(l1);
78723684 2468 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2469 gen_store_gpr(t0, rt);
2470 tcg_temp_free(t0);
48d38ca5 2471 }
6af0bf9c
FB
2472 break;
2473 case OPC_ADDIU:
324d9e32
AJ
2474 if (rs != 0) {
2475 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2476 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2477 } else {
2478 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2479 }
6af0bf9c 2480 break;
d26bc211 2481#if defined(TARGET_MIPS64)
7a387fff 2482 case OPC_DADDI:
48d38ca5 2483 {
324d9e32
AJ
2484 TCGv t0 = tcg_temp_local_new();
2485 TCGv t1 = tcg_temp_new();
2486 TCGv t2 = tcg_temp_new();
42a268c2 2487 TCGLabel *l1 = gen_new_label();
48d38ca5 2488
324d9e32
AJ
2489 gen_load_gpr(t1, rs);
2490 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2491
324d9e32
AJ
2492 tcg_gen_xori_tl(t1, t1, ~uimm);
2493 tcg_gen_xori_tl(t2, t0, uimm);
2494 tcg_gen_and_tl(t1, t1, t2);
2495 tcg_temp_free(t2);
2496 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2497 tcg_temp_free(t1);
48d38ca5
TS
2498 /* operands of same sign, result different sign */
2499 generate_exception(ctx, EXCP_OVERFLOW);
2500 gen_set_label(l1);
324d9e32
AJ
2501 gen_store_gpr(t0, rt);
2502 tcg_temp_free(t0);
48d38ca5 2503 }
7a387fff
TS
2504 break;
2505 case OPC_DADDIU:
324d9e32
AJ
2506 if (rs != 0) {
2507 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2508 } else {
2509 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2510 }
7a387fff
TS
2511 break;
2512#endif
324d9e32 2513 }
324d9e32
AJ
2514}
2515
2516/* Logic with immediate operand */
d75c135e 2517static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2518 int rt, int rs, int16_t imm)
324d9e32
AJ
2519{
2520 target_ulong uimm;
324d9e32
AJ
2521
2522 if (rt == 0) {
2523 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2524 return;
2525 }
2526 uimm = (uint16_t)imm;
2527 switch (opc) {
6af0bf9c 2528 case OPC_ANDI:
324d9e32
AJ
2529 if (likely(rs != 0))
2530 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2531 else
2532 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2533 break;
2534 case OPC_ORI:
324d9e32
AJ
2535 if (rs != 0)
2536 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2537 else
2538 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2539 break;
2540 case OPC_XORI:
324d9e32
AJ
2541 if (likely(rs != 0))
2542 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2543 else
2544 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2545 break;
2546 case OPC_LUI:
d4ea6acd
LA
2547 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2548 /* OPC_AUI */
2549 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2550 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2551 } else {
2552 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2553 }
7c2c3ea3
EJ
2554 break;
2555
2556 default:
6af0bf9c 2557 break;
324d9e32 2558 }
324d9e32
AJ
2559}
2560
2561/* Set on less than with immediate operand */
d75c135e 2562static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2563 int rt, int rs, int16_t imm)
324d9e32
AJ
2564{
2565 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2566 TCGv t0;
2567
2568 if (rt == 0) {
2569 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2570 return;
2571 }
2572 t0 = tcg_temp_new();
2573 gen_load_gpr(t0, rs);
2574 switch (opc) {
2575 case OPC_SLTI:
e68dd28f 2576 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2577 break;
2578 case OPC_SLTIU:
e68dd28f 2579 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2580 break;
2581 }
324d9e32
AJ
2582 tcg_temp_free(t0);
2583}
2584
2585/* Shifts with immediate operand */
d75c135e 2586static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2587 int rt, int rs, int16_t imm)
2588{
2589 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2590 TCGv t0;
2591
2592 if (rt == 0) {
2593 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2594 return;
2595 }
2596
2597 t0 = tcg_temp_new();
2598 gen_load_gpr(t0, rs);
2599 switch (opc) {
6af0bf9c 2600 case OPC_SLL:
78723684 2601 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2602 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2603 break;
2604 case OPC_SRA:
324d9e32 2605 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2606 break;
2607 case OPC_SRL:
ea63e2c3
NF
2608 if (uimm != 0) {
2609 tcg_gen_ext32u_tl(t0, t0);
2610 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2611 } else {
2612 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2613 }
ea63e2c3
NF
2614 break;
2615 case OPC_ROTR:
2616 if (uimm != 0) {
2617 TCGv_i32 t1 = tcg_temp_new_i32();
2618
2619 tcg_gen_trunc_tl_i32(t1, t0);
2620 tcg_gen_rotri_i32(t1, t1, uimm);
2621 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2622 tcg_temp_free_i32(t1);
3399e30f
NF
2623 } else {
2624 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2625 }
7a387fff 2626 break;
d26bc211 2627#if defined(TARGET_MIPS64)
7a387fff 2628 case OPC_DSLL:
324d9e32 2629 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2630 break;
2631 case OPC_DSRA:
324d9e32 2632 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2633 break;
2634 case OPC_DSRL:
ea63e2c3 2635 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2636 break;
2637 case OPC_DROTR:
2638 if (uimm != 0) {
2639 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2640 } else {
2641 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2642 }
7a387fff
TS
2643 break;
2644 case OPC_DSLL32:
324d9e32 2645 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2646 break;
2647 case OPC_DSRA32:
324d9e32 2648 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2649 break;
2650 case OPC_DSRL32:
ea63e2c3 2651 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2652 break;
2653 case OPC_DROTR32:
2654 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2655 break;
7a387fff 2656#endif
6af0bf9c 2657 }
78723684 2658 tcg_temp_free(t0);
6af0bf9c
FB
2659}
2660
2661/* Arithmetic */
d75c135e
AJ
2662static void gen_arith(DisasContext *ctx, uint32_t opc,
2663 int rd, int rs, int rt)
6af0bf9c 2664{
7a387fff
TS
2665 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2666 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2667 /* If no destination, treat it as a NOP.
2668 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2669 return;
185f0762 2670 }
460f00c4 2671
6af0bf9c
FB
2672 switch (opc) {
2673 case OPC_ADD:
48d38ca5 2674 {
460f00c4
AJ
2675 TCGv t0 = tcg_temp_local_new();
2676 TCGv t1 = tcg_temp_new();
2677 TCGv t2 = tcg_temp_new();
42a268c2 2678 TCGLabel *l1 = gen_new_label();
48d38ca5 2679
460f00c4
AJ
2680 gen_load_gpr(t1, rs);
2681 gen_load_gpr(t2, rt);
2682 tcg_gen_add_tl(t0, t1, t2);
2683 tcg_gen_ext32s_tl(t0, t0);
2684 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2685 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2686 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2687 tcg_temp_free(t2);
2688 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2689 tcg_temp_free(t1);
48d38ca5
TS
2690 /* operands of same sign, result different sign */
2691 generate_exception(ctx, EXCP_OVERFLOW);
2692 gen_set_label(l1);
460f00c4
AJ
2693 gen_store_gpr(t0, rd);
2694 tcg_temp_free(t0);
48d38ca5 2695 }
6af0bf9c
FB
2696 break;
2697 case OPC_ADDU:
460f00c4
AJ
2698 if (rs != 0 && rt != 0) {
2699 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2700 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2701 } else if (rs == 0 && rt != 0) {
2702 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2703 } else if (rs != 0 && rt == 0) {
2704 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2705 } else {
2706 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2707 }
6af0bf9c
FB
2708 break;
2709 case OPC_SUB:
48d38ca5 2710 {
460f00c4
AJ
2711 TCGv t0 = tcg_temp_local_new();
2712 TCGv t1 = tcg_temp_new();
2713 TCGv t2 = tcg_temp_new();
42a268c2 2714 TCGLabel *l1 = gen_new_label();
48d38ca5 2715
460f00c4
AJ
2716 gen_load_gpr(t1, rs);
2717 gen_load_gpr(t2, rt);
2718 tcg_gen_sub_tl(t0, t1, t2);
2719 tcg_gen_ext32s_tl(t0, t0);
2720 tcg_gen_xor_tl(t2, t1, t2);
2721 tcg_gen_xor_tl(t1, t0, t1);
2722 tcg_gen_and_tl(t1, t1, t2);
2723 tcg_temp_free(t2);
2724 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2725 tcg_temp_free(t1);
31e3104f 2726 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2727 generate_exception(ctx, EXCP_OVERFLOW);
2728 gen_set_label(l1);
460f00c4
AJ
2729 gen_store_gpr(t0, rd);
2730 tcg_temp_free(t0);
48d38ca5 2731 }
6af0bf9c
FB
2732 break;
2733 case OPC_SUBU:
460f00c4
AJ
2734 if (rs != 0 && rt != 0) {
2735 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2736 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2737 } else if (rs == 0 && rt != 0) {
2738 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2739 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2740 } else if (rs != 0 && rt == 0) {
2741 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2742 } else {
2743 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2744 }
6af0bf9c 2745 break;
d26bc211 2746#if defined(TARGET_MIPS64)
7a387fff 2747 case OPC_DADD:
48d38ca5 2748 {
460f00c4
AJ
2749 TCGv t0 = tcg_temp_local_new();
2750 TCGv t1 = tcg_temp_new();
2751 TCGv t2 = tcg_temp_new();
42a268c2 2752 TCGLabel *l1 = gen_new_label();
48d38ca5 2753
460f00c4
AJ
2754 gen_load_gpr(t1, rs);
2755 gen_load_gpr(t2, rt);
2756 tcg_gen_add_tl(t0, t1, t2);
2757 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2758 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2759 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2760 tcg_temp_free(t2);
2761 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2762 tcg_temp_free(t1);
48d38ca5
TS
2763 /* operands of same sign, result different sign */
2764 generate_exception(ctx, EXCP_OVERFLOW);
2765 gen_set_label(l1);
460f00c4
AJ
2766 gen_store_gpr(t0, rd);
2767 tcg_temp_free(t0);
48d38ca5 2768 }
7a387fff
TS
2769 break;
2770 case OPC_DADDU:
460f00c4
AJ
2771 if (rs != 0 && rt != 0) {
2772 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2773 } else if (rs == 0 && rt != 0) {
2774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2775 } else if (rs != 0 && rt == 0) {
2776 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2777 } else {
2778 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2779 }
7a387fff
TS
2780 break;
2781 case OPC_DSUB:
48d38ca5 2782 {
460f00c4
AJ
2783 TCGv t0 = tcg_temp_local_new();
2784 TCGv t1 = tcg_temp_new();
2785 TCGv t2 = tcg_temp_new();
42a268c2 2786 TCGLabel *l1 = gen_new_label();
48d38ca5 2787
460f00c4
AJ
2788 gen_load_gpr(t1, rs);
2789 gen_load_gpr(t2, rt);
2790 tcg_gen_sub_tl(t0, t1, t2);
2791 tcg_gen_xor_tl(t2, t1, t2);
2792 tcg_gen_xor_tl(t1, t0, t1);
2793 tcg_gen_and_tl(t1, t1, t2);
2794 tcg_temp_free(t2);
2795 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2796 tcg_temp_free(t1);
31e3104f 2797 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2798 generate_exception(ctx, EXCP_OVERFLOW);
2799 gen_set_label(l1);
460f00c4
AJ
2800 gen_store_gpr(t0, rd);
2801 tcg_temp_free(t0);
48d38ca5 2802 }
7a387fff
TS
2803 break;
2804 case OPC_DSUBU:
460f00c4
AJ
2805 if (rs != 0 && rt != 0) {
2806 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2807 } else if (rs == 0 && rt != 0) {
2808 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2809 } else if (rs != 0 && rt == 0) {
2810 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2811 } else {
2812 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2813 }
7a387fff
TS
2814 break;
2815#endif
460f00c4
AJ
2816 case OPC_MUL:
2817 if (likely(rs != 0 && rt != 0)) {
2818 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2819 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2820 } else {
2821 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2822 }
6af0bf9c 2823 break;
460f00c4 2824 }
460f00c4
AJ
2825}
2826
2827/* Conditional move */
d75c135e 2828static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2829 int rd, int rs, int rt)
460f00c4 2830{
acf12465 2831 TCGv t0, t1, t2;
460f00c4
AJ
2832
2833 if (rd == 0) {
acf12465 2834 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2835 return;
2836 }
2837
acf12465
AJ
2838 t0 = tcg_temp_new();
2839 gen_load_gpr(t0, rt);
2840 t1 = tcg_const_tl(0);
2841 t2 = tcg_temp_new();
2842 gen_load_gpr(t2, rs);
460f00c4
AJ
2843 switch (opc) {
2844 case OPC_MOVN:
acf12465 2845 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2846 break;
460f00c4 2847 case OPC_MOVZ:
acf12465 2848 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2849 break;
b691d9d2
LA
2850 case OPC_SELNEZ:
2851 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2852 break;
2853 case OPC_SELEQZ:
2854 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2855 break;
460f00c4 2856 }
acf12465
AJ
2857 tcg_temp_free(t2);
2858 tcg_temp_free(t1);
2859 tcg_temp_free(t0);
460f00c4
AJ
2860}
2861
2862/* Logic */
d75c135e 2863static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2864 int rd, int rs, int rt)
460f00c4 2865{
460f00c4
AJ
2866 if (rd == 0) {
2867 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2868 return;
2869 }
2870
2871 switch (opc) {
6af0bf9c 2872 case OPC_AND:
460f00c4
AJ
2873 if (likely(rs != 0 && rt != 0)) {
2874 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2875 } else {
2876 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2877 }
6af0bf9c
FB
2878 break;
2879 case OPC_NOR:
460f00c4
AJ
2880 if (rs != 0 && rt != 0) {
2881 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2882 } else if (rs == 0 && rt != 0) {
2883 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2884 } else if (rs != 0 && rt == 0) {
2885 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2886 } else {
2887 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2888 }
6af0bf9c
FB
2889 break;
2890 case OPC_OR:
460f00c4
AJ
2891 if (likely(rs != 0 && rt != 0)) {
2892 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2893 } else if (rs == 0 && rt != 0) {
2894 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2895 } else if (rs != 0 && rt == 0) {
2896 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2897 } else {
2898 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2899 }
6af0bf9c
FB
2900 break;
2901 case OPC_XOR:
460f00c4
AJ
2902 if (likely(rs != 0 && rt != 0)) {
2903 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2904 } else if (rs == 0 && rt != 0) {
2905 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2906 } else if (rs != 0 && rt == 0) {
2907 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2908 } else {
2909 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2910 }
6af0bf9c 2911 break;
460f00c4 2912 }
460f00c4
AJ
2913}
2914
2915/* Set on lower than */
d75c135e 2916static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2917 int rd, int rs, int rt)
460f00c4 2918{
460f00c4
AJ
2919 TCGv t0, t1;
2920
2921 if (rd == 0) {
2922 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2923 return;
2924 }
2925
2926 t0 = tcg_temp_new();
2927 t1 = tcg_temp_new();
2928 gen_load_gpr(t0, rs);
2929 gen_load_gpr(t1, rt);
2930 switch (opc) {
2931 case OPC_SLT:
e68dd28f 2932 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2933 break;
460f00c4 2934 case OPC_SLTU:
e68dd28f 2935 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2936 break;
2937 }
460f00c4
AJ
2938 tcg_temp_free(t0);
2939 tcg_temp_free(t1);
2940}
20c4c97c 2941
460f00c4 2942/* Shifts */
d75c135e
AJ
2943static void gen_shift(DisasContext *ctx, uint32_t opc,
2944 int rd, int rs, int rt)
460f00c4 2945{
460f00c4 2946 TCGv t0, t1;
20c4c97c 2947
460f00c4
AJ
2948 if (rd == 0) {
2949 /* If no destination, treat it as a NOP.
2950 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
2951 return;
2952 }
2953
2954 t0 = tcg_temp_new();
2955 t1 = tcg_temp_new();
2956 gen_load_gpr(t0, rs);
2957 gen_load_gpr(t1, rt);
2958 switch (opc) {
6af0bf9c 2959 case OPC_SLLV:
78723684
TS
2960 tcg_gen_andi_tl(t0, t0, 0x1f);
2961 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2962 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2963 break;
2964 case OPC_SRAV:
78723684 2965 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2966 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2967 break;
2968 case OPC_SRLV:
ea63e2c3
NF
2969 tcg_gen_ext32u_tl(t1, t1);
2970 tcg_gen_andi_tl(t0, t0, 0x1f);
2971 tcg_gen_shr_tl(t0, t1, t0);
2972 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2973 break;
2974 case OPC_ROTRV:
2975 {
2976 TCGv_i32 t2 = tcg_temp_new_i32();
2977 TCGv_i32 t3 = tcg_temp_new_i32();
2978
2979 tcg_gen_trunc_tl_i32(t2, t0);
2980 tcg_gen_trunc_tl_i32(t3, t1);
2981 tcg_gen_andi_i32(t2, t2, 0x1f);
2982 tcg_gen_rotr_i32(t2, t3, t2);
2983 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2984 tcg_temp_free_i32(t2);
2985 tcg_temp_free_i32(t3);
5a63bcb2 2986 }
7a387fff 2987 break;
d26bc211 2988#if defined(TARGET_MIPS64)
7a387fff 2989 case OPC_DSLLV:
78723684 2990 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2991 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2992 break;
2993 case OPC_DSRAV:
78723684 2994 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2995 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2996 break;
2997 case OPC_DSRLV:
ea63e2c3
NF
2998 tcg_gen_andi_tl(t0, t0, 0x3f);
2999 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3000 break;
3001 case OPC_DROTRV:
3002 tcg_gen_andi_tl(t0, t0, 0x3f);
3003 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3004 break;
7a387fff 3005#endif
6af0bf9c 3006 }
78723684
TS
3007 tcg_temp_free(t0);
3008 tcg_temp_free(t1);
6af0bf9c
FB
3009}
3010
3011/* Arithmetic on HI/LO registers */
26135ead 3012static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3013{
6af0bf9c 3014 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3015 /* Treat as NOP. */
a1f6684d 3016 return;
6af0bf9c 3017 }
4133498f 3018
4133498f
JL
3019 if (acc != 0) {
3020 check_dsp(ctx);
3021 }
3022
6af0bf9c
FB
3023 switch (opc) {
3024 case OPC_MFHI:
4133498f
JL
3025#if defined(TARGET_MIPS64)
3026 if (acc != 0) {
3027 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3028 } else
3029#endif
3030 {
3031 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3032 }
6af0bf9c
FB
3033 break;
3034 case OPC_MFLO:
4133498f
JL
3035#if defined(TARGET_MIPS64)
3036 if (acc != 0) {
3037 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3038 } else
3039#endif
3040 {
3041 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3042 }
6af0bf9c
FB
3043 break;
3044 case OPC_MTHI:
4133498f
JL
3045 if (reg != 0) {
3046#if defined(TARGET_MIPS64)
3047 if (acc != 0) {
3048 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3049 } else
3050#endif
3051 {
3052 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3053 }
3054 } else {
3055 tcg_gen_movi_tl(cpu_HI[acc], 0);
3056 }
6af0bf9c
FB
3057 break;
3058 case OPC_MTLO:
4133498f
JL
3059 if (reg != 0) {
3060#if defined(TARGET_MIPS64)
3061 if (acc != 0) {
3062 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3063 } else
3064#endif
3065 {
3066 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3067 }
3068 } else {
3069 tcg_gen_movi_tl(cpu_LO[acc], 0);
3070 }
6af0bf9c 3071 break;
6af0bf9c 3072 }
6af0bf9c
FB
3073}
3074
d4ea6acd
LA
3075static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3076 TCGMemOp memop)
3077{
3078 TCGv t0 = tcg_const_tl(addr);
3079 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3080 gen_store_gpr(t0, reg);
3081 tcg_temp_free(t0);
3082}
3083
ab39ee45
YK
3084static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3085 int rs)
d4ea6acd
LA
3086{
3087 target_long offset;
3088 target_long addr;
3089
ab39ee45 3090 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3091 case OPC_ADDIUPC:
3092 if (rs != 0) {
3093 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3094 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3095 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3096 }
3097 break;
3098 case R6_OPC_LWPC:
3099 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3100 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3101 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3102 break;
3103#if defined(TARGET_MIPS64)
3104 case OPC_LWUPC:
3105 check_mips_64(ctx);
3106 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3107 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3108 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3109 break;
3110#endif
3111 default:
ab39ee45 3112 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3113 case OPC_AUIPC:
3114 if (rs != 0) {
ab39ee45
YK
3115 offset = sextract32(ctx->opcode, 0, 16) << 16;
3116 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3117 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3118 }
3119 break;
3120 case OPC_ALUIPC:
3121 if (rs != 0) {
ab39ee45
YK
3122 offset = sextract32(ctx->opcode, 0, 16) << 16;
3123 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3124 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3125 }
3126 break;
3127#if defined(TARGET_MIPS64)
3128 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3129 case R6_OPC_LDPC + (1 << 16):
3130 case R6_OPC_LDPC + (2 << 16):
3131 case R6_OPC_LDPC + (3 << 16):
3132 check_mips_64(ctx);
3133 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3134 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3135 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3136 break;
3137#endif
3138 default:
3139 MIPS_INVAL("OPC_PCREL");
3140 generate_exception(ctx, EXCP_RI);
3141 break;
3142 }
3143 break;
3144 }
3145}
3146
b42ee5e1
LA
3147static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3148{
b42ee5e1
LA
3149 TCGv t0, t1;
3150
3151 if (rd == 0) {
3152 /* Treat as NOP. */
b42ee5e1
LA
3153 return;
3154 }
3155
3156 t0 = tcg_temp_new();
3157 t1 = tcg_temp_new();
3158
3159 gen_load_gpr(t0, rs);
3160 gen_load_gpr(t1, rt);
3161
3162 switch (opc) {
3163 case R6_OPC_DIV:
3164 {
3165 TCGv t2 = tcg_temp_new();
3166 TCGv t3 = tcg_temp_new();
3167 tcg_gen_ext32s_tl(t0, t0);
3168 tcg_gen_ext32s_tl(t1, t1);
3169 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3170 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3171 tcg_gen_and_tl(t2, t2, t3);
3172 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3173 tcg_gen_or_tl(t2, t2, t3);
3174 tcg_gen_movi_tl(t3, 0);
3175 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3176 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3177 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3178 tcg_temp_free(t3);
3179 tcg_temp_free(t2);
3180 }
b42ee5e1
LA
3181 break;
3182 case R6_OPC_MOD:
3183 {
3184 TCGv t2 = tcg_temp_new();
3185 TCGv t3 = tcg_temp_new();
3186 tcg_gen_ext32s_tl(t0, t0);
3187 tcg_gen_ext32s_tl(t1, t1);
3188 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3189 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3190 tcg_gen_and_tl(t2, t2, t3);
3191 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3192 tcg_gen_or_tl(t2, t2, t3);
3193 tcg_gen_movi_tl(t3, 0);
3194 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3195 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3196 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3197 tcg_temp_free(t3);
3198 tcg_temp_free(t2);
3199 }
b42ee5e1
LA
3200 break;
3201 case R6_OPC_DIVU:
3202 {
3203 TCGv t2 = tcg_const_tl(0);
3204 TCGv t3 = tcg_const_tl(1);
3205 tcg_gen_ext32u_tl(t0, t0);
3206 tcg_gen_ext32u_tl(t1, t1);
3207 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3208 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3209 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3210 tcg_temp_free(t3);
3211 tcg_temp_free(t2);
3212 }
b42ee5e1
LA
3213 break;
3214 case R6_OPC_MODU:
3215 {
3216 TCGv t2 = tcg_const_tl(0);
3217 TCGv t3 = tcg_const_tl(1);
3218 tcg_gen_ext32u_tl(t0, t0);
3219 tcg_gen_ext32u_tl(t1, t1);
3220 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3221 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3222 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3223 tcg_temp_free(t3);
3224 tcg_temp_free(t2);
3225 }
b42ee5e1
LA
3226 break;
3227 case R6_OPC_MUL:
3228 {
3229 TCGv_i32 t2 = tcg_temp_new_i32();
3230 TCGv_i32 t3 = tcg_temp_new_i32();
3231 tcg_gen_trunc_tl_i32(t2, t0);
3232 tcg_gen_trunc_tl_i32(t3, t1);
3233 tcg_gen_mul_i32(t2, t2, t3);
3234 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3235 tcg_temp_free_i32(t2);
3236 tcg_temp_free_i32(t3);
3237 }
b42ee5e1
LA
3238 break;
3239 case R6_OPC_MUH:
3240 {
3241 TCGv_i32 t2 = tcg_temp_new_i32();
3242 TCGv_i32 t3 = tcg_temp_new_i32();
3243 tcg_gen_trunc_tl_i32(t2, t0);
3244 tcg_gen_trunc_tl_i32(t3, t1);
3245 tcg_gen_muls2_i32(t2, t3, t2, t3);
3246 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3247 tcg_temp_free_i32(t2);
3248 tcg_temp_free_i32(t3);
3249 }
b42ee5e1
LA
3250 break;
3251 case R6_OPC_MULU:
3252 {
3253 TCGv_i32 t2 = tcg_temp_new_i32();
3254 TCGv_i32 t3 = tcg_temp_new_i32();
3255 tcg_gen_trunc_tl_i32(t2, t0);
3256 tcg_gen_trunc_tl_i32(t3, t1);
3257 tcg_gen_mul_i32(t2, t2, t3);
3258 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3259 tcg_temp_free_i32(t2);
3260 tcg_temp_free_i32(t3);
3261 }
b42ee5e1
LA
3262 break;
3263 case R6_OPC_MUHU:
3264 {
3265 TCGv_i32 t2 = tcg_temp_new_i32();
3266 TCGv_i32 t3 = tcg_temp_new_i32();
3267 tcg_gen_trunc_tl_i32(t2, t0);
3268 tcg_gen_trunc_tl_i32(t3, t1);
3269 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3270 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3271 tcg_temp_free_i32(t2);
3272 tcg_temp_free_i32(t3);
3273 }
b42ee5e1
LA
3274 break;
3275#if defined(TARGET_MIPS64)
3276 case R6_OPC_DDIV:
3277 {
3278 TCGv t2 = tcg_temp_new();
3279 TCGv t3 = tcg_temp_new();
3280 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3282 tcg_gen_and_tl(t2, t2, t3);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3284 tcg_gen_or_tl(t2, t2, t3);
3285 tcg_gen_movi_tl(t3, 0);
3286 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3287 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3288 tcg_temp_free(t3);
3289 tcg_temp_free(t2);
3290 }
b42ee5e1
LA
3291 break;
3292 case R6_OPC_DMOD:
3293 {
3294 TCGv t2 = tcg_temp_new();
3295 TCGv t3 = tcg_temp_new();
3296 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3297 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3298 tcg_gen_and_tl(t2, t2, t3);
3299 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3300 tcg_gen_or_tl(t2, t2, t3);
3301 tcg_gen_movi_tl(t3, 0);
3302 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3303 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3304 tcg_temp_free(t3);
3305 tcg_temp_free(t2);
3306 }
b42ee5e1
LA
3307 break;
3308 case R6_OPC_DDIVU:
3309 {
3310 TCGv t2 = tcg_const_tl(0);
3311 TCGv t3 = tcg_const_tl(1);
3312 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3313 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3314 tcg_temp_free(t3);
3315 tcg_temp_free(t2);
3316 }
b42ee5e1
LA
3317 break;
3318 case R6_OPC_DMODU:
3319 {
3320 TCGv t2 = tcg_const_tl(0);
3321 TCGv t3 = tcg_const_tl(1);
3322 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3323 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3324 tcg_temp_free(t3);
3325 tcg_temp_free(t2);
3326 }
b42ee5e1
LA
3327 break;
3328 case R6_OPC_DMUL:
3329 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3330 break;
3331 case R6_OPC_DMUH:
3332 {
3333 TCGv t2 = tcg_temp_new();
3334 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3335 tcg_temp_free(t2);
3336 }
b42ee5e1
LA
3337 break;
3338 case R6_OPC_DMULU:
3339 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3340 break;
3341 case R6_OPC_DMUHU:
3342 {
3343 TCGv t2 = tcg_temp_new();
3344 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3345 tcg_temp_free(t2);
3346 }
b42ee5e1
LA
3347 break;
3348#endif
3349 default:
9d68ac14 3350 MIPS_INVAL("r6 mul/div");
b42ee5e1
LA
3351 generate_exception(ctx, EXCP_RI);
3352 goto out;
3353 }
b42ee5e1
LA
3354 out:
3355 tcg_temp_free(t0);
3356 tcg_temp_free(t1);
3357}
3358
26135ead
RS
3359static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3360 int acc, int rs, int rt)
6af0bf9c 3361{
d45f89f4
AJ
3362 TCGv t0, t1;
3363
51127181
AJ
3364 t0 = tcg_temp_new();
3365 t1 = tcg_temp_new();
6af0bf9c 3366
78723684
TS
3367 gen_load_gpr(t0, rs);
3368 gen_load_gpr(t1, rt);
51127181 3369
26135ead
RS
3370 if (acc != 0) {
3371 check_dsp(ctx);
3372 }
3373
6af0bf9c
FB
3374 switch (opc) {
3375 case OPC_DIV:
48d38ca5 3376 {
51127181
AJ
3377 TCGv t2 = tcg_temp_new();
3378 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3379 tcg_gen_ext32s_tl(t0, t0);
3380 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3381 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3383 tcg_gen_and_tl(t2, t2, t3);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3385 tcg_gen_or_tl(t2, t2, t3);
3386 tcg_gen_movi_tl(t3, 0);
3387 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3388 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3389 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3390 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3391 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3392 tcg_temp_free(t3);
3393 tcg_temp_free(t2);
48d38ca5 3394 }
6af0bf9c
FB
3395 break;
3396 case OPC_DIVU:
48d38ca5 3397 {
51127181
AJ
3398 TCGv t2 = tcg_const_tl(0);
3399 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3400 tcg_gen_ext32u_tl(t0, t0);
3401 tcg_gen_ext32u_tl(t1, t1);
51127181 3402 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3403 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3404 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3405 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3406 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3407 tcg_temp_free(t3);
3408 tcg_temp_free(t2);
48d38ca5 3409 }
6af0bf9c
FB
3410 break;
3411 case OPC_MULT:
214c465f 3412 {
ce1dd5d1
RH
3413 TCGv_i32 t2 = tcg_temp_new_i32();
3414 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3415 tcg_gen_trunc_tl_i32(t2, t0);
3416 tcg_gen_trunc_tl_i32(t3, t1);
3417 tcg_gen_muls2_i32(t2, t3, t2, t3);
3418 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3419 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3420 tcg_temp_free_i32(t2);
3421 tcg_temp_free_i32(t3);
214c465f 3422 }
6af0bf9c
FB
3423 break;
3424 case OPC_MULTU:
214c465f 3425 {
ce1dd5d1
RH
3426 TCGv_i32 t2 = tcg_temp_new_i32();
3427 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3428 tcg_gen_trunc_tl_i32(t2, t0);
3429 tcg_gen_trunc_tl_i32(t3, t1);
3430 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3431 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3432 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3433 tcg_temp_free_i32(t2);
3434 tcg_temp_free_i32(t3);
214c465f 3435 }
6af0bf9c 3436 break;
d26bc211 3437#if defined(TARGET_MIPS64)
7a387fff 3438 case OPC_DDIV:
48d38ca5 3439 {
51127181
AJ
3440 TCGv t2 = tcg_temp_new();
3441 TCGv t3 = tcg_temp_new();
3442 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3443 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3444 tcg_gen_and_tl(t2, t2, t3);
3445 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3446 tcg_gen_or_tl(t2, t2, t3);
3447 tcg_gen_movi_tl(t3, 0);
3448 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3449 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3450 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3451 tcg_temp_free(t3);
3452 tcg_temp_free(t2);
48d38ca5 3453 }
7a387fff
TS
3454 break;
3455 case OPC_DDIVU:
48d38ca5 3456 {
51127181
AJ
3457 TCGv t2 = tcg_const_tl(0);
3458 TCGv t3 = tcg_const_tl(1);
3459 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3460 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3461 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3462 tcg_temp_free(t3);
3463 tcg_temp_free(t2);
48d38ca5 3464 }
7a387fff
TS
3465 break;
3466 case OPC_DMULT:
26135ead 3467 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3468 break;
3469 case OPC_DMULTU:
26135ead 3470 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3471 break;
3472#endif
6af0bf9c 3473 case OPC_MADD:
214c465f 3474 {
d45f89f4
AJ
3475 TCGv_i64 t2 = tcg_temp_new_i64();
3476 TCGv_i64 t3 = tcg_temp_new_i64();
3477
3478 tcg_gen_ext_tl_i64(t2, t0);
3479 tcg_gen_ext_tl_i64(t3, t1);
3480 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3481 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3482 tcg_gen_add_i64(t2, t2, t3);
3483 tcg_temp_free_i64(t3);
71f303cd
RH
3484 gen_move_low32(cpu_LO[acc], t2);
3485 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3486 tcg_temp_free_i64(t2);
214c465f 3487 }
6af0bf9c
FB
3488 break;
3489 case OPC_MADDU:
4133498f 3490 {
d45f89f4
AJ
3491 TCGv_i64 t2 = tcg_temp_new_i64();
3492 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3493
78723684
TS
3494 tcg_gen_ext32u_tl(t0, t0);
3495 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3496 tcg_gen_extu_tl_i64(t2, t0);
3497 tcg_gen_extu_tl_i64(t3, t1);
3498 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3499 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3500 tcg_gen_add_i64(t2, t2, t3);
3501 tcg_temp_free_i64(t3);
71f303cd
RH
3502 gen_move_low32(cpu_LO[acc], t2);
3503 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3504 tcg_temp_free_i64(t2);
214c465f 3505 }
6af0bf9c
FB
3506 break;
3507 case OPC_MSUB:
214c465f 3508 {
d45f89f4
AJ
3509 TCGv_i64 t2 = tcg_temp_new_i64();
3510 TCGv_i64 t3 = tcg_temp_new_i64();
3511
3512 tcg_gen_ext_tl_i64(t2, t0);
3513 tcg_gen_ext_tl_i64(t3, t1);
3514 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3515 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3516 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3517 tcg_temp_free_i64(t3);
71f303cd
RH
3518 gen_move_low32(cpu_LO[acc], t2);
3519 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3520 tcg_temp_free_i64(t2);
214c465f 3521 }
6af0bf9c
FB
3522 break;
3523 case OPC_MSUBU:
214c465f 3524 {
d45f89f4
AJ
3525 TCGv_i64 t2 = tcg_temp_new_i64();
3526 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3527
78723684
TS
3528 tcg_gen_ext32u_tl(t0, t0);
3529 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3530 tcg_gen_extu_tl_i64(t2, t0);
3531 tcg_gen_extu_tl_i64(t3, t1);
3532 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3533 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3534 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3535 tcg_temp_free_i64(t3);
71f303cd
RH
3536 gen_move_low32(cpu_LO[acc], t2);
3537 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3538 tcg_temp_free_i64(t2);
214c465f 3539 }
6af0bf9c
FB
3540 break;
3541 default:
9d68ac14 3542 MIPS_INVAL("mul/div");
6af0bf9c 3543 generate_exception(ctx, EXCP_RI);
78723684 3544 goto out;
6af0bf9c 3545 }
78723684
TS
3546 out:
3547 tcg_temp_free(t0);
3548 tcg_temp_free(t1);
6af0bf9c
FB
3549}
3550
e9c71dd1
TS
3551static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3552 int rd, int rs, int rt)
3553{
f157bfe1
AJ
3554 TCGv t0 = tcg_temp_new();
3555 TCGv t1 = tcg_temp_new();
e9c71dd1 3556
6c5c1e20
TS
3557 gen_load_gpr(t0, rs);
3558 gen_load_gpr(t1, rt);
e9c71dd1
TS
3559
3560 switch (opc) {
3561 case OPC_VR54XX_MULS:
895c2d04 3562 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3563 break;
e9c71dd1 3564 case OPC_VR54XX_MULSU:
895c2d04 3565 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3566 break;
e9c71dd1 3567 case OPC_VR54XX_MACC:
895c2d04 3568 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3569 break;
e9c71dd1 3570 case OPC_VR54XX_MACCU:
895c2d04 3571 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3572 break;
e9c71dd1 3573 case OPC_VR54XX_MSAC:
895c2d04 3574 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3575 break;
e9c71dd1 3576 case OPC_VR54XX_MSACU:
895c2d04 3577 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3578 break;
e9c71dd1 3579 case OPC_VR54XX_MULHI:
895c2d04 3580 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3581 break;
e9c71dd1 3582 case OPC_VR54XX_MULHIU:
895c2d04 3583 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3584 break;
e9c71dd1 3585 case OPC_VR54XX_MULSHI:
895c2d04 3586 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3587 break;
e9c71dd1 3588 case OPC_VR54XX_MULSHIU:
895c2d04 3589 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3590 break;
e9c71dd1 3591 case OPC_VR54XX_MACCHI:
895c2d04 3592 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3593 break;
e9c71dd1 3594 case OPC_VR54XX_MACCHIU:
895c2d04 3595 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3596 break;
e9c71dd1 3597 case OPC_VR54XX_MSACHI:
895c2d04 3598 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3599 break;
e9c71dd1 3600 case OPC_VR54XX_MSACHIU:
895c2d04 3601 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3602 break;
e9c71dd1
TS
3603 default:
3604 MIPS_INVAL("mul vr54xx");
3605 generate_exception(ctx, EXCP_RI);
6c5c1e20 3606 goto out;
e9c71dd1 3607 }
6c5c1e20 3608 gen_store_gpr(t0, rd);
6c5c1e20
TS
3609
3610 out:
3611 tcg_temp_free(t0);
3612 tcg_temp_free(t1);
e9c71dd1
TS
3613}
3614
7a387fff 3615static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3616 int rd, int rs)
3617{
20e1fb52 3618 TCGv t0;
6c5c1e20 3619
6af0bf9c 3620 if (rd == 0) {
ead9360e 3621 /* Treat as NOP. */
20e1fb52 3622 return;
6af0bf9c 3623 }
20e1fb52 3624 t0 = tcg_temp_new();
6c5c1e20 3625 gen_load_gpr(t0, rs);
6af0bf9c
FB
3626 switch (opc) {
3627 case OPC_CLO:
4267d3e6 3628 case R6_OPC_CLO:
20e1fb52 3629 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3630 break;
3631 case OPC_CLZ:
4267d3e6 3632 case R6_OPC_CLZ:
20e1fb52 3633 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c 3634 break;
d26bc211 3635#if defined(TARGET_MIPS64)
7a387fff 3636 case OPC_DCLO:
4267d3e6 3637 case R6_OPC_DCLO:
20e1fb52 3638 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3639 break;
3640 case OPC_DCLZ:
4267d3e6 3641 case R6_OPC_DCLZ:
20e1fb52 3642 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3643 break;
3644#endif
6af0bf9c 3645 }
6c5c1e20 3646 tcg_temp_free(t0);
6af0bf9c
FB
3647}
3648
161f85e6 3649/* Godson integer instructions */
bd277fa1
RH
3650static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3651 int rd, int rs, int rt)
161f85e6 3652{
161f85e6
AJ
3653 TCGv t0, t1;
3654
3655 if (rd == 0) {
3656 /* Treat as NOP. */
161f85e6
AJ
3657 return;
3658 }
3659
3660 switch (opc) {
3661 case OPC_MULT_G_2E:
3662 case OPC_MULT_G_2F:
3663 case OPC_MULTU_G_2E:
3664 case OPC_MULTU_G_2F:
3665#if defined(TARGET_MIPS64)
3666 case OPC_DMULT_G_2E:
3667 case OPC_DMULT_G_2F:
3668 case OPC_DMULTU_G_2E:
3669 case OPC_DMULTU_G_2F:
3670#endif
3671 t0 = tcg_temp_new();
3672 t1 = tcg_temp_new();
3673 break;
3674 default:
3675 t0 = tcg_temp_local_new();
3676 t1 = tcg_temp_local_new();
3677 break;
3678 }
3679
3680 gen_load_gpr(t0, rs);
3681 gen_load_gpr(t1, rt);
3682
3683 switch (opc) {
3684 case OPC_MULT_G_2E:
3685 case OPC_MULT_G_2F:
3686 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3687 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3688 break;
3689 case OPC_MULTU_G_2E:
3690 case OPC_MULTU_G_2F:
3691 tcg_gen_ext32u_tl(t0, t0);
3692 tcg_gen_ext32u_tl(t1, t1);
3693 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3694 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3695 break;
3696 case OPC_DIV_G_2E:
3697 case OPC_DIV_G_2F:
3698 {
42a268c2
RH
3699 TCGLabel *l1 = gen_new_label();
3700 TCGLabel *l2 = gen_new_label();
3701 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3702 tcg_gen_ext32s_tl(t0, t0);
3703 tcg_gen_ext32s_tl(t1, t1);
3704 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3705 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3706 tcg_gen_br(l3);
3707 gen_set_label(l1);
3708 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3709 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3710 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3711 tcg_gen_br(l3);
3712 gen_set_label(l2);
3713 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3714 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3715 gen_set_label(l3);
3716 }
161f85e6
AJ
3717 break;
3718 case OPC_DIVU_G_2E:
3719 case OPC_DIVU_G_2F:
3720 {
42a268c2
RH
3721 TCGLabel *l1 = gen_new_label();
3722 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3723 tcg_gen_ext32u_tl(t0, t0);
3724 tcg_gen_ext32u_tl(t1, t1);
3725 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3726 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3727 tcg_gen_br(l2);
3728 gen_set_label(l1);
3729 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3730 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3731 gen_set_label(l2);
3732 }
161f85e6
AJ
3733 break;
3734 case OPC_MOD_G_2E:
3735 case OPC_MOD_G_2F:
3736 {
42a268c2
RH
3737 TCGLabel *l1 = gen_new_label();
3738 TCGLabel *l2 = gen_new_label();
3739 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3740 tcg_gen_ext32u_tl(t0, t0);
3741 tcg_gen_ext32u_tl(t1, t1);
3742 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3743 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3744 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3745 gen_set_label(l1);
3746 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3747 tcg_gen_br(l3);
3748 gen_set_label(l2);
3749 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3750 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3751 gen_set_label(l3);
3752 }
161f85e6
AJ
3753 break;
3754 case OPC_MODU_G_2E:
3755 case OPC_MODU_G_2F:
3756 {
42a268c2
RH
3757 TCGLabel *l1 = gen_new_label();
3758 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3759 tcg_gen_ext32u_tl(t0, t0);
3760 tcg_gen_ext32u_tl(t1, t1);
3761 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3762 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3763 tcg_gen_br(l2);
3764 gen_set_label(l1);
3765 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3766 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3767 gen_set_label(l2);
3768 }
161f85e6
AJ
3769 break;
3770#if defined(TARGET_MIPS64)
3771 case OPC_DMULT_G_2E:
3772 case OPC_DMULT_G_2F:
3773 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3774 break;
3775 case OPC_DMULTU_G_2E:
3776 case OPC_DMULTU_G_2F:
3777 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3778 break;
3779 case OPC_DDIV_G_2E:
3780 case OPC_DDIV_G_2F:
3781 {
42a268c2
RH
3782 TCGLabel *l1 = gen_new_label();
3783 TCGLabel *l2 = gen_new_label();
3784 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3785 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3786 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3787 tcg_gen_br(l3);
3788 gen_set_label(l1);
3789 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3790 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3791 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3792 tcg_gen_br(l3);
3793 gen_set_label(l2);
3794 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3795 gen_set_label(l3);
3796 }
161f85e6
AJ
3797 break;
3798 case OPC_DDIVU_G_2E:
3799 case OPC_DDIVU_G_2F:
3800 {
42a268c2
RH
3801 TCGLabel *l1 = gen_new_label();
3802 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3803 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3804 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3805 tcg_gen_br(l2);
3806 gen_set_label(l1);
3807 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3808 gen_set_label(l2);
3809 }
161f85e6
AJ
3810 break;
3811 case OPC_DMOD_G_2E:
3812 case OPC_DMOD_G_2F:
3813 {
42a268c2
RH
3814 TCGLabel *l1 = gen_new_label();
3815 TCGLabel *l2 = gen_new_label();
3816 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3817 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3818 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3819 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3820 gen_set_label(l1);
3821 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3822 tcg_gen_br(l3);
3823 gen_set_label(l2);
3824 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3825 gen_set_label(l3);
3826 }
161f85e6
AJ
3827 break;
3828 case OPC_DMODU_G_2E:
3829 case OPC_DMODU_G_2F:
3830 {
42a268c2
RH
3831 TCGLabel *l1 = gen_new_label();
3832 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3833 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3834 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3835 tcg_gen_br(l2);
3836 gen_set_label(l1);
3837 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3838 gen_set_label(l2);
3839 }
161f85e6
AJ
3840 break;
3841#endif
3842 }
3843
161f85e6
AJ
3844 tcg_temp_free(t0);
3845 tcg_temp_free(t1);
3846}
3847
bd277fa1
RH
3848/* Loongson multimedia instructions */
3849static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3850{
bd277fa1
RH
3851 uint32_t opc, shift_max;
3852 TCGv_i64 t0, t1;
3853
3854 opc = MASK_LMI(ctx->opcode);
3855 switch (opc) {
3856 case OPC_ADD_CP2:
3857 case OPC_SUB_CP2:
3858 case OPC_DADD_CP2:
3859 case OPC_DSUB_CP2:
3860 t0 = tcg_temp_local_new_i64();
3861 t1 = tcg_temp_local_new_i64();
3862 break;
3863 default:
3864 t0 = tcg_temp_new_i64();
3865 t1 = tcg_temp_new_i64();
3866 break;
3867 }
3868
3869 gen_load_fpr64(ctx, t0, rs);
3870 gen_load_fpr64(ctx, t1, rt);
3871
3872#define LMI_HELPER(UP, LO) \
9d68ac14 3873 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3874#define LMI_HELPER_1(UP, LO) \
9d68ac14 3875 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3876#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3877 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3878
3879 switch (opc) {
3880 LMI_HELPER(PADDSH, paddsh);
3881 LMI_HELPER(PADDUSH, paddush);
3882 LMI_HELPER(PADDH, paddh);
3883 LMI_HELPER(PADDW, paddw);
3884 LMI_HELPER(PADDSB, paddsb);
3885 LMI_HELPER(PADDUSB, paddusb);
3886 LMI_HELPER(PADDB, paddb);
3887
3888 LMI_HELPER(PSUBSH, psubsh);
3889 LMI_HELPER(PSUBUSH, psubush);
3890 LMI_HELPER(PSUBH, psubh);
3891 LMI_HELPER(PSUBW, psubw);
3892 LMI_HELPER(PSUBSB, psubsb);
3893 LMI_HELPER(PSUBUSB, psubusb);
3894 LMI_HELPER(PSUBB, psubb);
3895
3896 LMI_HELPER(PSHUFH, pshufh);
3897 LMI_HELPER(PACKSSWH, packsswh);
3898 LMI_HELPER(PACKSSHB, packsshb);
3899 LMI_HELPER(PACKUSHB, packushb);
3900
3901 LMI_HELPER(PUNPCKLHW, punpcklhw);
3902 LMI_HELPER(PUNPCKHHW, punpckhhw);
3903 LMI_HELPER(PUNPCKLBH, punpcklbh);
3904 LMI_HELPER(PUNPCKHBH, punpckhbh);
3905 LMI_HELPER(PUNPCKLWD, punpcklwd);
3906 LMI_HELPER(PUNPCKHWD, punpckhwd);
3907
3908 LMI_HELPER(PAVGH, pavgh);
3909 LMI_HELPER(PAVGB, pavgb);
3910 LMI_HELPER(PMAXSH, pmaxsh);
3911 LMI_HELPER(PMINSH, pminsh);
3912 LMI_HELPER(PMAXUB, pmaxub);
3913 LMI_HELPER(PMINUB, pminub);
3914
3915 LMI_HELPER(PCMPEQW, pcmpeqw);
3916 LMI_HELPER(PCMPGTW, pcmpgtw);
3917 LMI_HELPER(PCMPEQH, pcmpeqh);
3918 LMI_HELPER(PCMPGTH, pcmpgth);
3919 LMI_HELPER(PCMPEQB, pcmpeqb);
3920 LMI_HELPER(PCMPGTB, pcmpgtb);
3921
3922 LMI_HELPER(PSLLW, psllw);
3923 LMI_HELPER(PSLLH, psllh);
3924 LMI_HELPER(PSRLW, psrlw);
3925 LMI_HELPER(PSRLH, psrlh);
3926 LMI_HELPER(PSRAW, psraw);
3927 LMI_HELPER(PSRAH, psrah);
3928
3929 LMI_HELPER(PMULLH, pmullh);
3930 LMI_HELPER(PMULHH, pmulhh);
3931 LMI_HELPER(PMULHUH, pmulhuh);
3932 LMI_HELPER(PMADDHW, pmaddhw);
3933
3934 LMI_HELPER(PASUBUB, pasubub);
3935 LMI_HELPER_1(BIADD, biadd);
3936 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3937
3938 LMI_DIRECT(PADDD, paddd, add);
3939 LMI_DIRECT(PSUBD, psubd, sub);
3940 LMI_DIRECT(XOR_CP2, xor, xor);
3941 LMI_DIRECT(NOR_CP2, nor, nor);
3942 LMI_DIRECT(AND_CP2, and, and);
3943 LMI_DIRECT(PANDN, pandn, andc);
3944 LMI_DIRECT(OR, or, or);
3945
3946 case OPC_PINSRH_0:
3947 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
3948 break;
3949 case OPC_PINSRH_1:
3950 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
3951 break;
3952 case OPC_PINSRH_2:
3953 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
3954 break;
3955 case OPC_PINSRH_3:
3956 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
3957 break;
3958
3959 case OPC_PEXTRH:
3960 tcg_gen_andi_i64(t1, t1, 3);
3961 tcg_gen_shli_i64(t1, t1, 4);
3962 tcg_gen_shr_i64(t0, t0, t1);
3963 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
3964 break;
3965
3966 case OPC_ADDU_CP2:
3967 tcg_gen_add_i64(t0, t0, t1);
3968 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3969 break;
3970 case OPC_SUBU_CP2:
3971 tcg_gen_sub_i64(t0, t0, t1);
3972 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3973 break;
3974
3975 case OPC_SLL_CP2:
bd277fa1
RH
3976 shift_max = 32;
3977 goto do_shift;
3978 case OPC_SRL_CP2:
bd277fa1
RH
3979 shift_max = 32;
3980 goto do_shift;
3981 case OPC_SRA_CP2:
bd277fa1
RH
3982 shift_max = 32;
3983 goto do_shift;
3984 case OPC_DSLL_CP2:
bd277fa1
RH
3985 shift_max = 64;
3986 goto do_shift;
3987 case OPC_DSRL_CP2:
bd277fa1
RH
3988 shift_max = 64;
3989 goto do_shift;
3990 case OPC_DSRA_CP2:
bd277fa1
RH
3991 shift_max = 64;
3992 goto do_shift;
3993 do_shift:
3994 /* Make sure shift count isn't TCG undefined behaviour. */
3995 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3996
3997 switch (opc) {
3998 case OPC_SLL_CP2:
3999 case OPC_DSLL_CP2:
4000 tcg_gen_shl_i64(t0, t0, t1);
4001 break;
4002 case OPC_SRA_CP2:
4003 case OPC_DSRA_CP2:
4004 /* Since SRA is UndefinedResult without sign-extended inputs,
4005 we can treat SRA and DSRA the same. */
4006 tcg_gen_sar_i64(t0, t0, t1);
4007 break;
4008 case OPC_SRL_CP2:
4009 /* We want to shift in zeros for SRL; zero-extend first. */
4010 tcg_gen_ext32u_i64(t0, t0);
4011 /* FALLTHRU */
4012 case OPC_DSRL_CP2:
4013 tcg_gen_shr_i64(t0, t0, t1);
4014 break;
4015 }
4016
4017 if (shift_max == 32) {
4018 tcg_gen_ext32s_i64(t0, t0);
4019 }
4020
4021 /* Shifts larger than MAX produce zero. */
4022 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4023 tcg_gen_neg_i64(t1, t1);
4024 tcg_gen_and_i64(t0, t0, t1);
4025 break;
4026
4027 case OPC_ADD_CP2:
4028 case OPC_DADD_CP2:
4029 {
4030 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4031 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4032
4033 tcg_gen_mov_i64(t2, t0);
4034 tcg_gen_add_i64(t0, t1, t2);
4035 if (opc == OPC_ADD_CP2) {
4036 tcg_gen_ext32s_i64(t0, t0);
4037 }
4038 tcg_gen_xor_i64(t1, t1, t2);
4039 tcg_gen_xor_i64(t2, t2, t0);
4040 tcg_gen_andc_i64(t1, t2, t1);
4041 tcg_temp_free_i64(t2);
4042 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4043 generate_exception(ctx, EXCP_OVERFLOW);
4044 gen_set_label(lab);
bd277fa1
RH
4045 break;
4046 }
4047
4048 case OPC_SUB_CP2:
4049 case OPC_DSUB_CP2:
4050 {
4051 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4052 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4053
4054 tcg_gen_mov_i64(t2, t0);
4055 tcg_gen_sub_i64(t0, t1, t2);
4056 if (opc == OPC_SUB_CP2) {
4057 tcg_gen_ext32s_i64(t0, t0);
4058 }
4059 tcg_gen_xor_i64(t1, t1, t2);
4060 tcg_gen_xor_i64(t2, t2, t0);
4061 tcg_gen_and_i64(t1, t1, t2);
4062 tcg_temp_free_i64(t2);
4063 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4064 generate_exception(ctx, EXCP_OVERFLOW);
4065 gen_set_label(lab);
bd277fa1
RH
4066 break;
4067 }
4068
4069 case OPC_PMULUW:
4070 tcg_gen_ext32u_i64(t0, t0);
4071 tcg_gen_ext32u_i64(t1, t1);
4072 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4073 break;
4074
4075 case OPC_SEQU_CP2:
4076 case OPC_SEQ_CP2:
4077 case OPC_SLTU_CP2:
4078 case OPC_SLT_CP2:
4079 case OPC_SLEU_CP2:
4080 case OPC_SLE_CP2:
4081 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4082 FD field is the CC field? */
4083 default:
9d68ac14 4084 MIPS_INVAL("loongson_cp2");
bd277fa1
RH
4085 generate_exception(ctx, EXCP_RI);
4086 return;
4087 }
4088
4089#undef LMI_HELPER
4090#undef LMI_DIRECT
4091
4092 gen_store_fpr64(ctx, t0, rd);
4093
bd277fa1
RH
4094 tcg_temp_free_i64(t0);
4095 tcg_temp_free_i64(t1);
4096}
4097
6af0bf9c 4098/* Traps */
7a387fff 4099static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4100 int rs, int rt, int16_t imm)
4101{
4102 int cond;
cdc0faa6 4103 TCGv t0 = tcg_temp_new();
1ba74fb8 4104 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4105
4106 cond = 0;
4107 /* Load needed operands */
4108 switch (opc) {
4109 case OPC_TEQ:
4110 case OPC_TGE:
4111 case OPC_TGEU:
4112 case OPC_TLT:
4113 case OPC_TLTU:
4114 case OPC_TNE:
4115 /* Compare two registers */
4116 if (rs != rt) {
be24bb4f
TS
4117 gen_load_gpr(t0, rs);
4118 gen_load_gpr(t1, rt);
6af0bf9c
FB
4119 cond = 1;
4120 }
179e32bb 4121 break;
6af0bf9c
FB
4122 case OPC_TEQI:
4123 case OPC_TGEI:
4124 case OPC_TGEIU:
4125 case OPC_TLTI:
4126 case OPC_TLTIU:
4127 case OPC_TNEI:
4128 /* Compare register to immediate */
4129 if (rs != 0 || imm != 0) {
be24bb4f
TS
4130 gen_load_gpr(t0, rs);
4131 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4132 cond = 1;
4133 }
4134 break;
4135 }
4136 if (cond == 0) {
4137 switch (opc) {
4138 case OPC_TEQ: /* rs == rs */
4139 case OPC_TEQI: /* r0 == 0 */
4140 case OPC_TGE: /* rs >= rs */
4141 case OPC_TGEI: /* r0 >= 0 */
4142 case OPC_TGEU: /* rs >= rs unsigned */
4143 case OPC_TGEIU: /* r0 >= 0 unsigned */
4144 /* Always trap */
cdc0faa6 4145 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4146 break;
4147 case OPC_TLT: /* rs < rs */
4148 case OPC_TLTI: /* r0 < 0 */
4149 case OPC_TLTU: /* rs < rs unsigned */
4150 case OPC_TLTIU: /* r0 < 0 unsigned */
4151 case OPC_TNE: /* rs != rs */
4152 case OPC_TNEI: /* r0 != 0 */
ead9360e 4153 /* Never trap: treat as NOP. */
cdc0faa6 4154 break;
6af0bf9c
FB
4155 }
4156 } else {
42a268c2 4157 TCGLabel *l1 = gen_new_label();
cdc0faa6 4158
6af0bf9c
FB
4159 switch (opc) {
4160 case OPC_TEQ:
4161 case OPC_TEQI:
cdc0faa6 4162 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4163 break;
4164 case OPC_TGE:
4165 case OPC_TGEI:
cdc0faa6 4166 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4167 break;
4168 case OPC_TGEU:
4169 case OPC_TGEIU:
cdc0faa6 4170 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4171 break;
4172 case OPC_TLT:
4173 case OPC_TLTI:
cdc0faa6 4174 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4175 break;
4176 case OPC_TLTU:
4177 case OPC_TLTIU:
cdc0faa6 4178 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4179 break;
4180 case OPC_TNE:
4181 case OPC_TNEI:
cdc0faa6 4182 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4183 break;
6af0bf9c 4184 }
cdc0faa6 4185 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4186 gen_set_label(l1);
4187 }
be24bb4f
TS
4188 tcg_temp_free(t0);
4189 tcg_temp_free(t1);
6af0bf9c
FB
4190}
4191
356265ae 4192static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4193{
6e256c93
FB
4194 TranslationBlock *tb;
4195 tb = ctx->tb;
7b270ef2
NF
4196 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4197 likely(!ctx->singlestep_enabled)) {
57fec1fe 4198 tcg_gen_goto_tb(n);
9b9e4393 4199 gen_save_pc(dest);
8cfd0495 4200 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4201 } else {
9b9e4393 4202 gen_save_pc(dest);
7b270ef2
NF
4203 if (ctx->singlestep_enabled) {
4204 save_cpu_state(ctx, 0);
895c2d04 4205 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4206 }
57fec1fe 4207 tcg_gen_exit_tb(0);
6e256c93 4208 }
c53be334
FB
4209}
4210
6af0bf9c 4211/* Branches (before delay slot) */
7a387fff 4212static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4213 int insn_bytes,
b231c103
YK
4214 int rs, int rt, int32_t offset,
4215 int delayslot_size)
6af0bf9c 4216{
d077b6f7 4217 target_ulong btgt = -1;
3ad4bb2d 4218 int blink = 0;
2fdbad25 4219 int bcond_compute = 0;
1ba74fb8
AJ
4220 TCGv t0 = tcg_temp_new();
4221 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4222
4223 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4224#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4225 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4226 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4227#endif
3ad4bb2d 4228 generate_exception(ctx, EXCP_RI);
6c5c1e20 4229 goto out;
3ad4bb2d 4230 }
6af0bf9c 4231
6af0bf9c
FB
4232 /* Load needed operands */
4233 switch (opc) {
4234 case OPC_BEQ:
4235 case OPC_BEQL:
4236 case OPC_BNE:
4237 case OPC_BNEL:
4238 /* Compare two registers */
4239 if (rs != rt) {
6c5c1e20
TS
4240 gen_load_gpr(t0, rs);
4241 gen_load_gpr(t1, rt);
2fdbad25 4242 bcond_compute = 1;
6af0bf9c 4243 }
7dca4ad0 4244 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4245 break;
4246 case OPC_BGEZ:
4247 case OPC_BGEZAL:
4248 case OPC_BGEZALL:
4249 case OPC_BGEZL:
4250 case OPC_BGTZ:
4251 case OPC_BGTZL:
4252 case OPC_BLEZ:
4253 case OPC_BLEZL:
4254 case OPC_BLTZ:
4255 case OPC_BLTZAL:
4256 case OPC_BLTZALL:
4257 case OPC_BLTZL:
4258 /* Compare to zero */
4259 if (rs != 0) {
6c5c1e20 4260 gen_load_gpr(t0, rs);
2fdbad25 4261 bcond_compute = 1;
6af0bf9c 4262 }
7dca4ad0 4263 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4264 break;
e45a93e2
JL
4265 case OPC_BPOSGE32:
4266#if defined(TARGET_MIPS64)
4267 case OPC_BPOSGE64:
4268 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4269#else
4270 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4271#endif
4272 bcond_compute = 1;
4273 btgt = ctx->pc + insn_bytes + offset;
4274 break;
6af0bf9c
FB
4275 case OPC_J:
4276 case OPC_JAL:
364d4831 4277 case OPC_JALX:
6af0bf9c 4278 /* Jump to immediate */
7dca4ad0 4279 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4280 break;
4281 case OPC_JR:
4282 case OPC_JALR:
4283 /* Jump to register */
7a387fff
TS
4284 if (offset != 0 && offset != 16) {
4285 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4286 others are reserved. */
923617a3 4287 MIPS_INVAL("jump hint");
6af0bf9c 4288 generate_exception(ctx, EXCP_RI);
6c5c1e20 4289 goto out;
6af0bf9c 4290 }
d077b6f7 4291 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4292 break;
4293 default:
4294 MIPS_INVAL("branch/jump");
4295 generate_exception(ctx, EXCP_RI);
6c5c1e20 4296 goto out;
6af0bf9c 4297 }
2fdbad25 4298 if (bcond_compute == 0) {
6af0bf9c
FB
4299 /* No condition to be computed */
4300 switch (opc) {
4301 case OPC_BEQ: /* rx == rx */
4302 case OPC_BEQL: /* rx == rx likely */
4303 case OPC_BGEZ: /* 0 >= 0 */
4304 case OPC_BGEZL: /* 0 >= 0 likely */
4305 case OPC_BLEZ: /* 0 <= 0 */
4306 case OPC_BLEZL: /* 0 <= 0 likely */
4307 /* Always take */
4ad40f36 4308 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4309 break;
4310 case OPC_BGEZAL: /* 0 >= 0 */
4311 case OPC_BGEZALL: /* 0 >= 0 likely */
4312 /* Always take and link */
4313 blink = 31;
4ad40f36 4314 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4315 break;
4316 case OPC_BNE: /* rx != rx */
4317 case OPC_BGTZ: /* 0 > 0 */
4318 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4319 /* Treat as NOP. */
6c5c1e20 4320 goto out;
eeef26cd 4321 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4322 /* Handle as an unconditional branch to get correct delay
4323 slot checking. */
4324 blink = 31;
b231c103 4325 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4326 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4327 break;
eeef26cd 4328 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4329 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4330 /* Skip the instruction in the delay slot */
9898128f 4331 ctx->pc += 4;
6c5c1e20 4332 goto out;
6af0bf9c
FB
4333 case OPC_BNEL: /* rx != rx likely */
4334 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4335 case OPC_BLTZL: /* 0 < 0 likely */
4336 /* Skip the instruction in the delay slot */
9898128f 4337 ctx->pc += 4;
6c5c1e20 4338 goto out;
6af0bf9c 4339 case OPC_J:
4ad40f36 4340 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4341 break;
364d4831
NF
4342 case OPC_JALX:
4343 ctx->hflags |= MIPS_HFLAG_BX;
4344 /* Fallthrough */
6af0bf9c
FB
4345 case OPC_JAL:
4346 blink = 31;
4ad40f36 4347 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4348 break;
4349 case OPC_JR:
4ad40f36 4350 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4351 break;
4352 case OPC_JALR:
4353 blink = rt;
4ad40f36 4354 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4355 break;
4356 default:
4357 MIPS_INVAL("branch/jump");
4358 generate_exception(ctx, EXCP_RI);
6c5c1e20 4359 goto out;
6af0bf9c
FB
4360 }
4361 } else {
4362 switch (opc) {
4363 case OPC_BEQ:
e68dd28f 4364 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4365 goto not_likely;
4366 case OPC_BEQL:
e68dd28f 4367 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4368 goto likely;
4369 case OPC_BNE:
e68dd28f 4370 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4371 goto not_likely;
4372 case OPC_BNEL:
e68dd28f 4373 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4374 goto likely;
4375 case OPC_BGEZ:
e68dd28f 4376 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4377 goto not_likely;
4378 case OPC_BGEZL:
e68dd28f 4379 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4380 goto likely;
4381 case OPC_BGEZAL:
e68dd28f 4382 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4383 blink = 31;
4384 goto not_likely;
4385 case OPC_BGEZALL:
e68dd28f 4386 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4387 blink = 31;
6af0bf9c
FB
4388 goto likely;
4389 case OPC_BGTZ:
e68dd28f 4390 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4391 goto not_likely;
4392 case OPC_BGTZL:
e68dd28f 4393 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4394 goto likely;
4395 case OPC_BLEZ:
e68dd28f 4396 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4397 goto not_likely;
4398 case OPC_BLEZL:
e68dd28f 4399 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4400 goto likely;
4401 case OPC_BLTZ:
e68dd28f 4402 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4403 goto not_likely;
4404 case OPC_BLTZL:
e68dd28f 4405 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4406 goto likely;
e45a93e2
JL
4407 case OPC_BPOSGE32:
4408 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4409 goto not_likely;
4410#if defined(TARGET_MIPS64)
4411 case OPC_BPOSGE64:
4412 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4413 goto not_likely;
4414#endif
6af0bf9c 4415 case OPC_BLTZAL:
e68dd28f 4416 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4417 blink = 31;
6af0bf9c 4418 not_likely:
4ad40f36 4419 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4420 break;
4421 case OPC_BLTZALL:
e68dd28f 4422 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4423 blink = 31;
6af0bf9c 4424 likely:
4ad40f36 4425 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4426 break;
c53f4a62
TS
4427 default:
4428 MIPS_INVAL("conditional branch/jump");
4429 generate_exception(ctx, EXCP_RI);
6c5c1e20 4430 goto out;
6af0bf9c 4431 }
6af0bf9c 4432 }
9b9e4393 4433
d077b6f7 4434 ctx->btarget = btgt;
b231c103
YK
4435
4436 switch (delayslot_size) {
4437 case 2:
4438 ctx->hflags |= MIPS_HFLAG_BDS16;
4439 break;
4440 case 4:
4441 ctx->hflags |= MIPS_HFLAG_BDS32;
4442 break;
4443 }
4444
6af0bf9c 4445 if (blink > 0) {
b231c103 4446 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4447 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4448
364d4831 4449 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4450 }
6c5c1e20
TS
4451
4452 out:
364d4831
NF
4453 if (insn_bytes == 2)
4454 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4455 tcg_temp_free(t0);
4456 tcg_temp_free(t1);
6af0bf9c
FB
4457}
4458
7a387fff
TS
4459/* special3 bitfield operations */
4460static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4461 int rs, int lsb, int msb)
7a387fff 4462{
a7812ae4
PB
4463 TCGv t0 = tcg_temp_new();
4464 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4465
4466 gen_load_gpr(t1, rs);
7a387fff
TS
4467 switch (opc) {
4468 case OPC_EXT:
b7f26e52 4469 if (lsb + msb > 31) {
7a387fff 4470 goto fail;
b7f26e52 4471 }
505ad7c2
AJ
4472 tcg_gen_shri_tl(t0, t1, lsb);
4473 if (msb != 31) {
b7f26e52 4474 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
505ad7c2
AJ
4475 } else {
4476 tcg_gen_ext32s_tl(t0, t0);
4477 }
7a387fff 4478 break;
c6d6dd7c 4479#if defined(TARGET_MIPS64)
7a387fff 4480 case OPC_DEXTU:
b7f26e52
RH
4481 lsb += 32;
4482 goto do_dext;
4483 case OPC_DEXTM:
4484 msb += 32;
4485 goto do_dext;
7a387fff 4486 case OPC_DEXT:
b7f26e52
RH
4487 do_dext:
4488 if (lsb + msb > 63) {
4489 goto fail;
4490 }
505ad7c2 4491 tcg_gen_shri_tl(t0, t1, lsb);
b7f26e52
RH
4492 if (msb != 63) {
4493 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4494 }
7a387fff 4495 break;
c6d6dd7c 4496#endif
7a387fff 4497 case OPC_INS:
b7f26e52 4498 if (lsb > msb) {
7a387fff 4499 goto fail;
b7f26e52 4500 }
6c5c1e20 4501 gen_load_gpr(t0, rt);
e0d002f1 4502 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4503 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4504 break;
c6d6dd7c 4505#if defined(TARGET_MIPS64)
7a387fff 4506 case OPC_DINSU:
b7f26e52
RH
4507 lsb += 32;
4508 /* FALLTHRU */
4509 case OPC_DINSM:
4510 msb += 32;
4511 /* FALLTHRU */
7a387fff 4512 case OPC_DINS:
b7f26e52
RH
4513 if (lsb > msb) {
4514 goto fail;
4515 }
6c5c1e20 4516 gen_load_gpr(t0, rt);
e0d002f1 4517 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4518 break;
c6d6dd7c 4519#endif
7a387fff
TS
4520 default:
4521fail:
4522 MIPS_INVAL("bitops");
4523 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4524 tcg_temp_free(t0);
4525 tcg_temp_free(t1);
7a387fff
TS
4526 return;
4527 }
6c5c1e20
TS
4528 gen_store_gpr(t0, rt);
4529 tcg_temp_free(t0);
4530 tcg_temp_free(t1);
7a387fff
TS
4531}
4532
49bcf33c
AJ
4533static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4534{
3a55fa47 4535 TCGv t0;
49bcf33c 4536
3a55fa47
AJ
4537 if (rd == 0) {
4538 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4539 return;
4540 }
4541
4542 t0 = tcg_temp_new();
4543 gen_load_gpr(t0, rt);
49bcf33c
AJ
4544 switch (op2) {
4545 case OPC_WSBH:
3a55fa47
AJ
4546 {
4547 TCGv t1 = tcg_temp_new();
4548
4549 tcg_gen_shri_tl(t1, t0, 8);
4550 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4551 tcg_gen_shli_tl(t0, t0, 8);
4552 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4553 tcg_gen_or_tl(t0, t0, t1);
4554 tcg_temp_free(t1);
4555 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4556 }
49bcf33c
AJ
4557 break;
4558 case OPC_SEB:
3a55fa47 4559 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4560 break;
4561 case OPC_SEH:
3a55fa47 4562 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4563 break;
4564#if defined(TARGET_MIPS64)
4565 case OPC_DSBH:
3a55fa47
AJ
4566 {
4567 TCGv t1 = tcg_temp_new();
4568
4569 tcg_gen_shri_tl(t1, t0, 8);
4570 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4571 tcg_gen_shli_tl(t0, t0, 8);
4572 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4573 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4574 tcg_temp_free(t1);
4575 }
49bcf33c
AJ
4576 break;
4577 case OPC_DSHD:
3a55fa47
AJ
4578 {
4579 TCGv t1 = tcg_temp_new();
4580
4581 tcg_gen_shri_tl(t1, t0, 16);
4582 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4583 tcg_gen_shli_tl(t0, t0, 16);
4584 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4585 tcg_gen_or_tl(t0, t0, t1);
4586 tcg_gen_shri_tl(t1, t0, 32);
4587 tcg_gen_shli_tl(t0, t0, 32);
4588 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4589 tcg_temp_free(t1);
4590 }
49bcf33c
AJ
4591 break;
4592#endif
4593 default:
4594 MIPS_INVAL("bsfhl");
4595 generate_exception(ctx, EXCP_RI);
4596 tcg_temp_free(t0);
49bcf33c
AJ
4597 return;
4598 }
49bcf33c 4599 tcg_temp_free(t0);
49bcf33c
AJ
4600}
4601
1f1b4c00
YK
4602static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4603 int imm2)
4604{
4605 TCGv t0;
4606 TCGv t1;
4607 if (rd == 0) {
4608 /* Treat as NOP. */
4609 return;
4610 }
4611 t0 = tcg_temp_new();
4612 t1 = tcg_temp_new();
4613 gen_load_gpr(t0, rs);
4614 gen_load_gpr(t1, rt);
4615 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4616 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4617 if (opc == OPC_LSA) {
4618 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4619 }
4620
4621 tcg_temp_free(t1);
4622 tcg_temp_free(t0);
4623
4624 return;
4625}
4626
4627static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4628 int bp)
284b731a 4629{
1f1b4c00
YK
4630 TCGv t0;
4631 if (rd == 0) {
4632 /* Treat as NOP. */
4633 return;
4634 }
4635 t0 = tcg_temp_new();
4636 gen_load_gpr(t0, rt);
4637 if (bp == 0) {
4638 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4639 } else {
4640 TCGv t1 = tcg_temp_new();
4641 gen_load_gpr(t1, rs);
4642 switch (opc) {
4643 case OPC_ALIGN:
4644 {
4645 TCGv_i64 t2 = tcg_temp_new_i64();
4646 tcg_gen_concat_tl_i64(t2, t1, t0);
4647 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4648 gen_move_low32(cpu_gpr[rd], t2);
4649 tcg_temp_free_i64(t2);
4650 }
4651 break;
284b731a 4652#if defined(TARGET_MIPS64)
1f1b4c00
YK
4653 case OPC_DALIGN:
4654 tcg_gen_shli_tl(t0, t0, 8 * bp);
4655 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4656 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4657 break;
284b731a 4658#endif
1f1b4c00
YK
4659 }
4660 tcg_temp_free(t1);
4661 }
4662
4663 tcg_temp_free(t0);
4664}
4665
4666static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4667{
4668 TCGv t0;
4669 if (rd == 0) {
4670 /* Treat as NOP. */
4671 return;
4672 }
4673 t0 = tcg_temp_new();
4674 gen_load_gpr(t0, rt);
4675 switch (opc) {
4676 case OPC_BITSWAP:
4677 gen_helper_bitswap(cpu_gpr[rd], t0);
4678 break;
4679#if defined(TARGET_MIPS64)
4680 case OPC_DBITSWAP:
4681 gen_helper_dbitswap(cpu_gpr[rd], t0);
4682 break;
4683#endif
4684 }
4685 tcg_temp_free(t0);
284b731a
LA
4686}
4687
1f1b4c00
YK
4688#ifndef CONFIG_USER_ONLY
4689/* CP0 (MMU and control) */
5204ea79
LA
4690static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4691{
4692 TCGv_i64 t0 = tcg_temp_new_i64();
4693 TCGv_i64 t1 = tcg_temp_new_i64();
4694
4695 tcg_gen_ext_tl_i64(t0, arg);
4696 tcg_gen_ld_i64(t1, cpu_env, off);
4697#if defined(TARGET_MIPS64)
4698 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4699#else
4700 tcg_gen_concat32_i64(t1, t1, t0);
4701#endif
4702 tcg_gen_st_i64(t1, cpu_env, off);
4703 tcg_temp_free_i64(t1);
4704 tcg_temp_free_i64(t0);
4705}
4706
4707static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4708{
4709 TCGv_i64 t0 = tcg_temp_new_i64();
4710 TCGv_i64 t1 = tcg_temp_new_i64();
4711
4712 tcg_gen_ext_tl_i64(t0, arg);
4713 tcg_gen_ld_i64(t1, cpu_env, off);
4714 tcg_gen_concat32_i64(t1, t1, t0);
4715 tcg_gen_st_i64(t1, cpu_env, off);
4716 tcg_temp_free_i64(t1);
4717 tcg_temp_free_i64(t0);
4718}
4719
4720static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4721{
4722 TCGv_i64 t0 = tcg_temp_new_i64();
4723
4724 tcg_gen_ld_i64(t0, cpu_env, off);
4725#if defined(TARGET_MIPS64)
4726 tcg_gen_shri_i64(t0, t0, 30);
4727#else
4728 tcg_gen_shri_i64(t0, t0, 32);
4729#endif
4730 gen_move_low32(arg, t0);
4731 tcg_temp_free_i64(t0);
4732}
4733
4734static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4735{
4736 TCGv_i64 t0 = tcg_temp_new_i64();
4737
4738 tcg_gen_ld_i64(t0, cpu_env, off);
4739 tcg_gen_shri_i64(t0, t0, 32 + shift);
4740 gen_move_low32(arg, t0);
4741 tcg_temp_free_i64(t0);
4742}
4743
d9bea114 4744static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4745{
d9bea114 4746 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4747
d9bea114
AJ
4748 tcg_gen_ld_i32(t0, cpu_env, off);
4749 tcg_gen_ext_i32_tl(arg, t0);
4750 tcg_temp_free_i32(t0);
4f57689a
TS
4751}
4752
d9bea114 4753static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4754{
d9bea114
AJ
4755 tcg_gen_ld_tl(arg, cpu_env, off);
4756 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4757}
4758
d9bea114 4759static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4760{
d9bea114 4761 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4762
d9bea114
AJ
4763 tcg_gen_trunc_tl_i32(t0, arg);
4764 tcg_gen_st_i32(t0, cpu_env, off);
4765 tcg_temp_free_i32(t0);
f1aa6320
TS
4766}
4767
d9bea114 4768static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4769{
d9bea114
AJ
4770 tcg_gen_ext32s_tl(arg, arg);
4771 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4772}
4773
5204ea79
LA
4774static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4775{
4776 const char *rn = "invalid";
4777
4778 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4779 goto mfhc0_read_zero;
4780 }
4781
4782 switch (reg) {
4783 case 2:
4784 switch (sel) {
4785 case 0:
4786 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4787 rn = "EntryLo0";
4788 break;
4789 default:
4790 goto mfhc0_read_zero;
4791 }
4792 break;
4793 case 3:
4794 switch (sel) {
4795 case 0:
4796 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4797 rn = "EntryLo1";
4798 break;
4799 default:
4800 goto mfhc0_read_zero;
4801 }
4802 break;
4803 case 17:
4804 switch (sel) {
4805 case 0:
4806 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4807 ctx->CP0_LLAddr_shift);
4808 rn = "LLAddr";
4809 break;
4810 default:
4811 goto mfhc0_read_zero;
4812 }
4813 break;
4814 case 28:
4815 switch (sel) {
4816 case 0:
4817 case 2:
4818 case 4:
4819 case 6:
4820 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4821 rn = "TagLo";
4822 break;
4823 default:
4824 goto mfhc0_read_zero;
4825 }
4826 break;
4827 default:
4828 goto mfhc0_read_zero;
4829 }
4830
4831 (void)rn; /* avoid a compiler warning */
4832 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4833 return;
4834
4835mfhc0_read_zero:
4836 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4837 tcg_gen_movi_tl(arg, 0);
4838}
4839
4840static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4841{
4842 const char *rn = "invalid";
4843 uint64_t mask = ctx->PAMask >> 36;
4844
4845 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4846 goto mthc0_nop;
4847 }
4848
4849 switch (reg) {
4850 case 2:
4851 switch (sel) {
4852 case 0:
4853 tcg_gen_andi_tl(arg, arg, mask);
4854 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4855 rn = "EntryLo0";
4856 break;
4857 default:
4858 goto mthc0_nop;
4859 }
4860 break;
4861 case 3:
4862 switch (sel) {
4863 case 0:
4864 tcg_gen_andi_tl(arg, arg, mask);
4865 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4866 rn = "EntryLo1";
4867 break;
4868 default:
4869 goto mthc0_nop;
4870 }
4871 break;
4872 case 17:
4873 switch (sel) {
4874 case 0:
4875 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4876 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4877 relevant for modern MIPS cores supporting MTHC0, therefore
4878 treating MTHC0 to LLAddr as NOP. */
4879 rn = "LLAddr";
4880 break;
4881 default:
4882 goto mthc0_nop;
4883 }
4884 break;
4885 case 28:
4886 switch (sel) {
4887 case 0:
4888 case 2:
4889 case 4:
4890 case 6:
4891 tcg_gen_andi_tl(arg, arg, mask);
4892 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4893 rn = "TagLo";
4894 break;
4895 default:
4896 goto mthc0_nop;
4897 }
4898 break;
4899 default:
4900 goto mthc0_nop;
4901 }
4902
4903 (void)rn; /* avoid a compiler warning */
4904mthc0_nop:
4905 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4906}
4907
e98c0d17
LA
4908static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4909{
4910 if (ctx->insn_flags & ISA_MIPS32R6) {
4911 tcg_gen_movi_tl(arg, 0);
4912 } else {
4913 tcg_gen_movi_tl(arg, ~0);
4914 }
4915}
4916
f31b035a
LA
4917#define CP0_CHECK(c) \
4918 do { \
4919 if (!(c)) { \
4920 goto cp0_unimplemented; \
4921 } \
4922 } while (0)
4923
d75c135e 4924static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4925{
7a387fff 4926 const char *rn = "invalid";
873eb012 4927
e189e748 4928 if (sel != 0)
d75c135e 4929 check_insn(ctx, ISA_MIPS32);
e189e748 4930
873eb012
TS
4931 switch (reg) {
4932 case 0:
7a387fff
TS
4933 switch (sel) {
4934 case 0:
7db13fae 4935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4936 rn = "Index";
4937 break;
4938 case 1:
f31b035a 4939 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4940 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4941 rn = "MVPControl";
ead9360e 4942 break;
7a387fff 4943 case 2:
f31b035a 4944 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4945 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4946 rn = "MVPConf0";
ead9360e 4947 break;
7a387fff 4948 case 3:
f31b035a 4949 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4950 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4951 rn = "MVPConf1";
ead9360e 4952 break;
7a387fff 4953 default:
f31b035a 4954 goto cp0_unimplemented;
7a387fff 4955 }
873eb012
TS
4956 break;
4957 case 1:
7a387fff
TS
4958 switch (sel) {
4959 case 0:
f31b035a 4960 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4961 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4962 rn = "Random";
2423f660 4963 break;
7a387fff 4964 case 1:
f31b035a 4965 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4967 rn = "VPEControl";
ead9360e 4968 break;
7a387fff 4969 case 2:
f31b035a 4970 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4972 rn = "VPEConf0";
ead9360e 4973 break;
7a387fff 4974 case 3:
f31b035a 4975 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4976 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4977 rn = "VPEConf1";
ead9360e 4978 break;
7a387fff 4979 case 4:
f31b035a 4980 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4981 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4982 rn = "YQMask";
ead9360e 4983 break;
7a387fff 4984 case 5:
f31b035a 4985 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4986 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4987 rn = "VPESchedule";
ead9360e 4988 break;
7a387fff 4989 case 6:
f31b035a 4990 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4991 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4992 rn = "VPEScheFBack";
ead9360e 4993 break;
7a387fff 4994 case 7:
f31b035a 4995 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4996 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4997 rn = "VPEOpt";
ead9360e 4998 break;
7a387fff 4999 default:
f31b035a 5000 goto cp0_unimplemented;
7a387fff 5001 }
873eb012
TS
5002 break;
5003 case 2:
7a387fff
TS
5004 switch (sel) {
5005 case 0:
284b731a
LA
5006 {
5007 TCGv_i64 tmp = tcg_temp_new_i64();
5008 tcg_gen_ld_i64(tmp, cpu_env,
5009 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5010#if defined(TARGET_MIPS64)
284b731a
LA
5011 if (ctx->rxi) {
5012 /* Move RI/XI fields to bits 31:30 */
5013 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5014 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5015 }
7207c7f9 5016#endif
284b731a
LA
5017 gen_move_low32(arg, tmp);
5018 tcg_temp_free_i64(tmp);
5019 }
2423f660
TS
5020 rn = "EntryLo0";
5021 break;
7a387fff 5022 case 1:
f31b035a 5023 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5024 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5025 rn = "TCStatus";
ead9360e 5026 break;
7a387fff 5027 case 2:
f31b035a 5028 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5029 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5030 rn = "TCBind";
ead9360e 5031 break;
7a387fff 5032 case 3:
f31b035a 5033 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5034 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5035 rn = "TCRestart";
ead9360e 5036 break;
7a387fff 5037 case 4:
f31b035a 5038 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5039 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5040 rn = "TCHalt";
ead9360e 5041 break;
7a387fff 5042 case 5:
f31b035a 5043 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5044 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5045 rn = "TCContext";
ead9360e 5046 break;
7a387fff 5047 case 6:
f31b035a 5048 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5049 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5050 rn = "TCSchedule";
ead9360e 5051 break;
7a387fff 5052 case 7:
f31b035a 5053 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5054 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5055 rn = "TCScheFBack";
ead9360e 5056 break;
7a387fff 5057 default:
f31b035a 5058 goto cp0_unimplemented;
7a387fff 5059 }
873eb012
TS
5060 break;
5061 case 3:
7a387fff
TS
5062 switch (sel) {
5063 case 0:
284b731a
LA
5064 {
5065 TCGv_i64 tmp = tcg_temp_new_i64();
5066 tcg_gen_ld_i64(tmp, cpu_env,
5067 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5068#if defined(TARGET_MIPS64)
284b731a
LA
5069 if (ctx->rxi) {
5070 /* Move RI/XI fields to bits 31:30 */
5071 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5072 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5073 }
7207c7f9 5074#endif
284b731a
LA
5075 gen_move_low32(arg, tmp);
5076 tcg_temp_free_i64(tmp);
5077 }
2423f660
TS
5078 rn = "EntryLo1";
5079 break;
7a387fff 5080 default:
f31b035a 5081 goto cp0_unimplemented;
1579a72e 5082 }
873eb012
TS
5083 break;
5084 case 4:
7a387fff
TS
5085 switch (sel) {
5086 case 0:
7db13fae 5087 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5088 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5089 rn = "Context";
5090 break;
7a387fff 5091 case 1:
d9bea114 5092// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5093 rn = "ContextConfig";
f31b035a 5094 goto cp0_unimplemented;
2423f660 5095// break;
d279279e 5096 case 2:
f31b035a
LA
5097 CP0_CHECK(ctx->ulri);
5098 tcg_gen_ld32s_tl(arg, cpu_env,
5099 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5100 rn = "UserLocal";
d279279e 5101 break;
7a387fff 5102 default:
f31b035a 5103 goto cp0_unimplemented;
1579a72e 5104 }
873eb012
TS
5105 break;
5106 case 5:
7a387fff
TS
5107 switch (sel) {
5108 case 0:
7db13fae 5109 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5110 rn = "PageMask";
5111 break;
7a387fff 5112 case 1:
d75c135e 5113 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5115 rn = "PageGrain";
5116 break;
7a387fff 5117 default:
f31b035a 5118 goto cp0_unimplemented;
1579a72e 5119 }
873eb012
TS
5120 break;
5121 case 6:
7a387fff
TS
5122 switch (sel) {
5123 case 0:
7db13fae 5124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5125 rn = "Wired";
5126 break;
7a387fff 5127 case 1:
d75c135e 5128 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5129 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5130 rn = "SRSConf0";
ead9360e 5131 break;
7a387fff 5132 case 2:
d75c135e 5133 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5134 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5135 rn = "SRSConf1";
ead9360e 5136 break;
7a387fff 5137 case 3:
d75c135e 5138 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5139 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5140 rn = "SRSConf2";
ead9360e 5141 break;
7a387fff 5142 case 4:
d75c135e 5143 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5145 rn = "SRSConf3";
ead9360e 5146 break;
7a387fff 5147 case 5:
d75c135e 5148 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5150 rn = "SRSConf4";
ead9360e 5151 break;
7a387fff 5152 default:
f31b035a 5153 goto cp0_unimplemented;
1579a72e 5154 }
873eb012 5155 break;
8c0fdd85 5156 case 7:
7a387fff
TS
5157 switch (sel) {
5158 case 0:
d75c135e 5159 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5161 rn = "HWREna";
5162 break;
7a387fff 5163 default:
f31b035a 5164 goto cp0_unimplemented;
1579a72e 5165 }
8c0fdd85 5166 break;
873eb012 5167 case 8:
7a387fff
TS
5168 switch (sel) {
5169 case 0:
7db13fae 5170 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5171 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5172 rn = "BadVAddr";
2423f660 5173 break;
aea14095 5174 case 1:
f31b035a
LA
5175 CP0_CHECK(ctx->bi);
5176 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5177 rn = "BadInstr";
aea14095
LA
5178 break;
5179 case 2:
f31b035a
LA
5180 CP0_CHECK(ctx->bp);
5181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5182 rn = "BadInstrP";
aea14095 5183 break;
7a387fff 5184 default:
f31b035a 5185 goto cp0_unimplemented;
aea14095 5186 }
873eb012
TS
5187 break;
5188 case 9:
7a387fff
TS
5189 switch (sel) {
5190 case 0:
2e70f6ef 5191 /* Mark as an IO operation because we read the time. */
bd79255d 5192 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5193 gen_io_start();
bd79255d 5194 }
895c2d04 5195 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5196 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5197 gen_io_end();
2e70f6ef 5198 }
55807224
EI
5199 /* Break the TB to be able to take timer interrupts immediately
5200 after reading count. */
5201 ctx->bstate = BS_STOP;
2423f660
TS
5202 rn = "Count";
5203 break;
5204 /* 6,7 are implementation dependent */
7a387fff 5205 default:
f31b035a 5206 goto cp0_unimplemented;
2423f660 5207 }
873eb012
TS
5208 break;
5209 case 10:
7a387fff
TS
5210 switch (sel) {
5211 case 0:
7db13fae 5212 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5213 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5214 rn = "EntryHi";
5215 break;
7a387fff 5216 default:
f31b035a 5217 goto cp0_unimplemented;
1579a72e 5218 }
873eb012
TS
5219 break;
5220 case 11:
7a387fff
TS
5221 switch (sel) {
5222 case 0:
7db13fae 5223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5224 rn = "Compare";
5225 break;
5226 /* 6,7 are implementation dependent */
7a387fff 5227 default:
f31b035a 5228 goto cp0_unimplemented;
2423f660 5229 }
873eb012
TS
5230 break;
5231 case 12:
7a387fff
TS
5232 switch (sel) {
5233 case 0:
7db13fae 5234 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5235 rn = "Status";
5236 break;
7a387fff 5237 case 1:
d75c135e 5238 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5240 rn = "IntCtl";
5241 break;
7a387fff 5242 case 2:
d75c135e 5243 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5244 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5245 rn = "SRSCtl";
5246 break;
7a387fff 5247 case 3:
d75c135e 5248 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5250 rn = "SRSMap";
fd88b6ab 5251 break;
7a387fff 5252 default:
f31b035a 5253 goto cp0_unimplemented;
7a387fff 5254 }
873eb012
TS
5255 break;
5256 case 13:
7a387fff
TS
5257 switch (sel) {
5258 case 0:
7db13fae 5259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5260 rn = "Cause";
5261 break;
7a387fff 5262 default:
f31b035a 5263 goto cp0_unimplemented;
7a387fff 5264 }
873eb012
TS
5265 break;
5266 case 14:
7a387fff
TS
5267 switch (sel) {
5268 case 0:
7db13fae 5269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5270 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5271 rn = "EPC";
5272 break;
7a387fff 5273 default:
f31b035a 5274 goto cp0_unimplemented;
1579a72e 5275 }
873eb012
TS
5276 break;
5277 case 15:
7a387fff
TS
5278 switch (sel) {
5279 case 0:
7db13fae 5280 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5281 rn = "PRid";
5282 break;
7a387fff 5283 case 1:
d75c135e 5284 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5286 rn = "EBase";
5287 break;
7a387fff 5288 default:
f31b035a 5289 goto cp0_unimplemented;
7a387fff 5290 }
873eb012
TS
5291 break;
5292 case 16:
5293 switch (sel) {
5294 case 0:
7db13fae 5295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5296 rn = "Config";
5297 break;
5298 case 1:
7db13fae 5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5300 rn = "Config1";
5301 break;
7a387fff 5302 case 2:
7db13fae 5303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5304 rn = "Config2";
5305 break;
5306 case 3:
7db13fae 5307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5308 rn = "Config3";
5309 break;
b4160af1
PJ
5310 case 4:
5311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5312 rn = "Config4";
5313 break;
b4dd99a3
PJ
5314 case 5:
5315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5316 rn = "Config5";
5317 break;
e397ee33
TS
5318 /* 6,7 are implementation dependent */
5319 case 6:
7db13fae 5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5321 rn = "Config6";
5322 break;
5323 case 7:
7db13fae 5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5325 rn = "Config7";
5326 break;
873eb012 5327 default:
f31b035a 5328 goto cp0_unimplemented;
873eb012
TS
5329 }
5330 break;
5331 case 17:
7a387fff
TS
5332 switch (sel) {
5333 case 0:
895c2d04 5334 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5335 rn = "LLAddr";
5336 break;
7a387fff 5337 default:
f31b035a 5338 goto cp0_unimplemented;
7a387fff 5339 }
873eb012
TS
5340 break;
5341 case 18:
7a387fff 5342 switch (sel) {
fd88b6ab 5343 case 0 ... 7:
895c2d04 5344 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5345 rn = "WatchLo";
5346 break;
7a387fff 5347 default:
f31b035a 5348 goto cp0_unimplemented;
7a387fff 5349 }
873eb012
TS
5350 break;
5351 case 19:
7a387fff 5352 switch (sel) {
fd88b6ab 5353 case 0 ...7:
895c2d04 5354 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5355 rn = "WatchHi";
5356 break;
7a387fff 5357 default:
f31b035a 5358 goto cp0_unimplemented;
7a387fff 5359 }
873eb012 5360 break;
8c0fdd85 5361 case 20:
7a387fff
TS
5362 switch (sel) {
5363 case 0:
d26bc211 5364#if defined(TARGET_MIPS64)
d75c135e 5365 check_insn(ctx, ISA_MIPS3);
7db13fae 5366 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5367 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5368 rn = "XContext";
5369 break;
703eaf37 5370#endif
7a387fff 5371 default:
f31b035a 5372 goto cp0_unimplemented;
7a387fff 5373 }
8c0fdd85
TS
5374 break;
5375 case 21:
7a387fff 5376 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5377 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5378 switch (sel) {
5379 case 0:
7db13fae 5380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5381 rn = "Framemask";
5382 break;
7a387fff 5383 default:
f31b035a 5384 goto cp0_unimplemented;
7a387fff 5385 }
8c0fdd85
TS
5386 break;
5387 case 22:
d9bea114 5388 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5389 rn = "'Diagnostic"; /* implementation dependent */
5390 break;
873eb012 5391 case 23:
7a387fff
TS
5392 switch (sel) {
5393 case 0:
895c2d04 5394 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5395 rn = "Debug";
5396 break;
7a387fff 5397 case 1:
d9bea114 5398// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5399 rn = "TraceControl";
5400// break;
7a387fff 5401 case 2:
d9bea114 5402// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5403 rn = "TraceControl2";
5404// break;
7a387fff 5405 case 3:
d9bea114 5406// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5407 rn = "UserTraceData";
5408// break;
7a387fff 5409 case 4:
d9bea114 5410// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5411 rn = "TraceBPC";
5412// break;
7a387fff 5413 default:
f31b035a 5414 goto cp0_unimplemented;
7a387fff 5415 }
873eb012
TS
5416 break;
5417 case 24:
7a387fff
TS
5418 switch (sel) {
5419 case 0:
f0b3f3ae 5420 /* EJTAG support */
7db13fae 5421 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5422 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5423 rn = "DEPC";
5424 break;
7a387fff 5425 default:
f31b035a 5426 goto cp0_unimplemented;
7a387fff 5427 }
873eb012 5428 break;
8c0fdd85 5429 case 25:
7a387fff
TS
5430 switch (sel) {
5431 case 0:
7db13fae 5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5433 rn = "Performance0";
7a387fff
TS
5434 break;
5435 case 1:
d9bea114 5436// gen_helper_mfc0_performance1(arg);
2423f660
TS
5437 rn = "Performance1";
5438// break;
7a387fff 5439 case 2:
d9bea114 5440// gen_helper_mfc0_performance2(arg);
2423f660
TS
5441 rn = "Performance2";
5442// break;
7a387fff 5443 case 3:
d9bea114 5444// gen_helper_mfc0_performance3(arg);
2423f660
TS
5445 rn = "Performance3";
5446// break;
7a387fff 5447 case 4:
d9bea114 5448// gen_helper_mfc0_performance4(arg);
2423f660
TS
5449 rn = "Performance4";
5450// break;
7a387fff 5451 case 5:
d9bea114 5452// gen_helper_mfc0_performance5(arg);
2423f660
TS
5453 rn = "Performance5";
5454// break;
7a387fff 5455 case 6:
d9bea114 5456// gen_helper_mfc0_performance6(arg);
2423f660
TS
5457 rn = "Performance6";
5458// break;
7a387fff 5459 case 7:
d9bea114 5460// gen_helper_mfc0_performance7(arg);
2423f660
TS
5461 rn = "Performance7";
5462// break;
7a387fff 5463 default:
f31b035a 5464 goto cp0_unimplemented;
7a387fff 5465 }
8c0fdd85
TS
5466 break;
5467 case 26:
d9bea114 5468 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5469 rn = "ECC";
5470 break;
8c0fdd85 5471 case 27:
7a387fff 5472 switch (sel) {
7a387fff 5473 case 0 ... 3:
d9bea114 5474 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5475 rn = "CacheErr";
5476 break;
7a387fff 5477 default:
f31b035a 5478 goto cp0_unimplemented;
7a387fff 5479 }
8c0fdd85 5480 break;
873eb012
TS
5481 case 28:
5482 switch (sel) {
5483 case 0:
7a387fff
TS
5484 case 2:
5485 case 4:
5486 case 6:
284b731a
LA
5487 {
5488 TCGv_i64 tmp = tcg_temp_new_i64();
5489 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5490 gen_move_low32(arg, tmp);
5491 tcg_temp_free_i64(tmp);
5492 }
873eb012
TS
5493 rn = "TagLo";
5494 break;
5495 case 1:
7a387fff
TS
5496 case 3:
5497 case 5:
5498 case 7:
7db13fae 5499 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5500 rn = "DataLo";
5501 break;
5502 default:
f31b035a 5503 goto cp0_unimplemented;
873eb012
TS
5504 }
5505 break;
8c0fdd85 5506 case 29:
7a387fff
TS
5507 switch (sel) {
5508 case 0:
5509 case 2:
5510 case 4:
5511 case 6:
7db13fae 5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5513 rn = "TagHi";
5514 break;
5515 case 1:
5516 case 3:
5517 case 5:
5518 case 7:
7db13fae 5519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5520 rn = "DataHi";
5521 break;
5522 default:
f31b035a 5523 goto cp0_unimplemented;
7a387fff 5524 }
8c0fdd85 5525 break;
873eb012 5526 case 30:
7a387fff
TS
5527 switch (sel) {
5528 case 0:
7db13fae 5529 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5530 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5531 rn = "ErrorEPC";
5532 break;
7a387fff 5533 default:
f31b035a 5534 goto cp0_unimplemented;
7a387fff 5535 }
873eb012
TS
5536 break;
5537 case 31:
7a387fff
TS
5538 switch (sel) {
5539 case 0:
f0b3f3ae 5540 /* EJTAG support */
7db13fae 5541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5542 rn = "DESAVE";
5543 break;
e98c0d17 5544 case 2 ... 7:
f31b035a
LA
5545 CP0_CHECK(ctx->kscrexist & (1 << sel));
5546 tcg_gen_ld_tl(arg, cpu_env,
5547 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5548 tcg_gen_ext32s_tl(arg, arg);
5549 rn = "KScratch";
e98c0d17 5550 break;
7a387fff 5551 default:
f31b035a 5552 goto cp0_unimplemented;
7a387fff 5553 }
873eb012
TS
5554 break;
5555 default:
f31b035a 5556 goto cp0_unimplemented;
873eb012 5557 }
2abf314d 5558 (void)rn; /* avoid a compiler warning */
d12d51d5 5559 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5560 return;
5561
f31b035a 5562cp0_unimplemented:
d12d51d5 5563 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5564 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5565}
5566
d75c135e 5567static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5568{
7a387fff
TS
5569 const char *rn = "invalid";
5570
e189e748 5571 if (sel != 0)
d75c135e 5572 check_insn(ctx, ISA_MIPS32);
e189e748 5573
bd79255d 5574 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5575 gen_io_start();
bd79255d 5576 }
2e70f6ef 5577
8c0fdd85
TS
5578 switch (reg) {
5579 case 0:
7a387fff
TS
5580 switch (sel) {
5581 case 0:
895c2d04 5582 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5583 rn = "Index";
5584 break;
5585 case 1:
f31b035a 5586 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5587 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5588 rn = "MVPControl";
ead9360e 5589 break;
7a387fff 5590 case 2:
f31b035a 5591 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5592 /* ignored */
7a387fff 5593 rn = "MVPConf0";
ead9360e 5594 break;
7a387fff 5595 case 3:
f31b035a 5596 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5597 /* ignored */
7a387fff 5598 rn = "MVPConf1";
ead9360e 5599 break;
7a387fff 5600 default:
f31b035a 5601 goto cp0_unimplemented;
7a387fff 5602 }
8c0fdd85
TS
5603 break;
5604 case 1:
7a387fff
TS
5605 switch (sel) {
5606 case 0:
2423f660 5607 /* ignored */
7a387fff 5608 rn = "Random";
2423f660 5609 break;
7a387fff 5610 case 1:
f31b035a 5611 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5612 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5613 rn = "VPEControl";
ead9360e 5614 break;
7a387fff 5615 case 2:
f31b035a 5616 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5617 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5618 rn = "VPEConf0";
ead9360e 5619 break;
7a387fff 5620 case 3:
f31b035a 5621 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5622 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5623 rn = "VPEConf1";
ead9360e 5624 break;
7a387fff 5625 case 4:
f31b035a 5626 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5627 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5628 rn = "YQMask";
ead9360e 5629 break;
7a387fff 5630 case 5:
f31b035a 5631 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5632 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5633 rn = "VPESchedule";
ead9360e 5634 break;
7a387fff 5635 case 6:
f31b035a 5636 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5637 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5638 rn = "VPEScheFBack";
ead9360e 5639 break;
7a387fff 5640 case 7:
f31b035a 5641 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5642 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5643 rn = "VPEOpt";
ead9360e 5644 break;
7a387fff 5645 default:
f31b035a 5646 goto cp0_unimplemented;
7a387fff 5647 }
8c0fdd85
TS
5648 break;
5649 case 2:
7a387fff
TS
5650 switch (sel) {
5651 case 0:
895c2d04 5652 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5653 rn = "EntryLo0";
5654 break;
7a387fff 5655 case 1:
f31b035a 5656 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5657 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5658 rn = "TCStatus";
ead9360e 5659 break;
7a387fff 5660 case 2:
f31b035a 5661 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5662 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5663 rn = "TCBind";
ead9360e 5664 break;
7a387fff 5665 case 3:
f31b035a 5666 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5667 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5668 rn = "TCRestart";
ead9360e 5669 break;
7a387fff 5670 case 4:
f31b035a 5671 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5672 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5673 rn = "TCHalt";
ead9360e 5674 break;
7a387fff 5675 case 5:
f31b035a 5676 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5677 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5678 rn = "TCContext";
ead9360e 5679 break;
7a387fff 5680 case 6:
f31b035a 5681 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5682 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5683 rn = "TCSchedule";
ead9360e 5684 break;
7a387fff 5685 case 7:
f31b035a 5686 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5687 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5688 rn = "TCScheFBack";
ead9360e 5689 break;
7a387fff 5690 default:
f31b035a 5691 goto cp0_unimplemented;
7a387fff 5692 }
8c0fdd85
TS
5693 break;
5694 case 3:
7a387fff
TS
5695 switch (sel) {
5696 case 0:
895c2d04 5697 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5698 rn = "EntryLo1";
5699 break;
7a387fff 5700 default:
f31b035a 5701 goto cp0_unimplemented;
876d4b07 5702 }
8c0fdd85
TS
5703 break;
5704 case 4:
7a387fff
TS
5705 switch (sel) {
5706 case 0:
895c2d04 5707 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5708 rn = "Context";
5709 break;
7a387fff 5710 case 1:
895c2d04 5711// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5712 rn = "ContextConfig";
f31b035a 5713 goto cp0_unimplemented;
2423f660 5714// break;
d279279e 5715 case 2:
f31b035a
LA
5716 CP0_CHECK(ctx->ulri);
5717 tcg_gen_st_tl(arg, cpu_env,
5718 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5719 rn = "UserLocal";
d279279e 5720 break;
7a387fff 5721 default:
f31b035a 5722 goto cp0_unimplemented;
876d4b07 5723 }
8c0fdd85
TS
5724 break;
5725 case 5:
7a387fff
TS
5726 switch (sel) {
5727 case 0:
895c2d04 5728 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5729 rn = "PageMask";
5730 break;
7a387fff 5731 case 1:
d75c135e 5732 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5733 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5734 rn = "PageGrain";
e117f526 5735 ctx->bstate = BS_STOP;
2423f660 5736 break;
7a387fff 5737 default:
f31b035a 5738 goto cp0_unimplemented;
876d4b07 5739 }
8c0fdd85
TS
5740 break;
5741 case 6:
7a387fff
TS
5742 switch (sel) {
5743 case 0:
895c2d04 5744 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5745 rn = "Wired";
5746 break;
7a387fff 5747 case 1:
d75c135e 5748 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5749 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5750 rn = "SRSConf0";
ead9360e 5751 break;
7a387fff 5752 case 2:
d75c135e 5753 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5754 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5755 rn = "SRSConf1";
ead9360e 5756 break;
7a387fff 5757 case 3:
d75c135e 5758 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5759 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5760 rn = "SRSConf2";
ead9360e 5761 break;
7a387fff 5762 case 4:
d75c135e 5763 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5764 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5765 rn = "SRSConf3";
ead9360e 5766 break;
7a387fff 5767 case 5:
d75c135e 5768 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5769 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5770 rn = "SRSConf4";
ead9360e 5771 break;
7a387fff 5772 default:
f31b035a 5773 goto cp0_unimplemented;
876d4b07 5774 }
8c0fdd85
TS
5775 break;
5776 case 7:
7a387fff
TS
5777 switch (sel) {
5778 case 0:
d75c135e 5779 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5780 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5781 ctx->bstate = BS_STOP;
2423f660
TS
5782 rn = "HWREna";
5783 break;
7a387fff 5784 default:
f31b035a 5785 goto cp0_unimplemented;
876d4b07 5786 }
8c0fdd85
TS
5787 break;
5788 case 8:
aea14095
LA
5789 switch (sel) {
5790 case 0:
5791 /* ignored */
5792 rn = "BadVAddr";
5793 break;
5794 case 1:
5795 /* ignored */
5796 rn = "BadInstr";
5797 break;
5798 case 2:
5799 /* ignored */
5800 rn = "BadInstrP";
5801 break;
5802 default:
f31b035a 5803 goto cp0_unimplemented;
aea14095 5804 }
8c0fdd85
TS
5805 break;
5806 case 9:
7a387fff
TS
5807 switch (sel) {
5808 case 0:
895c2d04 5809 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5810 rn = "Count";
5811 break;
876d4b07 5812 /* 6,7 are implementation dependent */
7a387fff 5813 default:
f31b035a 5814 goto cp0_unimplemented;
876d4b07 5815 }
8c0fdd85
TS
5816 break;
5817 case 10:
7a387fff
TS
5818 switch (sel) {
5819 case 0:
895c2d04 5820 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5821 rn = "EntryHi";
5822 break;
7a387fff 5823 default:
f31b035a 5824 goto cp0_unimplemented;
876d4b07 5825 }
8c0fdd85
TS
5826 break;
5827 case 11:
7a387fff
TS
5828 switch (sel) {
5829 case 0:
895c2d04 5830 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5831 rn = "Compare";
5832 break;
5833 /* 6,7 are implementation dependent */
7a387fff 5834 default:
f31b035a 5835 goto cp0_unimplemented;
876d4b07 5836 }
8c0fdd85
TS
5837 break;
5838 case 12:
7a387fff
TS
5839 switch (sel) {
5840 case 0:
867abc7e 5841 save_cpu_state(ctx, 1);
895c2d04 5842 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5843 /* BS_STOP isn't good enough here, hflags may have changed. */
5844 gen_save_pc(ctx->pc + 4);
5845 ctx->bstate = BS_EXCP;
2423f660
TS
5846 rn = "Status";
5847 break;
7a387fff 5848 case 1:
d75c135e 5849 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5850 gen_helper_mtc0_intctl(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 = "IntCtl";
5854 break;
7a387fff 5855 case 2:
d75c135e 5856 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5857 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5858 /* Stop translation as we may have switched the execution mode */
5859 ctx->bstate = BS_STOP;
2423f660
TS
5860 rn = "SRSCtl";
5861 break;
7a387fff 5862 case 3:
d75c135e 5863 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5864 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5865 /* Stop translation as we may have switched the execution mode */
5866 ctx->bstate = BS_STOP;
2423f660 5867 rn = "SRSMap";
fd88b6ab 5868 break;
7a387fff 5869 default:
f31b035a 5870 goto cp0_unimplemented;
876d4b07 5871 }
8c0fdd85
TS
5872 break;
5873 case 13:
7a387fff
TS
5874 switch (sel) {
5875 case 0:
867abc7e 5876 save_cpu_state(ctx, 1);
895c2d04 5877 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5878 rn = "Cause";
5879 break;
7a387fff 5880 default:
f31b035a 5881 goto cp0_unimplemented;
876d4b07 5882 }
8c0fdd85
TS
5883 break;
5884 case 14:
7a387fff
TS
5885 switch (sel) {
5886 case 0:
7db13fae 5887 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5888 rn = "EPC";
5889 break;
7a387fff 5890 default:
f31b035a 5891 goto cp0_unimplemented;
876d4b07 5892 }
8c0fdd85
TS
5893 break;
5894 case 15:
7a387fff
TS
5895 switch (sel) {
5896 case 0:
2423f660
TS
5897 /* ignored */
5898 rn = "PRid";
5899 break;
7a387fff 5900 case 1:
d75c135e 5901 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5902 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5903 rn = "EBase";
5904 break;
7a387fff 5905 default:
f31b035a 5906 goto cp0_unimplemented;
1579a72e 5907 }
8c0fdd85
TS
5908 break;
5909 case 16:
5910 switch (sel) {
5911 case 0:
895c2d04 5912 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5913 rn = "Config";
2423f660
TS
5914 /* Stop translation as we may have switched the execution mode */
5915 ctx->bstate = BS_STOP;
7a387fff
TS
5916 break;
5917 case 1:
e397ee33 5918 /* ignored, read only */
7a387fff
TS
5919 rn = "Config1";
5920 break;
5921 case 2:
895c2d04 5922 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5923 rn = "Config2";
2423f660
TS
5924 /* Stop translation as we may have switched the execution mode */
5925 ctx->bstate = BS_STOP;
8c0fdd85 5926 break;
7a387fff 5927 case 3:
90f12d73 5928 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5929 rn = "Config3";
90f12d73
MR
5930 /* Stop translation as we may have switched the execution mode */
5931 ctx->bstate = BS_STOP;
7a387fff 5932 break;
b4160af1
PJ
5933 case 4:
5934 gen_helper_mtc0_config4(cpu_env, arg);
5935 rn = "Config4";
5936 ctx->bstate = BS_STOP;
5937 break;
b4dd99a3
PJ
5938 case 5:
5939 gen_helper_mtc0_config5(cpu_env, arg);
5940 rn = "Config5";
5941 /* Stop translation as we may have switched the execution mode */
5942 ctx->bstate = BS_STOP;
5943 break;
e397ee33
TS
5944 /* 6,7 are implementation dependent */
5945 case 6:
5946 /* ignored */
5947 rn = "Config6";
5948 break;
5949 case 7:
5950 /* ignored */
5951 rn = "Config7";
5952 break;
8c0fdd85
TS
5953 default:
5954 rn = "Invalid config selector";
f31b035a 5955 goto cp0_unimplemented;
8c0fdd85
TS
5956 }
5957 break;
5958 case 17:
7a387fff
TS
5959 switch (sel) {
5960 case 0:
895c2d04 5961 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5962 rn = "LLAddr";
5963 break;
7a387fff 5964 default:
f31b035a 5965 goto cp0_unimplemented;
7a387fff 5966 }
8c0fdd85
TS
5967 break;
5968 case 18:
7a387fff 5969 switch (sel) {
fd88b6ab 5970 case 0 ... 7:
895c2d04 5971 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5972 rn = "WatchLo";
5973 break;
7a387fff 5974 default:
f31b035a 5975 goto cp0_unimplemented;
7a387fff 5976 }
8c0fdd85
TS
5977 break;
5978 case 19:
7a387fff 5979 switch (sel) {
fd88b6ab 5980 case 0 ... 7:
895c2d04 5981 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5982 rn = "WatchHi";
5983 break;
7a387fff 5984 default:
f31b035a 5985 goto cp0_unimplemented;
7a387fff 5986 }
8c0fdd85
TS
5987 break;
5988 case 20:
7a387fff
TS
5989 switch (sel) {
5990 case 0:
d26bc211 5991#if defined(TARGET_MIPS64)
d75c135e 5992 check_insn(ctx, ISA_MIPS3);
895c2d04 5993 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5994 rn = "XContext";
5995 break;
703eaf37 5996#endif
7a387fff 5997 default:
f31b035a 5998 goto cp0_unimplemented;
7a387fff 5999 }
8c0fdd85
TS
6000 break;
6001 case 21:
7a387fff 6002 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6003 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6004 switch (sel) {
6005 case 0:
895c2d04 6006 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6007 rn = "Framemask";
6008 break;
7a387fff 6009 default:
f31b035a 6010 goto cp0_unimplemented;
7a387fff
TS
6011 }
6012 break;
8c0fdd85 6013 case 22:
7a387fff
TS
6014 /* ignored */
6015 rn = "Diagnostic"; /* implementation dependent */
2423f660 6016 break;
8c0fdd85 6017 case 23:
7a387fff
TS
6018 switch (sel) {
6019 case 0:
895c2d04 6020 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6021 /* BS_STOP isn't good enough here, hflags may have changed. */
6022 gen_save_pc(ctx->pc + 4);
6023 ctx->bstate = BS_EXCP;
2423f660
TS
6024 rn = "Debug";
6025 break;
7a387fff 6026 case 1:
895c2d04 6027// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6028 rn = "TraceControl";
8487327a
TS
6029 /* Stop translation as we may have switched the execution mode */
6030 ctx->bstate = BS_STOP;
2423f660 6031// break;
7a387fff 6032 case 2:
895c2d04 6033// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6034 rn = "TraceControl2";
8487327a
TS
6035 /* Stop translation as we may have switched the execution mode */
6036 ctx->bstate = BS_STOP;
2423f660 6037// break;
7a387fff 6038 case 3:
8487327a
TS
6039 /* Stop translation as we may have switched the execution mode */
6040 ctx->bstate = BS_STOP;
895c2d04 6041// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6042 rn = "UserTraceData";
8487327a
TS
6043 /* Stop translation as we may have switched the execution mode */
6044 ctx->bstate = BS_STOP;
2423f660 6045// break;
7a387fff 6046 case 4:
895c2d04 6047// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6048 /* Stop translation as we may have switched the execution mode */
6049 ctx->bstate = BS_STOP;
2423f660
TS
6050 rn = "TraceBPC";
6051// break;
7a387fff 6052 default:
f31b035a 6053 goto cp0_unimplemented;
7a387fff 6054 }
8c0fdd85
TS
6055 break;
6056 case 24:
7a387fff
TS
6057 switch (sel) {
6058 case 0:
f1aa6320 6059 /* EJTAG support */
7db13fae 6060 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6061 rn = "DEPC";
6062 break;
7a387fff 6063 default:
f31b035a 6064 goto cp0_unimplemented;
7a387fff 6065 }
8c0fdd85
TS
6066 break;
6067 case 25:
7a387fff
TS
6068 switch (sel) {
6069 case 0:
895c2d04 6070 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6071 rn = "Performance0";
6072 break;
7a387fff 6073 case 1:
d9bea114 6074// gen_helper_mtc0_performance1(arg);
2423f660
TS
6075 rn = "Performance1";
6076// break;
7a387fff 6077 case 2:
d9bea114 6078// gen_helper_mtc0_performance2(arg);
2423f660
TS
6079 rn = "Performance2";
6080// break;
7a387fff 6081 case 3:
d9bea114 6082// gen_helper_mtc0_performance3(arg);
2423f660
TS
6083 rn = "Performance3";
6084// break;
7a387fff 6085 case 4:
d9bea114 6086// gen_helper_mtc0_performance4(arg);
2423f660
TS
6087 rn = "Performance4";
6088// break;
7a387fff 6089 case 5:
d9bea114 6090// gen_helper_mtc0_performance5(arg);
2423f660
TS
6091 rn = "Performance5";
6092// break;
7a387fff 6093 case 6:
d9bea114 6094// gen_helper_mtc0_performance6(arg);
2423f660
TS
6095 rn = "Performance6";
6096// break;
7a387fff 6097 case 7:
d9bea114 6098// gen_helper_mtc0_performance7(arg);
2423f660
TS
6099 rn = "Performance7";
6100// break;
7a387fff 6101 default:
f31b035a 6102 goto cp0_unimplemented;
7a387fff 6103 }
8c0fdd85
TS
6104 break;
6105 case 26:
2423f660 6106 /* ignored */
8c0fdd85 6107 rn = "ECC";
2423f660 6108 break;
8c0fdd85 6109 case 27:
7a387fff
TS
6110 switch (sel) {
6111 case 0 ... 3:
2423f660
TS
6112 /* ignored */
6113 rn = "CacheErr";
6114 break;
7a387fff 6115 default:
f31b035a 6116 goto cp0_unimplemented;
7a387fff 6117 }
8c0fdd85
TS
6118 break;
6119 case 28:
6120 switch (sel) {
6121 case 0:
7a387fff
TS
6122 case 2:
6123 case 4:
6124 case 6:
895c2d04 6125 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6126 rn = "TagLo";
6127 break;
7a387fff
TS
6128 case 1:
6129 case 3:
6130 case 5:
6131 case 7:
895c2d04 6132 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6133 rn = "DataLo";
6134 break;
8c0fdd85 6135 default:
f31b035a 6136 goto cp0_unimplemented;
8c0fdd85
TS
6137 }
6138 break;
6139 case 29:
7a387fff
TS
6140 switch (sel) {
6141 case 0:
6142 case 2:
6143 case 4:
6144 case 6:
895c2d04 6145 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6146 rn = "TagHi";
6147 break;
6148 case 1:
6149 case 3:
6150 case 5:
6151 case 7:
895c2d04 6152 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6153 rn = "DataHi";
6154 break;
6155 default:
6156 rn = "invalid sel";
f31b035a 6157 goto cp0_unimplemented;
7a387fff 6158 }
8c0fdd85
TS
6159 break;
6160 case 30:
7a387fff
TS
6161 switch (sel) {
6162 case 0:
7db13fae 6163 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6164 rn = "ErrorEPC";
6165 break;
7a387fff 6166 default:
f31b035a 6167 goto cp0_unimplemented;
7a387fff 6168 }
8c0fdd85
TS
6169 break;
6170 case 31:
7a387fff
TS
6171 switch (sel) {
6172 case 0:
f1aa6320 6173 /* EJTAG support */
7db13fae 6174 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6175 rn = "DESAVE";
6176 break;
e98c0d17 6177 case 2 ... 7:
f31b035a
LA
6178 CP0_CHECK(ctx->kscrexist & (1 << sel));
6179 tcg_gen_st_tl(arg, cpu_env,
6180 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6181 rn = "KScratch";
e98c0d17 6182 break;
7a387fff 6183 default:
f31b035a 6184 goto cp0_unimplemented;
7a387fff 6185 }
2423f660
TS
6186 /* Stop translation as we may have switched the execution mode */
6187 ctx->bstate = BS_STOP;
8c0fdd85
TS
6188 break;
6189 default:
f31b035a 6190 goto cp0_unimplemented;
8c0fdd85 6191 }
2abf314d 6192 (void)rn; /* avoid a compiler warning */
d12d51d5 6193 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6194 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6195 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6196 gen_io_end();
6197 ctx->bstate = BS_STOP;
6198 }
8c0fdd85
TS
6199 return;
6200
f31b035a 6201cp0_unimplemented:
d12d51d5 6202 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6203}
6204
d26bc211 6205#if defined(TARGET_MIPS64)
d75c135e 6206static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6207{
6208 const char *rn = "invalid";
6209
e189e748 6210 if (sel != 0)
d75c135e 6211 check_insn(ctx, ISA_MIPS64);
e189e748 6212
9c2149c8
TS
6213 switch (reg) {
6214 case 0:
6215 switch (sel) {
6216 case 0:
7db13fae 6217 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6218 rn = "Index";
6219 break;
6220 case 1:
f31b035a 6221 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6222 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6223 rn = "MVPControl";
ead9360e 6224 break;
9c2149c8 6225 case 2:
f31b035a 6226 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6227 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6228 rn = "MVPConf0";
ead9360e 6229 break;
9c2149c8 6230 case 3:
f31b035a 6231 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6232 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6233 rn = "MVPConf1";
ead9360e 6234 break;
9c2149c8 6235 default:
f31b035a 6236 goto cp0_unimplemented;
9c2149c8
TS
6237 }
6238 break;
6239 case 1:
6240 switch (sel) {
6241 case 0:
f31b035a 6242 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6243 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6244 rn = "Random";
2423f660 6245 break;
9c2149c8 6246 case 1:
f31b035a 6247 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6249 rn = "VPEControl";
ead9360e 6250 break;
9c2149c8 6251 case 2:
f31b035a 6252 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6254 rn = "VPEConf0";
ead9360e 6255 break;
9c2149c8 6256 case 3:
f31b035a 6257 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6259 rn = "VPEConf1";
ead9360e 6260 break;
9c2149c8 6261 case 4:
f31b035a 6262 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6263 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6264 rn = "YQMask";
ead9360e 6265 break;
9c2149c8 6266 case 5:
f31b035a 6267 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6268 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6269 rn = "VPESchedule";
ead9360e 6270 break;
9c2149c8 6271 case 6:
f31b035a 6272 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6273 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6274 rn = "VPEScheFBack";
ead9360e 6275 break;
9c2149c8 6276 case 7:
f31b035a 6277 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6279 rn = "VPEOpt";
ead9360e 6280 break;
9c2149c8 6281 default:
f31b035a 6282 goto cp0_unimplemented;
9c2149c8
TS
6283 }
6284 break;
6285 case 2:
6286 switch (sel) {
6287 case 0:
7db13fae 6288 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6289 rn = "EntryLo0";
6290 break;
9c2149c8 6291 case 1:
f31b035a 6292 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6293 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6294 rn = "TCStatus";
ead9360e 6295 break;
9c2149c8 6296 case 2:
f31b035a 6297 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6298 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6299 rn = "TCBind";
ead9360e 6300 break;
9c2149c8 6301 case 3:
f31b035a 6302 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6303 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6304 rn = "TCRestart";
ead9360e 6305 break;
9c2149c8 6306 case 4:
f31b035a 6307 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6308 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6309 rn = "TCHalt";
ead9360e 6310 break;
9c2149c8 6311 case 5:
f31b035a 6312 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6313 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6314 rn = "TCContext";
ead9360e 6315 break;
9c2149c8 6316 case 6:
f31b035a 6317 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6318 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6319 rn = "TCSchedule";
ead9360e 6320 break;
9c2149c8 6321 case 7:
f31b035a 6322 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6323 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6324 rn = "TCScheFBack";
ead9360e 6325 break;
9c2149c8 6326 default:
f31b035a 6327 goto cp0_unimplemented;
9c2149c8
TS
6328 }
6329 break;
6330 case 3:
6331 switch (sel) {
6332 case 0:
7db13fae 6333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6334 rn = "EntryLo1";
6335 break;
9c2149c8 6336 default:
f31b035a 6337 goto cp0_unimplemented;
1579a72e 6338 }
9c2149c8
TS
6339 break;
6340 case 4:
6341 switch (sel) {
6342 case 0:
7db13fae 6343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6344 rn = "Context";
6345 break;
9c2149c8 6346 case 1:
d9bea114 6347// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6348 rn = "ContextConfig";
f31b035a 6349 goto cp0_unimplemented;
2423f660 6350// break;
d279279e 6351 case 2:
f31b035a
LA
6352 CP0_CHECK(ctx->ulri);
6353 tcg_gen_ld_tl(arg, cpu_env,
6354 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6355 rn = "UserLocal";
d279279e 6356 break;
9c2149c8 6357 default:
f31b035a 6358 goto cp0_unimplemented;
876d4b07 6359 }
9c2149c8
TS
6360 break;
6361 case 5:
6362 switch (sel) {
6363 case 0:
7db13fae 6364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6365 rn = "PageMask";
6366 break;
9c2149c8 6367 case 1:
d75c135e 6368 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6370 rn = "PageGrain";
6371 break;
9c2149c8 6372 default:
f31b035a 6373 goto cp0_unimplemented;
876d4b07 6374 }
9c2149c8
TS
6375 break;
6376 case 6:
6377 switch (sel) {
6378 case 0:
7db13fae 6379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6380 rn = "Wired";
6381 break;
9c2149c8 6382 case 1:
d75c135e 6383 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6385 rn = "SRSConf0";
ead9360e 6386 break;
9c2149c8 6387 case 2:
d75c135e 6388 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6390 rn = "SRSConf1";
ead9360e 6391 break;
9c2149c8 6392 case 3:
d75c135e 6393 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6395 rn = "SRSConf2";
ead9360e 6396 break;
9c2149c8 6397 case 4:
d75c135e 6398 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6400 rn = "SRSConf3";
ead9360e 6401 break;
9c2149c8 6402 case 5:
d75c135e 6403 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6405 rn = "SRSConf4";
ead9360e 6406 break;
9c2149c8 6407 default:
f31b035a 6408 goto cp0_unimplemented;
876d4b07 6409 }
9c2149c8
TS
6410 break;
6411 case 7:
6412 switch (sel) {
6413 case 0:
d75c135e 6414 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6416 rn = "HWREna";
6417 break;
9c2149c8 6418 default:
f31b035a 6419 goto cp0_unimplemented;
876d4b07 6420 }
9c2149c8
TS
6421 break;
6422 case 8:
6423 switch (sel) {
6424 case 0:
7db13fae 6425 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6426 rn = "BadVAddr";
2423f660 6427 break;
aea14095 6428 case 1:
f31b035a
LA
6429 CP0_CHECK(ctx->bi);
6430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6431 rn = "BadInstr";
aea14095
LA
6432 break;
6433 case 2:
f31b035a
LA
6434 CP0_CHECK(ctx->bp);
6435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6436 rn = "BadInstrP";
aea14095 6437 break;
9c2149c8 6438 default:
f31b035a 6439 goto cp0_unimplemented;
876d4b07 6440 }
9c2149c8
TS
6441 break;
6442 case 9:
6443 switch (sel) {
6444 case 0:
2e70f6ef 6445 /* Mark as an IO operation because we read the time. */
bd79255d 6446 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6447 gen_io_start();
bd79255d 6448 }
895c2d04 6449 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6450 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6451 gen_io_end();
2e70f6ef 6452 }
55807224
EI
6453 /* Break the TB to be able to take timer interrupts immediately
6454 after reading count. */
6455 ctx->bstate = BS_STOP;
2423f660
TS
6456 rn = "Count";
6457 break;
6458 /* 6,7 are implementation dependent */
9c2149c8 6459 default:
f31b035a 6460 goto cp0_unimplemented;
876d4b07 6461 }
9c2149c8
TS
6462 break;
6463 case 10:
6464 switch (sel) {
6465 case 0:
7db13fae 6466 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6467 rn = "EntryHi";
6468 break;
9c2149c8 6469 default:
f31b035a 6470 goto cp0_unimplemented;
876d4b07 6471 }
9c2149c8
TS
6472 break;
6473 case 11:
6474 switch (sel) {
6475 case 0:
7db13fae 6476 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6477 rn = "Compare";
6478 break;
876d4b07 6479 /* 6,7 are implementation dependent */
9c2149c8 6480 default:
f31b035a 6481 goto cp0_unimplemented;
876d4b07 6482 }
9c2149c8
TS
6483 break;
6484 case 12:
6485 switch (sel) {
6486 case 0:
7db13fae 6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6488 rn = "Status";
6489 break;
9c2149c8 6490 case 1:
d75c135e 6491 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6493 rn = "IntCtl";
6494 break;
9c2149c8 6495 case 2:
d75c135e 6496 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6498 rn = "SRSCtl";
6499 break;
9c2149c8 6500 case 3:
d75c135e 6501 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6503 rn = "SRSMap";
6504 break;
9c2149c8 6505 default:
f31b035a 6506 goto cp0_unimplemented;
876d4b07 6507 }
9c2149c8
TS
6508 break;
6509 case 13:
6510 switch (sel) {
6511 case 0:
7db13fae 6512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6513 rn = "Cause";
6514 break;
9c2149c8 6515 default:
f31b035a 6516 goto cp0_unimplemented;
876d4b07 6517 }
9c2149c8
TS
6518 break;
6519 case 14:
6520 switch (sel) {
6521 case 0:
7db13fae 6522 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6523 rn = "EPC";
6524 break;
9c2149c8 6525 default:
f31b035a 6526 goto cp0_unimplemented;
876d4b07 6527 }
9c2149c8
TS
6528 break;
6529 case 15:
6530 switch (sel) {
6531 case 0:
7db13fae 6532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6533 rn = "PRid";
6534 break;
9c2149c8 6535 case 1:
d75c135e 6536 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6538 rn = "EBase";
6539 break;
9c2149c8 6540 default:
f31b035a 6541 goto cp0_unimplemented;
876d4b07 6542 }
9c2149c8
TS
6543 break;
6544 case 16:
6545 switch (sel) {
6546 case 0:
7db13fae 6547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6548 rn = "Config";
6549 break;
6550 case 1:
7db13fae 6551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6552 rn = "Config1";
6553 break;
6554 case 2:
7db13fae 6555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6556 rn = "Config2";
6557 break;
6558 case 3:
7db13fae 6559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6560 rn = "Config3";
6561 break;
faf1f68b
LA
6562 case 4:
6563 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6564 rn = "Config4";
6565 break;
6566 case 5:
6567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6568 rn = "Config5";
6569 break;
9c2149c8 6570 /* 6,7 are implementation dependent */
f0b3f3ae 6571 case 6:
7db13fae 6572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6573 rn = "Config6";
6574 break;
6575 case 7:
7db13fae 6576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6577 rn = "Config7";
6578 break;
9c2149c8 6579 default:
f31b035a 6580 goto cp0_unimplemented;
9c2149c8
TS
6581 }
6582 break;
6583 case 17:
6584 switch (sel) {
6585 case 0:
895c2d04 6586 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6587 rn = "LLAddr";
6588 break;
9c2149c8 6589 default:
f31b035a 6590 goto cp0_unimplemented;
9c2149c8
TS
6591 }
6592 break;
6593 case 18:
6594 switch (sel) {
fd88b6ab 6595 case 0 ... 7:
895c2d04 6596 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6597 rn = "WatchLo";
6598 break;
9c2149c8 6599 default:
f31b035a 6600 goto cp0_unimplemented;
9c2149c8
TS
6601 }
6602 break;
6603 case 19:
6604 switch (sel) {
fd88b6ab 6605 case 0 ... 7:
895c2d04 6606 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6607 rn = "WatchHi";
6608 break;
9c2149c8 6609 default:
f31b035a 6610 goto cp0_unimplemented;
9c2149c8
TS
6611 }
6612 break;
6613 case 20:
6614 switch (sel) {
6615 case 0:
d75c135e 6616 check_insn(ctx, ISA_MIPS3);
7db13fae 6617 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6618 rn = "XContext";
6619 break;
9c2149c8 6620 default:
f31b035a 6621 goto cp0_unimplemented;
9c2149c8
TS
6622 }
6623 break;
6624 case 21:
6625 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6626 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6627 switch (sel) {
6628 case 0:
7db13fae 6629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6630 rn = "Framemask";
6631 break;
9c2149c8 6632 default:
f31b035a 6633 goto cp0_unimplemented;
9c2149c8
TS
6634 }
6635 break;
6636 case 22:
d9bea114 6637 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6638 rn = "'Diagnostic"; /* implementation dependent */
6639 break;
9c2149c8
TS
6640 case 23:
6641 switch (sel) {
6642 case 0:
895c2d04 6643 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6644 rn = "Debug";
6645 break;
9c2149c8 6646 case 1:
895c2d04 6647// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6648 rn = "TraceControl";
6649// break;
9c2149c8 6650 case 2:
895c2d04 6651// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6652 rn = "TraceControl2";
6653// break;
9c2149c8 6654 case 3:
895c2d04 6655// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6656 rn = "UserTraceData";
6657// break;
9c2149c8 6658 case 4:
895c2d04 6659// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6660 rn = "TraceBPC";
6661// break;
9c2149c8 6662 default:
f31b035a 6663 goto cp0_unimplemented;
9c2149c8
TS
6664 }
6665 break;
6666 case 24:
6667 switch (sel) {
6668 case 0:
f0b3f3ae 6669 /* EJTAG support */
7db13fae 6670 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6671 rn = "DEPC";
6672 break;
9c2149c8 6673 default:
f31b035a 6674 goto cp0_unimplemented;
9c2149c8
TS
6675 }
6676 break;
6677 case 25:
6678 switch (sel) {
6679 case 0:
7db13fae 6680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6681 rn = "Performance0";
9c2149c8
TS
6682 break;
6683 case 1:
d9bea114 6684// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6685 rn = "Performance1";
6686// break;
9c2149c8 6687 case 2:
d9bea114 6688// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6689 rn = "Performance2";
6690// break;
9c2149c8 6691 case 3:
d9bea114 6692// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6693 rn = "Performance3";
6694// break;
9c2149c8 6695 case 4:
d9bea114 6696// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6697 rn = "Performance4";
6698// break;
9c2149c8 6699 case 5:
d9bea114 6700// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6701 rn = "Performance5";
6702// break;
9c2149c8 6703 case 6:
d9bea114 6704// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6705 rn = "Performance6";
6706// break;
9c2149c8 6707 case 7:
d9bea114 6708// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6709 rn = "Performance7";
6710// break;
9c2149c8 6711 default:
f31b035a 6712 goto cp0_unimplemented;
9c2149c8
TS
6713 }
6714 break;
6715 case 26:
d9bea114 6716 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6717 rn = "ECC";
6718 break;
9c2149c8
TS
6719 case 27:
6720 switch (sel) {
6721 /* ignored */
6722 case 0 ... 3:
d9bea114 6723 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6724 rn = "CacheErr";
6725 break;
9c2149c8 6726 default:
f31b035a 6727 goto cp0_unimplemented;
9c2149c8
TS
6728 }
6729 break;
6730 case 28:
6731 switch (sel) {
6732 case 0:
6733 case 2:
6734 case 4:
6735 case 6:
7db13fae 6736 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6737 rn = "TagLo";
6738 break;
6739 case 1:
6740 case 3:
6741 case 5:
6742 case 7:
7db13fae 6743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6744 rn = "DataLo";
6745 break;
6746 default:
f31b035a 6747 goto cp0_unimplemented;
9c2149c8
TS
6748 }
6749 break;
6750 case 29:
6751 switch (sel) {
6752 case 0:
6753 case 2:
6754 case 4:
6755 case 6:
7db13fae 6756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6757 rn = "TagHi";
6758 break;
6759 case 1:
6760 case 3:
6761 case 5:
6762 case 7:
7db13fae 6763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6764 rn = "DataHi";
6765 break;
6766 default:
f31b035a 6767 goto cp0_unimplemented;
9c2149c8
TS
6768 }
6769 break;
6770 case 30:
6771 switch (sel) {
6772 case 0:
7db13fae 6773 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6774 rn = "ErrorEPC";
6775 break;
9c2149c8 6776 default:
f31b035a 6777 goto cp0_unimplemented;
9c2149c8
TS
6778 }
6779 break;
6780 case 31:
6781 switch (sel) {
6782 case 0:
f0b3f3ae 6783 /* EJTAG support */
7db13fae 6784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6785 rn = "DESAVE";
6786 break;
e98c0d17 6787 case 2 ... 7:
f31b035a
LA
6788 CP0_CHECK(ctx->kscrexist & (1 << sel));
6789 tcg_gen_ld_tl(arg, cpu_env,
6790 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6791 rn = "KScratch";
e98c0d17 6792 break;
9c2149c8 6793 default:
f31b035a 6794 goto cp0_unimplemented;
9c2149c8
TS
6795 }
6796 break;
6797 default:
f31b035a 6798 goto cp0_unimplemented;
9c2149c8 6799 }
2abf314d 6800 (void)rn; /* avoid a compiler warning */
d12d51d5 6801 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6802 return;
6803
f31b035a 6804cp0_unimplemented:
d12d51d5 6805 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6806 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6807}
6808
d75c135e 6809static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6810{
6811 const char *rn = "invalid";
6812
e189e748 6813 if (sel != 0)
d75c135e 6814 check_insn(ctx, ISA_MIPS64);
e189e748 6815
bd79255d 6816 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6817 gen_io_start();
bd79255d 6818 }
2e70f6ef 6819
9c2149c8
TS
6820 switch (reg) {
6821 case 0:
6822 switch (sel) {
6823 case 0:
895c2d04 6824 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6825 rn = "Index";
6826 break;
6827 case 1:
f31b035a 6828 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6829 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6830 rn = "MVPControl";
ead9360e 6831 break;
9c2149c8 6832 case 2:
f31b035a 6833 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6834 /* ignored */
9c2149c8 6835 rn = "MVPConf0";
ead9360e 6836 break;
9c2149c8 6837 case 3:
f31b035a 6838 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6839 /* ignored */
9c2149c8 6840 rn = "MVPConf1";
ead9360e 6841 break;
9c2149c8 6842 default:
f31b035a 6843 goto cp0_unimplemented;
9c2149c8
TS
6844 }
6845 break;
6846 case 1:
6847 switch (sel) {
6848 case 0:
2423f660 6849 /* ignored */
9c2149c8 6850 rn = "Random";
2423f660 6851 break;
9c2149c8 6852 case 1:
f31b035a 6853 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6854 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6855 rn = "VPEControl";
ead9360e 6856 break;
9c2149c8 6857 case 2:
f31b035a 6858 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6859 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6860 rn = "VPEConf0";
ead9360e 6861 break;
9c2149c8 6862 case 3:
f31b035a 6863 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6864 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6865 rn = "VPEConf1";
ead9360e 6866 break;
9c2149c8 6867 case 4:
f31b035a 6868 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6869 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6870 rn = "YQMask";
ead9360e 6871 break;
9c2149c8 6872 case 5:
f31b035a 6873 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6874 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6875 rn = "VPESchedule";
ead9360e 6876 break;
9c2149c8 6877 case 6:
f31b035a 6878 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6879 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6880 rn = "VPEScheFBack";
ead9360e 6881 break;
9c2149c8 6882 case 7:
f31b035a 6883 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6884 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6885 rn = "VPEOpt";
ead9360e 6886 break;
9c2149c8 6887 default:
f31b035a 6888 goto cp0_unimplemented;
9c2149c8
TS
6889 }
6890 break;
6891 case 2:
6892 switch (sel) {
6893 case 0:
7207c7f9 6894 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6895 rn = "EntryLo0";
6896 break;
9c2149c8 6897 case 1:
f31b035a 6898 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6899 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6900 rn = "TCStatus";
ead9360e 6901 break;
9c2149c8 6902 case 2:
f31b035a 6903 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6904 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6905 rn = "TCBind";
ead9360e 6906 break;
9c2149c8 6907 case 3:
f31b035a 6908 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6909 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6910 rn = "TCRestart";
ead9360e 6911 break;
9c2149c8 6912 case 4:
f31b035a 6913 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6914 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6915 rn = "TCHalt";
ead9360e 6916 break;
9c2149c8 6917 case 5:
f31b035a 6918 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6919 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6920 rn = "TCContext";
ead9360e 6921 break;
9c2149c8 6922 case 6:
f31b035a 6923 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6924 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6925 rn = "TCSchedule";
ead9360e 6926 break;
9c2149c8 6927 case 7:
f31b035a 6928 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6929 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6930 rn = "TCScheFBack";
ead9360e 6931 break;
9c2149c8 6932 default:
f31b035a 6933 goto cp0_unimplemented;
9c2149c8
TS
6934 }
6935 break;
6936 case 3:
6937 switch (sel) {
6938 case 0:
7207c7f9 6939 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6940 rn = "EntryLo1";
6941 break;
9c2149c8 6942 default:
f31b035a 6943 goto cp0_unimplemented;
876d4b07 6944 }
9c2149c8
TS
6945 break;
6946 case 4:
6947 switch (sel) {
6948 case 0:
895c2d04 6949 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6950 rn = "Context";
6951 break;
9c2149c8 6952 case 1:
895c2d04 6953// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6954 rn = "ContextConfig";
f31b035a 6955 goto cp0_unimplemented;
2423f660 6956// break;
d279279e 6957 case 2:
f31b035a
LA
6958 CP0_CHECK(ctx->ulri);
6959 tcg_gen_st_tl(arg, cpu_env,
6960 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6961 rn = "UserLocal";
d279279e 6962 break;
9c2149c8 6963 default:
f31b035a 6964 goto cp0_unimplemented;
876d4b07 6965 }
9c2149c8
TS
6966 break;
6967 case 5:
6968 switch (sel) {
6969 case 0:
895c2d04 6970 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6971 rn = "PageMask";
6972 break;
9c2149c8 6973 case 1:
d75c135e 6974 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6975 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6976 rn = "PageGrain";
6977 break;
9c2149c8 6978 default:
f31b035a 6979 goto cp0_unimplemented;
876d4b07 6980 }
9c2149c8
TS
6981 break;
6982 case 6:
6983 switch (sel) {
6984 case 0:
895c2d04 6985 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6986 rn = "Wired";
6987 break;
9c2149c8 6988 case 1:
d75c135e 6989 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6990 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6991 rn = "SRSConf0";
ead9360e 6992 break;
9c2149c8 6993 case 2:
d75c135e 6994 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6995 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6996 rn = "SRSConf1";
ead9360e 6997 break;
9c2149c8 6998 case 3:
d75c135e 6999 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7000 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7001 rn = "SRSConf2";
ead9360e 7002 break;
9c2149c8 7003 case 4:
d75c135e 7004 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7005 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7006 rn = "SRSConf3";
ead9360e 7007 break;
9c2149c8 7008 case 5:
d75c135e 7009 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7010 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7011 rn = "SRSConf4";
ead9360e 7012 break;
9c2149c8 7013 default:
f31b035a 7014 goto cp0_unimplemented;
876d4b07 7015 }
9c2149c8
TS
7016 break;
7017 case 7:
7018 switch (sel) {
7019 case 0:
d75c135e 7020 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7021 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7022 ctx->bstate = BS_STOP;
2423f660
TS
7023 rn = "HWREna";
7024 break;
9c2149c8 7025 default:
f31b035a 7026 goto cp0_unimplemented;
876d4b07 7027 }
9c2149c8
TS
7028 break;
7029 case 8:
aea14095
LA
7030 switch (sel) {
7031 case 0:
7032 /* ignored */
7033 rn = "BadVAddr";
7034 break;
7035 case 1:
7036 /* ignored */
7037 rn = "BadInstr";
7038 break;
7039 case 2:
7040 /* ignored */
7041 rn = "BadInstrP";
7042 break;
7043 default:
f31b035a 7044 goto cp0_unimplemented;
aea14095 7045 }
9c2149c8
TS
7046 break;
7047 case 9:
7048 switch (sel) {
7049 case 0:
895c2d04 7050 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7051 rn = "Count";
7052 break;
876d4b07 7053 /* 6,7 are implementation dependent */
9c2149c8 7054 default:
f31b035a 7055 goto cp0_unimplemented;
876d4b07
TS
7056 }
7057 /* Stop translation as we may have switched the execution mode */
7058 ctx->bstate = BS_STOP;
9c2149c8
TS
7059 break;
7060 case 10:
7061 switch (sel) {
7062 case 0:
895c2d04 7063 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7064 rn = "EntryHi";
7065 break;
9c2149c8 7066 default:
f31b035a 7067 goto cp0_unimplemented;
876d4b07 7068 }
9c2149c8
TS
7069 break;
7070 case 11:
7071 switch (sel) {
7072 case 0:
895c2d04 7073 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7074 rn = "Compare";
7075 break;
876d4b07 7076 /* 6,7 are implementation dependent */
9c2149c8 7077 default:
f31b035a 7078 goto cp0_unimplemented;
876d4b07 7079 }
de9a95f0
AJ
7080 /* Stop translation as we may have switched the execution mode */
7081 ctx->bstate = BS_STOP;
9c2149c8
TS
7082 break;
7083 case 12:
7084 switch (sel) {
7085 case 0:
867abc7e 7086 save_cpu_state(ctx, 1);
895c2d04 7087 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7088 /* BS_STOP isn't good enough here, hflags may have changed. */
7089 gen_save_pc(ctx->pc + 4);
7090 ctx->bstate = BS_EXCP;
2423f660
TS
7091 rn = "Status";
7092 break;
9c2149c8 7093 case 1:
d75c135e 7094 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7095 gen_helper_mtc0_intctl(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 = "IntCtl";
7099 break;
9c2149c8 7100 case 2:
d75c135e 7101 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7102 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7103 /* Stop translation as we may have switched the execution mode */
7104 ctx->bstate = BS_STOP;
2423f660
TS
7105 rn = "SRSCtl";
7106 break;
9c2149c8 7107 case 3:
d75c135e 7108 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7109 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7110 /* Stop translation as we may have switched the execution mode */
7111 ctx->bstate = BS_STOP;
2423f660
TS
7112 rn = "SRSMap";
7113 break;
7114 default:
f31b035a 7115 goto cp0_unimplemented;
876d4b07 7116 }
9c2149c8
TS
7117 break;
7118 case 13:
7119 switch (sel) {
7120 case 0:
867abc7e 7121 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7122 /* Mark as an IO operation because we may trigger a software
7123 interrupt. */
bd79255d 7124 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7125 gen_io_start();
7126 }
895c2d04 7127 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7128 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7129 gen_io_end();
7130 }
7131 /* Stop translation as we may have triggered an intetrupt */
7132 ctx->bstate = BS_STOP;
2423f660
TS
7133 rn = "Cause";
7134 break;
9c2149c8 7135 default:
f31b035a 7136 goto cp0_unimplemented;
876d4b07 7137 }
9c2149c8
TS
7138 break;
7139 case 14:
7140 switch (sel) {
7141 case 0:
7db13fae 7142 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7143 rn = "EPC";
7144 break;
9c2149c8 7145 default:
f31b035a 7146 goto cp0_unimplemented;
876d4b07 7147 }
9c2149c8
TS
7148 break;
7149 case 15:
7150 switch (sel) {
7151 case 0:
2423f660
TS
7152 /* ignored */
7153 rn = "PRid";
7154 break;
9c2149c8 7155 case 1:
d75c135e 7156 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7157 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7158 rn = "EBase";
7159 break;
9c2149c8 7160 default:
f31b035a 7161 goto cp0_unimplemented;
876d4b07 7162 }
9c2149c8
TS
7163 break;
7164 case 16:
7165 switch (sel) {
7166 case 0:
895c2d04 7167 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7168 rn = "Config";
2423f660
TS
7169 /* Stop translation as we may have switched the execution mode */
7170 ctx->bstate = BS_STOP;
9c2149c8
TS
7171 break;
7172 case 1:
1fc7bf6e 7173 /* ignored, read only */
9c2149c8
TS
7174 rn = "Config1";
7175 break;
7176 case 2:
895c2d04 7177 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7178 rn = "Config2";
2423f660
TS
7179 /* Stop translation as we may have switched the execution mode */
7180 ctx->bstate = BS_STOP;
9c2149c8
TS
7181 break;
7182 case 3:
90f12d73 7183 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7184 rn = "Config3";
90f12d73
MR
7185 /* Stop translation as we may have switched the execution mode */
7186 ctx->bstate = BS_STOP;
9c2149c8 7187 break;
faf1f68b
LA
7188 case 4:
7189 /* currently ignored */
7190 rn = "Config4";
7191 break;
7192 case 5:
7193 gen_helper_mtc0_config5(cpu_env, arg);
7194 rn = "Config5";
7195 /* Stop translation as we may have switched the execution mode */
7196 ctx->bstate = BS_STOP;
7197 break;
9c2149c8
TS
7198 /* 6,7 are implementation dependent */
7199 default:
7200 rn = "Invalid config selector";
f31b035a 7201 goto cp0_unimplemented;
9c2149c8 7202 }
9c2149c8
TS
7203 break;
7204 case 17:
7205 switch (sel) {
7206 case 0:
895c2d04 7207 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7208 rn = "LLAddr";
7209 break;
9c2149c8 7210 default:
f31b035a 7211 goto cp0_unimplemented;
9c2149c8
TS
7212 }
7213 break;
7214 case 18:
7215 switch (sel) {
fd88b6ab 7216 case 0 ... 7:
895c2d04 7217 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7218 rn = "WatchLo";
7219 break;
9c2149c8 7220 default:
f31b035a 7221 goto cp0_unimplemented;
9c2149c8
TS
7222 }
7223 break;
7224 case 19:
7225 switch (sel) {
fd88b6ab 7226 case 0 ... 7:
895c2d04 7227 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7228 rn = "WatchHi";
7229 break;
9c2149c8 7230 default:
f31b035a 7231 goto cp0_unimplemented;
9c2149c8
TS
7232 }
7233 break;
7234 case 20:
7235 switch (sel) {
7236 case 0:
d75c135e 7237 check_insn(ctx, ISA_MIPS3);
895c2d04 7238 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7239 rn = "XContext";
7240 break;
9c2149c8 7241 default:
f31b035a 7242 goto cp0_unimplemented;
9c2149c8
TS
7243 }
7244 break;
7245 case 21:
7246 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7247 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7248 switch (sel) {
7249 case 0:
895c2d04 7250 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7251 rn = "Framemask";
7252 break;
9c2149c8 7253 default:
f31b035a 7254 goto cp0_unimplemented;
9c2149c8
TS
7255 }
7256 break;
7257 case 22:
7258 /* ignored */
7259 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7260 break;
9c2149c8
TS
7261 case 23:
7262 switch (sel) {
7263 case 0:
895c2d04 7264 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7265 /* BS_STOP isn't good enough here, hflags may have changed. */
7266 gen_save_pc(ctx->pc + 4);
7267 ctx->bstate = BS_EXCP;
2423f660
TS
7268 rn = "Debug";
7269 break;
9c2149c8 7270 case 1:
895c2d04 7271// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7272 /* Stop translation as we may have switched the execution mode */
7273 ctx->bstate = BS_STOP;
2423f660
TS
7274 rn = "TraceControl";
7275// break;
9c2149c8 7276 case 2:
895c2d04 7277// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7278 /* Stop translation as we may have switched the execution mode */
7279 ctx->bstate = BS_STOP;
2423f660
TS
7280 rn = "TraceControl2";
7281// break;
9c2149c8 7282 case 3:
895c2d04 7283// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7284 /* Stop translation as we may have switched the execution mode */
7285 ctx->bstate = BS_STOP;
2423f660
TS
7286 rn = "UserTraceData";
7287// break;
9c2149c8 7288 case 4:
895c2d04 7289// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7290 /* Stop translation as we may have switched the execution mode */
7291 ctx->bstate = BS_STOP;
2423f660
TS
7292 rn = "TraceBPC";
7293// break;
9c2149c8 7294 default:
f31b035a 7295 goto cp0_unimplemented;
9c2149c8 7296 }
9c2149c8
TS
7297 break;
7298 case 24:
7299 switch (sel) {
7300 case 0:
f1aa6320 7301 /* EJTAG support */
7db13fae 7302 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7303 rn = "DEPC";
7304 break;
9c2149c8 7305 default:
f31b035a 7306 goto cp0_unimplemented;
9c2149c8
TS
7307 }
7308 break;
7309 case 25:
7310 switch (sel) {
7311 case 0:
895c2d04 7312 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7313 rn = "Performance0";
7314 break;
9c2149c8 7315 case 1:
895c2d04 7316// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7317 rn = "Performance1";
7318// break;
9c2149c8 7319 case 2:
895c2d04 7320// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7321 rn = "Performance2";
7322// break;
9c2149c8 7323 case 3:
895c2d04 7324// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7325 rn = "Performance3";
7326// break;
9c2149c8 7327 case 4:
895c2d04 7328// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7329 rn = "Performance4";
7330// break;
9c2149c8 7331 case 5:
895c2d04 7332// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7333 rn = "Performance5";
7334// break;
9c2149c8 7335 case 6:
895c2d04 7336// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7337 rn = "Performance6";
7338// break;
9c2149c8 7339 case 7:
895c2d04 7340// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7341 rn = "Performance7";
7342// break;
9c2149c8 7343 default:
f31b035a 7344 goto cp0_unimplemented;
9c2149c8 7345 }
876d4b07 7346 break;
9c2149c8 7347 case 26:
876d4b07 7348 /* ignored */
9c2149c8 7349 rn = "ECC";
876d4b07 7350 break;
9c2149c8
TS
7351 case 27:
7352 switch (sel) {
7353 case 0 ... 3:
2423f660
TS
7354 /* ignored */
7355 rn = "CacheErr";
7356 break;
9c2149c8 7357 default:
f31b035a 7358 goto cp0_unimplemented;
9c2149c8 7359 }
876d4b07 7360 break;
9c2149c8
TS
7361 case 28:
7362 switch (sel) {
7363 case 0:
7364 case 2:
7365 case 4:
7366 case 6:
895c2d04 7367 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7368 rn = "TagLo";
7369 break;
7370 case 1:
7371 case 3:
7372 case 5:
7373 case 7:
895c2d04 7374 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7375 rn = "DataLo";
7376 break;
7377 default:
f31b035a 7378 goto cp0_unimplemented;
9c2149c8
TS
7379 }
7380 break;
7381 case 29:
7382 switch (sel) {
7383 case 0:
7384 case 2:
7385 case 4:
7386 case 6:
895c2d04 7387 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7388 rn = "TagHi";
7389 break;
7390 case 1:
7391 case 3:
7392 case 5:
7393 case 7:
895c2d04 7394 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7395 rn = "DataHi";
7396 break;
7397 default:
7398 rn = "invalid sel";
f31b035a 7399 goto cp0_unimplemented;
9c2149c8 7400 }
876d4b07 7401 break;
9c2149c8
TS
7402 case 30:
7403 switch (sel) {
7404 case 0:
7db13fae 7405 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7406 rn = "ErrorEPC";
7407 break;
9c2149c8 7408 default:
f31b035a 7409 goto cp0_unimplemented;
9c2149c8
TS
7410 }
7411 break;
7412 case 31:
7413 switch (sel) {
7414 case 0:
f1aa6320 7415 /* EJTAG support */
7db13fae 7416 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7417 rn = "DESAVE";
7418 break;
e98c0d17 7419 case 2 ... 7:
f31b035a
LA
7420 CP0_CHECK(ctx->kscrexist & (1 << sel));
7421 tcg_gen_st_tl(arg, cpu_env,
7422 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7423 rn = "KScratch";
e98c0d17 7424 break;
9c2149c8 7425 default:
f31b035a 7426 goto cp0_unimplemented;
9c2149c8 7427 }
876d4b07
TS
7428 /* Stop translation as we may have switched the execution mode */
7429 ctx->bstate = BS_STOP;
9c2149c8
TS
7430 break;
7431 default:
f31b035a 7432 goto cp0_unimplemented;
9c2149c8 7433 }
2abf314d 7434 (void)rn; /* avoid a compiler warning */
d12d51d5 7435 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7436 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7437 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7438 gen_io_end();
7439 ctx->bstate = BS_STOP;
7440 }
9c2149c8
TS
7441 return;
7442
f31b035a 7443cp0_unimplemented:
d12d51d5 7444 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7445}
d26bc211 7446#endif /* TARGET_MIPS64 */
9c2149c8 7447
7db13fae 7448static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7449 int u, int sel, int h)
7450{
7451 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7452 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7453
7454 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7455 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7456 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7457 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7458 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7459 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7460 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7461 else if (u == 0) {
7462 switch (rt) {
5a25ce94
EI
7463 case 1:
7464 switch (sel) {
7465 case 1:
895c2d04 7466 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7467 break;
7468 case 2:
895c2d04 7469 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7470 break;
7471 default:
7472 goto die;
7473 break;
7474 }
7475 break;
ead9360e
TS
7476 case 2:
7477 switch (sel) {
7478 case 1:
895c2d04 7479 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7480 break;
7481 case 2:
895c2d04 7482 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7483 break;
7484 case 3:
895c2d04 7485 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7486 break;
7487 case 4:
895c2d04 7488 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7489 break;
7490 case 5:
895c2d04 7491 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7492 break;
7493 case 6:
895c2d04 7494 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7495 break;
7496 case 7:
895c2d04 7497 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7498 break;
7499 default:
d75c135e 7500 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7501 break;
7502 }
7503 break;
7504 case 10:
7505 switch (sel) {
7506 case 0:
895c2d04 7507 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7508 break;
7509 default:
d75c135e 7510 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7511 break;
7512 }
7513 case 12:
7514 switch (sel) {
7515 case 0:
895c2d04 7516 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7517 break;
7518 default:
d75c135e 7519 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7520 break;
7521 }
5a25ce94
EI
7522 case 13:
7523 switch (sel) {
7524 case 0:
895c2d04 7525 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7526 break;
7527 default:
7528 goto die;
7529 break;
7530 }
7531 break;
7532 case 14:
7533 switch (sel) {
7534 case 0:
895c2d04 7535 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7536 break;
7537 default:
7538 goto die;
7539 break;
7540 }
7541 break;
7542 case 15:
7543 switch (sel) {
7544 case 1:
895c2d04 7545 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7546 break;
7547 default:
7548 goto die;
7549 break;
7550 }
7551 break;
7552 case 16:
7553 switch (sel) {
7554 case 0 ... 7:
895c2d04 7555 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7556 break;
7557 default:
7558 goto die;
7559 break;
7560 }
7561 break;
ead9360e
TS
7562 case 23:
7563 switch (sel) {
7564 case 0:
895c2d04 7565 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7566 break;
7567 default:
d75c135e 7568 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7569 break;
7570 }
7571 break;
7572 default:
d75c135e 7573 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7574 }
7575 } else switch (sel) {
7576 /* GPR registers. */
7577 case 0:
895c2d04 7578 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7579 break;
7580 /* Auxiliary CPU registers */
7581 case 1:
7582 switch (rt) {
7583 case 0:
895c2d04 7584 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7585 break;
7586 case 1:
895c2d04 7587 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7588 break;
7589 case 2:
895c2d04 7590 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7591 break;
7592 case 4:
895c2d04 7593 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7594 break;
7595 case 5:
895c2d04 7596 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7597 break;
7598 case 6:
895c2d04 7599 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7600 break;
7601 case 8:
895c2d04 7602 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7603 break;
7604 case 9:
895c2d04 7605 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7606 break;
7607 case 10:
895c2d04 7608 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7609 break;
7610 case 12:
895c2d04 7611 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7612 break;
7613 case 13:
895c2d04 7614 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7615 break;
7616 case 14:
895c2d04 7617 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7618 break;
7619 case 16:
895c2d04 7620 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7621 break;
7622 default:
7623 goto die;
7624 }
7625 break;
7626 /* Floating point (COP1). */
7627 case 2:
7628 /* XXX: For now we support only a single FPU context. */
7629 if (h == 0) {
a7812ae4 7630 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7631
7c979afd 7632 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7633 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7634 tcg_temp_free_i32(fp0);
ead9360e 7635 } else {
a7812ae4 7636 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7637
7f6613ce 7638 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7639 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7640 tcg_temp_free_i32(fp0);
ead9360e
TS
7641 }
7642 break;
7643 case 3:
7644 /* XXX: For now we support only a single FPU context. */
895c2d04 7645 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7646 break;
7647 /* COP2: Not implemented. */
7648 case 4:
7649 case 5:
7650 /* fall through */
7651 default:
7652 goto die;
7653 }
d12d51d5 7654 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7655 gen_store_gpr(t0, rd);
7656 tcg_temp_free(t0);
ead9360e
TS
7657 return;
7658
7659die:
1a3fd9c3 7660 tcg_temp_free(t0);
d12d51d5 7661 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7662 generate_exception(ctx, EXCP_RI);
7663}
7664
7db13fae 7665static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7666 int u, int sel, int h)
7667{
7668 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7669 TCGv t0 = tcg_temp_local_new();
ead9360e 7670
1a3fd9c3 7671 gen_load_gpr(t0, rt);
ead9360e 7672 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7673 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7674 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7675 /* NOP */ ;
7676 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7677 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7678 /* NOP */ ;
7679 else if (u == 0) {
7680 switch (rd) {
5a25ce94
EI
7681 case 1:
7682 switch (sel) {
7683 case 1:
895c2d04 7684 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7685 break;
7686 case 2:
895c2d04 7687 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7688 break;
7689 default:
7690 goto die;
7691 break;
7692 }
7693 break;
ead9360e
TS
7694 case 2:
7695 switch (sel) {
7696 case 1:
895c2d04 7697 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7698 break;
7699 case 2:
895c2d04 7700 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7701 break;
7702 case 3:
895c2d04 7703 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7704 break;
7705 case 4:
895c2d04 7706 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7707 break;
7708 case 5:
895c2d04 7709 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7710 break;
7711 case 6:
895c2d04 7712 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7713 break;
7714 case 7:
895c2d04 7715 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7716 break;
7717 default:
d75c135e 7718 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7719 break;
7720 }
7721 break;
7722 case 10:
7723 switch (sel) {
7724 case 0:
895c2d04 7725 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7726 break;
7727 default:
d75c135e 7728 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7729 break;
7730 }
7731 case 12:
7732 switch (sel) {
7733 case 0:
895c2d04 7734 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7735 break;
7736 default:
d75c135e 7737 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7738 break;
7739 }
5a25ce94
EI
7740 case 13:
7741 switch (sel) {
7742 case 0:
895c2d04 7743 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7744 break;
7745 default:
7746 goto die;
7747 break;
7748 }
7749 break;
7750 case 15:
7751 switch (sel) {
7752 case 1:
895c2d04 7753 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7754 break;
7755 default:
7756 goto die;
7757 break;
7758 }
7759 break;
ead9360e
TS
7760 case 23:
7761 switch (sel) {
7762 case 0:
895c2d04 7763 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7764 break;
7765 default:
d75c135e 7766 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7767 break;
7768 }
7769 break;
7770 default:
d75c135e 7771 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7772 }
7773 } else switch (sel) {
7774 /* GPR registers. */
7775 case 0:
895c2d04 7776 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7777 break;
7778 /* Auxiliary CPU registers */
7779 case 1:
7780 switch (rd) {
7781 case 0:
895c2d04 7782 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7783 break;
7784 case 1:
895c2d04 7785 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7786 break;
7787 case 2:
895c2d04 7788 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7789 break;
7790 case 4:
895c2d04 7791 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7792 break;
7793 case 5:
895c2d04 7794 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7795 break;
7796 case 6:
895c2d04 7797 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7798 break;
7799 case 8:
895c2d04 7800 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7801 break;
7802 case 9:
895c2d04 7803 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7804 break;
7805 case 10:
895c2d04 7806 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7807 break;
7808 case 12:
895c2d04 7809 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7810 break;
7811 case 13:
895c2d04 7812 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7813 break;
7814 case 14:
895c2d04 7815 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7816 break;
7817 case 16:
895c2d04 7818 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7819 break;
7820 default:
7821 goto die;
7822 }
7823 break;
7824 /* Floating point (COP1). */
7825 case 2:
7826 /* XXX: For now we support only a single FPU context. */
7827 if (h == 0) {
a7812ae4 7828 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7829
7830 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7831 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7832 tcg_temp_free_i32(fp0);
ead9360e 7833 } else {
a7812ae4 7834 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7835
7836 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7837 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7838 tcg_temp_free_i32(fp0);
ead9360e
TS
7839 }
7840 break;
7841 case 3:
7842 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7843 save_cpu_state(ctx, 1);
736d120a
PJ
7844 {
7845 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7846
7847 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7848 tcg_temp_free_i32(fs_tmp);
7849 }
4cf8a45f
YK
7850 /* Stop translation as we may have changed hflags */
7851 ctx->bstate = BS_STOP;
ead9360e
TS
7852 break;
7853 /* COP2: Not implemented. */
7854 case 4:
7855 case 5:
7856 /* fall through */
7857 default:
7858 goto die;
7859 }
d12d51d5 7860 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7861 tcg_temp_free(t0);
ead9360e
TS
7862 return;
7863
7864die:
1a3fd9c3 7865 tcg_temp_free(t0);
d12d51d5 7866 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7867 generate_exception(ctx, EXCP_RI);
7868}
7869
7db13fae 7870static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7871{
287c4b84 7872 const char *opn = "ldst";
6af0bf9c 7873
2e15497c 7874 check_cp0_enabled(ctx);
6af0bf9c
FB
7875 switch (opc) {
7876 case OPC_MFC0:
7877 if (rt == 0) {
ead9360e 7878 /* Treat as NOP. */
6af0bf9c
FB
7879 return;
7880 }
d75c135e 7881 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7882 opn = "mfc0";
7883 break;
7884 case OPC_MTC0:
1a3fd9c3 7885 {
1fc7bf6e 7886 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7887
7888 gen_load_gpr(t0, rt);
d75c135e 7889 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7890 tcg_temp_free(t0);
7891 }
6af0bf9c
FB
7892 opn = "mtc0";
7893 break;
d26bc211 7894#if defined(TARGET_MIPS64)
9c2149c8 7895 case OPC_DMFC0:
d75c135e 7896 check_insn(ctx, ISA_MIPS3);
9c2149c8 7897 if (rt == 0) {
ead9360e 7898 /* Treat as NOP. */
9c2149c8
TS
7899 return;
7900 }
d75c135e 7901 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7902 opn = "dmfc0";
7903 break;
7904 case OPC_DMTC0:
d75c135e 7905 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7906 {
1fc7bf6e 7907 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7908
7909 gen_load_gpr(t0, rt);
d75c135e 7910 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7911 tcg_temp_free(t0);
7912 }
9c2149c8
TS
7913 opn = "dmtc0";
7914 break;
534ce69f 7915#endif
5204ea79
LA
7916 case OPC_MFHC0:
7917 check_mvh(ctx);
7918 if (rt == 0) {
7919 /* Treat as NOP. */
7920 return;
7921 }
7922 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7923 opn = "mfhc0";
7924 break;
7925 case OPC_MTHC0:
7926 check_mvh(ctx);
7927 {
7928 TCGv t0 = tcg_temp_new();
7929 gen_load_gpr(t0, rt);
7930 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7931 tcg_temp_free(t0);
7932 }
7933 opn = "mthc0";
7934 break;
ead9360e 7935 case OPC_MFTR:
d75c135e 7936 check_insn(ctx, ASE_MT);
ead9360e
TS
7937 if (rd == 0) {
7938 /* Treat as NOP. */
7939 return;
7940 }
6c5c1e20 7941 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7942 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7943 opn = "mftr";
7944 break;
7945 case OPC_MTTR:
d75c135e 7946 check_insn(ctx, ASE_MT);
6c5c1e20 7947 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7948 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7949 opn = "mttr";
7950 break;
6af0bf9c 7951 case OPC_TLBWI:
6af0bf9c 7952 opn = "tlbwi";
c01fccd2 7953 if (!env->tlb->helper_tlbwi)
29929e34 7954 goto die;
895c2d04 7955 gen_helper_tlbwi(cpu_env);
6af0bf9c 7956 break;
9456c2fb
LA
7957 case OPC_TLBINV:
7958 opn = "tlbinv";
7959 if (ctx->ie >= 2) {
7960 if (!env->tlb->helper_tlbinv) {
7961 goto die;
7962 }
7963 gen_helper_tlbinv(cpu_env);
7964 } /* treat as nop if TLBINV not supported */
7965 break;
7966 case OPC_TLBINVF:
7967 opn = "tlbinvf";
7968 if (ctx->ie >= 2) {
7969 if (!env->tlb->helper_tlbinvf) {
7970 goto die;
7971 }
7972 gen_helper_tlbinvf(cpu_env);
7973 } /* treat as nop if TLBINV not supported */
7974 break;
6af0bf9c 7975 case OPC_TLBWR:
6af0bf9c 7976 opn = "tlbwr";
c01fccd2 7977 if (!env->tlb->helper_tlbwr)
29929e34 7978 goto die;
895c2d04 7979 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7980 break;
7981 case OPC_TLBP:
6af0bf9c 7982 opn = "tlbp";
c01fccd2 7983 if (!env->tlb->helper_tlbp)
29929e34 7984 goto die;
895c2d04 7985 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7986 break;
7987 case OPC_TLBR:
6af0bf9c 7988 opn = "tlbr";
c01fccd2 7989 if (!env->tlb->helper_tlbr)
29929e34 7990 goto die;
895c2d04 7991 gen_helper_tlbr(cpu_env);
6af0bf9c 7992 break;
ce9782f4 7993 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
7994 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7995 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 7996 goto die;
ce9782f4
LA
7997 } else {
7998 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
7999 if (ctx->opcode & (1 << bit_shift)) {
8000 /* OPC_ERETNC */
8001 opn = "eretnc";
8002 check_insn(ctx, ISA_MIPS32R5);
8003 gen_helper_eretnc(cpu_env);
8004 } else {
8005 /* OPC_ERET */
8006 opn = "eret";
8007 check_insn(ctx, ISA_MIPS2);
8008 gen_helper_eret(cpu_env);
8009 }
8010 ctx->bstate = BS_EXCP;
339cd2a8 8011 }
6af0bf9c
FB
8012 break;
8013 case OPC_DERET:
8014 opn = "deret";
d75c135e 8015 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8016 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8017 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8018 goto die;
8019 }
6af0bf9c 8020 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8021 MIPS_INVAL(opn);
6af0bf9c
FB
8022 generate_exception(ctx, EXCP_RI);
8023 } else {
895c2d04 8024 gen_helper_deret(cpu_env);
6af0bf9c
FB
8025 ctx->bstate = BS_EXCP;
8026 }
8027 break;
4ad40f36
FB
8028 case OPC_WAIT:
8029 opn = "wait";
d75c135e 8030 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8031 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8032 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8033 goto die;
8034 }
4ad40f36
FB
8035 /* If we get an exception, we want to restart at next instruction */
8036 ctx->pc += 4;
8037 save_cpu_state(ctx, 1);
8038 ctx->pc -= 4;
895c2d04 8039 gen_helper_wait(cpu_env);
4ad40f36
FB
8040 ctx->bstate = BS_EXCP;
8041 break;
6af0bf9c 8042 default:
29929e34 8043 die:
923617a3 8044 MIPS_INVAL(opn);
6af0bf9c
FB
8045 generate_exception(ctx, EXCP_RI);
8046 return;
8047 }
2abf314d 8048 (void)opn; /* avoid a compiler warning */
6af0bf9c 8049}
f1aa6320 8050#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8051
6ea83fed 8052/* CP1 Branches (before delay slot) */
d75c135e
AJ
8053static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8054 int32_t cc, int32_t offset)
6ea83fed
FB
8055{
8056 target_ulong btarget;
a7812ae4 8057 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8058
339cd2a8 8059 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8060 generate_exception(ctx, EXCP_RI);
8061 goto out;
8062 }
8063
e189e748 8064 if (cc != 0)
d75c135e 8065 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8066
6ea83fed
FB
8067 btarget = ctx->pc + 4 + offset;
8068
7a387fff
TS
8069 switch (op) {
8070 case OPC_BC1F:
d94536f4
AJ
8071 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8072 tcg_gen_not_i32(t0, t0);
8073 tcg_gen_andi_i32(t0, t0, 1);
8074 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8075 goto not_likely;
7a387fff 8076 case OPC_BC1FL:
d94536f4
AJ
8077 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8078 tcg_gen_not_i32(t0, t0);
8079 tcg_gen_andi_i32(t0, t0, 1);
8080 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8081 goto likely;
7a387fff 8082 case OPC_BC1T:
d94536f4
AJ
8083 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8084 tcg_gen_andi_i32(t0, t0, 1);
8085 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8086 goto not_likely;
7a387fff 8087 case OPC_BC1TL:
d94536f4
AJ
8088 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8089 tcg_gen_andi_i32(t0, t0, 1);
8090 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8091 likely:
8092 ctx->hflags |= MIPS_HFLAG_BL;
8093 break;
5a5012ec 8094 case OPC_BC1FANY2:
a16336e4 8095 {
d94536f4
AJ
8096 TCGv_i32 t1 = tcg_temp_new_i32();
8097 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8098 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8099 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8100 tcg_temp_free_i32(t1);
d94536f4
AJ
8101 tcg_gen_andi_i32(t0, t0, 1);
8102 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8103 }
5a5012ec
TS
8104 goto not_likely;
8105 case OPC_BC1TANY2:
a16336e4 8106 {
d94536f4
AJ
8107 TCGv_i32 t1 = tcg_temp_new_i32();
8108 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8109 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8110 tcg_gen_or_i32(t0, t0, t1);
8111 tcg_temp_free_i32(t1);
8112 tcg_gen_andi_i32(t0, t0, 1);
8113 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8114 }
5a5012ec
TS
8115 goto not_likely;
8116 case OPC_BC1FANY4:
a16336e4 8117 {
d94536f4
AJ
8118 TCGv_i32 t1 = tcg_temp_new_i32();
8119 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8120 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8121 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8122 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8123 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8124 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8125 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8126 tcg_temp_free_i32(t1);
d94536f4
AJ
8127 tcg_gen_andi_i32(t0, t0, 1);
8128 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8129 }
5a5012ec
TS
8130 goto not_likely;
8131 case OPC_BC1TANY4:
a16336e4 8132 {
d94536f4
AJ
8133 TCGv_i32 t1 = tcg_temp_new_i32();
8134 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8135 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8136 tcg_gen_or_i32(t0, t0, t1);
8137 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8138 tcg_gen_or_i32(t0, t0, t1);
8139 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8140 tcg_gen_or_i32(t0, t0, t1);
8141 tcg_temp_free_i32(t1);
8142 tcg_gen_andi_i32(t0, t0, 1);
8143 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8144 }
5a5012ec
TS
8145 not_likely:
8146 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8147 break;
8148 default:
9d68ac14 8149 MIPS_INVAL("cp1 cond branch");
e397ee33 8150 generate_exception (ctx, EXCP_RI);
6c5c1e20 8151 goto out;
6ea83fed 8152 }
6ea83fed 8153 ctx->btarget = btarget;
b231c103 8154 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8155 out:
a7812ae4 8156 tcg_temp_free_i32(t0);
6ea83fed
FB
8157}
8158
31837be3
YK
8159/* R6 CP1 Branches */
8160static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8161 int32_t ft, int32_t offset,
8162 int delayslot_size)
31837be3
YK
8163{
8164 target_ulong btarget;
31837be3
YK
8165 TCGv_i64 t0 = tcg_temp_new_i64();
8166
8167 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8168#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8169 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8170 "\n", ctx->pc);
31837be3
YK
8171#endif
8172 generate_exception(ctx, EXCP_RI);
8173 goto out;
8174 }
8175
8176 gen_load_fpr64(ctx, t0, ft);
8177 tcg_gen_andi_i64(t0, t0, 1);
8178
8179 btarget = addr_add(ctx, ctx->pc + 4, offset);
8180
8181 switch (op) {
8182 case OPC_BC1EQZ:
8183 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8184 ctx->hflags |= MIPS_HFLAG_BC;
8185 break;
8186 case OPC_BC1NEZ:
8187 /* t0 already set */
31837be3
YK
8188 ctx->hflags |= MIPS_HFLAG_BC;
8189 break;
8190 default:
9d68ac14 8191 MIPS_INVAL("cp1 cond branch");
31837be3
YK
8192 generate_exception(ctx, EXCP_RI);
8193 goto out;
8194 }
8195
8196 tcg_gen_trunc_i64_tl(bcond, t0);
8197
31837be3 8198 ctx->btarget = btarget;
65935f07
YK
8199
8200 switch (delayslot_size) {
8201 case 2:
8202 ctx->hflags |= MIPS_HFLAG_BDS16;
8203 break;
8204 case 4:
8205 ctx->hflags |= MIPS_HFLAG_BDS32;
8206 break;
8207 }
31837be3
YK
8208
8209out:
8210 tcg_temp_free_i64(t0);
8211}
8212
6af0bf9c 8213/* Coprocessor 1 (FPU) */
5a5012ec 8214
5a5012ec
TS
8215#define FOP(func, fmt) (((fmt) << 21) | (func))
8216
bf4120ad
NF
8217enum fopcode {
8218 OPC_ADD_S = FOP(0, FMT_S),
8219 OPC_SUB_S = FOP(1, FMT_S),
8220 OPC_MUL_S = FOP(2, FMT_S),
8221 OPC_DIV_S = FOP(3, FMT_S),
8222 OPC_SQRT_S = FOP(4, FMT_S),
8223 OPC_ABS_S = FOP(5, FMT_S),
8224 OPC_MOV_S = FOP(6, FMT_S),
8225 OPC_NEG_S = FOP(7, FMT_S),
8226 OPC_ROUND_L_S = FOP(8, FMT_S),
8227 OPC_TRUNC_L_S = FOP(9, FMT_S),
8228 OPC_CEIL_L_S = FOP(10, FMT_S),
8229 OPC_FLOOR_L_S = FOP(11, FMT_S),
8230 OPC_ROUND_W_S = FOP(12, FMT_S),
8231 OPC_TRUNC_W_S = FOP(13, FMT_S),
8232 OPC_CEIL_W_S = FOP(14, FMT_S),
8233 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8234 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8235 OPC_MOVCF_S = FOP(17, FMT_S),
8236 OPC_MOVZ_S = FOP(18, FMT_S),
8237 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8238 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8239 OPC_RECIP_S = FOP(21, FMT_S),
8240 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8241 OPC_SELNEZ_S = FOP(23, FMT_S),
8242 OPC_MADDF_S = FOP(24, FMT_S),
8243 OPC_MSUBF_S = FOP(25, FMT_S),
8244 OPC_RINT_S = FOP(26, FMT_S),
8245 OPC_CLASS_S = FOP(27, FMT_S),
8246 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8247 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8248 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8249 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8250 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8251 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8252 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8253 OPC_RSQRT2_S = FOP(31, FMT_S),
8254 OPC_CVT_D_S = FOP(33, FMT_S),
8255 OPC_CVT_W_S = FOP(36, FMT_S),
8256 OPC_CVT_L_S = FOP(37, FMT_S),
8257 OPC_CVT_PS_S = FOP(38, FMT_S),
8258 OPC_CMP_F_S = FOP (48, FMT_S),
8259 OPC_CMP_UN_S = FOP (49, FMT_S),
8260 OPC_CMP_EQ_S = FOP (50, FMT_S),
8261 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8262 OPC_CMP_OLT_S = FOP (52, FMT_S),
8263 OPC_CMP_ULT_S = FOP (53, FMT_S),
8264 OPC_CMP_OLE_S = FOP (54, FMT_S),
8265 OPC_CMP_ULE_S = FOP (55, FMT_S),
8266 OPC_CMP_SF_S = FOP (56, FMT_S),
8267 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8268 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8269 OPC_CMP_NGL_S = FOP (59, FMT_S),
8270 OPC_CMP_LT_S = FOP (60, FMT_S),
8271 OPC_CMP_NGE_S = FOP (61, FMT_S),
8272 OPC_CMP_LE_S = FOP (62, FMT_S),
8273 OPC_CMP_NGT_S = FOP (63, FMT_S),
8274
8275 OPC_ADD_D = FOP(0, FMT_D),
8276 OPC_SUB_D = FOP(1, FMT_D),
8277 OPC_MUL_D = FOP(2, FMT_D),
8278 OPC_DIV_D = FOP(3, FMT_D),
8279 OPC_SQRT_D = FOP(4, FMT_D),
8280 OPC_ABS_D = FOP(5, FMT_D),
8281 OPC_MOV_D = FOP(6, FMT_D),
8282 OPC_NEG_D = FOP(7, FMT_D),
8283 OPC_ROUND_L_D = FOP(8, FMT_D),
8284 OPC_TRUNC_L_D = FOP(9, FMT_D),
8285 OPC_CEIL_L_D = FOP(10, FMT_D),
8286 OPC_FLOOR_L_D = FOP(11, FMT_D),
8287 OPC_ROUND_W_D = FOP(12, FMT_D),
8288 OPC_TRUNC_W_D = FOP(13, FMT_D),
8289 OPC_CEIL_W_D = FOP(14, FMT_D),
8290 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8291 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8292 OPC_MOVCF_D = FOP(17, FMT_D),
8293 OPC_MOVZ_D = FOP(18, FMT_D),
8294 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8295 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8296 OPC_RECIP_D = FOP(21, FMT_D),
8297 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8298 OPC_SELNEZ_D = FOP(23, FMT_D),
8299 OPC_MADDF_D = FOP(24, FMT_D),
8300 OPC_MSUBF_D = FOP(25, FMT_D),
8301 OPC_RINT_D = FOP(26, FMT_D),
8302 OPC_CLASS_D = FOP(27, FMT_D),
8303 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8304 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8305 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8306 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8307 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8308 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8309 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8310 OPC_RSQRT2_D = FOP(31, FMT_D),
8311 OPC_CVT_S_D = FOP(32, FMT_D),
8312 OPC_CVT_W_D = FOP(36, FMT_D),
8313 OPC_CVT_L_D = FOP(37, FMT_D),
8314 OPC_CMP_F_D = FOP (48, FMT_D),
8315 OPC_CMP_UN_D = FOP (49, FMT_D),
8316 OPC_CMP_EQ_D = FOP (50, FMT_D),
8317 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8318 OPC_CMP_OLT_D = FOP (52, FMT_D),
8319 OPC_CMP_ULT_D = FOP (53, FMT_D),
8320 OPC_CMP_OLE_D = FOP (54, FMT_D),
8321 OPC_CMP_ULE_D = FOP (55, FMT_D),
8322 OPC_CMP_SF_D = FOP (56, FMT_D),
8323 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8324 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8325 OPC_CMP_NGL_D = FOP (59, FMT_D),
8326 OPC_CMP_LT_D = FOP (60, FMT_D),
8327 OPC_CMP_NGE_D = FOP (61, FMT_D),
8328 OPC_CMP_LE_D = FOP (62, FMT_D),
8329 OPC_CMP_NGT_D = FOP (63, FMT_D),
8330
8331 OPC_CVT_S_W = FOP(32, FMT_W),
8332 OPC_CVT_D_W = FOP(33, FMT_W),
8333 OPC_CVT_S_L = FOP(32, FMT_L),
8334 OPC_CVT_D_L = FOP(33, FMT_L),
8335 OPC_CVT_PS_PW = FOP(38, FMT_W),
8336
8337 OPC_ADD_PS = FOP(0, FMT_PS),
8338 OPC_SUB_PS = FOP(1, FMT_PS),
8339 OPC_MUL_PS = FOP(2, FMT_PS),
8340 OPC_DIV_PS = FOP(3, FMT_PS),
8341 OPC_ABS_PS = FOP(5, FMT_PS),
8342 OPC_MOV_PS = FOP(6, FMT_PS),
8343 OPC_NEG_PS = FOP(7, FMT_PS),
8344 OPC_MOVCF_PS = FOP(17, FMT_PS),
8345 OPC_MOVZ_PS = FOP(18, FMT_PS),
8346 OPC_MOVN_PS = FOP(19, FMT_PS),
8347 OPC_ADDR_PS = FOP(24, FMT_PS),
8348 OPC_MULR_PS = FOP(26, FMT_PS),
8349 OPC_RECIP2_PS = FOP(28, FMT_PS),
8350 OPC_RECIP1_PS = FOP(29, FMT_PS),
8351 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8352 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8353
8354 OPC_CVT_S_PU = FOP(32, FMT_PS),
8355 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8356 OPC_CVT_S_PL = FOP(40, FMT_PS),
8357 OPC_PLL_PS = FOP(44, FMT_PS),
8358 OPC_PLU_PS = FOP(45, FMT_PS),
8359 OPC_PUL_PS = FOP(46, FMT_PS),
8360 OPC_PUU_PS = FOP(47, FMT_PS),
8361 OPC_CMP_F_PS = FOP (48, FMT_PS),
8362 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8363 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8364 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8365 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8366 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8367 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8368 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8369 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8370 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8371 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8372 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8373 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8374 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8375 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8376 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8377};
8378
3f493883
YK
8379enum r6_f_cmp_op {
8380 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8381 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8382 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8383 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8384 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8385 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8386 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8387 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8388 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8389 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8390 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8391 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8392 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8393 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8394 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8395 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8396 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8397 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8398 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8399 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8400 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8401 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8402
8403 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8404 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8405 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8406 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8407 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8408 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8409 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8410 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8411 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8412 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8413 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8414 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8415 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8416 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8417 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8418 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8419 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8420 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8421 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8422 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8423 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8424 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8425};
7a387fff 8426static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8427{
72c3a3ee 8428 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8429
8430 switch (opc) {
8431 case OPC_MFC1:
b6d96bed 8432 {
a7812ae4 8433 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8434
7c979afd 8435 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8436 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8437 tcg_temp_free_i32(fp0);
6958549d 8438 }
6c5c1e20 8439 gen_store_gpr(t0, rt);
6ea83fed
FB
8440 break;
8441 case OPC_MTC1:
6c5c1e20 8442 gen_load_gpr(t0, rt);
b6d96bed 8443 {
a7812ae4 8444 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8445
8446 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8447 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8448 tcg_temp_free_i32(fp0);
6958549d 8449 }
6ea83fed
FB
8450 break;
8451 case OPC_CFC1:
895c2d04 8452 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8453 gen_store_gpr(t0, rt);
6ea83fed
FB
8454 break;
8455 case OPC_CTC1:
6c5c1e20 8456 gen_load_gpr(t0, rt);
4cf8a45f 8457 save_cpu_state(ctx, 1);
736d120a
PJ
8458 {
8459 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8460
8461 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8462 tcg_temp_free_i32(fs_tmp);
8463 }
4cf8a45f
YK
8464 /* Stop translation as we may have changed hflags */
8465 ctx->bstate = BS_STOP;
6ea83fed 8466 break;
72c3a3ee 8467#if defined(TARGET_MIPS64)
9c2149c8 8468 case OPC_DMFC1:
72c3a3ee 8469 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8470 gen_store_gpr(t0, rt);
5a5012ec 8471 break;
9c2149c8 8472 case OPC_DMTC1:
6c5c1e20 8473 gen_load_gpr(t0, rt);
72c3a3ee 8474 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8475 break;
72c3a3ee 8476#endif
5a5012ec 8477 case OPC_MFHC1:
b6d96bed 8478 {
a7812ae4 8479 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8480
7f6613ce 8481 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8482 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8483 tcg_temp_free_i32(fp0);
6958549d 8484 }
6c5c1e20 8485 gen_store_gpr(t0, rt);
5a5012ec
TS
8486 break;
8487 case OPC_MTHC1:
6c5c1e20 8488 gen_load_gpr(t0, rt);
b6d96bed 8489 {
a7812ae4 8490 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8491
8492 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8493 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8494 tcg_temp_free_i32(fp0);
6958549d 8495 }
5a5012ec 8496 break;
6ea83fed 8497 default:
9d68ac14 8498 MIPS_INVAL("cp1 move");
e397ee33 8499 generate_exception (ctx, EXCP_RI);
6c5c1e20 8500 goto out;
6ea83fed 8501 }
6c5c1e20
TS
8502
8503 out:
8504 tcg_temp_free(t0);
6ea83fed
FB
8505}
8506
5a5012ec
TS
8507static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8508{
42a268c2 8509 TCGLabel *l1;
e214b9bb 8510 TCGCond cond;
af58f9ca
AJ
8511 TCGv_i32 t0;
8512
8513 if (rd == 0) {
8514 /* Treat as NOP. */
8515 return;
8516 }
6ea83fed 8517
e214b9bb 8518 if (tf)
e214b9bb 8519 cond = TCG_COND_EQ;
27848470
TS
8520 else
8521 cond = TCG_COND_NE;
8522
af58f9ca
AJ
8523 l1 = gen_new_label();
8524 t0 = tcg_temp_new_i32();
fa31af0e 8525 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8526 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8527 tcg_temp_free_i32(t0);
af58f9ca
AJ
8528 if (rs == 0) {
8529 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8530 } else {
8531 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8532 }
e214b9bb 8533 gen_set_label(l1);
5a5012ec
TS
8534}
8535
7c979afd
LA
8536static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8537 int tf)
a16336e4 8538{
a16336e4 8539 int cond;
cbc37b28 8540 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8541 TCGLabel *l1 = gen_new_label();
a16336e4 8542
a16336e4
TS
8543 if (tf)
8544 cond = TCG_COND_EQ;
8545 else
8546 cond = TCG_COND_NE;
8547
fa31af0e 8548 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8549 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8550 gen_load_fpr32(ctx, t0, fs);
8551 gen_store_fpr32(ctx, t0, fd);
a16336e4 8552 gen_set_label(l1);
cbc37b28 8553 tcg_temp_free_i32(t0);
5a5012ec 8554}
a16336e4 8555
b6d96bed 8556static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8557{
a16336e4 8558 int cond;
cbc37b28
AJ
8559 TCGv_i32 t0 = tcg_temp_new_i32();
8560 TCGv_i64 fp0;
42a268c2 8561 TCGLabel *l1 = gen_new_label();
a16336e4 8562
a16336e4
TS
8563 if (tf)
8564 cond = TCG_COND_EQ;
8565 else
8566 cond = TCG_COND_NE;
8567
fa31af0e 8568 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8569 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8570 tcg_temp_free_i32(t0);
11f94258 8571 fp0 = tcg_temp_new_i64();
9bf3eb2c 8572 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8573 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8574 tcg_temp_free_i64(fp0);
cbc37b28 8575 gen_set_label(l1);
a16336e4
TS
8576}
8577
7f6613ce
PJ
8578static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8579 int cc, int tf)
a16336e4
TS
8580{
8581 int cond;
cbc37b28 8582 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8583 TCGLabel *l1 = gen_new_label();
8584 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8585
8586 if (tf)
8587 cond = TCG_COND_EQ;
8588 else
8589 cond = TCG_COND_NE;
8590
fa31af0e 8591 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8592 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8593 gen_load_fpr32(ctx, t0, fs);
8594 gen_store_fpr32(ctx, t0, fd);
a16336e4 8595 gen_set_label(l1);
9bf3eb2c 8596
fa31af0e 8597 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8598 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8599 gen_load_fpr32h(ctx, t0, fs);
8600 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8601 tcg_temp_free_i32(t0);
a16336e4 8602 gen_set_label(l2);
a16336e4
TS
8603}
8604
e7f16abb
LA
8605static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8606 int fs)
8607{
8608 TCGv_i32 t1 = tcg_const_i32(0);
8609 TCGv_i32 fp0 = tcg_temp_new_i32();
8610 TCGv_i32 fp1 = tcg_temp_new_i32();
8611 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8612 gen_load_fpr32(ctx, fp0, fd);
8613 gen_load_fpr32(ctx, fp1, ft);
8614 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8615
8616 switch (op1) {
8617 case OPC_SEL_S:
8618 tcg_gen_andi_i32(fp0, fp0, 1);
8619 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8620 break;
8621 case OPC_SELEQZ_S:
8622 tcg_gen_andi_i32(fp1, fp1, 1);
8623 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8624 break;
8625 case OPC_SELNEZ_S:
8626 tcg_gen_andi_i32(fp1, fp1, 1);
8627 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8628 break;
8629 default:
8630 MIPS_INVAL("gen_sel_s");
8631 generate_exception (ctx, EXCP_RI);
8632 break;
8633 }
8634
7c979afd 8635 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8636 tcg_temp_free_i32(fp2);
8637 tcg_temp_free_i32(fp1);
8638 tcg_temp_free_i32(fp0);
8639 tcg_temp_free_i32(t1);
8640}
8641
8642static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8643 int fs)
8644{
8645 TCGv_i64 t1 = tcg_const_i64(0);
8646 TCGv_i64 fp0 = tcg_temp_new_i64();
8647 TCGv_i64 fp1 = tcg_temp_new_i64();
8648 TCGv_i64 fp2 = tcg_temp_new_i64();
8649 gen_load_fpr64(ctx, fp0, fd);
8650 gen_load_fpr64(ctx, fp1, ft);
8651 gen_load_fpr64(ctx, fp2, fs);
8652
8653 switch (op1) {
8654 case OPC_SEL_D:
8655 tcg_gen_andi_i64(fp0, fp0, 1);
8656 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8657 break;
8658 case OPC_SELEQZ_D:
8659 tcg_gen_andi_i64(fp1, fp1, 1);
8660 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8661 break;
8662 case OPC_SELNEZ_D:
8663 tcg_gen_andi_i64(fp1, fp1, 1);
8664 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8665 break;
8666 default:
8667 MIPS_INVAL("gen_sel_d");
8668 generate_exception (ctx, EXCP_RI);
8669 break;
8670 }
8671
8672 gen_store_fpr64(ctx, fp0, fd);
8673 tcg_temp_free_i64(fp2);
8674 tcg_temp_free_i64(fp1);
8675 tcg_temp_free_i64(fp0);
8676 tcg_temp_free_i64(t1);
8677}
6ea83fed 8678
bf4120ad 8679static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8680 int ft, int fs, int fd, int cc)
6ea83fed 8681{
7a387fff 8682 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8683 switch (op1) {
8684 case OPC_ADD_S:
b6d96bed 8685 {
a7812ae4
PB
8686 TCGv_i32 fp0 = tcg_temp_new_i32();
8687 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8688
7c979afd
LA
8689 gen_load_fpr32(ctx, fp0, fs);
8690 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8691 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8692 tcg_temp_free_i32(fp1);
7c979afd 8693 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8694 tcg_temp_free_i32(fp0);
b6d96bed 8695 }
5a5012ec 8696 break;
bf4120ad 8697 case OPC_SUB_S:
b6d96bed 8698 {
a7812ae4
PB
8699 TCGv_i32 fp0 = tcg_temp_new_i32();
8700 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8701
7c979afd
LA
8702 gen_load_fpr32(ctx, fp0, fs);
8703 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8704 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8705 tcg_temp_free_i32(fp1);
7c979afd 8706 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8707 tcg_temp_free_i32(fp0);
b6d96bed 8708 }
5a5012ec 8709 break;
bf4120ad 8710 case OPC_MUL_S:
b6d96bed 8711 {
a7812ae4
PB
8712 TCGv_i32 fp0 = tcg_temp_new_i32();
8713 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8714
7c979afd
LA
8715 gen_load_fpr32(ctx, fp0, fs);
8716 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8717 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8718 tcg_temp_free_i32(fp1);
7c979afd 8719 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8720 tcg_temp_free_i32(fp0);
b6d96bed 8721 }
5a5012ec 8722 break;
bf4120ad 8723 case OPC_DIV_S:
b6d96bed 8724 {
a7812ae4
PB
8725 TCGv_i32 fp0 = tcg_temp_new_i32();
8726 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8727
7c979afd
LA
8728 gen_load_fpr32(ctx, fp0, fs);
8729 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8730 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8731 tcg_temp_free_i32(fp1);
7c979afd 8732 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8733 tcg_temp_free_i32(fp0);
b6d96bed 8734 }
5a5012ec 8735 break;
bf4120ad 8736 case OPC_SQRT_S:
b6d96bed 8737 {
a7812ae4 8738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8739
7c979afd 8740 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8741 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8742 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8743 tcg_temp_free_i32(fp0);
b6d96bed 8744 }
5a5012ec 8745 break;
bf4120ad 8746 case OPC_ABS_S:
b6d96bed 8747 {
a7812ae4 8748 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8749
7c979afd 8750 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8751 gen_helper_float_abs_s(fp0, fp0);
7c979afd 8752 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8753 tcg_temp_free_i32(fp0);
b6d96bed 8754 }
5a5012ec 8755 break;
bf4120ad 8756 case OPC_MOV_S:
b6d96bed 8757 {
a7812ae4 8758 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8759
7c979afd
LA
8760 gen_load_fpr32(ctx, fp0, fs);
8761 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8762 tcg_temp_free_i32(fp0);
b6d96bed 8763 }
5a5012ec 8764 break;
bf4120ad 8765 case OPC_NEG_S:
b6d96bed 8766 {
a7812ae4 8767 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8768
7c979afd 8769 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8770 gen_helper_float_chs_s(fp0, fp0);
7c979afd 8771 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8772 tcg_temp_free_i32(fp0);
b6d96bed 8773 }
5a5012ec 8774 break;
bf4120ad 8775 case OPC_ROUND_L_S:
5e755519 8776 check_cp1_64bitmode(ctx);
b6d96bed 8777 {
a7812ae4
PB
8778 TCGv_i32 fp32 = tcg_temp_new_i32();
8779 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8780
7c979afd 8781 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8782 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8783 tcg_temp_free_i32(fp32);
b6d96bed 8784 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8785 tcg_temp_free_i64(fp64);
b6d96bed 8786 }
5a5012ec 8787 break;
bf4120ad 8788 case OPC_TRUNC_L_S:
5e755519 8789 check_cp1_64bitmode(ctx);
b6d96bed 8790 {
a7812ae4
PB
8791 TCGv_i32 fp32 = tcg_temp_new_i32();
8792 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8793
7c979afd 8794 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8795 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8796 tcg_temp_free_i32(fp32);
b6d96bed 8797 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8798 tcg_temp_free_i64(fp64);
b6d96bed 8799 }
5a5012ec 8800 break;
bf4120ad 8801 case OPC_CEIL_L_S:
5e755519 8802 check_cp1_64bitmode(ctx);
b6d96bed 8803 {
a7812ae4
PB
8804 TCGv_i32 fp32 = tcg_temp_new_i32();
8805 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8806
7c979afd 8807 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8808 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8809 tcg_temp_free_i32(fp32);
b6d96bed 8810 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8811 tcg_temp_free_i64(fp64);
b6d96bed 8812 }
5a5012ec 8813 break;
bf4120ad 8814 case OPC_FLOOR_L_S:
5e755519 8815 check_cp1_64bitmode(ctx);
b6d96bed 8816 {
a7812ae4
PB
8817 TCGv_i32 fp32 = tcg_temp_new_i32();
8818 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8819
7c979afd 8820 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8821 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8822 tcg_temp_free_i32(fp32);
b6d96bed 8823 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8824 tcg_temp_free_i64(fp64);
b6d96bed 8825 }
5a5012ec 8826 break;
bf4120ad 8827 case OPC_ROUND_W_S:
b6d96bed 8828 {
a7812ae4 8829 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8830
7c979afd 8831 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8832 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 8833 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8834 tcg_temp_free_i32(fp0);
b6d96bed 8835 }
5a5012ec 8836 break;
bf4120ad 8837 case OPC_TRUNC_W_S:
b6d96bed 8838 {
a7812ae4 8839 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8840
7c979afd 8841 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8842 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 8843 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8844 tcg_temp_free_i32(fp0);
b6d96bed 8845 }
5a5012ec 8846 break;
bf4120ad 8847 case OPC_CEIL_W_S:
b6d96bed 8848 {
a7812ae4 8849 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8850
7c979afd 8851 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8852 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 8853 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8854 tcg_temp_free_i32(fp0);
b6d96bed 8855 }
5a5012ec 8856 break;
bf4120ad 8857 case OPC_FLOOR_W_S:
b6d96bed 8858 {
a7812ae4 8859 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8860
7c979afd 8861 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8862 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 8863 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8864 tcg_temp_free_i32(fp0);
b6d96bed 8865 }
5a5012ec 8866 break;
e7f16abb
LA
8867 case OPC_SEL_S:
8868 check_insn(ctx, ISA_MIPS32R6);
8869 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8870 break;
8871 case OPC_SELEQZ_S:
8872 check_insn(ctx, ISA_MIPS32R6);
8873 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8874 break;
8875 case OPC_SELNEZ_S:
8876 check_insn(ctx, ISA_MIPS32R6);
8877 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 8878 break;
bf4120ad 8879 case OPC_MOVCF_S:
fecd2646 8880 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 8881 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8882 break;
bf4120ad 8883 case OPC_MOVZ_S:
fecd2646 8884 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8885 {
42a268c2 8886 TCGLabel *l1 = gen_new_label();
c9297f4d 8887 TCGv_i32 fp0;
a16336e4 8888
c9297f4d
AJ
8889 if (ft != 0) {
8890 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8891 }
8892 fp0 = tcg_temp_new_i32();
7c979afd
LA
8893 gen_load_fpr32(ctx, fp0, fs);
8894 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8895 tcg_temp_free_i32(fp0);
a16336e4
TS
8896 gen_set_label(l1);
8897 }
5a5012ec 8898 break;
bf4120ad 8899 case OPC_MOVN_S:
fecd2646 8900 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8901 {
42a268c2 8902 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8903 TCGv_i32 fp0;
8904
8905 if (ft != 0) {
8906 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8907 fp0 = tcg_temp_new_i32();
7c979afd
LA
8908 gen_load_fpr32(ctx, fp0, fs);
8909 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
8910 tcg_temp_free_i32(fp0);
8911 gen_set_label(l1);
8912 }
a16336e4 8913 }
5a5012ec 8914 break;
bf4120ad 8915 case OPC_RECIP_S:
b6d96bed 8916 {
a7812ae4 8917 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8918
7c979afd 8919 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8920 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 8921 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8922 tcg_temp_free_i32(fp0);
b6d96bed 8923 }
57fa1fb3 8924 break;
bf4120ad 8925 case OPC_RSQRT_S:
b6d96bed 8926 {
a7812ae4 8927 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8928
7c979afd 8929 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8930 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 8931 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8932 tcg_temp_free_i32(fp0);
b6d96bed 8933 }
57fa1fb3 8934 break;
e7f16abb
LA
8935 case OPC_MADDF_S:
8936 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8937 {
a7812ae4
PB
8938 TCGv_i32 fp0 = tcg_temp_new_i32();
8939 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8940 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8941 gen_load_fpr32(ctx, fp0, fs);
8942 gen_load_fpr32(ctx, fp1, ft);
8943 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8944 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8945 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 8946 tcg_temp_free_i32(fp2);
a7812ae4 8947 tcg_temp_free_i32(fp1);
a7812ae4 8948 tcg_temp_free_i32(fp0);
b6d96bed 8949 }
57fa1fb3 8950 break;
e7f16abb
LA
8951 case OPC_MSUBF_S:
8952 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8953 {
a7812ae4 8954 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8955 TCGv_i32 fp1 = tcg_temp_new_i32();
8956 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8957 gen_load_fpr32(ctx, fp0, fs);
8958 gen_load_fpr32(ctx, fp1, ft);
8959 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8960 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8961 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
8962 tcg_temp_free_i32(fp2);
8963 tcg_temp_free_i32(fp1);
a7812ae4 8964 tcg_temp_free_i32(fp0);
b6d96bed 8965 }
57fa1fb3 8966 break;
e7f16abb
LA
8967 case OPC_RINT_S:
8968 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8969 {
a7812ae4 8970 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8971 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8972 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 8973 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8974 tcg_temp_free_i32(fp0);
b6d96bed 8975 }
57fa1fb3 8976 break;
e7f16abb
LA
8977 case OPC_CLASS_S:
8978 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8979 {
e7f16abb 8980 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 8981 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 8982 gen_helper_float_class_s(fp0, fp0);
7c979afd 8983 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 8984 tcg_temp_free_i32(fp0);
e7f16abb
LA
8985 }
8986 break;
8987 case OPC_MIN_S: /* OPC_RECIP2_S */
8988 if (ctx->insn_flags & ISA_MIPS32R6) {
8989 /* OPC_MIN_S */
a7812ae4
PB
8990 TCGv_i32 fp0 = tcg_temp_new_i32();
8991 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8992 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8993 gen_load_fpr32(ctx, fp0, fs);
8994 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 8995 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 8996 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
8997 tcg_temp_free_i32(fp2);
8998 tcg_temp_free_i32(fp1);
8999 tcg_temp_free_i32(fp0);
e7f16abb
LA
9000 } else {
9001 /* OPC_RECIP2_S */
9002 check_cp1_64bitmode(ctx);
9003 {
9004 TCGv_i32 fp0 = tcg_temp_new_i32();
9005 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9006
7c979afd
LA
9007 gen_load_fpr32(ctx, fp0, fs);
9008 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9009 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9010 tcg_temp_free_i32(fp1);
7c979afd 9011 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9012 tcg_temp_free_i32(fp0);
9013 }
e7f16abb
LA
9014 }
9015 break;
9016 case OPC_MINA_S: /* OPC_RECIP1_S */
9017 if (ctx->insn_flags & ISA_MIPS32R6) {
9018 /* OPC_MINA_S */
9019 TCGv_i32 fp0 = tcg_temp_new_i32();
9020 TCGv_i32 fp1 = tcg_temp_new_i32();
9021 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9022 gen_load_fpr32(ctx, fp0, fs);
9023 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9024 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9025 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9026 tcg_temp_free_i32(fp2);
9027 tcg_temp_free_i32(fp1);
9028 tcg_temp_free_i32(fp0);
e7f16abb
LA
9029 } else {
9030 /* OPC_RECIP1_S */
9031 check_cp1_64bitmode(ctx);
9032 {
9033 TCGv_i32 fp0 = tcg_temp_new_i32();
9034
7c979afd 9035 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9036 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9037 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9038 tcg_temp_free_i32(fp0);
9039 }
e7f16abb
LA
9040 }
9041 break;
9042 case OPC_MAX_S: /* OPC_RSQRT1_S */
9043 if (ctx->insn_flags & ISA_MIPS32R6) {
9044 /* OPC_MAX_S */
9045 TCGv_i32 fp0 = tcg_temp_new_i32();
9046 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9047 gen_load_fpr32(ctx, fp0, fs);
9048 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9049 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9050 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9051 tcg_temp_free_i32(fp1);
9052 tcg_temp_free_i32(fp0);
e7f16abb
LA
9053 } else {
9054 /* OPC_RSQRT1_S */
9055 check_cp1_64bitmode(ctx);
9056 {
9057 TCGv_i32 fp0 = tcg_temp_new_i32();
9058
7c979afd 9059 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9060 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9061 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9062 tcg_temp_free_i32(fp0);
9063 }
e7f16abb
LA
9064 }
9065 break;
9066 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9067 if (ctx->insn_flags & ISA_MIPS32R6) {
9068 /* OPC_MAXA_S */
9069 TCGv_i32 fp0 = tcg_temp_new_i32();
9070 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9071 gen_load_fpr32(ctx, fp0, fs);
9072 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9073 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9074 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9075 tcg_temp_free_i32(fp1);
a7812ae4 9076 tcg_temp_free_i32(fp0);
e7f16abb
LA
9077 } else {
9078 /* OPC_RSQRT2_S */
9079 check_cp1_64bitmode(ctx);
9080 {
9081 TCGv_i32 fp0 = tcg_temp_new_i32();
9082 TCGv_i32 fp1 = tcg_temp_new_i32();
9083
7c979afd
LA
9084 gen_load_fpr32(ctx, fp0, fs);
9085 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9086 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9087 tcg_temp_free_i32(fp1);
7c979afd 9088 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9089 tcg_temp_free_i32(fp0);
9090 }
b6d96bed 9091 }
57fa1fb3 9092 break;
bf4120ad 9093 case OPC_CVT_D_S:
5e755519 9094 check_cp1_registers(ctx, fd);
b6d96bed 9095 {
a7812ae4
PB
9096 TCGv_i32 fp32 = tcg_temp_new_i32();
9097 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9098
7c979afd 9099 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9100 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9101 tcg_temp_free_i32(fp32);
b6d96bed 9102 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9103 tcg_temp_free_i64(fp64);
b6d96bed 9104 }
5a5012ec 9105 break;
bf4120ad 9106 case OPC_CVT_W_S:
b6d96bed 9107 {
a7812ae4 9108 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9109
7c979afd 9110 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9111 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9112 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9113 tcg_temp_free_i32(fp0);
b6d96bed 9114 }
5a5012ec 9115 break;
bf4120ad 9116 case OPC_CVT_L_S:
5e755519 9117 check_cp1_64bitmode(ctx);
b6d96bed 9118 {
a7812ae4
PB
9119 TCGv_i32 fp32 = tcg_temp_new_i32();
9120 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9121
7c979afd 9122 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9123 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9124 tcg_temp_free_i32(fp32);
b6d96bed 9125 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9126 tcg_temp_free_i64(fp64);
b6d96bed 9127 }
5a5012ec 9128 break;
bf4120ad 9129 case OPC_CVT_PS_S:
e29c9628 9130 check_ps(ctx);
b6d96bed 9131 {
a7812ae4
PB
9132 TCGv_i64 fp64 = tcg_temp_new_i64();
9133 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9134 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9135
7c979afd
LA
9136 gen_load_fpr32(ctx, fp32_0, fs);
9137 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9138 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9139 tcg_temp_free_i32(fp32_1);
9140 tcg_temp_free_i32(fp32_0);
36aa55dc 9141 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9142 tcg_temp_free_i64(fp64);
b6d96bed 9143 }
5a5012ec 9144 break;
bf4120ad
NF
9145 case OPC_CMP_F_S:
9146 case OPC_CMP_UN_S:
9147 case OPC_CMP_EQ_S:
9148 case OPC_CMP_UEQ_S:
9149 case OPC_CMP_OLT_S:
9150 case OPC_CMP_ULT_S:
9151 case OPC_CMP_OLE_S:
9152 case OPC_CMP_ULE_S:
9153 case OPC_CMP_SF_S:
9154 case OPC_CMP_NGLE_S:
9155 case OPC_CMP_SEQ_S:
9156 case OPC_CMP_NGL_S:
9157 case OPC_CMP_LT_S:
9158 case OPC_CMP_NGE_S:
9159 case OPC_CMP_LE_S:
9160 case OPC_CMP_NGT_S:
fecd2646 9161 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9162 if (ctx->opcode & (1 << 6)) {
9163 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9164 } else {
9165 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9166 }
5a5012ec 9167 break;
bf4120ad 9168 case OPC_ADD_D:
5e755519 9169 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9170 {
a7812ae4
PB
9171 TCGv_i64 fp0 = tcg_temp_new_i64();
9172 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9173
9174 gen_load_fpr64(ctx, fp0, fs);
9175 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9176 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9177 tcg_temp_free_i64(fp1);
b6d96bed 9178 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9179 tcg_temp_free_i64(fp0);
b6d96bed 9180 }
6ea83fed 9181 break;
bf4120ad 9182 case OPC_SUB_D:
5e755519 9183 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9184 {
a7812ae4
PB
9185 TCGv_i64 fp0 = tcg_temp_new_i64();
9186 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9187
9188 gen_load_fpr64(ctx, fp0, fs);
9189 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9190 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9191 tcg_temp_free_i64(fp1);
b6d96bed 9192 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9193 tcg_temp_free_i64(fp0);
b6d96bed 9194 }
6ea83fed 9195 break;
bf4120ad 9196 case OPC_MUL_D:
5e755519 9197 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9198 {
a7812ae4
PB
9199 TCGv_i64 fp0 = tcg_temp_new_i64();
9200 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9201
9202 gen_load_fpr64(ctx, fp0, fs);
9203 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9204 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9205 tcg_temp_free_i64(fp1);
b6d96bed 9206 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9207 tcg_temp_free_i64(fp0);
b6d96bed 9208 }
6ea83fed 9209 break;
bf4120ad 9210 case OPC_DIV_D:
5e755519 9211 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9212 {
a7812ae4
PB
9213 TCGv_i64 fp0 = tcg_temp_new_i64();
9214 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9215
9216 gen_load_fpr64(ctx, fp0, fs);
9217 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9218 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9219 tcg_temp_free_i64(fp1);
b6d96bed 9220 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9221 tcg_temp_free_i64(fp0);
b6d96bed 9222 }
6ea83fed 9223 break;
bf4120ad 9224 case OPC_SQRT_D:
5e755519 9225 check_cp1_registers(ctx, fs | fd);
b6d96bed 9226 {
a7812ae4 9227 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9228
9229 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9230 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9231 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9232 tcg_temp_free_i64(fp0);
b6d96bed 9233 }
6ea83fed 9234 break;
bf4120ad 9235 case OPC_ABS_D:
5e755519 9236 check_cp1_registers(ctx, fs | fd);
b6d96bed 9237 {
a7812ae4 9238 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9239
9240 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9241 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9242 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9243 tcg_temp_free_i64(fp0);
b6d96bed 9244 }
6ea83fed 9245 break;
bf4120ad 9246 case OPC_MOV_D:
5e755519 9247 check_cp1_registers(ctx, fs | fd);
b6d96bed 9248 {
a7812ae4 9249 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9250
9251 gen_load_fpr64(ctx, fp0, fs);
9252 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9253 tcg_temp_free_i64(fp0);
b6d96bed 9254 }
6ea83fed 9255 break;
bf4120ad 9256 case OPC_NEG_D:
5e755519 9257 check_cp1_registers(ctx, fs | fd);
b6d96bed 9258 {
a7812ae4 9259 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9260
9261 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9262 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9263 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9264 tcg_temp_free_i64(fp0);
b6d96bed 9265 }
6ea83fed 9266 break;
bf4120ad 9267 case OPC_ROUND_L_D:
5e755519 9268 check_cp1_64bitmode(ctx);
b6d96bed 9269 {
a7812ae4 9270 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9271
9272 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9273 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9274 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9275 tcg_temp_free_i64(fp0);
b6d96bed 9276 }
5a5012ec 9277 break;
bf4120ad 9278 case OPC_TRUNC_L_D:
5e755519 9279 check_cp1_64bitmode(ctx);
b6d96bed 9280 {
a7812ae4 9281 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9282
9283 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9284 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9285 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9286 tcg_temp_free_i64(fp0);
b6d96bed 9287 }
5a5012ec 9288 break;
bf4120ad 9289 case OPC_CEIL_L_D:
5e755519 9290 check_cp1_64bitmode(ctx);
b6d96bed 9291 {
a7812ae4 9292 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9293
9294 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9295 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9296 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9297 tcg_temp_free_i64(fp0);
b6d96bed 9298 }
5a5012ec 9299 break;
bf4120ad 9300 case OPC_FLOOR_L_D:
5e755519 9301 check_cp1_64bitmode(ctx);
b6d96bed 9302 {
a7812ae4 9303 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9304
9305 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9306 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9307 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9308 tcg_temp_free_i64(fp0);
b6d96bed 9309 }
5a5012ec 9310 break;
bf4120ad 9311 case OPC_ROUND_W_D:
5e755519 9312 check_cp1_registers(ctx, fs);
b6d96bed 9313 {
a7812ae4
PB
9314 TCGv_i32 fp32 = tcg_temp_new_i32();
9315 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9316
9317 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9318 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9319 tcg_temp_free_i64(fp64);
7c979afd 9320 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9321 tcg_temp_free_i32(fp32);
b6d96bed 9322 }
6ea83fed 9323 break;
bf4120ad 9324 case OPC_TRUNC_W_D:
5e755519 9325 check_cp1_registers(ctx, fs);
b6d96bed 9326 {
a7812ae4
PB
9327 TCGv_i32 fp32 = tcg_temp_new_i32();
9328 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9329
9330 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9331 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9332 tcg_temp_free_i64(fp64);
7c979afd 9333 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9334 tcg_temp_free_i32(fp32);
b6d96bed 9335 }
6ea83fed 9336 break;
bf4120ad 9337 case OPC_CEIL_W_D:
5e755519 9338 check_cp1_registers(ctx, fs);
b6d96bed 9339 {
a7812ae4
PB
9340 TCGv_i32 fp32 = tcg_temp_new_i32();
9341 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9342
9343 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9344 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9345 tcg_temp_free_i64(fp64);
7c979afd 9346 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9347 tcg_temp_free_i32(fp32);
b6d96bed 9348 }
6ea83fed 9349 break;
bf4120ad 9350 case OPC_FLOOR_W_D:
5e755519 9351 check_cp1_registers(ctx, fs);
b6d96bed 9352 {
a7812ae4
PB
9353 TCGv_i32 fp32 = tcg_temp_new_i32();
9354 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9355
9356 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9357 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9358 tcg_temp_free_i64(fp64);
7c979afd 9359 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9360 tcg_temp_free_i32(fp32);
b6d96bed 9361 }
6ea83fed 9362 break;
e7f16abb
LA
9363 case OPC_SEL_D:
9364 check_insn(ctx, ISA_MIPS32R6);
9365 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9366 break;
9367 case OPC_SELEQZ_D:
9368 check_insn(ctx, ISA_MIPS32R6);
9369 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9370 break;
9371 case OPC_SELNEZ_D:
9372 check_insn(ctx, ISA_MIPS32R6);
9373 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9374 break;
bf4120ad 9375 case OPC_MOVCF_D:
fecd2646 9376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9377 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9378 break;
bf4120ad 9379 case OPC_MOVZ_D:
fecd2646 9380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9381 {
42a268c2 9382 TCGLabel *l1 = gen_new_label();
c9297f4d 9383 TCGv_i64 fp0;
a16336e4 9384
c9297f4d
AJ
9385 if (ft != 0) {
9386 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9387 }
9388 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9389 gen_load_fpr64(ctx, fp0, fs);
9390 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9391 tcg_temp_free_i64(fp0);
a16336e4
TS
9392 gen_set_label(l1);
9393 }
5a5012ec 9394 break;
bf4120ad 9395 case OPC_MOVN_D:
fecd2646 9396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9397 {
42a268c2 9398 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9399 TCGv_i64 fp0;
9400
9401 if (ft != 0) {
9402 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9403 fp0 = tcg_temp_new_i64();
9404 gen_load_fpr64(ctx, fp0, fs);
9405 gen_store_fpr64(ctx, fp0, fd);
9406 tcg_temp_free_i64(fp0);
9407 gen_set_label(l1);
9408 }
a16336e4 9409 }
6ea83fed 9410 break;
bf4120ad 9411 case OPC_RECIP_D:
ca6c7803 9412 check_cp1_registers(ctx, fs | fd);
b6d96bed 9413 {
a7812ae4 9414 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9415
9416 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9417 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9418 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9419 tcg_temp_free_i64(fp0);
b6d96bed 9420 }
57fa1fb3 9421 break;
bf4120ad 9422 case OPC_RSQRT_D:
ca6c7803 9423 check_cp1_registers(ctx, fs | fd);
b6d96bed 9424 {
a7812ae4 9425 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9426
9427 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9428 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9429 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9430 tcg_temp_free_i64(fp0);
b6d96bed 9431 }
57fa1fb3 9432 break;
e7f16abb
LA
9433 case OPC_MADDF_D:
9434 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9435 {
a7812ae4
PB
9436 TCGv_i64 fp0 = tcg_temp_new_i64();
9437 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9438 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9439 gen_load_fpr64(ctx, fp0, fs);
9440 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9441 gen_load_fpr64(ctx, fp2, fd);
9442 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9443 gen_store_fpr64(ctx, fp2, fd);
9444 tcg_temp_free_i64(fp2);
a7812ae4 9445 tcg_temp_free_i64(fp1);
a7812ae4 9446 tcg_temp_free_i64(fp0);
b6d96bed 9447 }
57fa1fb3 9448 break;
e7f16abb
LA
9449 case OPC_MSUBF_D:
9450 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9451 {
a7812ae4 9452 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9453 TCGv_i64 fp1 = tcg_temp_new_i64();
9454 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9455 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9456 gen_load_fpr64(ctx, fp1, ft);
9457 gen_load_fpr64(ctx, fp2, fd);
9458 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9459 gen_store_fpr64(ctx, fp2, fd);
9460 tcg_temp_free_i64(fp2);
9461 tcg_temp_free_i64(fp1);
a7812ae4 9462 tcg_temp_free_i64(fp0);
b6d96bed 9463 }
57fa1fb3 9464 break;
e7f16abb
LA
9465 case OPC_RINT_D:
9466 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9467 {
a7812ae4 9468 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9469 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9470 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9471 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9472 tcg_temp_free_i64(fp0);
b6d96bed 9473 }
57fa1fb3 9474 break;
e7f16abb
LA
9475 case OPC_CLASS_D:
9476 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9477 {
e7f16abb
LA
9478 TCGv_i64 fp0 = tcg_temp_new_i64();
9479 gen_load_fpr64(ctx, fp0, fs);
9480 gen_helper_float_class_d(fp0, fp0);
9481 gen_store_fpr64(ctx, fp0, fd);
9482 tcg_temp_free_i64(fp0);
e7f16abb
LA
9483 }
9484 break;
9485 case OPC_MIN_D: /* OPC_RECIP2_D */
9486 if (ctx->insn_flags & ISA_MIPS32R6) {
9487 /* OPC_MIN_D */
a7812ae4
PB
9488 TCGv_i64 fp0 = tcg_temp_new_i64();
9489 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9490 gen_load_fpr64(ctx, fp0, fs);
9491 gen_load_fpr64(ctx, fp1, ft);
9492 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9493 gen_store_fpr64(ctx, fp1, fd);
9494 tcg_temp_free_i64(fp1);
9495 tcg_temp_free_i64(fp0);
e7f16abb
LA
9496 } else {
9497 /* OPC_RECIP2_D */
9498 check_cp1_64bitmode(ctx);
9499 {
9500 TCGv_i64 fp0 = tcg_temp_new_i64();
9501 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9502
e7f16abb
LA
9503 gen_load_fpr64(ctx, fp0, fs);
9504 gen_load_fpr64(ctx, fp1, ft);
9505 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9506 tcg_temp_free_i64(fp1);
9507 gen_store_fpr64(ctx, fp0, fd);
9508 tcg_temp_free_i64(fp0);
9509 }
e7f16abb
LA
9510 }
9511 break;
9512 case OPC_MINA_D: /* OPC_RECIP1_D */
9513 if (ctx->insn_flags & ISA_MIPS32R6) {
9514 /* OPC_MINA_D */
9515 TCGv_i64 fp0 = tcg_temp_new_i64();
9516 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9517 gen_load_fpr64(ctx, fp0, fs);
9518 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9519 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9520 gen_store_fpr64(ctx, fp1, fd);
9521 tcg_temp_free_i64(fp1);
9522 tcg_temp_free_i64(fp0);
e7f16abb
LA
9523 } else {
9524 /* OPC_RECIP1_D */
9525 check_cp1_64bitmode(ctx);
9526 {
9527 TCGv_i64 fp0 = tcg_temp_new_i64();
9528
9529 gen_load_fpr64(ctx, fp0, fs);
9530 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9531 gen_store_fpr64(ctx, fp0, fd);
9532 tcg_temp_free_i64(fp0);
9533 }
e7f16abb
LA
9534 }
9535 break;
9536 case OPC_MAX_D: /* OPC_RSQRT1_D */
9537 if (ctx->insn_flags & ISA_MIPS32R6) {
9538 /* OPC_MAX_D */
9539 TCGv_i64 fp0 = tcg_temp_new_i64();
9540 TCGv_i64 fp1 = tcg_temp_new_i64();
9541 gen_load_fpr64(ctx, fp0, fs);
9542 gen_load_fpr64(ctx, fp1, ft);
9543 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9544 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9545 tcg_temp_free_i64(fp1);
a7812ae4 9546 tcg_temp_free_i64(fp0);
e7f16abb
LA
9547 } else {
9548 /* OPC_RSQRT1_D */
9549 check_cp1_64bitmode(ctx);
9550 {
9551 TCGv_i64 fp0 = tcg_temp_new_i64();
9552
9553 gen_load_fpr64(ctx, fp0, fs);
9554 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9555 gen_store_fpr64(ctx, fp0, fd);
9556 tcg_temp_free_i64(fp0);
9557 }
e7f16abb
LA
9558 }
9559 break;
9560 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9561 if (ctx->insn_flags & ISA_MIPS32R6) {
9562 /* OPC_MAXA_D */
9563 TCGv_i64 fp0 = tcg_temp_new_i64();
9564 TCGv_i64 fp1 = tcg_temp_new_i64();
9565 gen_load_fpr64(ctx, fp0, fs);
9566 gen_load_fpr64(ctx, fp1, ft);
9567 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9568 gen_store_fpr64(ctx, fp1, fd);
9569 tcg_temp_free_i64(fp1);
9570 tcg_temp_free_i64(fp0);
e7f16abb
LA
9571 } else {
9572 /* OPC_RSQRT2_D */
9573 check_cp1_64bitmode(ctx);
9574 {
9575 TCGv_i64 fp0 = tcg_temp_new_i64();
9576 TCGv_i64 fp1 = tcg_temp_new_i64();
9577
9578 gen_load_fpr64(ctx, fp0, fs);
9579 gen_load_fpr64(ctx, fp1, ft);
9580 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9581 tcg_temp_free_i64(fp1);
9582 gen_store_fpr64(ctx, fp0, fd);
9583 tcg_temp_free_i64(fp0);
9584 }
b6d96bed 9585 }
57fa1fb3 9586 break;
bf4120ad
NF
9587 case OPC_CMP_F_D:
9588 case OPC_CMP_UN_D:
9589 case OPC_CMP_EQ_D:
9590 case OPC_CMP_UEQ_D:
9591 case OPC_CMP_OLT_D:
9592 case OPC_CMP_ULT_D:
9593 case OPC_CMP_OLE_D:
9594 case OPC_CMP_ULE_D:
9595 case OPC_CMP_SF_D:
9596 case OPC_CMP_NGLE_D:
9597 case OPC_CMP_SEQ_D:
9598 case OPC_CMP_NGL_D:
9599 case OPC_CMP_LT_D:
9600 case OPC_CMP_NGE_D:
9601 case OPC_CMP_LE_D:
9602 case OPC_CMP_NGT_D:
fecd2646 9603 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9604 if (ctx->opcode & (1 << 6)) {
9605 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9606 } else {
9607 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9608 }
6ea83fed 9609 break;
bf4120ad 9610 case OPC_CVT_S_D:
5e755519 9611 check_cp1_registers(ctx, fs);
b6d96bed 9612 {
a7812ae4
PB
9613 TCGv_i32 fp32 = tcg_temp_new_i32();
9614 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9615
9616 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9617 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9618 tcg_temp_free_i64(fp64);
7c979afd 9619 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9620 tcg_temp_free_i32(fp32);
b6d96bed 9621 }
5a5012ec 9622 break;
bf4120ad 9623 case OPC_CVT_W_D:
5e755519 9624 check_cp1_registers(ctx, fs);
b6d96bed 9625 {
a7812ae4
PB
9626 TCGv_i32 fp32 = tcg_temp_new_i32();
9627 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9628
9629 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9630 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9631 tcg_temp_free_i64(fp64);
7c979afd 9632 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9633 tcg_temp_free_i32(fp32);
b6d96bed 9634 }
5a5012ec 9635 break;
bf4120ad 9636 case OPC_CVT_L_D:
5e755519 9637 check_cp1_64bitmode(ctx);
b6d96bed 9638 {
a7812ae4 9639 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9640
9641 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9642 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9643 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9644 tcg_temp_free_i64(fp0);
b6d96bed 9645 }
5a5012ec 9646 break;
bf4120ad 9647 case OPC_CVT_S_W:
b6d96bed 9648 {
a7812ae4 9649 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9650
7c979afd 9651 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9652 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9653 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9654 tcg_temp_free_i32(fp0);
b6d96bed 9655 }
6ea83fed 9656 break;
bf4120ad 9657 case OPC_CVT_D_W:
5e755519 9658 check_cp1_registers(ctx, fd);
b6d96bed 9659 {
a7812ae4
PB
9660 TCGv_i32 fp32 = tcg_temp_new_i32();
9661 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9662
7c979afd 9663 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9664 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9665 tcg_temp_free_i32(fp32);
b6d96bed 9666 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9667 tcg_temp_free_i64(fp64);
b6d96bed 9668 }
5a5012ec 9669 break;
bf4120ad 9670 case OPC_CVT_S_L:
5e755519 9671 check_cp1_64bitmode(ctx);
b6d96bed 9672 {
a7812ae4
PB
9673 TCGv_i32 fp32 = tcg_temp_new_i32();
9674 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9675
9676 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9677 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9678 tcg_temp_free_i64(fp64);
7c979afd 9679 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9680 tcg_temp_free_i32(fp32);
b6d96bed 9681 }
5a5012ec 9682 break;
bf4120ad 9683 case OPC_CVT_D_L:
5e755519 9684 check_cp1_64bitmode(ctx);
b6d96bed 9685 {
a7812ae4 9686 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9687
9688 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9689 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9690 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9691 tcg_temp_free_i64(fp0);
b6d96bed 9692 }
5a5012ec 9693 break;
bf4120ad 9694 case OPC_CVT_PS_PW:
e29c9628 9695 check_ps(ctx);
b6d96bed 9696 {
a7812ae4 9697 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9698
9699 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9700 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9701 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9702 tcg_temp_free_i64(fp0);
b6d96bed 9703 }
5a5012ec 9704 break;
bf4120ad 9705 case OPC_ADD_PS:
e29c9628 9706 check_ps(ctx);
b6d96bed 9707 {
a7812ae4
PB
9708 TCGv_i64 fp0 = tcg_temp_new_i64();
9709 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9710
9711 gen_load_fpr64(ctx, fp0, fs);
9712 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9713 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9714 tcg_temp_free_i64(fp1);
b6d96bed 9715 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9716 tcg_temp_free_i64(fp0);
b6d96bed 9717 }
6ea83fed 9718 break;
bf4120ad 9719 case OPC_SUB_PS:
e29c9628 9720 check_ps(ctx);
b6d96bed 9721 {
a7812ae4
PB
9722 TCGv_i64 fp0 = tcg_temp_new_i64();
9723 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9724
9725 gen_load_fpr64(ctx, fp0, fs);
9726 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9727 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9728 tcg_temp_free_i64(fp1);
b6d96bed 9729 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9730 tcg_temp_free_i64(fp0);
b6d96bed 9731 }
6ea83fed 9732 break;
bf4120ad 9733 case OPC_MUL_PS:
e29c9628 9734 check_ps(ctx);
b6d96bed 9735 {
a7812ae4
PB
9736 TCGv_i64 fp0 = tcg_temp_new_i64();
9737 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9738
9739 gen_load_fpr64(ctx, fp0, fs);
9740 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9741 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9742 tcg_temp_free_i64(fp1);
b6d96bed 9743 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9744 tcg_temp_free_i64(fp0);
b6d96bed 9745 }
6ea83fed 9746 break;
bf4120ad 9747 case OPC_ABS_PS:
e29c9628 9748 check_ps(ctx);
b6d96bed 9749 {
a7812ae4 9750 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9751
9752 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9753 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9754 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9755 tcg_temp_free_i64(fp0);
b6d96bed 9756 }
6ea83fed 9757 break;
bf4120ad 9758 case OPC_MOV_PS:
e29c9628 9759 check_ps(ctx);
b6d96bed 9760 {
a7812ae4 9761 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9762
9763 gen_load_fpr64(ctx, fp0, fs);
9764 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9765 tcg_temp_free_i64(fp0);
b6d96bed 9766 }
6ea83fed 9767 break;
bf4120ad 9768 case OPC_NEG_PS:
e29c9628 9769 check_ps(ctx);
b6d96bed 9770 {
a7812ae4 9771 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9772
9773 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9774 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9775 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9776 tcg_temp_free_i64(fp0);
b6d96bed 9777 }
6ea83fed 9778 break;
bf4120ad 9779 case OPC_MOVCF_PS:
e29c9628 9780 check_ps(ctx);
7f6613ce 9781 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 9782 break;
bf4120ad 9783 case OPC_MOVZ_PS:
e29c9628 9784 check_ps(ctx);
a16336e4 9785 {
42a268c2 9786 TCGLabel *l1 = gen_new_label();
30a3848b 9787 TCGv_i64 fp0;
a16336e4 9788
c9297f4d
AJ
9789 if (ft != 0)
9790 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9791 fp0 = tcg_temp_new_i64();
9792 gen_load_fpr64(ctx, fp0, fs);
9793 gen_store_fpr64(ctx, fp0, fd);
9794 tcg_temp_free_i64(fp0);
a16336e4
TS
9795 gen_set_label(l1);
9796 }
6ea83fed 9797 break;
bf4120ad 9798 case OPC_MOVN_PS:
e29c9628 9799 check_ps(ctx);
a16336e4 9800 {
42a268c2 9801 TCGLabel *l1 = gen_new_label();
30a3848b 9802 TCGv_i64 fp0;
c9297f4d
AJ
9803
9804 if (ft != 0) {
9805 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9806 fp0 = tcg_temp_new_i64();
9807 gen_load_fpr64(ctx, fp0, fs);
9808 gen_store_fpr64(ctx, fp0, fd);
9809 tcg_temp_free_i64(fp0);
9810 gen_set_label(l1);
9811 }
a16336e4 9812 }
6ea83fed 9813 break;
bf4120ad 9814 case OPC_ADDR_PS:
e29c9628 9815 check_ps(ctx);
b6d96bed 9816 {
a7812ae4
PB
9817 TCGv_i64 fp0 = tcg_temp_new_i64();
9818 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9819
9820 gen_load_fpr64(ctx, fp0, ft);
9821 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9822 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9823 tcg_temp_free_i64(fp1);
b6d96bed 9824 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9825 tcg_temp_free_i64(fp0);
b6d96bed 9826 }
fbcc6828 9827 break;
bf4120ad 9828 case OPC_MULR_PS:
e29c9628 9829 check_ps(ctx);
b6d96bed 9830 {
a7812ae4
PB
9831 TCGv_i64 fp0 = tcg_temp_new_i64();
9832 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9833
9834 gen_load_fpr64(ctx, fp0, ft);
9835 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9836 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9837 tcg_temp_free_i64(fp1);
b6d96bed 9838 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9839 tcg_temp_free_i64(fp0);
b6d96bed 9840 }
57fa1fb3 9841 break;
bf4120ad 9842 case OPC_RECIP2_PS:
e29c9628 9843 check_ps(ctx);
b6d96bed 9844 {
a7812ae4
PB
9845 TCGv_i64 fp0 = tcg_temp_new_i64();
9846 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9847
9848 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9849 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9850 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9851 tcg_temp_free_i64(fp1);
b6d96bed 9852 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9853 tcg_temp_free_i64(fp0);
b6d96bed 9854 }
57fa1fb3 9855 break;
bf4120ad 9856 case OPC_RECIP1_PS:
e29c9628 9857 check_ps(ctx);
b6d96bed 9858 {
a7812ae4 9859 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9860
9861 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9862 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9863 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9864 tcg_temp_free_i64(fp0);
b6d96bed 9865 }
57fa1fb3 9866 break;
bf4120ad 9867 case OPC_RSQRT1_PS:
e29c9628 9868 check_ps(ctx);
b6d96bed 9869 {
a7812ae4 9870 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9871
9872 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9873 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9874 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9875 tcg_temp_free_i64(fp0);
b6d96bed 9876 }
57fa1fb3 9877 break;
bf4120ad 9878 case OPC_RSQRT2_PS:
e29c9628 9879 check_ps(ctx);
b6d96bed 9880 {
a7812ae4
PB
9881 TCGv_i64 fp0 = tcg_temp_new_i64();
9882 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9883
9884 gen_load_fpr64(ctx, fp0, fs);
9885 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9886 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9887 tcg_temp_free_i64(fp1);
b6d96bed 9888 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9889 tcg_temp_free_i64(fp0);
b6d96bed 9890 }
57fa1fb3 9891 break;
bf4120ad 9892 case OPC_CVT_S_PU:
5e755519 9893 check_cp1_64bitmode(ctx);
b6d96bed 9894 {
a7812ae4 9895 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9896
7f6613ce 9897 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9898 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 9899 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9900 tcg_temp_free_i32(fp0);
b6d96bed 9901 }
dd016883 9902 break;
bf4120ad 9903 case OPC_CVT_PW_PS:
e29c9628 9904 check_ps(ctx);
b6d96bed 9905 {
a7812ae4 9906 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9907
9908 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9909 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9910 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9911 tcg_temp_free_i64(fp0);
b6d96bed 9912 }
6ea83fed 9913 break;
bf4120ad 9914 case OPC_CVT_S_PL:
5e755519 9915 check_cp1_64bitmode(ctx);
b6d96bed 9916 {
a7812ae4 9917 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9918
7c979afd 9919 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9920 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 9921 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9922 tcg_temp_free_i32(fp0);
b6d96bed 9923 }
6ea83fed 9924 break;
bf4120ad 9925 case OPC_PLL_PS:
e29c9628 9926 check_ps(ctx);
b6d96bed 9927 {
a7812ae4
PB
9928 TCGv_i32 fp0 = tcg_temp_new_i32();
9929 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9930
7c979afd
LA
9931 gen_load_fpr32(ctx, fp0, fs);
9932 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 9933 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 9934 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
9935 tcg_temp_free_i32(fp0);
9936 tcg_temp_free_i32(fp1);
b6d96bed 9937 }
6ea83fed 9938 break;
bf4120ad 9939 case OPC_PLU_PS:
e29c9628 9940 check_ps(ctx);
b6d96bed 9941 {
a7812ae4
PB
9942 TCGv_i32 fp0 = tcg_temp_new_i32();
9943 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9944
7c979afd 9945 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 9946 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 9947 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9948 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9949 tcg_temp_free_i32(fp0);
9950 tcg_temp_free_i32(fp1);
b6d96bed 9951 }
5a5012ec 9952 break;
bf4120ad 9953 case OPC_PUL_PS:
e29c9628 9954 check_ps(ctx);
b6d96bed 9955 {
a7812ae4
PB
9956 TCGv_i32 fp0 = tcg_temp_new_i32();
9957 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9958
7f6613ce 9959 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
9960 gen_load_fpr32(ctx, fp1, ft);
9961 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9962 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9963 tcg_temp_free_i32(fp0);
9964 tcg_temp_free_i32(fp1);
b6d96bed 9965 }
5a5012ec 9966 break;
bf4120ad 9967 case OPC_PUU_PS:
e29c9628 9968 check_ps(ctx);
b6d96bed 9969 {
a7812ae4
PB
9970 TCGv_i32 fp0 = tcg_temp_new_i32();
9971 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9972
7f6613ce
PJ
9973 gen_load_fpr32h(ctx, fp0, fs);
9974 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 9975 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9976 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9977 tcg_temp_free_i32(fp0);
9978 tcg_temp_free_i32(fp1);
b6d96bed 9979 }
5a5012ec 9980 break;
bf4120ad
NF
9981 case OPC_CMP_F_PS:
9982 case OPC_CMP_UN_PS:
9983 case OPC_CMP_EQ_PS:
9984 case OPC_CMP_UEQ_PS:
9985 case OPC_CMP_OLT_PS:
9986 case OPC_CMP_ULT_PS:
9987 case OPC_CMP_OLE_PS:
9988 case OPC_CMP_ULE_PS:
9989 case OPC_CMP_SF_PS:
9990 case OPC_CMP_NGLE_PS:
9991 case OPC_CMP_SEQ_PS:
9992 case OPC_CMP_NGL_PS:
9993 case OPC_CMP_LT_PS:
9994 case OPC_CMP_NGE_PS:
9995 case OPC_CMP_LE_PS:
9996 case OPC_CMP_NGT_PS:
8153667c
NF
9997 if (ctx->opcode & (1 << 6)) {
9998 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
9999 } else {
10000 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10001 }
6ea83fed 10002 break;
5a5012ec 10003 default:
9d68ac14 10004 MIPS_INVAL("farith");
e397ee33 10005 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10006 return;
10007 }
6ea83fed 10008}
6af0bf9c 10009
5a5012ec 10010/* Coprocessor 3 (FPU) */
5e755519
TS
10011static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10012 int fd, int fs, int base, int index)
7a387fff 10013{
4e2474d6 10014 TCGv t0 = tcg_temp_new();
7a387fff 10015
93b12ccc 10016 if (base == 0) {
6c5c1e20 10017 gen_load_gpr(t0, index);
93b12ccc 10018 } else if (index == 0) {
6c5c1e20 10019 gen_load_gpr(t0, base);
93b12ccc 10020 } else {
05168674 10021 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10022 }
5a5012ec 10023 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10024 memory access. */
5a5012ec
TS
10025 switch (opc) {
10026 case OPC_LWXC1:
8c0ab41f 10027 check_cop1x(ctx);
b6d96bed 10028 {
a7812ae4 10029 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10030
5f68f5ae 10031 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10032 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10033 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10034 tcg_temp_free_i32(fp0);
b6d96bed 10035 }
5a5012ec
TS
10036 break;
10037 case OPC_LDXC1:
8c0ab41f
AJ
10038 check_cop1x(ctx);
10039 check_cp1_registers(ctx, fd);
b6d96bed 10040 {
a7812ae4 10041 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10042 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10043 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10044 tcg_temp_free_i64(fp0);
b6d96bed 10045 }
5a5012ec
TS
10046 break;
10047 case OPC_LUXC1:
8c0ab41f 10048 check_cp1_64bitmode(ctx);
6c5c1e20 10049 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10050 {
a7812ae4 10051 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10052
5f68f5ae 10053 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10054 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10055 tcg_temp_free_i64(fp0);
b6d96bed 10056 }
5a5012ec
TS
10057 break;
10058 case OPC_SWXC1:
8c0ab41f 10059 check_cop1x(ctx);
b6d96bed 10060 {
a7812ae4 10061 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10062 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10063 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10064 tcg_temp_free_i32(fp0);
b6d96bed 10065 }
5a5012ec
TS
10066 break;
10067 case OPC_SDXC1:
8c0ab41f
AJ
10068 check_cop1x(ctx);
10069 check_cp1_registers(ctx, fs);
b6d96bed 10070 {
a7812ae4 10071 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10072 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10073 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10074 tcg_temp_free_i64(fp0);
b6d96bed 10075 }
5a5012ec
TS
10076 break;
10077 case OPC_SUXC1:
8c0ab41f 10078 check_cp1_64bitmode(ctx);
6c5c1e20 10079 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10080 {
a7812ae4 10081 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10082 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10083 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10084 tcg_temp_free_i64(fp0);
b6d96bed 10085 }
5a5012ec 10086 break;
5a5012ec 10087 }
6c5c1e20 10088 tcg_temp_free(t0);
5a5012ec
TS
10089}
10090
5e755519
TS
10091static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10092 int fd, int fr, int fs, int ft)
5a5012ec 10093{
5a5012ec
TS
10094 switch (opc) {
10095 case OPC_ALNV_PS:
e29c9628 10096 check_ps(ctx);
a16336e4 10097 {
a7812ae4 10098 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10099 TCGv_i32 fp = tcg_temp_new_i32();
10100 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10101 TCGLabel *l1 = gen_new_label();
10102 TCGLabel *l2 = gen_new_label();
a16336e4 10103
6c5c1e20
TS
10104 gen_load_gpr(t0, fr);
10105 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10106
10107 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10108 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10109 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10110 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10111 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10112 tcg_gen_br(l2);
10113 gen_set_label(l1);
6c5c1e20
TS
10114 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10115 tcg_temp_free(t0);
a16336e4 10116#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10117 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10118 gen_load_fpr32h(ctx, fph, ft);
10119 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10120 gen_store_fpr32(ctx, fph, fd);
a16336e4 10121#else
7f6613ce 10122 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10123 gen_load_fpr32(ctx, fp, ft);
10124 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10125 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10126#endif
10127 gen_set_label(l2);
c905fdac
AJ
10128 tcg_temp_free_i32(fp);
10129 tcg_temp_free_i32(fph);
a16336e4 10130 }
5a5012ec
TS
10131 break;
10132 case OPC_MADD_S:
b8aa4598 10133 check_cop1x(ctx);
b6d96bed 10134 {
a7812ae4
PB
10135 TCGv_i32 fp0 = tcg_temp_new_i32();
10136 TCGv_i32 fp1 = tcg_temp_new_i32();
10137 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10138
7c979afd
LA
10139 gen_load_fpr32(ctx, fp0, fs);
10140 gen_load_fpr32(ctx, fp1, ft);
10141 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10142 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10143 tcg_temp_free_i32(fp0);
10144 tcg_temp_free_i32(fp1);
7c979afd 10145 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10146 tcg_temp_free_i32(fp2);
b6d96bed 10147 }
5a5012ec
TS
10148 break;
10149 case OPC_MADD_D:
b8aa4598
TS
10150 check_cop1x(ctx);
10151 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10152 {
a7812ae4
PB
10153 TCGv_i64 fp0 = tcg_temp_new_i64();
10154 TCGv_i64 fp1 = tcg_temp_new_i64();
10155 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10156
10157 gen_load_fpr64(ctx, fp0, fs);
10158 gen_load_fpr64(ctx, fp1, ft);
10159 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10160 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10161 tcg_temp_free_i64(fp0);
10162 tcg_temp_free_i64(fp1);
b6d96bed 10163 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10164 tcg_temp_free_i64(fp2);
b6d96bed 10165 }
5a5012ec
TS
10166 break;
10167 case OPC_MADD_PS:
e29c9628 10168 check_ps(ctx);
b6d96bed 10169 {
a7812ae4
PB
10170 TCGv_i64 fp0 = tcg_temp_new_i64();
10171 TCGv_i64 fp1 = tcg_temp_new_i64();
10172 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10173
10174 gen_load_fpr64(ctx, fp0, fs);
10175 gen_load_fpr64(ctx, fp1, ft);
10176 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10177 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10178 tcg_temp_free_i64(fp0);
10179 tcg_temp_free_i64(fp1);
b6d96bed 10180 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10181 tcg_temp_free_i64(fp2);
b6d96bed 10182 }
5a5012ec
TS
10183 break;
10184 case OPC_MSUB_S:
b8aa4598 10185 check_cop1x(ctx);
b6d96bed 10186 {
a7812ae4
PB
10187 TCGv_i32 fp0 = tcg_temp_new_i32();
10188 TCGv_i32 fp1 = tcg_temp_new_i32();
10189 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10190
7c979afd
LA
10191 gen_load_fpr32(ctx, fp0, fs);
10192 gen_load_fpr32(ctx, fp1, ft);
10193 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10194 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10195 tcg_temp_free_i32(fp0);
10196 tcg_temp_free_i32(fp1);
7c979afd 10197 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10198 tcg_temp_free_i32(fp2);
b6d96bed 10199 }
5a5012ec
TS
10200 break;
10201 case OPC_MSUB_D:
b8aa4598
TS
10202 check_cop1x(ctx);
10203 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10204 {
a7812ae4
PB
10205 TCGv_i64 fp0 = tcg_temp_new_i64();
10206 TCGv_i64 fp1 = tcg_temp_new_i64();
10207 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10208
10209 gen_load_fpr64(ctx, fp0, fs);
10210 gen_load_fpr64(ctx, fp1, ft);
10211 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10212 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10213 tcg_temp_free_i64(fp0);
10214 tcg_temp_free_i64(fp1);
b6d96bed 10215 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10216 tcg_temp_free_i64(fp2);
b6d96bed 10217 }
5a5012ec
TS
10218 break;
10219 case OPC_MSUB_PS:
e29c9628 10220 check_ps(ctx);
b6d96bed 10221 {
a7812ae4
PB
10222 TCGv_i64 fp0 = tcg_temp_new_i64();
10223 TCGv_i64 fp1 = tcg_temp_new_i64();
10224 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10225
10226 gen_load_fpr64(ctx, fp0, fs);
10227 gen_load_fpr64(ctx, fp1, ft);
10228 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10229 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10230 tcg_temp_free_i64(fp0);
10231 tcg_temp_free_i64(fp1);
b6d96bed 10232 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10233 tcg_temp_free_i64(fp2);
b6d96bed 10234 }
5a5012ec
TS
10235 break;
10236 case OPC_NMADD_S:
b8aa4598 10237 check_cop1x(ctx);
b6d96bed 10238 {
a7812ae4
PB
10239 TCGv_i32 fp0 = tcg_temp_new_i32();
10240 TCGv_i32 fp1 = tcg_temp_new_i32();
10241 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10242
7c979afd
LA
10243 gen_load_fpr32(ctx, fp0, fs);
10244 gen_load_fpr32(ctx, fp1, ft);
10245 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10246 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10247 tcg_temp_free_i32(fp0);
10248 tcg_temp_free_i32(fp1);
7c979afd 10249 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10250 tcg_temp_free_i32(fp2);
b6d96bed 10251 }
5a5012ec
TS
10252 break;
10253 case OPC_NMADD_D:
b8aa4598
TS
10254 check_cop1x(ctx);
10255 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10256 {
a7812ae4
PB
10257 TCGv_i64 fp0 = tcg_temp_new_i64();
10258 TCGv_i64 fp1 = tcg_temp_new_i64();
10259 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10260
10261 gen_load_fpr64(ctx, fp0, fs);
10262 gen_load_fpr64(ctx, fp1, ft);
10263 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10264 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10265 tcg_temp_free_i64(fp0);
10266 tcg_temp_free_i64(fp1);
b6d96bed 10267 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10268 tcg_temp_free_i64(fp2);
b6d96bed 10269 }
5a5012ec
TS
10270 break;
10271 case OPC_NMADD_PS:
e29c9628 10272 check_ps(ctx);
b6d96bed 10273 {
a7812ae4
PB
10274 TCGv_i64 fp0 = tcg_temp_new_i64();
10275 TCGv_i64 fp1 = tcg_temp_new_i64();
10276 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10277
10278 gen_load_fpr64(ctx, fp0, fs);
10279 gen_load_fpr64(ctx, fp1, ft);
10280 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10281 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10282 tcg_temp_free_i64(fp0);
10283 tcg_temp_free_i64(fp1);
b6d96bed 10284 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10285 tcg_temp_free_i64(fp2);
b6d96bed 10286 }
5a5012ec
TS
10287 break;
10288 case OPC_NMSUB_S:
b8aa4598 10289 check_cop1x(ctx);
b6d96bed 10290 {
a7812ae4
PB
10291 TCGv_i32 fp0 = tcg_temp_new_i32();
10292 TCGv_i32 fp1 = tcg_temp_new_i32();
10293 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10294
7c979afd
LA
10295 gen_load_fpr32(ctx, fp0, fs);
10296 gen_load_fpr32(ctx, fp1, ft);
10297 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10298 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10299 tcg_temp_free_i32(fp0);
10300 tcg_temp_free_i32(fp1);
7c979afd 10301 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10302 tcg_temp_free_i32(fp2);
b6d96bed 10303 }
5a5012ec
TS
10304 break;
10305 case OPC_NMSUB_D:
b8aa4598
TS
10306 check_cop1x(ctx);
10307 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10308 {
a7812ae4
PB
10309 TCGv_i64 fp0 = tcg_temp_new_i64();
10310 TCGv_i64 fp1 = tcg_temp_new_i64();
10311 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10312
10313 gen_load_fpr64(ctx, fp0, fs);
10314 gen_load_fpr64(ctx, fp1, ft);
10315 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10316 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10317 tcg_temp_free_i64(fp0);
10318 tcg_temp_free_i64(fp1);
b6d96bed 10319 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10320 tcg_temp_free_i64(fp2);
b6d96bed 10321 }
5a5012ec
TS
10322 break;
10323 case OPC_NMSUB_PS:
e29c9628 10324 check_ps(ctx);
b6d96bed 10325 {
a7812ae4
PB
10326 TCGv_i64 fp0 = tcg_temp_new_i64();
10327 TCGv_i64 fp1 = tcg_temp_new_i64();
10328 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10329
10330 gen_load_fpr64(ctx, fp0, fs);
10331 gen_load_fpr64(ctx, fp1, ft);
10332 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10333 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10334 tcg_temp_free_i64(fp0);
10335 tcg_temp_free_i64(fp1);
b6d96bed 10336 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10337 tcg_temp_free_i64(fp2);
b6d96bed 10338 }
5a5012ec 10339 break;
923617a3 10340 default:
9d68ac14 10341 MIPS_INVAL("flt3_arith");
5a5012ec
TS
10342 generate_exception (ctx, EXCP_RI);
10343 return;
10344 }
7a387fff
TS
10345}
10346
d75c135e 10347static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10348{
10349 TCGv t0;
10350
b3167288
RH
10351#if !defined(CONFIG_USER_ONLY)
10352 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10353 Therefore only check the ISA in system mode. */
d75c135e 10354 check_insn(ctx, ISA_MIPS32R2);
b3167288 10355#endif
26ebe468
NF
10356 t0 = tcg_temp_new();
10357
10358 switch (rd) {
10359 case 0:
10360 save_cpu_state(ctx, 1);
895c2d04 10361 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10362 gen_store_gpr(t0, rt);
10363 break;
10364 case 1:
10365 save_cpu_state(ctx, 1);
895c2d04 10366 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10367 gen_store_gpr(t0, rt);
10368 break;
10369 case 2:
10370 save_cpu_state(ctx, 1);
895c2d04 10371 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10372 gen_store_gpr(t0, rt);
10373 break;
10374 case 3:
10375 save_cpu_state(ctx, 1);
895c2d04 10376 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10377 gen_store_gpr(t0, rt);
10378 break;
10379 case 29:
10380#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10381 tcg_gen_ld_tl(t0, cpu_env,
10382 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10383 gen_store_gpr(t0, rt);
10384 break;
10385#else
d279279e
PJ
10386 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10387 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10388 tcg_gen_ld_tl(t0, cpu_env,
10389 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10390 gen_store_gpr(t0, rt);
10391 } else {
10392 generate_exception(ctx, EXCP_RI);
10393 }
10394 break;
26ebe468
NF
10395#endif
10396 default: /* Invalid */
10397 MIPS_INVAL("rdhwr");
10398 generate_exception(ctx, EXCP_RI);
10399 break;
10400 }
10401 tcg_temp_free(t0);
10402}
10403
a5f53390
LA
10404static inline void clear_branch_hflags(DisasContext *ctx)
10405{
10406 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10407 if (ctx->bstate == BS_NONE) {
10408 save_cpu_state(ctx, 0);
10409 } else {
10410 /* it is not safe to save ctx->hflags as hflags may be changed
10411 in execution time by the instruction in delay / forbidden slot. */
10412 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10413 }
10414}
10415
31837be3 10416static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10417{
10418 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10419 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10420 /* Branches completion */
a5f53390 10421 clear_branch_hflags(ctx);
c9602061 10422 ctx->bstate = BS_BRANCH;
c9602061 10423 /* FIXME: Need to clear can_do_io. */
364d4831 10424 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10425 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10426 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10427 break;
c9602061
NF
10428 case MIPS_HFLAG_B:
10429 /* unconditional branch */
364d4831
NF
10430 if (proc_hflags & MIPS_HFLAG_BX) {
10431 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10432 }
c9602061
NF
10433 gen_goto_tb(ctx, 0, ctx->btarget);
10434 break;
10435 case MIPS_HFLAG_BL:
10436 /* blikely taken case */
c9602061
NF
10437 gen_goto_tb(ctx, 0, ctx->btarget);
10438 break;
10439 case MIPS_HFLAG_BC:
10440 /* Conditional branch */
c9602061 10441 {
42a268c2 10442 TCGLabel *l1 = gen_new_label();
c9602061
NF
10443
10444 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10445 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10446 gen_set_label(l1);
10447 gen_goto_tb(ctx, 0, ctx->btarget);
10448 }
10449 break;
10450 case MIPS_HFLAG_BR:
10451 /* unconditional branch to register */
d75c135e 10452 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10453 TCGv t0 = tcg_temp_new();
10454 TCGv_i32 t1 = tcg_temp_new_i32();
10455
10456 tcg_gen_andi_tl(t0, btarget, 0x1);
10457 tcg_gen_trunc_tl_i32(t1, t0);
10458 tcg_temp_free(t0);
10459 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10460 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10461 tcg_gen_or_i32(hflags, hflags, t1);
10462 tcg_temp_free_i32(t1);
10463
10464 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10465 } else {
10466 tcg_gen_mov_tl(cpu_PC, btarget);
10467 }
c9602061
NF
10468 if (ctx->singlestep_enabled) {
10469 save_cpu_state(ctx, 0);
895c2d04 10470 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10471 }
10472 tcg_gen_exit_tb(0);
10473 break;
10474 default:
a5f53390
LA
10475 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10476 abort();
c9602061
NF
10477 }
10478 }
10479}
10480
6893f074
YK
10481/* Compact Branches */
10482static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10483 int rs, int rt, int32_t offset)
10484{
10485 int bcond_compute = 0;
10486 TCGv t0 = tcg_temp_new();
10487 TCGv t1 = tcg_temp_new();
65935f07 10488 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10489
10490 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10491#ifdef MIPS_DEBUG_DISAS
10492 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10493 "\n", ctx->pc);
10494#endif
10495 generate_exception(ctx, EXCP_RI);
10496 goto out;
10497 }
10498
10499 /* Load needed operands and calculate btarget */
10500 switch (opc) {
10501 /* compact branch */
10502 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10503 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10504 gen_load_gpr(t0, rs);
10505 gen_load_gpr(t1, rt);
10506 bcond_compute = 1;
10507 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10508 if (rs <= rt && rs == 0) {
10509 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10510 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10511 }
10512 break;
10513 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10514 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
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_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10521 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10522 if (rs == 0 || rs == rt) {
10523 /* OPC_BLEZALC, OPC_BGEZALC */
10524 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10525 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10526 }
10527 gen_load_gpr(t0, rs);
10528 gen_load_gpr(t1, rt);
10529 bcond_compute = 1;
10530 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10531 break;
10532 case OPC_BC:
10533 case OPC_BALC:
10534 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10535 break;
10536 case OPC_BEQZC:
10537 case OPC_BNEZC:
10538 if (rs != 0) {
10539 /* OPC_BEQZC, OPC_BNEZC */
10540 gen_load_gpr(t0, rs);
10541 bcond_compute = 1;
10542 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10543 } else {
10544 /* OPC_JIC, OPC_JIALC */
10545 TCGv tbase = tcg_temp_new();
10546 TCGv toffset = tcg_temp_new();
10547
10548 gen_load_gpr(tbase, rt);
10549 tcg_gen_movi_tl(toffset, offset);
10550 gen_op_addr_add(ctx, btarget, tbase, toffset);
10551 tcg_temp_free(tbase);
10552 tcg_temp_free(toffset);
10553 }
10554 break;
10555 default:
10556 MIPS_INVAL("Compact branch/jump");
10557 generate_exception(ctx, EXCP_RI);
10558 goto out;
10559 }
10560
10561 if (bcond_compute == 0) {
10562 /* Uncoditional compact branch */
10563 switch (opc) {
10564 case OPC_JIALC:
65935f07 10565 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10566 /* Fallthrough */
10567 case OPC_JIC:
10568 ctx->hflags |= MIPS_HFLAG_BR;
10569 break;
10570 case OPC_BALC:
65935f07 10571 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10572 /* Fallthrough */
10573 case OPC_BC:
10574 ctx->hflags |= MIPS_HFLAG_B;
10575 break;
10576 default:
10577 MIPS_INVAL("Compact branch/jump");
10578 generate_exception(ctx, EXCP_RI);
10579 goto out;
10580 }
10581
10582 /* Generating branch here as compact branches don't have delay slot */
10583 gen_branch(ctx, 4);
10584 } else {
10585 /* Conditional compact branch */
10586 TCGLabel *fs = gen_new_label();
10587 save_cpu_state(ctx, 0);
10588
10589 switch (opc) {
10590 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10591 if (rs == 0 && rt != 0) {
10592 /* OPC_BLEZALC */
10593 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10594 } else if (rs != 0 && rt != 0 && rs == rt) {
10595 /* OPC_BGEZALC */
10596 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10597 } else {
10598 /* OPC_BGEUC */
10599 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10600 }
10601 break;
10602 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10603 if (rs == 0 && rt != 0) {
10604 /* OPC_BGTZALC */
10605 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10606 } else if (rs != 0 && rt != 0 && rs == rt) {
10607 /* OPC_BLTZALC */
10608 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10609 } else {
10610 /* OPC_BLTUC */
10611 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10612 }
10613 break;
10614 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10615 if (rs == 0 && rt != 0) {
10616 /* OPC_BLEZC */
10617 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10618 } else if (rs != 0 && rt != 0 && rs == rt) {
10619 /* OPC_BGEZC */
10620 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10621 } else {
10622 /* OPC_BGEC */
10623 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10624 }
10625 break;
10626 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10627 if (rs == 0 && rt != 0) {
10628 /* OPC_BGTZC */
10629 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10630 } else if (rs != 0 && rt != 0 && rs == rt) {
10631 /* OPC_BLTZC */
10632 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10633 } else {
10634 /* OPC_BLTC */
10635 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10636 }
10637 break;
10638 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10639 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10640 if (rs >= rt) {
10641 /* OPC_BOVC, OPC_BNVC */
10642 TCGv t2 = tcg_temp_new();
10643 TCGv t3 = tcg_temp_new();
10644 TCGv t4 = tcg_temp_new();
10645 TCGv input_overflow = tcg_temp_new();
10646
10647 gen_load_gpr(t0, rs);
10648 gen_load_gpr(t1, rt);
10649 tcg_gen_ext32s_tl(t2, t0);
10650 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10651 tcg_gen_ext32s_tl(t3, t1);
10652 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10653 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10654
10655 tcg_gen_add_tl(t4, t2, t3);
10656 tcg_gen_ext32s_tl(t4, t4);
10657 tcg_gen_xor_tl(t2, t2, t3);
10658 tcg_gen_xor_tl(t3, t4, t3);
10659 tcg_gen_andc_tl(t2, t3, t2);
10660 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10661 tcg_gen_or_tl(t4, t4, input_overflow);
10662 if (opc == OPC_BOVC) {
10663 /* OPC_BOVC */
10664 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10665 } else {
10666 /* OPC_BNVC */
10667 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10668 }
10669 tcg_temp_free(input_overflow);
10670 tcg_temp_free(t4);
10671 tcg_temp_free(t3);
10672 tcg_temp_free(t2);
10673 } else if (rs < rt && rs == 0) {
10674 /* OPC_BEQZALC, OPC_BNEZALC */
10675 if (opc == OPC_BEQZALC) {
10676 /* OPC_BEQZALC */
10677 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10678 } else {
10679 /* OPC_BNEZALC */
10680 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10681 }
10682 } else {
10683 /* OPC_BEQC, OPC_BNEC */
10684 if (opc == OPC_BEQC) {
10685 /* OPC_BEQC */
10686 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10687 } else {
10688 /* OPC_BNEC */
10689 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10690 }
10691 }
10692 break;
10693 case OPC_BEQZC:
10694 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10695 break;
10696 case OPC_BNEZC:
10697 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10698 break;
10699 default:
10700 MIPS_INVAL("Compact conditional branch/jump");
10701 generate_exception(ctx, EXCP_RI);
10702 goto out;
10703 }
10704
10705 /* Generating branch here as compact branches don't have delay slot */
10706 gen_goto_tb(ctx, 1, ctx->btarget);
10707 gen_set_label(fs);
10708
10709 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
10710 }
10711
10712out:
10713 tcg_temp_free(t0);
10714 tcg_temp_free(t1);
10715}
10716
7a387fff 10717/* ISA extensions (ASEs) */
6af0bf9c 10718/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10719
10720/* MIPS16 major opcodes */
10721enum {
10722 M16_OPC_ADDIUSP = 0x00,
10723 M16_OPC_ADDIUPC = 0x01,
10724 M16_OPC_B = 0x02,
10725 M16_OPC_JAL = 0x03,
10726 M16_OPC_BEQZ = 0x04,
10727 M16_OPC_BNEQZ = 0x05,
10728 M16_OPC_SHIFT = 0x06,
10729 M16_OPC_LD = 0x07,
10730 M16_OPC_RRIA = 0x08,
10731 M16_OPC_ADDIU8 = 0x09,
10732 M16_OPC_SLTI = 0x0a,
10733 M16_OPC_SLTIU = 0x0b,
10734 M16_OPC_I8 = 0x0c,
10735 M16_OPC_LI = 0x0d,
10736 M16_OPC_CMPI = 0x0e,
10737 M16_OPC_SD = 0x0f,
10738 M16_OPC_LB = 0x10,
10739 M16_OPC_LH = 0x11,
10740 M16_OPC_LWSP = 0x12,
10741 M16_OPC_LW = 0x13,
10742 M16_OPC_LBU = 0x14,
10743 M16_OPC_LHU = 0x15,
10744 M16_OPC_LWPC = 0x16,
10745 M16_OPC_LWU = 0x17,
10746 M16_OPC_SB = 0x18,
10747 M16_OPC_SH = 0x19,
10748 M16_OPC_SWSP = 0x1a,
10749 M16_OPC_SW = 0x1b,
10750 M16_OPC_RRR = 0x1c,
10751 M16_OPC_RR = 0x1d,
10752 M16_OPC_EXTEND = 0x1e,
10753 M16_OPC_I64 = 0x1f
10754};
10755
10756/* I8 funct field */
10757enum {
10758 I8_BTEQZ = 0x0,
10759 I8_BTNEZ = 0x1,
10760 I8_SWRASP = 0x2,
10761 I8_ADJSP = 0x3,
10762 I8_SVRS = 0x4,
10763 I8_MOV32R = 0x5,
10764 I8_MOVR32 = 0x7
10765};
10766
10767/* RRR f field */
10768enum {
10769 RRR_DADDU = 0x0,
10770 RRR_ADDU = 0x1,
10771 RRR_DSUBU = 0x2,
10772 RRR_SUBU = 0x3
10773};
10774
10775/* RR funct field */
10776enum {
10777 RR_JR = 0x00,
10778 RR_SDBBP = 0x01,
10779 RR_SLT = 0x02,
10780 RR_SLTU = 0x03,
10781 RR_SLLV = 0x04,
10782 RR_BREAK = 0x05,
10783 RR_SRLV = 0x06,
10784 RR_SRAV = 0x07,
10785 RR_DSRL = 0x08,
10786 RR_CMP = 0x0a,
10787 RR_NEG = 0x0b,
10788 RR_AND = 0x0c,
10789 RR_OR = 0x0d,
10790 RR_XOR = 0x0e,
10791 RR_NOT = 0x0f,
10792 RR_MFHI = 0x10,
10793 RR_CNVT = 0x11,
10794 RR_MFLO = 0x12,
10795 RR_DSRA = 0x13,
10796 RR_DSLLV = 0x14,
10797 RR_DSRLV = 0x16,
10798 RR_DSRAV = 0x17,
10799 RR_MULT = 0x18,
10800 RR_MULTU = 0x19,
10801 RR_DIV = 0x1a,
10802 RR_DIVU = 0x1b,
10803 RR_DMULT = 0x1c,
10804 RR_DMULTU = 0x1d,
10805 RR_DDIV = 0x1e,
10806 RR_DDIVU = 0x1f
10807};
10808
10809/* I64 funct field */
10810enum {
10811 I64_LDSP = 0x0,
10812 I64_SDSP = 0x1,
10813 I64_SDRASP = 0x2,
10814 I64_DADJSP = 0x3,
10815 I64_LDPC = 0x4,
364d4831 10816 I64_DADDIU5 = 0x5,
6ea219d0
NF
10817 I64_DADDIUPC = 0x6,
10818 I64_DADDIUSP = 0x7
10819};
10820
10821/* RR ry field for CNVT */
10822enum {
10823 RR_RY_CNVT_ZEB = 0x0,
10824 RR_RY_CNVT_ZEH = 0x1,
10825 RR_RY_CNVT_ZEW = 0x2,
10826 RR_RY_CNVT_SEB = 0x4,
10827 RR_RY_CNVT_SEH = 0x5,
10828 RR_RY_CNVT_SEW = 0x6,
10829};
10830
364d4831
NF
10831static int xlat (int r)
10832{
10833 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10834
10835 return map[r];
10836}
10837
10838static void gen_mips16_save (DisasContext *ctx,
10839 int xsregs, int aregs,
10840 int do_ra, int do_s0, int do_s1,
10841 int framesize)
10842{
10843 TCGv t0 = tcg_temp_new();
10844 TCGv t1 = tcg_temp_new();
c48245f0 10845 TCGv t2 = tcg_temp_new();
364d4831
NF
10846 int args, astatic;
10847
10848 switch (aregs) {
10849 case 0:
10850 case 1:
10851 case 2:
10852 case 3:
10853 case 11:
10854 args = 0;
10855 break;
10856 case 4:
10857 case 5:
10858 case 6:
10859 case 7:
10860 args = 1;
10861 break;
10862 case 8:
10863 case 9:
10864 case 10:
10865 args = 2;
10866 break;
10867 case 12:
10868 case 13:
10869 args = 3;
10870 break;
10871 case 14:
10872 args = 4;
10873 break;
10874 default:
10875 generate_exception(ctx, EXCP_RI);
10876 return;
10877 }
10878
10879 switch (args) {
10880 case 4:
10881 gen_base_offset_addr(ctx, t0, 29, 12);
10882 gen_load_gpr(t1, 7);
5f68f5ae 10883 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10884 /* Fall through */
10885 case 3:
10886 gen_base_offset_addr(ctx, t0, 29, 8);
10887 gen_load_gpr(t1, 6);
5f68f5ae 10888 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10889 /* Fall through */
10890 case 2:
10891 gen_base_offset_addr(ctx, t0, 29, 4);
10892 gen_load_gpr(t1, 5);
5f68f5ae 10893 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10894 /* Fall through */
10895 case 1:
10896 gen_base_offset_addr(ctx, t0, 29, 0);
10897 gen_load_gpr(t1, 4);
5f68f5ae 10898 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10899 }
10900
10901 gen_load_gpr(t0, 29);
10902
5f68f5ae 10903#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10904 tcg_gen_movi_tl(t2, -4); \
10905 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10906 gen_load_gpr(t1, reg); \
10907 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10908 } while (0)
10909
10910 if (do_ra) {
10911 DECR_AND_STORE(31);
10912 }
10913
10914 switch (xsregs) {
10915 case 7:
10916 DECR_AND_STORE(30);
10917 /* Fall through */
10918 case 6:
10919 DECR_AND_STORE(23);
10920 /* Fall through */
10921 case 5:
10922 DECR_AND_STORE(22);
10923 /* Fall through */
10924 case 4:
10925 DECR_AND_STORE(21);
10926 /* Fall through */
10927 case 3:
10928 DECR_AND_STORE(20);
10929 /* Fall through */
10930 case 2:
10931 DECR_AND_STORE(19);
10932 /* Fall through */
10933 case 1:
10934 DECR_AND_STORE(18);
10935 }
10936
10937 if (do_s1) {
10938 DECR_AND_STORE(17);
10939 }
10940 if (do_s0) {
10941 DECR_AND_STORE(16);
10942 }
10943
10944 switch (aregs) {
10945 case 0:
10946 case 4:
10947 case 8:
10948 case 12:
10949 case 14:
10950 astatic = 0;
10951 break;
10952 case 1:
10953 case 5:
10954 case 9:
10955 case 13:
10956 astatic = 1;
10957 break;
10958 case 2:
10959 case 6:
10960 case 10:
10961 astatic = 2;
10962 break;
10963 case 3:
10964 case 7:
10965 astatic = 3;
10966 break;
10967 case 11:
10968 astatic = 4;
10969 break;
10970 default:
10971 generate_exception(ctx, EXCP_RI);
10972 return;
10973 }
10974
10975 if (astatic > 0) {
10976 DECR_AND_STORE(7);
10977 if (astatic > 1) {
10978 DECR_AND_STORE(6);
10979 if (astatic > 2) {
10980 DECR_AND_STORE(5);
10981 if (astatic > 3) {
10982 DECR_AND_STORE(4);
10983 }
10984 }
10985 }
10986 }
10987#undef DECR_AND_STORE
10988
c48245f0
MR
10989 tcg_gen_movi_tl(t2, -framesize);
10990 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
10991 tcg_temp_free(t0);
10992 tcg_temp_free(t1);
c48245f0 10993 tcg_temp_free(t2);
364d4831
NF
10994}
10995
10996static void gen_mips16_restore (DisasContext *ctx,
10997 int xsregs, int aregs,
10998 int do_ra, int do_s0, int do_s1,
10999 int framesize)
11000{
11001 int astatic;
11002 TCGv t0 = tcg_temp_new();
11003 TCGv t1 = tcg_temp_new();
c48245f0 11004 TCGv t2 = tcg_temp_new();
364d4831 11005
c48245f0
MR
11006 tcg_gen_movi_tl(t2, framesize);
11007 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11008
5f68f5ae 11009#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11010 tcg_gen_movi_tl(t2, -4); \
11011 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11012 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11013 gen_store_gpr(t1, reg); \
364d4831
NF
11014 } while (0)
11015
11016 if (do_ra) {
11017 DECR_AND_LOAD(31);
11018 }
11019
11020 switch (xsregs) {
11021 case 7:
11022 DECR_AND_LOAD(30);
11023 /* Fall through */
11024 case 6:
11025 DECR_AND_LOAD(23);
11026 /* Fall through */
11027 case 5:
11028 DECR_AND_LOAD(22);
11029 /* Fall through */
11030 case 4:
11031 DECR_AND_LOAD(21);
11032 /* Fall through */
11033 case 3:
11034 DECR_AND_LOAD(20);
11035 /* Fall through */
11036 case 2:
11037 DECR_AND_LOAD(19);
11038 /* Fall through */
11039 case 1:
11040 DECR_AND_LOAD(18);
11041 }
11042
11043 if (do_s1) {
11044 DECR_AND_LOAD(17);
11045 }
11046 if (do_s0) {
11047 DECR_AND_LOAD(16);
11048 }
11049
11050 switch (aregs) {
11051 case 0:
11052 case 4:
11053 case 8:
11054 case 12:
11055 case 14:
11056 astatic = 0;
11057 break;
11058 case 1:
11059 case 5:
11060 case 9:
11061 case 13:
11062 astatic = 1;
11063 break;
11064 case 2:
11065 case 6:
11066 case 10:
11067 astatic = 2;
11068 break;
11069 case 3:
11070 case 7:
11071 astatic = 3;
11072 break;
11073 case 11:
11074 astatic = 4;
11075 break;
11076 default:
11077 generate_exception(ctx, EXCP_RI);
11078 return;
11079 }
11080
11081 if (astatic > 0) {
11082 DECR_AND_LOAD(7);
11083 if (astatic > 1) {
11084 DECR_AND_LOAD(6);
11085 if (astatic > 2) {
11086 DECR_AND_LOAD(5);
11087 if (astatic > 3) {
11088 DECR_AND_LOAD(4);
11089 }
11090 }
11091 }
11092 }
11093#undef DECR_AND_LOAD
11094
c48245f0
MR
11095 tcg_gen_movi_tl(t2, framesize);
11096 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11097 tcg_temp_free(t0);
11098 tcg_temp_free(t1);
c48245f0 11099 tcg_temp_free(t2);
364d4831
NF
11100}
11101
11102static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11103 int is_64_bit, int extended)
11104{
11105 TCGv t0;
11106
11107 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11108 generate_exception(ctx, EXCP_RI);
11109 return;
11110 }
11111
11112 t0 = tcg_temp_new();
11113
11114 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11115 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11116 if (!is_64_bit) {
11117 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11118 }
11119
11120 tcg_temp_free(t0);
11121}
11122
11123#if defined(TARGET_MIPS64)
d75c135e 11124static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11125 int ry, int funct, int16_t offset,
11126 int extended)
11127{
11128 switch (funct) {
11129 case I64_LDSP:
d9224450 11130 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11131 check_mips_64(ctx);
11132 offset = extended ? offset : offset << 3;
d75c135e 11133 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11134 break;
11135 case I64_SDSP:
d9224450 11136 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11137 check_mips_64(ctx);
11138 offset = extended ? offset : offset << 3;
5c13fdfd 11139 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11140 break;
11141 case I64_SDRASP:
d9224450 11142 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11143 check_mips_64(ctx);
11144 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11145 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11146 break;
11147 case I64_DADJSP:
d9224450 11148 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11149 check_mips_64(ctx);
11150 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11151 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11152 break;
11153 case I64_LDPC:
d9224450
MR
11154 check_insn(ctx, ISA_MIPS3);
11155 check_mips_64(ctx);
364d4831
NF
11156 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11157 generate_exception(ctx, EXCP_RI);
11158 } else {
11159 offset = extended ? offset : offset << 3;
d75c135e 11160 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11161 }
11162 break;
11163 case I64_DADDIU5:
d9224450 11164 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11165 check_mips_64(ctx);
11166 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11167 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11168 break;
11169 case I64_DADDIUPC:
d9224450 11170 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11171 check_mips_64(ctx);
11172 offset = extended ? offset : offset << 2;
11173 gen_addiupc(ctx, ry, offset, 1, extended);
11174 break;
11175 case I64_DADDIUSP:
d9224450 11176 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11177 check_mips_64(ctx);
11178 offset = extended ? offset : offset << 2;
d75c135e 11179 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11180 break;
11181 }
11182}
11183#endif
11184
240ce26a 11185static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11186{
895c2d04 11187 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11188 int op, rx, ry, funct, sa;
11189 int16_t imm, offset;
11190
11191 ctx->opcode = (ctx->opcode << 16) | extend;
11192 op = (ctx->opcode >> 11) & 0x1f;
11193 sa = (ctx->opcode >> 22) & 0x1f;
11194 funct = (ctx->opcode >> 8) & 0x7;
11195 rx = xlat((ctx->opcode >> 8) & 0x7);
11196 ry = xlat((ctx->opcode >> 5) & 0x7);
11197 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11198 | ((ctx->opcode >> 21) & 0x3f) << 5
11199 | (ctx->opcode & 0x1f));
11200
11201 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11202 counterparts. */
11203 switch (op) {
11204 case M16_OPC_ADDIUSP:
d75c135e 11205 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11206 break;
11207 case M16_OPC_ADDIUPC:
11208 gen_addiupc(ctx, rx, imm, 0, 1);
11209 break;
11210 case M16_OPC_B:
b231c103 11211 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11212 /* No delay slot, so just process as a normal instruction */
11213 break;
11214 case M16_OPC_BEQZ:
b231c103 11215 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11216 /* No delay slot, so just process as a normal instruction */
11217 break;
11218 case M16_OPC_BNEQZ:
b231c103 11219 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11220 /* No delay slot, so just process as a normal instruction */
11221 break;
11222 case M16_OPC_SHIFT:
11223 switch (ctx->opcode & 0x3) {
11224 case 0x0:
d75c135e 11225 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11226 break;
11227 case 0x1:
11228#if defined(TARGET_MIPS64)
11229 check_mips_64(ctx);
d75c135e 11230 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11231#else
11232 generate_exception(ctx, EXCP_RI);
11233#endif
11234 break;
11235 case 0x2:
d75c135e 11236 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11237 break;
11238 case 0x3:
d75c135e 11239 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11240 break;
11241 }
11242 break;
11243#if defined(TARGET_MIPS64)
11244 case M16_OPC_LD:
d9224450 11245 check_insn(ctx, ISA_MIPS3);
d75de749 11246 check_mips_64(ctx);
d75c135e 11247 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11248 break;
11249#endif
11250 case M16_OPC_RRIA:
11251 imm = ctx->opcode & 0xf;
11252 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11253 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11254 imm = (int16_t) (imm << 1) >> 1;
11255 if ((ctx->opcode >> 4) & 0x1) {
11256#if defined(TARGET_MIPS64)
11257 check_mips_64(ctx);
d75c135e 11258 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11259#else
11260 generate_exception(ctx, EXCP_RI);
11261#endif
11262 } else {
d75c135e 11263 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11264 }
11265 break;
11266 case M16_OPC_ADDIU8:
d75c135e 11267 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11268 break;
11269 case M16_OPC_SLTI:
d75c135e 11270 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11271 break;
11272 case M16_OPC_SLTIU:
d75c135e 11273 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11274 break;
11275 case M16_OPC_I8:
11276 switch (funct) {
11277 case I8_BTEQZ:
b231c103 11278 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11279 break;
11280 case I8_BTNEZ:
b231c103 11281 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11282 break;
11283 case I8_SWRASP:
5c13fdfd 11284 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11285 break;
11286 case I8_ADJSP:
d75c135e 11287 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11288 break;
11289 case I8_SVRS:
d9224450 11290 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11291 {
11292 int xsregs = (ctx->opcode >> 24) & 0x7;
11293 int aregs = (ctx->opcode >> 16) & 0xf;
11294 int do_ra = (ctx->opcode >> 6) & 0x1;
11295 int do_s0 = (ctx->opcode >> 5) & 0x1;
11296 int do_s1 = (ctx->opcode >> 4) & 0x1;
11297 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11298 | (ctx->opcode & 0xf)) << 3;
11299
11300 if (ctx->opcode & (1 << 7)) {
11301 gen_mips16_save(ctx, xsregs, aregs,
11302 do_ra, do_s0, do_s1,
11303 framesize);
11304 } else {
11305 gen_mips16_restore(ctx, xsregs, aregs,
11306 do_ra, do_s0, do_s1,
11307 framesize);
11308 }
11309 }
11310 break;
11311 default:
11312 generate_exception(ctx, EXCP_RI);
11313 break;
11314 }
11315 break;
11316 case M16_OPC_LI:
11317 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11318 break;
11319 case M16_OPC_CMPI:
11320 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11321 break;
11322#if defined(TARGET_MIPS64)
11323 case M16_OPC_SD:
d9224450
MR
11324 check_insn(ctx, ISA_MIPS3);
11325 check_mips_64(ctx);
5c13fdfd 11326 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11327 break;
11328#endif
11329 case M16_OPC_LB:
d75c135e 11330 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11331 break;
11332 case M16_OPC_LH:
d75c135e 11333 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11334 break;
11335 case M16_OPC_LWSP:
d75c135e 11336 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11337 break;
11338 case M16_OPC_LW:
d75c135e 11339 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11340 break;
11341 case M16_OPC_LBU:
d75c135e 11342 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11343 break;
11344 case M16_OPC_LHU:
d75c135e 11345 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11346 break;
11347 case M16_OPC_LWPC:
d75c135e 11348 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11349 break;
11350#if defined(TARGET_MIPS64)
11351 case M16_OPC_LWU:
d9224450
MR
11352 check_insn(ctx, ISA_MIPS3);
11353 check_mips_64(ctx);
d75c135e 11354 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11355 break;
11356#endif
11357 case M16_OPC_SB:
5c13fdfd 11358 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11359 break;
11360 case M16_OPC_SH:
5c13fdfd 11361 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11362 break;
11363 case M16_OPC_SWSP:
5c13fdfd 11364 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11365 break;
11366 case M16_OPC_SW:
5c13fdfd 11367 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11368 break;
11369#if defined(TARGET_MIPS64)
11370 case M16_OPC_I64:
d75c135e 11371 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11372 break;
11373#endif
11374 default:
11375 generate_exception(ctx, EXCP_RI);
11376 break;
11377 }
11378
11379 return 4;
11380}
11381
3b3c1694
LA
11382static inline bool is_uhi(int sdbbp_code)
11383{
11384#ifdef CONFIG_USER_ONLY
11385 return false;
11386#else
11387 return semihosting_enabled() && sdbbp_code == 1;
11388#endif
11389}
11390
240ce26a 11391static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11392{
11393 int rx, ry;
11394 int sa;
11395 int op, cnvt_op, op1, offset;
11396 int funct;
11397 int n_bytes;
11398
11399 op = (ctx->opcode >> 11) & 0x1f;
11400 sa = (ctx->opcode >> 2) & 0x7;
11401 sa = sa == 0 ? 8 : sa;
11402 rx = xlat((ctx->opcode >> 8) & 0x7);
11403 cnvt_op = (ctx->opcode >> 5) & 0x7;
11404 ry = xlat((ctx->opcode >> 5) & 0x7);
11405 op1 = offset = ctx->opcode & 0x1f;
11406
11407 n_bytes = 2;
11408
11409 switch (op) {
11410 case M16_OPC_ADDIUSP:
11411 {
11412 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11413
d75c135e 11414 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11415 }
11416 break;
11417 case M16_OPC_ADDIUPC:
11418 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11419 break;
11420 case M16_OPC_B:
11421 offset = (ctx->opcode & 0x7ff) << 1;
11422 offset = (int16_t)(offset << 4) >> 4;
b231c103 11423 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11424 /* No delay slot, so just process as a normal instruction */
11425 break;
11426 case M16_OPC_JAL:
895c2d04 11427 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11428 offset = (((ctx->opcode & 0x1f) << 21)
11429 | ((ctx->opcode >> 5) & 0x1f) << 16
11430 | offset) << 2;
b231c103
YK
11431 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11432 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11433 n_bytes = 4;
364d4831
NF
11434 break;
11435 case M16_OPC_BEQZ:
b231c103
YK
11436 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11437 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11438 /* No delay slot, so just process as a normal instruction */
11439 break;
11440 case M16_OPC_BNEQZ:
b231c103
YK
11441 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11442 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11443 /* No delay slot, so just process as a normal instruction */
11444 break;
11445 case M16_OPC_SHIFT:
11446 switch (ctx->opcode & 0x3) {
11447 case 0x0:
d75c135e 11448 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11449 break;
11450 case 0x1:
11451#if defined(TARGET_MIPS64)
d9224450 11452 check_insn(ctx, ISA_MIPS3);
364d4831 11453 check_mips_64(ctx);
d75c135e 11454 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11455#else
11456 generate_exception(ctx, EXCP_RI);
11457#endif
11458 break;
11459 case 0x2:
d75c135e 11460 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11461 break;
11462 case 0x3:
d75c135e 11463 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11464 break;
11465 }
11466 break;
11467#if defined(TARGET_MIPS64)
11468 case M16_OPC_LD:
d9224450 11469 check_insn(ctx, ISA_MIPS3);
364d4831 11470 check_mips_64(ctx);
d75c135e 11471 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11472 break;
11473#endif
11474 case M16_OPC_RRIA:
11475 {
11476 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11477
11478 if ((ctx->opcode >> 4) & 1) {
11479#if defined(TARGET_MIPS64)
d9224450 11480 check_insn(ctx, ISA_MIPS3);
364d4831 11481 check_mips_64(ctx);
d75c135e 11482 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11483#else
11484 generate_exception(ctx, EXCP_RI);
11485#endif
11486 } else {
d75c135e 11487 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11488 }
11489 }
11490 break;
11491 case M16_OPC_ADDIU8:
11492 {
11493 int16_t imm = (int8_t) ctx->opcode;
11494
d75c135e 11495 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11496 }
11497 break;
11498 case M16_OPC_SLTI:
11499 {
11500 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11501 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11502 }
11503 break;
11504 case M16_OPC_SLTIU:
11505 {
11506 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11507 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11508 }
11509 break;
11510 case M16_OPC_I8:
11511 {
11512 int reg32;
11513
11514 funct = (ctx->opcode >> 8) & 0x7;
11515 switch (funct) {
11516 case I8_BTEQZ:
11517 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11518 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11519 break;
11520 case I8_BTNEZ:
11521 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11522 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11523 break;
11524 case I8_SWRASP:
5c13fdfd 11525 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11526 break;
11527 case I8_ADJSP:
d75c135e 11528 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11529 ((int8_t)ctx->opcode) << 3);
11530 break;
11531 case I8_SVRS:
d9224450 11532 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11533 {
11534 int do_ra = ctx->opcode & (1 << 6);
11535 int do_s0 = ctx->opcode & (1 << 5);
11536 int do_s1 = ctx->opcode & (1 << 4);
11537 int framesize = ctx->opcode & 0xf;
11538
11539 if (framesize == 0) {
11540 framesize = 128;
11541 } else {
11542 framesize = framesize << 3;
11543 }
11544
11545 if (ctx->opcode & (1 << 7)) {
11546 gen_mips16_save(ctx, 0, 0,
11547 do_ra, do_s0, do_s1, framesize);
11548 } else {
11549 gen_mips16_restore(ctx, 0, 0,
11550 do_ra, do_s0, do_s1, framesize);
11551 }
11552 }
11553 break;
11554 case I8_MOV32R:
11555 {
11556 int rz = xlat(ctx->opcode & 0x7);
11557
11558 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11559 ((ctx->opcode >> 5) & 0x7);
d75c135e 11560 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11561 }
11562 break;
11563 case I8_MOVR32:
11564 reg32 = ctx->opcode & 0x1f;
d75c135e 11565 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11566 break;
11567 default:
11568 generate_exception(ctx, EXCP_RI);
11569 break;
11570 }
11571 }
11572 break;
11573 case M16_OPC_LI:
11574 {
11575 int16_t imm = (uint8_t) ctx->opcode;
11576
d75c135e 11577 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11578 }
11579 break;
11580 case M16_OPC_CMPI:
11581 {
11582 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11583 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11584 }
11585 break;
11586#if defined(TARGET_MIPS64)
11587 case M16_OPC_SD:
d9224450 11588 check_insn(ctx, ISA_MIPS3);
364d4831 11589 check_mips_64(ctx);
5c13fdfd 11590 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11591 break;
11592#endif
11593 case M16_OPC_LB:
d75c135e 11594 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11595 break;
11596 case M16_OPC_LH:
d75c135e 11597 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11598 break;
11599 case M16_OPC_LWSP:
d75c135e 11600 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11601 break;
11602 case M16_OPC_LW:
d75c135e 11603 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11604 break;
11605 case M16_OPC_LBU:
d75c135e 11606 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11607 break;
11608 case M16_OPC_LHU:
d75c135e 11609 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11610 break;
11611 case M16_OPC_LWPC:
d75c135e 11612 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11613 break;
11614#if defined (TARGET_MIPS64)
11615 case M16_OPC_LWU:
d9224450 11616 check_insn(ctx, ISA_MIPS3);
364d4831 11617 check_mips_64(ctx);
d75c135e 11618 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11619 break;
11620#endif
11621 case M16_OPC_SB:
5c13fdfd 11622 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11623 break;
11624 case M16_OPC_SH:
5c13fdfd 11625 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11626 break;
11627 case M16_OPC_SWSP:
5c13fdfd 11628 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11629 break;
11630 case M16_OPC_SW:
5c13fdfd 11631 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11632 break;
11633 case M16_OPC_RRR:
11634 {
11635 int rz = xlat((ctx->opcode >> 2) & 0x7);
11636 int mips32_op;
11637
11638 switch (ctx->opcode & 0x3) {
11639 case RRR_ADDU:
11640 mips32_op = OPC_ADDU;
11641 break;
11642 case RRR_SUBU:
11643 mips32_op = OPC_SUBU;
11644 break;
11645#if defined(TARGET_MIPS64)
11646 case RRR_DADDU:
11647 mips32_op = OPC_DADDU;
d9224450 11648 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11649 check_mips_64(ctx);
11650 break;
11651 case RRR_DSUBU:
11652 mips32_op = OPC_DSUBU;
d9224450 11653 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11654 check_mips_64(ctx);
11655 break;
11656#endif
11657 default:
11658 generate_exception(ctx, EXCP_RI);
11659 goto done;
11660 }
11661
d75c135e 11662 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11663 done:
11664 ;
11665 }
11666 break;
11667 case M16_OPC_RR:
11668 switch (op1) {
11669 case RR_JR:
11670 {
11671 int nd = (ctx->opcode >> 7) & 0x1;
11672 int link = (ctx->opcode >> 6) & 0x1;
11673 int ra = (ctx->opcode >> 5) & 0x1;
11674
d9224450
MR
11675 if (nd) {
11676 check_insn(ctx, ISA_MIPS32);
11677 }
11678
364d4831 11679 if (link) {
b231c103 11680 op = OPC_JALR;
364d4831
NF
11681 } else {
11682 op = OPC_JR;
11683 }
11684
b231c103
YK
11685 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11686 (nd ? 0 : 2));
364d4831
NF
11687 }
11688 break;
11689 case RR_SDBBP:
3b3c1694
LA
11690 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11691 gen_helper_do_semihosting(cpu_env);
11692 } else {
11693 /* XXX: not clear which exception should be raised
11694 * when in debug mode...
11695 */
11696 check_insn(ctx, ISA_MIPS32);
11697 generate_exception(ctx, EXCP_DBp);
11698 }
364d4831
NF
11699 break;
11700 case RR_SLT:
d75c135e 11701 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11702 break;
11703 case RR_SLTU:
d75c135e 11704 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11705 break;
11706 case RR_BREAK:
11707 generate_exception(ctx, EXCP_BREAK);
11708 break;
11709 case RR_SLLV:
d75c135e 11710 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11711 break;
11712 case RR_SRLV:
d75c135e 11713 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11714 break;
11715 case RR_SRAV:
d75c135e 11716 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11717 break;
11718#if defined (TARGET_MIPS64)
11719 case RR_DSRL:
d9224450 11720 check_insn(ctx, ISA_MIPS3);
364d4831 11721 check_mips_64(ctx);
d75c135e 11722 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11723 break;
11724#endif
11725 case RR_CMP:
d75c135e 11726 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11727 break;
11728 case RR_NEG:
d75c135e 11729 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11730 break;
11731 case RR_AND:
d75c135e 11732 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11733 break;
11734 case RR_OR:
d75c135e 11735 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11736 break;
11737 case RR_XOR:
d75c135e 11738 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11739 break;
11740 case RR_NOT:
d75c135e 11741 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11742 break;
11743 case RR_MFHI:
26135ead 11744 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11745 break;
11746 case RR_CNVT:
d9224450 11747 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11748 switch (cnvt_op) {
11749 case RR_RY_CNVT_ZEB:
11750 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11751 break;
11752 case RR_RY_CNVT_ZEH:
11753 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11754 break;
11755 case RR_RY_CNVT_SEB:
11756 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11757 break;
11758 case RR_RY_CNVT_SEH:
11759 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11760 break;
11761#if defined (TARGET_MIPS64)
11762 case RR_RY_CNVT_ZEW:
d9224450 11763 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11764 check_mips_64(ctx);
11765 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11766 break;
11767 case RR_RY_CNVT_SEW:
d9224450 11768 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11769 check_mips_64(ctx);
11770 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11771 break;
11772#endif
11773 default:
11774 generate_exception(ctx, EXCP_RI);
11775 break;
11776 }
11777 break;
11778 case RR_MFLO:
26135ead 11779 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11780 break;
11781#if defined (TARGET_MIPS64)
11782 case RR_DSRA:
d9224450 11783 check_insn(ctx, ISA_MIPS3);
364d4831 11784 check_mips_64(ctx);
d75c135e 11785 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11786 break;
11787 case RR_DSLLV:
d9224450 11788 check_insn(ctx, ISA_MIPS3);
364d4831 11789 check_mips_64(ctx);
d75c135e 11790 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11791 break;
11792 case RR_DSRLV:
d9224450 11793 check_insn(ctx, ISA_MIPS3);
364d4831 11794 check_mips_64(ctx);
d75c135e 11795 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11796 break;
11797 case RR_DSRAV:
d9224450 11798 check_insn(ctx, ISA_MIPS3);
364d4831 11799 check_mips_64(ctx);
d75c135e 11800 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11801 break;
11802#endif
11803 case RR_MULT:
26135ead 11804 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11805 break;
11806 case RR_MULTU:
26135ead 11807 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11808 break;
11809 case RR_DIV:
26135ead 11810 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11811 break;
11812 case RR_DIVU:
26135ead 11813 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11814 break;
11815#if defined (TARGET_MIPS64)
11816 case RR_DMULT:
d9224450 11817 check_insn(ctx, ISA_MIPS3);
364d4831 11818 check_mips_64(ctx);
26135ead 11819 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11820 break;
11821 case RR_DMULTU:
d9224450 11822 check_insn(ctx, ISA_MIPS3);
364d4831 11823 check_mips_64(ctx);
26135ead 11824 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11825 break;
11826 case RR_DDIV:
d9224450 11827 check_insn(ctx, ISA_MIPS3);
364d4831 11828 check_mips_64(ctx);
26135ead 11829 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11830 break;
11831 case RR_DDIVU:
d9224450 11832 check_insn(ctx, ISA_MIPS3);
364d4831 11833 check_mips_64(ctx);
26135ead 11834 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11835 break;
11836#endif
11837 default:
11838 generate_exception(ctx, EXCP_RI);
11839 break;
11840 }
11841 break;
11842 case M16_OPC_EXTEND:
240ce26a 11843 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11844 n_bytes = 4;
11845 break;
11846#if defined(TARGET_MIPS64)
11847 case M16_OPC_I64:
11848 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11849 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11850 break;
11851#endif
11852 default:
11853 generate_exception(ctx, EXCP_RI);
11854 break;
11855 }
11856
11857 return n_bytes;
11858}
11859
211da992 11860/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11861
211da992
CWR
11862/*
11863 * microMIPS32/microMIPS64 major opcodes
11864 *
11865 * 1. MIPS Architecture for Programmers Volume II-B:
11866 * The microMIPS32 Instruction Set (Revision 3.05)
11867 *
11868 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11869 *
11870 * 2. MIPS Architecture For Programmers Volume II-A:
11871 * The MIPS64 Instruction Set (Revision 3.51)
11872 */
6af0bf9c 11873
3c824109
NF
11874enum {
11875 POOL32A = 0x00,
11876 POOL16A = 0x01,
11877 LBU16 = 0x02,
11878 MOVE16 = 0x03,
11879 ADDI32 = 0x04,
3a1f4268
YK
11880 R6_LUI = 0x04,
11881 AUI = 0x04,
3c824109
NF
11882 LBU32 = 0x05,
11883 SB32 = 0x06,
11884 LB32 = 0x07,
11885
11886 POOL32B = 0x08,
11887 POOL16B = 0x09,
11888 LHU16 = 0x0a,
11889 ANDI16 = 0x0b,
11890 ADDIU32 = 0x0c,
11891 LHU32 = 0x0d,
11892 SH32 = 0x0e,
11893 LH32 = 0x0f,
11894
11895 POOL32I = 0x10,
11896 POOL16C = 0x11,
11897 LWSP16 = 0x12,
11898 POOL16D = 0x13,
11899 ORI32 = 0x14,
11900 POOL32F = 0x15,
211da992
CWR
11901 POOL32S = 0x16, /* MIPS64 */
11902 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
11903
11904 POOL32C = 0x18,
11905 LWGP16 = 0x19,
11906 LW16 = 0x1a,
11907 POOL16E = 0x1b,
11908 XORI32 = 0x1c,
11909 JALS32 = 0x1d,
3a1f4268
YK
11910 BOVC = 0x1d,
11911 BEQC = 0x1d,
11912 BEQZALC = 0x1d,
3c824109 11913 ADDIUPC = 0x1e,
3a1f4268
YK
11914 PCREL = 0x1e,
11915 BNVC = 0x1f,
11916 BNEC = 0x1f,
11917 BNEZALC = 0x1f,
3c824109 11918
3a1f4268
YK
11919 R6_BEQZC = 0x20,
11920 JIC = 0x20,
3c824109
NF
11921 POOL16F = 0x21,
11922 SB16 = 0x22,
11923 BEQZ16 = 0x23,
3a1f4268 11924 BEQZC16 = 0x23,
3c824109
NF
11925 SLTI32 = 0x24,
11926 BEQ32 = 0x25,
3a1f4268 11927 BC = 0x25,
3c824109
NF
11928 SWC132 = 0x26,
11929 LWC132 = 0x27,
11930
3a1f4268 11931 /* 0x29 is reserved */
3c824109 11932 RES_29 = 0x29,
3a1f4268
YK
11933 R6_BNEZC = 0x28,
11934 JIALC = 0x28,
3c824109
NF
11935 SH16 = 0x2a,
11936 BNEZ16 = 0x2b,
3a1f4268 11937 BNEZC16 = 0x2b,
3c824109
NF
11938 SLTIU32 = 0x2c,
11939 BNE32 = 0x2d,
3a1f4268 11940 BALC = 0x2d,
3c824109
NF
11941 SDC132 = 0x2e,
11942 LDC132 = 0x2f,
11943
3a1f4268 11944 /* 0x31 is reserved */
3c824109 11945 RES_31 = 0x31,
3a1f4268
YK
11946 BLEZALC = 0x30,
11947 BGEZALC = 0x30,
11948 BGEUC = 0x30,
3c824109
NF
11949 SWSP16 = 0x32,
11950 B16 = 0x33,
3a1f4268 11951 BC16 = 0x33,
3c824109
NF
11952 ANDI32 = 0x34,
11953 J32 = 0x35,
3a1f4268
YK
11954 BGTZC = 0x35,
11955 BLTZC = 0x35,
11956 BLTC = 0x35,
211da992
CWR
11957 SD32 = 0x36, /* MIPS64 */
11958 LD32 = 0x37, /* MIPS64 */
3c824109 11959
3a1f4268 11960 /* 0x39 is reserved */
3c824109 11961 RES_39 = 0x39,
3a1f4268
YK
11962 BGTZALC = 0x38,
11963 BLTZALC = 0x38,
11964 BLTUC = 0x38,
3c824109
NF
11965 SW16 = 0x3a,
11966 LI16 = 0x3b,
11967 JALX32 = 0x3c,
11968 JAL32 = 0x3d,
3a1f4268
YK
11969 BLEZC = 0x3d,
11970 BGEZC = 0x3d,
11971 BGEC = 0x3d,
3c824109
NF
11972 SW32 = 0x3e,
11973 LW32 = 0x3f
11974};
11975
3a1f4268
YK
11976/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
11977enum {
11978 ADDIUPC_00 = 0x00,
11979 ADDIUPC_07 = 0x07,
11980 AUIPC = 0x1e,
11981 ALUIPC = 0x1f,
11982 LWPC_08 = 0x08,
11983 LWPC_0F = 0x0F,
11984};
11985
3c824109
NF
11986/* POOL32A encoding of minor opcode field */
11987
11988enum {
11989 /* These opcodes are distinguished only by bits 9..6; those bits are
11990 * what are recorded below. */
11991 SLL32 = 0x0,
11992 SRL32 = 0x1,
11993 SRA = 0x2,
11994 ROTR = 0x3,
3a1f4268
YK
11995 SELEQZ = 0x5,
11996 SELNEZ = 0x6,
3c824109
NF
11997
11998 SLLV = 0x0,
11999 SRLV = 0x1,
12000 SRAV = 0x2,
12001 ROTRV = 0x3,
12002 ADD = 0x4,
12003 ADDU32 = 0x5,
12004 SUB = 0x6,
12005 SUBU32 = 0x7,
12006 MUL = 0x8,
12007 AND = 0x9,
12008 OR32 = 0xa,
12009 NOR = 0xb,
12010 XOR32 = 0xc,
12011 SLT = 0xd,
12012 SLTU = 0xe,
12013
12014 MOVN = 0x0,
3a1f4268 12015 R6_MUL = 0x0,
3c824109 12016 MOVZ = 0x1,
3a1f4268
YK
12017 MUH = 0x1,
12018 MULU = 0x2,
12019 MUHU = 0x3,
3c824109 12020 LWXS = 0x4,
3a1f4268
YK
12021 R6_DIV = 0x4,
12022 MOD = 0x5,
12023 R6_DIVU = 0x6,
12024 MODU = 0x7,
3c824109
NF
12025
12026 /* The following can be distinguished by their lower 6 bits. */
12027 INS = 0x0c,
3a1f4268
YK
12028 LSA = 0x0f,
12029 ALIGN = 0x1f,
3c824109
NF
12030 EXT = 0x2c,
12031 POOL32AXF = 0x3c
12032};
12033
12034/* POOL32AXF encoding of minor opcode field extension */
12035
d132c79f
CWR
12036/*
12037 * 1. MIPS Architecture for Programmers Volume II-B:
12038 * The microMIPS32 Instruction Set (Revision 3.05)
12039 *
12040 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12041 *
12042 * 2. MIPS Architecture for Programmers VolumeIV-e:
12043 * The MIPS DSP Application-Specific Extension
12044 * to the microMIPS32 Architecture (Revision 2.34)
12045 *
12046 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12047 */
12048
3c824109
NF
12049enum {
12050 /* bits 11..6 */
12051 TEQ = 0x00,
12052 TGE = 0x08,
12053 TGEU = 0x10,
12054 TLT = 0x20,
12055 TLTU = 0x28,
12056 TNE = 0x30,
12057
12058 MFC0 = 0x03,
12059 MTC0 = 0x0b,
12060
d132c79f
CWR
12061 /* begin of microMIPS32 DSP */
12062
3c824109
NF
12063 /* bits 13..12 for 0x01 */
12064 MFHI_ACC = 0x0,
12065 MFLO_ACC = 0x1,
12066 MTHI_ACC = 0x2,
12067 MTLO_ACC = 0x3,
12068
12069 /* bits 13..12 for 0x2a */
12070 MADD_ACC = 0x0,
12071 MADDU_ACC = 0x1,
12072 MSUB_ACC = 0x2,
12073 MSUBU_ACC = 0x3,
12074
12075 /* bits 13..12 for 0x32 */
12076 MULT_ACC = 0x0,
6801038b 12077 MULTU_ACC = 0x1,
3c824109 12078
d132c79f
CWR
12079 /* end of microMIPS32 DSP */
12080
3c824109 12081 /* bits 15..12 for 0x2c */
3a1f4268 12082 BITSWAP = 0x0,
3c824109
NF
12083 SEB = 0x2,
12084 SEH = 0x3,
12085 CLO = 0x4,
12086 CLZ = 0x5,
12087 RDHWR = 0x6,
12088 WSBH = 0x7,
12089 MULT = 0x8,
12090 MULTU = 0x9,
12091 DIV = 0xa,
12092 DIVU = 0xb,
12093 MADD = 0xc,
12094 MADDU = 0xd,
12095 MSUB = 0xe,
12096 MSUBU = 0xf,
12097
12098 /* bits 15..12 for 0x34 */
12099 MFC2 = 0x4,
12100 MTC2 = 0x5,
12101 MFHC2 = 0x8,
12102 MTHC2 = 0x9,
12103 CFC2 = 0xc,
12104 CTC2 = 0xd,
12105
12106 /* bits 15..12 for 0x3c */
12107 JALR = 0x0,
12108 JR = 0x0, /* alias */
3a1f4268
YK
12109 JALRC = 0x0,
12110 JRC = 0x0,
3c824109 12111 JALR_HB = 0x1,
3a1f4268 12112 JALRC_HB = 0x1,
3c824109
NF
12113 JALRS = 0x4,
12114 JALRS_HB = 0x5,
12115
12116 /* bits 15..12 for 0x05 */
12117 RDPGPR = 0xe,
12118 WRPGPR = 0xf,
12119
12120 /* bits 15..12 for 0x0d */
12121 TLBP = 0x0,
12122 TLBR = 0x1,
12123 TLBWI = 0x2,
12124 TLBWR = 0x3,
e60ec063
YK
12125 TLBINV = 0x4,
12126 TLBINVF = 0x5,
3c824109
NF
12127 WAIT = 0x9,
12128 IRET = 0xd,
12129 DERET = 0xe,
12130 ERET = 0xf,
12131
12132 /* bits 15..12 for 0x15 */
12133 DMT = 0x0,
12134 DVPE = 0x1,
12135 EMT = 0x2,
12136 EVPE = 0x3,
12137
12138 /* bits 15..12 for 0x1d */
12139 DI = 0x4,
12140 EI = 0x5,
12141
12142 /* bits 15..12 for 0x2d */
12143 SYNC = 0x6,
12144 SYSCALL = 0x8,
12145 SDBBP = 0xd,
12146
12147 /* bits 15..12 for 0x35 */
12148 MFHI32 = 0x0,
12149 MFLO32 = 0x1,
12150 MTHI32 = 0x2,
12151 MTLO32 = 0x3,
12152};
12153
12154/* POOL32B encoding of minor opcode field (bits 15..12) */
12155
12156enum {
12157 LWC2 = 0x0,
12158 LWP = 0x1,
12159 LDP = 0x4,
12160 LWM32 = 0x5,
12161 CACHE = 0x6,
12162 LDM = 0x7,
12163 SWC2 = 0x8,
12164 SWP = 0x9,
12165 SDP = 0xc,
12166 SWM32 = 0xd,
12167 SDM = 0xf
12168};
12169
12170/* POOL32C encoding of minor opcode field (bits 15..12) */
12171
12172enum {
12173 LWL = 0x0,
12174 SWL = 0x8,
12175 LWR = 0x1,
12176 SWR = 0x9,
12177 PREF = 0x2,
12178 /* 0xa is reserved */
12179 LL = 0x3,
12180 SC = 0xb,
12181 LDL = 0x4,
12182 SDL = 0xc,
12183 LDR = 0x5,
12184 SDR = 0xd,
12185 /* 0x6 is reserved */
12186 LWU = 0xe,
12187 LLD = 0x7,
12188 SCD = 0xf
12189};
12190
12191/* POOL32F encoding of minor opcode field (bits 5..0) */
12192
12193enum {
12194 /* These are the bit 7..6 values */
12195 ADD_FMT = 0x0,
3c824109
NF
12196
12197 SUB_FMT = 0x1,
3c824109
NF
12198
12199 MUL_FMT = 0x2,
12200
12201 DIV_FMT = 0x3,
12202
12203 /* These are the bit 8..6 values */
3a1f4268 12204 MOVN_FMT = 0x0,
3c824109
NF
12205 RSQRT2_FMT = 0x0,
12206 MOVF_FMT = 0x0,
3a1f4268
YK
12207 RINT_FMT = 0x0,
12208 SELNEZ_FMT = 0x0,
3c824109 12209
3a1f4268 12210 MOVZ_FMT = 0x1,
3c824109
NF
12211 LWXC1 = 0x1,
12212 MOVT_FMT = 0x1,
3a1f4268
YK
12213 CLASS_FMT = 0x1,
12214 SELEQZ_FMT = 0x1,
3c824109
NF
12215
12216 PLL_PS = 0x2,
12217 SWXC1 = 0x2,
3a1f4268 12218 SEL_FMT = 0x2,
3c824109
NF
12219
12220 PLU_PS = 0x3,
12221 LDXC1 = 0x3,
12222
3a1f4268 12223 MOVN_FMT_04 = 0x4,
3c824109
NF
12224 PUL_PS = 0x4,
12225 SDXC1 = 0x4,
12226 RECIP2_FMT = 0x4,
12227
3a1f4268 12228 MOVZ_FMT_05 = 0x05,
3c824109
NF
12229 PUU_PS = 0x5,
12230 LUXC1 = 0x5,
12231
12232 CVT_PS_S = 0x6,
12233 SUXC1 = 0x6,
12234 ADDR_PS = 0x6,
12235 PREFX = 0x6,
3a1f4268 12236 MADDF_FMT = 0x6,
3c824109
NF
12237
12238 MULR_PS = 0x7,
3a1f4268 12239 MSUBF_FMT = 0x7,
3c824109
NF
12240
12241 MADD_S = 0x01,
12242 MADD_D = 0x09,
12243 MADD_PS = 0x11,
12244 ALNV_PS = 0x19,
12245 MSUB_S = 0x21,
12246 MSUB_D = 0x29,
12247 MSUB_PS = 0x31,
12248
12249 NMADD_S = 0x02,
12250 NMADD_D = 0x0a,
12251 NMADD_PS = 0x12,
12252 NMSUB_S = 0x22,
12253 NMSUB_D = 0x2a,
12254 NMSUB_PS = 0x32,
12255
3a1f4268
YK
12256 MIN_FMT = 0x3,
12257 MAX_FMT = 0xb,
12258 MINA_FMT = 0x23,
12259 MAXA_FMT = 0x2b,
3c824109
NF
12260 POOL32FXF = 0x3b,
12261
12262 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12263 C_COND_FMT = 0x3c,
12264
12265 CMP_CONDN_S = 0x5,
12266 CMP_CONDN_D = 0x15
3c824109
NF
12267};
12268
12269/* POOL32Fxf encoding of minor opcode extension field */
12270
12271enum {
12272 CVT_L = 0x04,
12273 RSQRT_FMT = 0x08,
12274 FLOOR_L = 0x0c,
12275 CVT_PW_PS = 0x1c,
12276 CVT_W = 0x24,
12277 SQRT_FMT = 0x28,
12278 FLOOR_W = 0x2c,
12279 CVT_PS_PW = 0x3c,
12280 CFC1 = 0x40,
12281 RECIP_FMT = 0x48,
12282 CEIL_L = 0x4c,
12283 CTC1 = 0x60,
12284 CEIL_W = 0x6c,
12285 MFC1 = 0x80,
12286 CVT_S_PL = 0x84,
12287 TRUNC_L = 0x8c,
12288 MTC1 = 0xa0,
12289 CVT_S_PU = 0xa4,
12290 TRUNC_W = 0xac,
12291 MFHC1 = 0xc0,
12292 ROUND_L = 0xcc,
12293 MTHC1 = 0xe0,
12294 ROUND_W = 0xec,
12295
12296 MOV_FMT = 0x01,
12297 MOVF = 0x05,
12298 ABS_FMT = 0x0d,
12299 RSQRT1_FMT = 0x1d,
12300 MOVT = 0x25,
12301 NEG_FMT = 0x2d,
12302 CVT_D = 0x4d,
12303 RECIP1_FMT = 0x5d,
12304 CVT_S = 0x6d
12305};
12306
12307/* POOL32I encoding of minor opcode field (bits 25..21) */
12308
12309enum {
12310 BLTZ = 0x00,
12311 BLTZAL = 0x01,
12312 BGEZ = 0x02,
12313 BGEZAL = 0x03,
12314 BLEZ = 0x04,
12315 BNEZC = 0x05,
12316 BGTZ = 0x06,
12317 BEQZC = 0x07,
12318 TLTI = 0x08,
3a1f4268 12319 BC1EQZC = 0x08,
3c824109 12320 TGEI = 0x09,
3a1f4268 12321 BC1NEZC = 0x09,
3c824109 12322 TLTIU = 0x0a,
3a1f4268 12323 BC2EQZC = 0x0a,
3c824109 12324 TGEIU = 0x0b,
3a1f4268 12325 BC2NEZC = 0x0a,
3c824109 12326 TNEI = 0x0c,
3a1f4268 12327 R6_SYNCI = 0x0c,
3c824109
NF
12328 LUI = 0x0d,
12329 TEQI = 0x0e,
12330 SYNCI = 0x10,
12331 BLTZALS = 0x11,
12332 BGEZALS = 0x13,
12333 BC2F = 0x14,
12334 BC2T = 0x15,
12335 BPOSGE64 = 0x1a,
12336 BPOSGE32 = 0x1b,
12337 /* These overlap and are distinguished by bit16 of the instruction */
12338 BC1F = 0x1c,
12339 BC1T = 0x1d,
12340 BC1ANY2F = 0x1c,
12341 BC1ANY2T = 0x1d,
12342 BC1ANY4F = 0x1e,
12343 BC1ANY4T = 0x1f
12344};
12345
12346/* POOL16A encoding of minor opcode field */
12347
12348enum {
12349 ADDU16 = 0x0,
12350 SUBU16 = 0x1
12351};
12352
12353/* POOL16B encoding of minor opcode field */
12354
12355enum {
12356 SLL16 = 0x0,
12357 SRL16 = 0x1
12358};
12359
12360/* POOL16C encoding of minor opcode field */
12361
12362enum {
12363 NOT16 = 0x00,
12364 XOR16 = 0x04,
12365 AND16 = 0x08,
12366 OR16 = 0x0c,
12367 LWM16 = 0x10,
12368 SWM16 = 0x14,
12369 JR16 = 0x18,
12370 JRC16 = 0x1a,
12371 JALR16 = 0x1c,
12372 JALR16S = 0x1e,
12373 MFHI16 = 0x20,
12374 MFLO16 = 0x24,
12375 BREAK16 = 0x28,
12376 SDBBP16 = 0x2c,
12377 JRADDIUSP = 0x30
12378};
12379
3a1f4268
YK
12380/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12381
12382enum {
12383 R6_NOT16 = 0x00,
12384 R6_AND16 = 0x01,
12385 R6_LWM16 = 0x02,
12386 R6_JRC16 = 0x03,
12387 MOVEP = 0x04,
12388 MOVEP_07 = 0x07,
12389 R6_XOR16 = 0x08,
12390 R6_OR16 = 0x09,
12391 R6_SWM16 = 0x0a,
12392 JALRC16 = 0x0b,
12393 MOVEP_0C = 0x0c,
12394 MOVEP_0F = 0x0f,
12395 JRCADDIUSP = 0x13,
12396 R6_BREAK16 = 0x1b,
12397 R6_SDBBP16 = 0x3b
12398};
12399
3c824109
NF
12400/* POOL16D encoding of minor opcode field */
12401
12402enum {
12403 ADDIUS5 = 0x0,
12404 ADDIUSP = 0x1
12405};
12406
12407/* POOL16E encoding of minor opcode field */
12408
12409enum {
12410 ADDIUR2 = 0x0,
12411 ADDIUR1SP = 0x1
12412};
12413
12414static int mmreg (int r)
12415{
12416 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12417
12418 return map[r];
12419}
12420
12421/* Used for 16-bit store instructions. */
12422static int mmreg2 (int r)
12423{
12424 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12425
12426 return map[r];
12427}
12428
12429#define uMIPS_RD(op) ((op >> 7) & 0x7)
12430#define uMIPS_RS(op) ((op >> 4) & 0x7)
12431#define uMIPS_RS2(op) uMIPS_RS(op)
12432#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12433#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12434#define uMIPS_RS5(op) (op & 0x1f)
12435
12436/* Signed immediate */
12437#define SIMM(op, start, width) \
12438 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12439 << (32-width)) \
12440 >> (32-width))
12441/* Zero-extended immediate */
12442#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12443
d75c135e 12444static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12445{
12446 int rd = mmreg(uMIPS_RD(ctx->opcode));
12447
d75c135e 12448 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12449}
12450
d75c135e 12451static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12452{
12453 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12454 int rd = mmreg(uMIPS_RD(ctx->opcode));
12455 int rs = mmreg(uMIPS_RS(ctx->opcode));
12456
d75c135e 12457 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12458}
12459
d75c135e 12460static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12461{
12462 int encoded = ZIMM(ctx->opcode, 1, 9);
12463 int decoded;
12464
12465 if (encoded <= 1) {
12466 decoded = 256 + encoded;
12467 } else if (encoded <= 255) {
12468 decoded = encoded;
12469 } else if (encoded <= 509) {
12470 decoded = encoded - 512;
12471 } else {
12472 decoded = encoded - 768;
12473 }
12474
d75c135e 12475 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12476}
12477
d75c135e 12478static void gen_addius5(DisasContext *ctx)
3c824109
NF
12479{
12480 int imm = SIMM(ctx->opcode, 1, 4);
12481 int rd = (ctx->opcode >> 5) & 0x1f;
12482
d75c135e 12483 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12484}
12485
d75c135e 12486static void gen_andi16(DisasContext *ctx)
3c824109
NF
12487{
12488 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12489 31, 32, 63, 64, 255, 32768, 65535 };
12490 int rd = mmreg(uMIPS_RD(ctx->opcode));
12491 int rs = mmreg(uMIPS_RS(ctx->opcode));
12492 int encoded = ZIMM(ctx->opcode, 0, 4);
12493
d75c135e 12494 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12495}
12496
12497static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12498 int base, int16_t offset)
12499{
12500 TCGv t0, t1;
12501 TCGv_i32 t2;
12502
12503 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12504 generate_exception(ctx, EXCP_RI);
12505 return;
12506 }
12507
12508 t0 = tcg_temp_new();
12509
12510 gen_base_offset_addr(ctx, t0, base, offset);
12511
12512 t1 = tcg_const_tl(reglist);
12513 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12514
3c824109
NF
12515 save_cpu_state(ctx, 1);
12516 switch (opc) {
12517 case LWM32:
895c2d04 12518 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12519 break;
12520 case SWM32:
895c2d04 12521 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12522 break;
12523#ifdef TARGET_MIPS64
12524 case LDM:
895c2d04 12525 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12526 break;
12527 case SDM:
895c2d04 12528 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12529 break;
6af0bf9c 12530#endif
3c824109 12531 }
3c824109 12532 tcg_temp_free(t0);
33087598 12533 tcg_temp_free(t1);
3c824109
NF
12534 tcg_temp_free_i32(t2);
12535}
6af0bf9c 12536
3c824109 12537
240ce26a 12538static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12539{
3c824109
NF
12540 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12541 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12542
3c824109
NF
12543 switch (((ctx->opcode) >> 4) & 0x3f) {
12544 case NOT16 + 0:
12545 case NOT16 + 1:
12546 case NOT16 + 2:
12547 case NOT16 + 3:
d75c135e 12548 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12549 break;
12550 case XOR16 + 0:
12551 case XOR16 + 1:
12552 case XOR16 + 2:
12553 case XOR16 + 3:
d75c135e 12554 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12555 break;
12556 case AND16 + 0:
12557 case AND16 + 1:
12558 case AND16 + 2:
12559 case AND16 + 3:
d75c135e 12560 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12561 break;
12562 case OR16 + 0:
12563 case OR16 + 1:
12564 case OR16 + 2:
12565 case OR16 + 3:
d75c135e 12566 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12567 break;
12568 case LWM16 + 0:
12569 case LWM16 + 1:
12570 case LWM16 + 2:
12571 case LWM16 + 3:
12572 {
12573 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12574 int offset = ZIMM(ctx->opcode, 0, 4);
12575
12576 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12577 29, offset << 2);
12578 }
12579 break;
12580 case SWM16 + 0:
12581 case SWM16 + 1:
12582 case SWM16 + 2:
12583 case SWM16 + 3:
12584 {
12585 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12586 int offset = ZIMM(ctx->opcode, 0, 4);
12587
12588 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12589 29, offset << 2);
12590 }
12591 break;
12592 case JR16 + 0:
12593 case JR16 + 1:
12594 {
12595 int reg = ctx->opcode & 0x1f;
12596
b231c103 12597 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12598 }
3c824109
NF
12599 break;
12600 case JRC16 + 0:
12601 case JRC16 + 1:
12602 {
12603 int reg = ctx->opcode & 0x1f;
b231c103 12604 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12605 /* Let normal delay slot handling in our caller take us
12606 to the branch target. */
12607 }
12608 break;
12609 case JALR16 + 0:
12610 case JALR16 + 1:
b231c103
YK
12611 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12612 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12613 break;
3c824109
NF
12614 case JALR16S + 0:
12615 case JALR16S + 1:
b231c103
YK
12616 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12617 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12618 break;
12619 case MFHI16 + 0:
12620 case MFHI16 + 1:
26135ead 12621 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12622 break;
12623 case MFLO16 + 0:
12624 case MFLO16 + 1:
26135ead 12625 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12626 break;
12627 case BREAK16:
12628 generate_exception(ctx, EXCP_BREAK);
12629 break;
12630 case SDBBP16:
3b3c1694
LA
12631 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12632 gen_helper_do_semihosting(cpu_env);
12633 } else {
12634 /* XXX: not clear which exception should be raised
12635 * when in debug mode...
12636 */
12637 check_insn(ctx, ISA_MIPS32);
12638 generate_exception(ctx, EXCP_DBp);
12639 }
3c824109
NF
12640 break;
12641 case JRADDIUSP + 0:
12642 case JRADDIUSP + 1:
12643 {
12644 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12645 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12646 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12647 /* Let normal delay slot handling in our caller take us
12648 to the branch target. */
12649 }
12650 break;
12651 default:
12652 generate_exception(ctx, EXCP_RI);
12653 break;
12654 }
12655}
12656
ed7ce6c0
YK
12657static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12658 int enc_rs)
12659{
12660 int rd, rs, re, rt;
12661 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12662 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12663 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12664 rd = rd_enc[enc_dest];
12665 re = re_enc[enc_dest];
12666 rs = rs_rt_enc[enc_rs];
12667 rt = rs_rt_enc[enc_rt];
12668 if (rs) {
12669 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12670 } else {
12671 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12672 }
12673 if (rt) {
12674 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12675 } else {
12676 tcg_gen_movi_tl(cpu_gpr[re], 0);
12677 }
12678}
12679
12680static void gen_pool16c_r6_insn(DisasContext *ctx)
12681{
12682 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12683 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12684
12685 switch (ctx->opcode & 0xf) {
12686 case R6_NOT16:
12687 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12688 break;
12689 case R6_AND16:
12690 gen_logic(ctx, OPC_AND, rt, rt, rs);
12691 break;
12692 case R6_LWM16:
12693 {
12694 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12695 int offset = extract32(ctx->opcode, 4, 4);
12696 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12697 }
12698 break;
12699 case R6_JRC16: /* JRCADDIUSP */
12700 if ((ctx->opcode >> 4) & 1) {
12701 /* JRCADDIUSP */
12702 int imm = extract32(ctx->opcode, 5, 5);
12703 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12704 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12705 } else {
12706 /* JRC16 */
12707 int rs = extract32(ctx->opcode, 5, 5);
12708 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12709 }
12710 break;
12711 case MOVEP ... MOVEP_07:
12712 case MOVEP_0C ... MOVEP_0F:
12713 {
12714 int enc_dest = uMIPS_RD(ctx->opcode);
12715 int enc_rt = uMIPS_RS2(ctx->opcode);
12716 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12717 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12718 }
12719 break;
12720 case R6_XOR16:
12721 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12722 break;
12723 case R6_OR16:
12724 gen_logic(ctx, OPC_OR, rt, rt, rs);
12725 break;
12726 case R6_SWM16:
12727 {
12728 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12729 int offset = extract32(ctx->opcode, 4, 4);
12730 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12731 }
12732 break;
12733 case JALRC16: /* BREAK16, SDBBP16 */
12734 switch (ctx->opcode & 0x3f) {
12735 case JALRC16:
12736 case JALRC16 + 0x20:
12737 /* JALRC16 */
12738 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12739 31, 0, 0);
12740 break;
12741 case R6_BREAK16:
12742 /* BREAK16 */
12743 generate_exception(ctx, EXCP_BREAK);
12744 break;
12745 case R6_SDBBP16:
12746 /* SDBBP16 */
060ebfef
LA
12747 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12748 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 12749 } else {
060ebfef
LA
12750 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12751 generate_exception(ctx, EXCP_RI);
12752 } else {
12753 generate_exception(ctx, EXCP_DBp);
12754 }
ed7ce6c0
YK
12755 }
12756 break;
12757 }
12758 break;
12759 default:
12760 generate_exception(ctx, EXCP_RI);
12761 break;
12762 }
12763}
12764
3c824109
NF
12765static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12766{
12767 TCGv t0 = tcg_temp_new();
12768 TCGv t1 = tcg_temp_new();
12769
12770 gen_load_gpr(t0, base);
12771
12772 if (index != 0) {
12773 gen_load_gpr(t1, index);
12774 tcg_gen_shli_tl(t1, t1, 2);
12775 gen_op_addr_add(ctx, t0, t1, t0);
12776 }
12777
5f68f5ae 12778 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12779 gen_store_gpr(t1, rd);
12780
12781 tcg_temp_free(t0);
12782 tcg_temp_free(t1);
12783}
12784
12785static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12786 int base, int16_t offset)
12787{
3c824109
NF
12788 TCGv t0, t1;
12789
36c6711b 12790 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12791 generate_exception(ctx, EXCP_RI);
d796321b
FB
12792 return;
12793 }
12794
3c824109
NF
12795 t0 = tcg_temp_new();
12796 t1 = tcg_temp_new();
8e9ade68 12797
3c824109
NF
12798 gen_base_offset_addr(ctx, t0, base, offset);
12799
12800 switch (opc) {
12801 case LWP:
36c6711b
EJ
12802 if (rd == base) {
12803 generate_exception(ctx, EXCP_RI);
12804 return;
12805 }
5f68f5ae 12806 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12807 gen_store_gpr(t1, rd);
12808 tcg_gen_movi_tl(t1, 4);
12809 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12810 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 12811 gen_store_gpr(t1, rd+1);
3c824109
NF
12812 break;
12813 case SWP:
3c824109 12814 gen_load_gpr(t1, rd);
5f68f5ae 12815 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12816 tcg_gen_movi_tl(t1, 4);
12817 gen_op_addr_add(ctx, t0, t0, t1);
12818 gen_load_gpr(t1, rd+1);
5f68f5ae 12819 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12820 break;
12821#ifdef TARGET_MIPS64
12822 case LDP:
36c6711b
EJ
12823 if (rd == base) {
12824 generate_exception(ctx, EXCP_RI);
12825 return;
12826 }
5f68f5ae 12827 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12828 gen_store_gpr(t1, rd);
12829 tcg_gen_movi_tl(t1, 8);
12830 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12831 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 12832 gen_store_gpr(t1, rd+1);
3c824109
NF
12833 break;
12834 case SDP:
3c824109 12835 gen_load_gpr(t1, rd);
5f68f5ae 12836 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12837 tcg_gen_movi_tl(t1, 8);
12838 gen_op_addr_add(ctx, t0, t0, t1);
12839 gen_load_gpr(t1, rd+1);
5f68f5ae 12840 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12841 break;
12842#endif
6af0bf9c 12843 }
3c824109
NF
12844 tcg_temp_free(t0);
12845 tcg_temp_free(t1);
12846}
618b0fe9 12847
240ce26a 12848static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12849{
12850 int extension = (ctx->opcode >> 6) & 0x3f;
12851 int minor = (ctx->opcode >> 12) & 0xf;
12852 uint32_t mips32_op;
12853
12854 switch (extension) {
12855 case TEQ:
12856 mips32_op = OPC_TEQ;
12857 goto do_trap;
12858 case TGE:
12859 mips32_op = OPC_TGE;
12860 goto do_trap;
12861 case TGEU:
12862 mips32_op = OPC_TGEU;
12863 goto do_trap;
12864 case TLT:
12865 mips32_op = OPC_TLT;
12866 goto do_trap;
12867 case TLTU:
12868 mips32_op = OPC_TLTU;
12869 goto do_trap;
12870 case TNE:
12871 mips32_op = OPC_TNE;
12872 do_trap:
12873 gen_trap(ctx, mips32_op, rs, rt, -1);
12874 break;
12875#ifndef CONFIG_USER_ONLY
12876 case MFC0:
12877 case MFC0 + 32:
2e15497c 12878 check_cp0_enabled(ctx);
3c824109
NF
12879 if (rt == 0) {
12880 /* Treat as NOP. */
12881 break;
12882 }
d75c135e 12883 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12884 break;
12885 case MTC0:
12886 case MTC0 + 32:
2e15497c 12887 check_cp0_enabled(ctx);
3c824109
NF
12888 {
12889 TCGv t0 = tcg_temp_new();
618b0fe9 12890
3c824109 12891 gen_load_gpr(t0, rt);
d75c135e 12892 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12893 tcg_temp_free(t0);
12894 }
12895 break;
12896#endif
a1fc6246
LA
12897 case 0x2a:
12898 switch (minor & 3) {
12899 case MADD_ACC:
12900 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12901 break;
12902 case MADDU_ACC:
12903 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12904 break;
12905 case MSUB_ACC:
12906 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12907 break;
12908 case MSUBU_ACC:
12909 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12910 break;
12911 default:
12912 goto pool32axf_invalid;
12913 }
12914 break;
12915 case 0x32:
12916 switch (minor & 3) {
12917 case MULT_ACC:
12918 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12919 break;
12920 case MULTU_ACC:
12921 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12922 break;
12923 default:
12924 goto pool32axf_invalid;
12925 }
12926 break;
3c824109
NF
12927 case 0x2c:
12928 switch (minor) {
e0332095
YK
12929 case BITSWAP:
12930 check_insn(ctx, ISA_MIPS32R6);
12931 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
12932 break;
3c824109
NF
12933 case SEB:
12934 gen_bshfl(ctx, OPC_SEB, rs, rt);
12935 break;
12936 case SEH:
12937 gen_bshfl(ctx, OPC_SEH, rs, rt);
12938 break;
12939 case CLO:
12940 mips32_op = OPC_CLO;
12941 goto do_cl;
12942 case CLZ:
12943 mips32_op = OPC_CLZ;
12944 do_cl:
d75c135e 12945 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12946 gen_cl(ctx, mips32_op, rt, rs);
12947 break;
12948 case RDHWR:
d75c135e 12949 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12950 break;
12951 case WSBH:
12952 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12953 break;
12954 case MULT:
9e8f441a 12955 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12956 mips32_op = OPC_MULT;
26135ead 12957 goto do_mul;
3c824109 12958 case MULTU:
9e8f441a 12959 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12960 mips32_op = OPC_MULTU;
26135ead 12961 goto do_mul;
3c824109 12962 case DIV:
9e8f441a 12963 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12964 mips32_op = OPC_DIV;
26135ead 12965 goto do_div;
3c824109 12966 case DIVU:
9e8f441a 12967 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12968 mips32_op = OPC_DIVU;
26135ead
RS
12969 goto do_div;
12970 do_div:
12971 check_insn(ctx, ISA_MIPS32);
12972 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12973 break;
3c824109 12974 case MADD:
9e8f441a 12975 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12976 mips32_op = OPC_MADD;
26135ead 12977 goto do_mul;
3c824109 12978 case MADDU:
9e8f441a 12979 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12980 mips32_op = OPC_MADDU;
26135ead 12981 goto do_mul;
3c824109 12982 case MSUB:
9e8f441a 12983 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12984 mips32_op = OPC_MSUB;
26135ead 12985 goto do_mul;
3c824109 12986 case MSUBU:
9e8f441a 12987 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 12988 mips32_op = OPC_MSUBU;
26135ead 12989 do_mul:
d75c135e 12990 check_insn(ctx, ISA_MIPS32);
a1fc6246 12991 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12992 break;
12993 default:
12994 goto pool32axf_invalid;
12995 }
12996 break;
12997 case 0x34:
12998 switch (minor) {
12999 case MFC2:
13000 case MTC2:
13001 case MFHC2:
13002 case MTHC2:
13003 case CFC2:
13004 case CTC2:
13005 generate_exception_err(ctx, EXCP_CpU, 2);
13006 break;
13007 default:
13008 goto pool32axf_invalid;
13009 }
13010 break;
13011 case 0x3c:
13012 switch (minor) {
65935f07
YK
13013 case JALR: /* JALRC */
13014 case JALR_HB: /* JALRC_HB */
13015 if (ctx->insn_flags & ISA_MIPS32R6) {
13016 /* JALRC, JALRC_HB */
13017 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13018 } else {
13019 /* JALR, JALR_HB */
13020 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13021 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13022 }
3c824109
NF
13023 break;
13024 case JALRS:
13025 case JALRS_HB:
9e8f441a 13026 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13027 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13028 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13029 break;
13030 default:
13031 goto pool32axf_invalid;
13032 }
13033 break;
13034 case 0x05:
13035 switch (minor) {
13036 case RDPGPR:
2e15497c 13037 check_cp0_enabled(ctx);
d75c135e 13038 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13039 gen_load_srsgpr(rs, rt);
3c824109
NF
13040 break;
13041 case WRPGPR:
2e15497c 13042 check_cp0_enabled(ctx);
d75c135e 13043 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13044 gen_store_srsgpr(rs, rt);
3c824109
NF
13045 break;
13046 default:
13047 goto pool32axf_invalid;
13048 }
13049 break;
13050#ifndef CONFIG_USER_ONLY
13051 case 0x0d:
13052 switch (minor) {
13053 case TLBP:
13054 mips32_op = OPC_TLBP;
13055 goto do_cp0;
13056 case TLBR:
13057 mips32_op = OPC_TLBR;
13058 goto do_cp0;
13059 case TLBWI:
13060 mips32_op = OPC_TLBWI;
13061 goto do_cp0;
13062 case TLBWR:
13063 mips32_op = OPC_TLBWR;
13064 goto do_cp0;
e60ec063
YK
13065 case TLBINV:
13066 mips32_op = OPC_TLBINV;
13067 goto do_cp0;
13068 case TLBINVF:
13069 mips32_op = OPC_TLBINVF;
13070 goto do_cp0;
3c824109
NF
13071 case WAIT:
13072 mips32_op = OPC_WAIT;
13073 goto do_cp0;
13074 case DERET:
13075 mips32_op = OPC_DERET;
13076 goto do_cp0;
13077 case ERET:
13078 mips32_op = OPC_ERET;
13079 do_cp0:
13080 gen_cp0(env, ctx, mips32_op, rt, rs);
13081 break;
13082 default:
13083 goto pool32axf_invalid;
13084 }
13085 break;
13086 case 0x1d:
13087 switch (minor) {
13088 case DI:
2e15497c 13089 check_cp0_enabled(ctx);
3c824109
NF
13090 {
13091 TCGv t0 = tcg_temp_new();
13092
13093 save_cpu_state(ctx, 1);
895c2d04 13094 gen_helper_di(t0, cpu_env);
3c824109
NF
13095 gen_store_gpr(t0, rs);
13096 /* Stop translation as we may have switched the execution mode */
13097 ctx->bstate = BS_STOP;
13098 tcg_temp_free(t0);
13099 }
13100 break;
13101 case EI:
2e15497c 13102 check_cp0_enabled(ctx);
3c824109
NF
13103 {
13104 TCGv t0 = tcg_temp_new();
13105
13106 save_cpu_state(ctx, 1);
895c2d04 13107 gen_helper_ei(t0, cpu_env);
3c824109
NF
13108 gen_store_gpr(t0, rs);
13109 /* Stop translation as we may have switched the execution mode */
13110 ctx->bstate = BS_STOP;
13111 tcg_temp_free(t0);
13112 }
13113 break;
13114 default:
13115 goto pool32axf_invalid;
13116 }
13117 break;
13118#endif
13119 case 0x2d:
13120 switch (minor) {
13121 case SYNC:
13122 /* NOP */
13123 break;
13124 case SYSCALL:
13125 generate_exception(ctx, EXCP_SYSCALL);
13126 ctx->bstate = BS_STOP;
13127 break;
13128 case SDBBP:
3b3c1694
LA
13129 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13130 gen_helper_do_semihosting(cpu_env);
13131 } else {
13132 check_insn(ctx, ISA_MIPS32);
e0332095
YK
13133 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13134 generate_exception(ctx, EXCP_RI);
13135 } else {
13136 generate_exception(ctx, EXCP_DBp);
13137 }
3b3c1694 13138 }
3c824109
NF
13139 break;
13140 default:
13141 goto pool32axf_invalid;
13142 }
13143 break;
a1fc6246 13144 case 0x01:
26135ead 13145 switch (minor & 3) {
a1fc6246 13146 case MFHI_ACC:
26135ead 13147 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13148 break;
a1fc6246 13149 case MFLO_ACC:
26135ead 13150 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13151 break;
a1fc6246 13152 case MTHI_ACC:
26135ead 13153 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13154 break;
a1fc6246 13155 case MTLO_ACC:
26135ead 13156 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13157 break;
13158 default:
13159 goto pool32axf_invalid;
13160 }
13161 break;
a1fc6246 13162 case 0x35:
9e8f441a 13163 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13164 switch (minor) {
13165 case MFHI32:
13166 gen_HILO(ctx, OPC_MFHI, 0, rs);
13167 break;
13168 case MFLO32:
13169 gen_HILO(ctx, OPC_MFLO, 0, rs);
13170 break;
13171 case MTHI32:
13172 gen_HILO(ctx, OPC_MTHI, 0, rs);
13173 break;
13174 case MTLO32:
13175 gen_HILO(ctx, OPC_MTLO, 0, rs);
13176 break;
13177 default:
13178 goto pool32axf_invalid;
13179 }
13180 break;
3c824109
NF
13181 default:
13182 pool32axf_invalid:
13183 MIPS_INVAL("pool32axf");
13184 generate_exception(ctx, EXCP_RI);
13185 break;
13186 }
13187}
13188
13189/* Values for microMIPS fmt field. Variable-width, depending on which
13190 formats the instruction supports. */
13191
13192enum {
13193 FMT_SD_S = 0,
13194 FMT_SD_D = 1,
13195
13196 FMT_SDPS_S = 0,
13197 FMT_SDPS_D = 1,
13198 FMT_SDPS_PS = 2,
13199
13200 FMT_SWL_S = 0,
13201 FMT_SWL_W = 1,
13202 FMT_SWL_L = 2,
13203
13204 FMT_DWL_D = 0,
13205 FMT_DWL_W = 1,
13206 FMT_DWL_L = 2
13207};
13208
d75c135e 13209static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13210{
13211 int extension = (ctx->opcode >> 6) & 0x3ff;
13212 uint32_t mips32_op;
13213
13214#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13215#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13216#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13217
13218 switch (extension) {
13219 case FLOAT_1BIT_FMT(CFC1, 0):
13220 mips32_op = OPC_CFC1;
13221 goto do_cp1;
13222 case FLOAT_1BIT_FMT(CTC1, 0):
13223 mips32_op = OPC_CTC1;
13224 goto do_cp1;
13225 case FLOAT_1BIT_FMT(MFC1, 0):
13226 mips32_op = OPC_MFC1;
13227 goto do_cp1;
13228 case FLOAT_1BIT_FMT(MTC1, 0):
13229 mips32_op = OPC_MTC1;
13230 goto do_cp1;
13231 case FLOAT_1BIT_FMT(MFHC1, 0):
13232 mips32_op = OPC_MFHC1;
13233 goto do_cp1;
13234 case FLOAT_1BIT_FMT(MTHC1, 0):
13235 mips32_op = OPC_MTHC1;
13236 do_cp1:
13237 gen_cp1(ctx, mips32_op, rt, rs);
13238 break;
13239
13240 /* Reciprocal square root */
13241 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13242 mips32_op = OPC_RSQRT_S;
13243 goto do_unaryfp;
13244 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13245 mips32_op = OPC_RSQRT_D;
13246 goto do_unaryfp;
13247
13248 /* Square root */
13249 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13250 mips32_op = OPC_SQRT_S;
13251 goto do_unaryfp;
13252 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13253 mips32_op = OPC_SQRT_D;
13254 goto do_unaryfp;
13255
13256 /* Reciprocal */
13257 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13258 mips32_op = OPC_RECIP_S;
13259 goto do_unaryfp;
13260 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13261 mips32_op = OPC_RECIP_D;
13262 goto do_unaryfp;
13263
13264 /* Floor */
13265 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13266 mips32_op = OPC_FLOOR_L_S;
13267 goto do_unaryfp;
13268 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13269 mips32_op = OPC_FLOOR_L_D;
13270 goto do_unaryfp;
13271 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13272 mips32_op = OPC_FLOOR_W_S;
13273 goto do_unaryfp;
13274 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13275 mips32_op = OPC_FLOOR_W_D;
13276 goto do_unaryfp;
13277
13278 /* Ceiling */
13279 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13280 mips32_op = OPC_CEIL_L_S;
13281 goto do_unaryfp;
13282 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13283 mips32_op = OPC_CEIL_L_D;
13284 goto do_unaryfp;
13285 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13286 mips32_op = OPC_CEIL_W_S;
13287 goto do_unaryfp;
13288 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13289 mips32_op = OPC_CEIL_W_D;
13290 goto do_unaryfp;
13291
13292 /* Truncation */
13293 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13294 mips32_op = OPC_TRUNC_L_S;
13295 goto do_unaryfp;
13296 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13297 mips32_op = OPC_TRUNC_L_D;
13298 goto do_unaryfp;
13299 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13300 mips32_op = OPC_TRUNC_W_S;
13301 goto do_unaryfp;
13302 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13303 mips32_op = OPC_TRUNC_W_D;
13304 goto do_unaryfp;
13305
13306 /* Round */
13307 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13308 mips32_op = OPC_ROUND_L_S;
13309 goto do_unaryfp;
13310 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13311 mips32_op = OPC_ROUND_L_D;
13312 goto do_unaryfp;
13313 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13314 mips32_op = OPC_ROUND_W_S;
13315 goto do_unaryfp;
13316 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13317 mips32_op = OPC_ROUND_W_D;
13318 goto do_unaryfp;
13319
13320 /* Integer to floating-point conversion */
13321 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13322 mips32_op = OPC_CVT_L_S;
13323 goto do_unaryfp;
13324 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13325 mips32_op = OPC_CVT_L_D;
13326 goto do_unaryfp;
13327 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13328 mips32_op = OPC_CVT_W_S;
13329 goto do_unaryfp;
13330 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13331 mips32_op = OPC_CVT_W_D;
13332 goto do_unaryfp;
13333
13334 /* Paired-foo conversions */
13335 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13336 mips32_op = OPC_CVT_S_PL;
13337 goto do_unaryfp;
13338 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13339 mips32_op = OPC_CVT_S_PU;
13340 goto do_unaryfp;
13341 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13342 mips32_op = OPC_CVT_PW_PS;
13343 goto do_unaryfp;
13344 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13345 mips32_op = OPC_CVT_PS_PW;
13346 goto do_unaryfp;
13347
13348 /* Floating-point moves */
13349 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13350 mips32_op = OPC_MOV_S;
13351 goto do_unaryfp;
13352 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13353 mips32_op = OPC_MOV_D;
13354 goto do_unaryfp;
13355 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13356 mips32_op = OPC_MOV_PS;
13357 goto do_unaryfp;
13358
13359 /* Absolute value */
13360 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13361 mips32_op = OPC_ABS_S;
13362 goto do_unaryfp;
13363 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13364 mips32_op = OPC_ABS_D;
13365 goto do_unaryfp;
13366 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13367 mips32_op = OPC_ABS_PS;
13368 goto do_unaryfp;
13369
13370 /* Negation */
13371 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13372 mips32_op = OPC_NEG_S;
13373 goto do_unaryfp;
13374 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13375 mips32_op = OPC_NEG_D;
13376 goto do_unaryfp;
13377 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13378 mips32_op = OPC_NEG_PS;
13379 goto do_unaryfp;
13380
13381 /* Reciprocal square root step */
13382 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13383 mips32_op = OPC_RSQRT1_S;
13384 goto do_unaryfp;
13385 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13386 mips32_op = OPC_RSQRT1_D;
13387 goto do_unaryfp;
13388 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13389 mips32_op = OPC_RSQRT1_PS;
13390 goto do_unaryfp;
13391
13392 /* Reciprocal step */
13393 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13394 mips32_op = OPC_RECIP1_S;
13395 goto do_unaryfp;
13396 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13397 mips32_op = OPC_RECIP1_S;
13398 goto do_unaryfp;
13399 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13400 mips32_op = OPC_RECIP1_PS;
13401 goto do_unaryfp;
13402
13403 /* Conversions from double */
13404 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13405 mips32_op = OPC_CVT_D_S;
13406 goto do_unaryfp;
13407 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13408 mips32_op = OPC_CVT_D_W;
13409 goto do_unaryfp;
13410 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13411 mips32_op = OPC_CVT_D_L;
13412 goto do_unaryfp;
13413
13414 /* Conversions from single */
13415 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13416 mips32_op = OPC_CVT_S_D;
13417 goto do_unaryfp;
13418 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13419 mips32_op = OPC_CVT_S_W;
13420 goto do_unaryfp;
13421 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13422 mips32_op = OPC_CVT_S_L;
13423 do_unaryfp:
13424 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13425 break;
13426
13427 /* Conditional moves on floating-point codes */
13428 case COND_FLOAT_MOV(MOVT, 0):
13429 case COND_FLOAT_MOV(MOVT, 1):
13430 case COND_FLOAT_MOV(MOVT, 2):
13431 case COND_FLOAT_MOV(MOVT, 3):
13432 case COND_FLOAT_MOV(MOVT, 4):
13433 case COND_FLOAT_MOV(MOVT, 5):
13434 case COND_FLOAT_MOV(MOVT, 6):
13435 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13436 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13437 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13438 break;
13439 case COND_FLOAT_MOV(MOVF, 0):
13440 case COND_FLOAT_MOV(MOVF, 1):
13441 case COND_FLOAT_MOV(MOVF, 2):
13442 case COND_FLOAT_MOV(MOVF, 3):
13443 case COND_FLOAT_MOV(MOVF, 4):
13444 case COND_FLOAT_MOV(MOVF, 5):
13445 case COND_FLOAT_MOV(MOVF, 6):
13446 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13447 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13448 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13449 break;
13450 default:
13451 MIPS_INVAL("pool32fxf");
13452 generate_exception(ctx, EXCP_RI);
13453 break;
13454 }
13455}
13456
f60eeb0c 13457static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13458{
13459 int32_t offset;
13460 uint16_t insn;
13461 int rt, rs, rd, rr;
13462 int16_t imm;
13463 uint32_t op, minor, mips32_op;
13464 uint32_t cond, fmt, cc;
13465
895c2d04 13466 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13467 ctx->opcode = (ctx->opcode << 16) | insn;
13468
13469 rt = (ctx->opcode >> 21) & 0x1f;
13470 rs = (ctx->opcode >> 16) & 0x1f;
13471 rd = (ctx->opcode >> 11) & 0x1f;
13472 rr = (ctx->opcode >> 6) & 0x1f;
13473 imm = (int16_t) ctx->opcode;
13474
13475 op = (ctx->opcode >> 26) & 0x3f;
13476 switch (op) {
13477 case POOL32A:
13478 minor = ctx->opcode & 0x3f;
13479 switch (minor) {
13480 case 0x00:
13481 minor = (ctx->opcode >> 6) & 0xf;
13482 switch (minor) {
13483 case SLL32:
13484 mips32_op = OPC_SLL;
13485 goto do_shifti;
13486 case SRA:
13487 mips32_op = OPC_SRA;
13488 goto do_shifti;
13489 case SRL32:
13490 mips32_op = OPC_SRL;
13491 goto do_shifti;
13492 case ROTR:
13493 mips32_op = OPC_ROTR;
13494 do_shifti:
d75c135e 13495 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13496 break;
e0332095
YK
13497 case SELEQZ:
13498 check_insn(ctx, ISA_MIPS32R6);
13499 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13500 break;
13501 case SELNEZ:
13502 check_insn(ctx, ISA_MIPS32R6);
13503 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13504 break;
3c824109
NF
13505 default:
13506 goto pool32a_invalid;
13507 }
13508 break;
13509 case 0x10:
13510 minor = (ctx->opcode >> 6) & 0xf;
13511 switch (minor) {
13512 /* Arithmetic */
13513 case ADD:
13514 mips32_op = OPC_ADD;
13515 goto do_arith;
13516 case ADDU32:
13517 mips32_op = OPC_ADDU;
13518 goto do_arith;
13519 case SUB:
13520 mips32_op = OPC_SUB;
13521 goto do_arith;
13522 case SUBU32:
13523 mips32_op = OPC_SUBU;
13524 goto do_arith;
13525 case MUL:
9e8f441a 13526 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13527 mips32_op = OPC_MUL;
13528 do_arith:
d75c135e 13529 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13530 break;
13531 /* Shifts */
13532 case SLLV:
13533 mips32_op = OPC_SLLV;
13534 goto do_shift;
13535 case SRLV:
13536 mips32_op = OPC_SRLV;
13537 goto do_shift;
13538 case SRAV:
13539 mips32_op = OPC_SRAV;
13540 goto do_shift;
13541 case ROTRV:
13542 mips32_op = OPC_ROTRV;
13543 do_shift:
d75c135e 13544 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13545 break;
13546 /* Logical operations */
13547 case AND:
13548 mips32_op = OPC_AND;
13549 goto do_logic;
13550 case OR32:
13551 mips32_op = OPC_OR;
13552 goto do_logic;
13553 case NOR:
13554 mips32_op = OPC_NOR;
13555 goto do_logic;
13556 case XOR32:
13557 mips32_op = OPC_XOR;
13558 do_logic:
d75c135e 13559 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13560 break;
13561 /* Set less than */
13562 case SLT:
13563 mips32_op = OPC_SLT;
13564 goto do_slt;
13565 case SLTU:
13566 mips32_op = OPC_SLTU;
13567 do_slt:
d75c135e 13568 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13569 break;
13570 default:
13571 goto pool32a_invalid;
13572 }
13573 break;
13574 case 0x18:
13575 minor = (ctx->opcode >> 6) & 0xf;
13576 switch (minor) {
13577 /* Conditional moves */
e0332095
YK
13578 case MOVN: /* MUL */
13579 if (ctx->insn_flags & ISA_MIPS32R6) {
13580 /* MUL */
13581 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13582 } else {
13583 /* MOVN */
13584 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13585 }
13586 break;
13587 case MOVZ: /* MUH */
13588 if (ctx->insn_flags & ISA_MIPS32R6) {
13589 /* MUH */
13590 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13591 } else {
13592 /* MOVZ */
13593 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13594 }
13595 break;
13596 case MULU:
13597 check_insn(ctx, ISA_MIPS32R6);
13598 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13599 break;
13600 case MUHU:
13601 check_insn(ctx, ISA_MIPS32R6);
13602 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13603 break;
13604 case LWXS: /* DIV */
13605 if (ctx->insn_flags & ISA_MIPS32R6) {
13606 /* DIV */
13607 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13608 } else {
13609 /* LWXS */
13610 gen_ldxs(ctx, rs, rt, rd);
13611 }
13612 break;
13613 case MOD:
13614 check_insn(ctx, ISA_MIPS32R6);
13615 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13616 break;
13617 case R6_DIVU:
13618 check_insn(ctx, ISA_MIPS32R6);
13619 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 13620 break;
e0332095
YK
13621 case MODU:
13622 check_insn(ctx, ISA_MIPS32R6);
13623 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
13624 break;
13625 default:
13626 goto pool32a_invalid;
13627 }
13628 break;
13629 case INS:
13630 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13631 return;
e0332095
YK
13632 case LSA:
13633 check_insn(ctx, ISA_MIPS32R6);
13634 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13635 extract32(ctx->opcode, 9, 2));
13636 break;
13637 case ALIGN:
13638 check_insn(ctx, ISA_MIPS32R6);
13639 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13640 extract32(ctx->opcode, 9, 2));
13641 break;
3c824109
NF
13642 case EXT:
13643 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13644 return;
13645 case POOL32AXF:
240ce26a 13646 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13647 break;
13648 case 0x07:
13649 generate_exception(ctx, EXCP_BREAK);
13650 break;
13651 default:
13652 pool32a_invalid:
13653 MIPS_INVAL("pool32a");
13654 generate_exception(ctx, EXCP_RI);
13655 break;
13656 }
13657 break;
13658 case POOL32B:
13659 minor = (ctx->opcode >> 12) & 0xf;
13660 switch (minor) {
13661 case CACHE:
2e15497c 13662 check_cp0_enabled(ctx);
3c824109
NF
13663 /* Treat as no-op. */
13664 break;
13665 case LWC2:
13666 case SWC2:
13667 /* COP2: Not implemented. */
13668 generate_exception_err(ctx, EXCP_CpU, 2);
13669 break;
3c824109
NF
13670#ifdef TARGET_MIPS64
13671 case LDP:
13672 case SDP:
d9224450
MR
13673 check_insn(ctx, ISA_MIPS3);
13674 check_mips_64(ctx);
13675 /* Fallthrough */
3c824109 13676#endif
d9224450
MR
13677 case LWP:
13678 case SWP:
3c824109
NF
13679 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13680 break;
3c824109
NF
13681#ifdef TARGET_MIPS64
13682 case LDM:
13683 case SDM:
d9224450
MR
13684 check_insn(ctx, ISA_MIPS3);
13685 check_mips_64(ctx);
13686 /* Fallthrough */
3c824109 13687#endif
d9224450
MR
13688 case LWM32:
13689 case SWM32:
3c824109
NF
13690 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13691 break;
13692 default:
13693 MIPS_INVAL("pool32b");
13694 generate_exception(ctx, EXCP_RI);
13695 break;
13696 }
13697 break;
13698 case POOL32F:
5ab5c041 13699 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13700 minor = ctx->opcode & 0x3f;
13701 check_cp1_enabled(ctx);
13702 switch (minor) {
13703 case ALNV_PS:
9e8f441a 13704 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13705 mips32_op = OPC_ALNV_PS;
13706 goto do_madd;
13707 case MADD_S:
9e8f441a 13708 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13709 mips32_op = OPC_MADD_S;
13710 goto do_madd;
13711 case MADD_D:
9e8f441a 13712 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13713 mips32_op = OPC_MADD_D;
13714 goto do_madd;
13715 case MADD_PS:
9e8f441a 13716 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13717 mips32_op = OPC_MADD_PS;
13718 goto do_madd;
13719 case MSUB_S:
9e8f441a 13720 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13721 mips32_op = OPC_MSUB_S;
13722 goto do_madd;
13723 case MSUB_D:
9e8f441a 13724 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13725 mips32_op = OPC_MSUB_D;
13726 goto do_madd;
13727 case MSUB_PS:
9e8f441a 13728 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13729 mips32_op = OPC_MSUB_PS;
13730 goto do_madd;
13731 case NMADD_S:
9e8f441a 13732 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13733 mips32_op = OPC_NMADD_S;
13734 goto do_madd;
13735 case NMADD_D:
9e8f441a 13736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13737 mips32_op = OPC_NMADD_D;
13738 goto do_madd;
13739 case NMADD_PS:
9e8f441a 13740 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13741 mips32_op = OPC_NMADD_PS;
13742 goto do_madd;
13743 case NMSUB_S:
9e8f441a 13744 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13745 mips32_op = OPC_NMSUB_S;
13746 goto do_madd;
13747 case NMSUB_D:
9e8f441a 13748 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13749 mips32_op = OPC_NMSUB_D;
13750 goto do_madd;
13751 case NMSUB_PS:
9e8f441a 13752 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13753 mips32_op = OPC_NMSUB_PS;
13754 do_madd:
13755 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13756 break;
13757 case CABS_COND_FMT:
9e8f441a 13758 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13759 cond = (ctx->opcode >> 6) & 0xf;
13760 cc = (ctx->opcode >> 13) & 0x7;
13761 fmt = (ctx->opcode >> 10) & 0x3;
13762 switch (fmt) {
13763 case 0x0:
13764 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13765 break;
13766 case 0x1:
13767 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13768 break;
13769 case 0x2:
13770 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13771 break;
13772 default:
13773 goto pool32f_invalid;
13774 }
13775 break;
13776 case C_COND_FMT:
9e8f441a 13777 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13778 cond = (ctx->opcode >> 6) & 0xf;
13779 cc = (ctx->opcode >> 13) & 0x7;
13780 fmt = (ctx->opcode >> 10) & 0x3;
13781 switch (fmt) {
13782 case 0x0:
13783 gen_cmp_s(ctx, cond, rt, rs, cc);
13784 break;
13785 case 0x1:
13786 gen_cmp_d(ctx, cond, rt, rs, cc);
13787 break;
13788 case 0x2:
13789 gen_cmp_ps(ctx, cond, rt, rs, cc);
13790 break;
13791 default:
13792 goto pool32f_invalid;
13793 }
13794 break;
2a24a7ba
YK
13795 case CMP_CONDN_S:
13796 check_insn(ctx, ISA_MIPS32R6);
13797 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13798 break;
13799 case CMP_CONDN_D:
13800 check_insn(ctx, ISA_MIPS32R6);
13801 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13802 break;
3c824109 13803 case POOL32FXF:
d75c135e 13804 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13805 break;
13806 case 0x00:
13807 /* PLL foo */
13808 switch ((ctx->opcode >> 6) & 0x7) {
13809 case PLL_PS:
13810 mips32_op = OPC_PLL_PS;
13811 goto do_ps;
13812 case PLU_PS:
13813 mips32_op = OPC_PLU_PS;
13814 goto do_ps;
13815 case PUL_PS:
13816 mips32_op = OPC_PUL_PS;
13817 goto do_ps;
13818 case PUU_PS:
13819 mips32_op = OPC_PUU_PS;
13820 goto do_ps;
13821 case CVT_PS_S:
9e8f441a 13822 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13823 mips32_op = OPC_CVT_PS_S;
13824 do_ps:
13825 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13826 break;
13827 default:
13828 goto pool32f_invalid;
13829 }
13830 break;
2a24a7ba
YK
13831 case MIN_FMT:
13832 check_insn(ctx, ISA_MIPS32R6);
13833 switch ((ctx->opcode >> 9) & 0x3) {
13834 case FMT_SDPS_S:
13835 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13836 break;
13837 case FMT_SDPS_D:
13838 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13839 break;
13840 default:
13841 goto pool32f_invalid;
13842 }
13843 break;
3c824109
NF
13844 case 0x08:
13845 /* [LS][WDU]XC1 */
13846 switch ((ctx->opcode >> 6) & 0x7) {
13847 case LWXC1:
9e8f441a 13848 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13849 mips32_op = OPC_LWXC1;
13850 goto do_ldst_cp1;
13851 case SWXC1:
9e8f441a 13852 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13853 mips32_op = OPC_SWXC1;
13854 goto do_ldst_cp1;
13855 case LDXC1:
9e8f441a 13856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13857 mips32_op = OPC_LDXC1;
13858 goto do_ldst_cp1;
13859 case SDXC1:
9e8f441a 13860 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13861 mips32_op = OPC_SDXC1;
13862 goto do_ldst_cp1;
13863 case LUXC1:
9e8f441a 13864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13865 mips32_op = OPC_LUXC1;
13866 goto do_ldst_cp1;
13867 case SUXC1:
9e8f441a 13868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13869 mips32_op = OPC_SUXC1;
13870 do_ldst_cp1:
13871 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13872 break;
13873 default:
13874 goto pool32f_invalid;
13875 }
13876 break;
2a24a7ba
YK
13877 case MAX_FMT:
13878 check_insn(ctx, ISA_MIPS32R6);
13879 switch ((ctx->opcode >> 9) & 0x3) {
13880 case FMT_SDPS_S:
13881 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13882 break;
13883 case FMT_SDPS_D:
13884 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13885 break;
13886 default:
13887 goto pool32f_invalid;
13888 }
13889 break;
3c824109
NF
13890 case 0x18:
13891 /* 3D insns */
9e8f441a 13892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13893 fmt = (ctx->opcode >> 9) & 0x3;
13894 switch ((ctx->opcode >> 6) & 0x7) {
13895 case RSQRT2_FMT:
13896 switch (fmt) {
13897 case FMT_SDPS_S:
13898 mips32_op = OPC_RSQRT2_S;
13899 goto do_3d;
13900 case FMT_SDPS_D:
13901 mips32_op = OPC_RSQRT2_D;
13902 goto do_3d;
13903 case FMT_SDPS_PS:
13904 mips32_op = OPC_RSQRT2_PS;
13905 goto do_3d;
13906 default:
13907 goto pool32f_invalid;
13908 }
13909 break;
13910 case RECIP2_FMT:
13911 switch (fmt) {
13912 case FMT_SDPS_S:
13913 mips32_op = OPC_RECIP2_S;
13914 goto do_3d;
13915 case FMT_SDPS_D:
13916 mips32_op = OPC_RECIP2_D;
13917 goto do_3d;
13918 case FMT_SDPS_PS:
13919 mips32_op = OPC_RECIP2_PS;
13920 goto do_3d;
13921 default:
13922 goto pool32f_invalid;
13923 }
13924 break;
13925 case ADDR_PS:
13926 mips32_op = OPC_ADDR_PS;
13927 goto do_3d;
13928 case MULR_PS:
13929 mips32_op = OPC_MULR_PS;
13930 do_3d:
13931 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13932 break;
13933 default:
13934 goto pool32f_invalid;
13935 }
13936 break;
13937 case 0x20:
2a24a7ba 13938 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
13939 cc = (ctx->opcode >> 13) & 0x7;
13940 fmt = (ctx->opcode >> 9) & 0x3;
13941 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
13942 case MOVF_FMT: /* RINT_FMT */
13943 if (ctx->insn_flags & ISA_MIPS32R6) {
13944 /* RINT_FMT */
13945 switch (fmt) {
13946 case FMT_SDPS_S:
13947 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
13948 break;
13949 case FMT_SDPS_D:
13950 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
13951 break;
13952 default:
13953 goto pool32f_invalid;
13954 }
13955 } else {
13956 /* MOVF_FMT */
13957 switch (fmt) {
13958 case FMT_SDPS_S:
13959 gen_movcf_s(ctx, rs, rt, cc, 0);
13960 break;
13961 case FMT_SDPS_D:
13962 gen_movcf_d(ctx, rs, rt, cc, 0);
13963 break;
13964 case FMT_SDPS_PS:
13965 check_ps(ctx);
13966 gen_movcf_ps(ctx, rs, rt, cc, 0);
13967 break;
13968 default:
13969 goto pool32f_invalid;
13970 }
3c824109
NF
13971 }
13972 break;
2a24a7ba
YK
13973 case MOVT_FMT: /* CLASS_FMT */
13974 if (ctx->insn_flags & ISA_MIPS32R6) {
13975 /* CLASS_FMT */
13976 switch (fmt) {
13977 case FMT_SDPS_S:
13978 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
13979 break;
13980 case FMT_SDPS_D:
13981 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
13982 break;
13983 default:
13984 goto pool32f_invalid;
13985 }
13986 } else {
13987 /* MOVT_FMT */
13988 switch (fmt) {
13989 case FMT_SDPS_S:
13990 gen_movcf_s(ctx, rs, rt, cc, 1);
13991 break;
13992 case FMT_SDPS_D:
13993 gen_movcf_d(ctx, rs, rt, cc, 1);
13994 break;
13995 case FMT_SDPS_PS:
13996 check_ps(ctx);
13997 gen_movcf_ps(ctx, rs, rt, cc, 1);
13998 break;
13999 default:
14000 goto pool32f_invalid;
14001 }
3c824109
NF
14002 }
14003 break;
14004 case PREFX:
9e8f441a 14005 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14006 break;
14007 default:
14008 goto pool32f_invalid;
14009 }
14010 break;
14011#define FINSN_3ARG_SDPS(prfx) \
14012 switch ((ctx->opcode >> 8) & 0x3) { \
14013 case FMT_SDPS_S: \
14014 mips32_op = OPC_##prfx##_S; \
14015 goto do_fpop; \
14016 case FMT_SDPS_D: \
14017 mips32_op = OPC_##prfx##_D; \
14018 goto do_fpop; \
14019 case FMT_SDPS_PS: \
e29c9628 14020 check_ps(ctx); \
3c824109
NF
14021 mips32_op = OPC_##prfx##_PS; \
14022 goto do_fpop; \
14023 default: \
14024 goto pool32f_invalid; \
14025 }
2a24a7ba
YK
14026 case MINA_FMT:
14027 check_insn(ctx, ISA_MIPS32R6);
14028 switch ((ctx->opcode >> 9) & 0x3) {
14029 case FMT_SDPS_S:
14030 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14031 break;
14032 case FMT_SDPS_D:
14033 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14034 break;
14035 default:
14036 goto pool32f_invalid;
14037 }
14038 break;
14039 case MAXA_FMT:
14040 check_insn(ctx, ISA_MIPS32R6);
14041 switch ((ctx->opcode >> 9) & 0x3) {
14042 case FMT_SDPS_S:
14043 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14044 break;
14045 case FMT_SDPS_D:
14046 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14047 break;
14048 default:
14049 goto pool32f_invalid;
14050 }
14051 break;
3c824109
NF
14052 case 0x30:
14053 /* regular FP ops */
14054 switch ((ctx->opcode >> 6) & 0x3) {
14055 case ADD_FMT:
14056 FINSN_3ARG_SDPS(ADD);
14057 break;
14058 case SUB_FMT:
14059 FINSN_3ARG_SDPS(SUB);
14060 break;
14061 case MUL_FMT:
14062 FINSN_3ARG_SDPS(MUL);
14063 break;
14064 case DIV_FMT:
14065 fmt = (ctx->opcode >> 8) & 0x3;
14066 if (fmt == 1) {
14067 mips32_op = OPC_DIV_D;
14068 } else if (fmt == 0) {
14069 mips32_op = OPC_DIV_S;
14070 } else {
14071 goto pool32f_invalid;
14072 }
14073 goto do_fpop;
14074 default:
14075 goto pool32f_invalid;
14076 }
14077 break;
14078 case 0x38:
14079 /* cmovs */
2a24a7ba
YK
14080 switch ((ctx->opcode >> 6) & 0x7) {
14081 case MOVN_FMT: /* SELNEZ_FMT */
14082 if (ctx->insn_flags & ISA_MIPS32R6) {
14083 /* SELNEZ_FMT */
14084 switch ((ctx->opcode >> 9) & 0x3) {
14085 case FMT_SDPS_S:
14086 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14087 break;
14088 case FMT_SDPS_D:
14089 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14090 break;
14091 default:
14092 goto pool32f_invalid;
14093 }
14094 } else {
14095 /* MOVN_FMT */
14096 FINSN_3ARG_SDPS(MOVN);
14097 }
14098 break;
14099 case MOVN_FMT_04:
14100 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14101 FINSN_3ARG_SDPS(MOVN);
14102 break;
2a24a7ba
YK
14103 case MOVZ_FMT: /* SELEQZ_FMT */
14104 if (ctx->insn_flags & ISA_MIPS32R6) {
14105 /* SELEQZ_FMT */
14106 switch ((ctx->opcode >> 9) & 0x3) {
14107 case FMT_SDPS_S:
14108 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14109 break;
14110 case FMT_SDPS_D:
14111 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14112 break;
14113 default:
14114 goto pool32f_invalid;
14115 }
14116 } else {
14117 /* MOVZ_FMT */
14118 FINSN_3ARG_SDPS(MOVZ);
14119 }
14120 break;
14121 case MOVZ_FMT_05:
14122 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14123 FINSN_3ARG_SDPS(MOVZ);
14124 break;
2a24a7ba
YK
14125 case SEL_FMT:
14126 check_insn(ctx, ISA_MIPS32R6);
14127 switch ((ctx->opcode >> 9) & 0x3) {
14128 case FMT_SDPS_S:
14129 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14130 break;
14131 case FMT_SDPS_D:
14132 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14133 break;
14134 default:
14135 goto pool32f_invalid;
14136 }
14137 break;
14138 case MADDF_FMT:
14139 check_insn(ctx, ISA_MIPS32R6);
14140 switch ((ctx->opcode >> 9) & 0x3) {
14141 case FMT_SDPS_S:
14142 mips32_op = OPC_MADDF_S;
14143 goto do_fpop;
14144 case FMT_SDPS_D:
14145 mips32_op = OPC_MADDF_D;
14146 goto do_fpop;
14147 default:
14148 goto pool32f_invalid;
14149 }
14150 break;
14151 case MSUBF_FMT:
14152 check_insn(ctx, ISA_MIPS32R6);
14153 switch ((ctx->opcode >> 9) & 0x3) {
14154 case FMT_SDPS_S:
14155 mips32_op = OPC_MSUBF_S;
14156 goto do_fpop;
14157 case FMT_SDPS_D:
14158 mips32_op = OPC_MSUBF_D;
14159 goto do_fpop;
14160 default:
14161 goto pool32f_invalid;
14162 }
14163 break;
3c824109
NF
14164 default:
14165 goto pool32f_invalid;
14166 }
14167 break;
14168 do_fpop:
14169 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14170 break;
14171 default:
14172 pool32f_invalid:
14173 MIPS_INVAL("pool32f");
14174 generate_exception(ctx, EXCP_RI);
14175 break;
14176 }
14177 } else {
14178 generate_exception_err(ctx, EXCP_CpU, 1);
14179 }
14180 break;
14181 case POOL32I:
14182 minor = (ctx->opcode >> 21) & 0x1f;
14183 switch (minor) {
14184 case BLTZ:
9e8f441a 14185 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14186 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14187 break;
3c824109 14188 case BLTZAL:
9e8f441a 14189 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14190 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14191 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14192 break;
3c824109 14193 case BLTZALS:
9e8f441a 14194 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14195 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14196 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14197 break;
3c824109 14198 case BGEZ:
9e8f441a 14199 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14200 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14201 break;
3c824109 14202 case BGEZAL:
9e8f441a 14203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14204 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14205 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14206 break;
3c824109 14207 case BGEZALS:
9e8f441a 14208 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14209 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14210 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14211 break;
3c824109 14212 case BLEZ:
9e8f441a 14213 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14214 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14215 break;
3c824109 14216 case BGTZ:
9e8f441a 14217 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14218 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14219 break;
14220
14221 /* Traps */
65935f07
YK
14222 case TLTI: /* BC1EQZC */
14223 if (ctx->insn_flags & ISA_MIPS32R6) {
14224 /* BC1EQZC */
14225 check_cp1_enabled(ctx);
14226 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14227 } else {
14228 /* TLTI */
14229 mips32_op = OPC_TLTI;
14230 goto do_trapi;
14231 }
14232 break;
14233 case TGEI: /* BC1NEZC */
14234 if (ctx->insn_flags & ISA_MIPS32R6) {
14235 /* BC1NEZC */
14236 check_cp1_enabled(ctx);
14237 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14238 } else {
14239 /* TGEI */
14240 mips32_op = OPC_TGEI;
14241 goto do_trapi;
14242 }
14243 break;
3c824109 14244 case TLTIU:
9e8f441a 14245 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14246 mips32_op = OPC_TLTIU;
14247 goto do_trapi;
14248 case TGEIU:
9e8f441a 14249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14250 mips32_op = OPC_TGEIU;
14251 goto do_trapi;
3b4a5489
YK
14252 case TNEI: /* SYNCI */
14253 if (ctx->insn_flags & ISA_MIPS32R6) {
14254 /* SYNCI */
14255 /* Break the TB to be able to sync copied instructions
14256 immediately */
14257 ctx->bstate = BS_STOP;
14258 } else {
14259 /* TNEI */
14260 mips32_op = OPC_TNEI;
14261 goto do_trapi;
14262 }
14263 break;
3c824109 14264 case TEQI:
9e8f441a 14265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14266 mips32_op = OPC_TEQI;
14267 do_trapi:
14268 gen_trap(ctx, mips32_op, rs, -1, imm);
14269 break;
14270
14271 case BNEZC:
14272 case BEQZC:
9e8f441a 14273 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14274 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14275 4, rs, 0, imm << 1, 0);
3c824109
NF
14276 /* Compact branches don't have a delay slot, so just let
14277 the normal delay slot handling take us to the branch
14278 target. */
14279 break;
14280 case LUI:
9e8f441a 14281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14282 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14283 break;
14284 case SYNCI:
9e8f441a 14285 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14286 /* Break the TB to be able to sync copied instructions
14287 immediately */
14288 ctx->bstate = BS_STOP;
3c824109
NF
14289 break;
14290 case BC2F:
14291 case BC2T:
9e8f441a 14292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14293 /* COP2: Not implemented. */
14294 generate_exception_err(ctx, EXCP_CpU, 2);
14295 break;
14296 case BC1F:
9e8f441a 14297 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14298 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14299 goto do_cp1branch;
14300 case BC1T:
9e8f441a 14301 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14302 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14303 goto do_cp1branch;
14304 case BC1ANY4F:
9e8f441a 14305 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14306 mips32_op = OPC_BC1FANY4;
14307 goto do_cp1mips3d;
14308 case BC1ANY4T:
9e8f441a 14309 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14310 mips32_op = OPC_BC1TANY4;
14311 do_cp1mips3d:
14312 check_cop1x(ctx);
d75c135e 14313 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14314 /* Fall through */
14315 do_cp1branch:
272f458d
MR
14316 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14317 check_cp1_enabled(ctx);
14318 gen_compute_branch1(ctx, mips32_op,
14319 (ctx->opcode >> 18) & 0x7, imm << 1);
14320 } else {
14321 generate_exception_err(ctx, EXCP_CpU, 1);
14322 }
3c824109
NF
14323 break;
14324 case BPOSGE64:
14325 case BPOSGE32:
14326 /* MIPS DSP: not implemented */
14327 /* Fall through */
14328 default:
14329 MIPS_INVAL("pool32i");
14330 generate_exception(ctx, EXCP_RI);
14331 break;
14332 }
14333 break;
14334 case POOL32C:
14335 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14336 offset = sextract32(ctx->opcode, 0,
14337 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14338 switch (minor) {
14339 case LWL:
9e8f441a 14340 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14341 mips32_op = OPC_LWL;
5c13fdfd 14342 goto do_ld_lr;
3c824109 14343 case SWL:
9e8f441a 14344 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14345 mips32_op = OPC_SWL;
5c13fdfd 14346 goto do_st_lr;
3c824109 14347 case LWR:
9e8f441a 14348 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14349 mips32_op = OPC_LWR;
5c13fdfd 14350 goto do_ld_lr;
3c824109 14351 case SWR:
9e8f441a 14352 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14353 mips32_op = OPC_SWR;
5c13fdfd 14354 goto do_st_lr;
3c824109
NF
14355#if defined(TARGET_MIPS64)
14356 case LDL:
d9224450
MR
14357 check_insn(ctx, ISA_MIPS3);
14358 check_mips_64(ctx);
9e8f441a 14359 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14360 mips32_op = OPC_LDL;
5c13fdfd 14361 goto do_ld_lr;
3c824109 14362 case SDL:
d9224450
MR
14363 check_insn(ctx, ISA_MIPS3);
14364 check_mips_64(ctx);
9e8f441a 14365 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14366 mips32_op = OPC_SDL;
5c13fdfd 14367 goto do_st_lr;
3c824109 14368 case LDR:
d9224450
MR
14369 check_insn(ctx, ISA_MIPS3);
14370 check_mips_64(ctx);
9e8f441a 14371 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14372 mips32_op = OPC_LDR;
5c13fdfd 14373 goto do_ld_lr;
3c824109 14374 case SDR:
d9224450
MR
14375 check_insn(ctx, ISA_MIPS3);
14376 check_mips_64(ctx);
9e8f441a 14377 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14378 mips32_op = OPC_SDR;
5c13fdfd 14379 goto do_st_lr;
3c824109 14380 case LWU:
d9224450
MR
14381 check_insn(ctx, ISA_MIPS3);
14382 check_mips_64(ctx);
3c824109 14383 mips32_op = OPC_LWU;
5c13fdfd 14384 goto do_ld_lr;
3c824109 14385 case LLD:
d9224450
MR
14386 check_insn(ctx, ISA_MIPS3);
14387 check_mips_64(ctx);
3c824109 14388 mips32_op = OPC_LLD;
5c13fdfd 14389 goto do_ld_lr;
3c824109
NF
14390#endif
14391 case LL:
14392 mips32_op = OPC_LL;
5c13fdfd
AJ
14393 goto do_ld_lr;
14394 do_ld_lr:
3b4a5489 14395 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14396 break;
14397 do_st_lr:
14398 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14399 break;
14400 case SC:
3b4a5489 14401 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14402 break;
14403#if defined(TARGET_MIPS64)
14404 case SCD:
d9224450
MR
14405 check_insn(ctx, ISA_MIPS3);
14406 check_mips_64(ctx);
3b4a5489 14407 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14408 break;
14409#endif
14410 case PREF:
14411 /* Treat as no-op */
3b4a5489
YK
14412 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14413 /* hint codes 24-31 are reserved and signal RI */
14414 generate_exception(ctx, EXCP_RI);
14415 }
3c824109
NF
14416 break;
14417 default:
14418 MIPS_INVAL("pool32c");
14419 generate_exception(ctx, EXCP_RI);
14420 break;
14421 }
14422 break;
ab39ee45
YK
14423 case ADDI32: /* AUI, LUI */
14424 if (ctx->insn_flags & ISA_MIPS32R6) {
14425 /* AUI, LUI */
14426 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14427 } else {
14428 /* ADDI32 */
14429 mips32_op = OPC_ADDI;
14430 goto do_addi;
14431 }
14432 break;
3c824109
NF
14433 case ADDIU32:
14434 mips32_op = OPC_ADDIU;
14435 do_addi:
d75c135e 14436 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14437 break;
14438
14439 /* Logical operations */
14440 case ORI32:
14441 mips32_op = OPC_ORI;
14442 goto do_logici;
14443 case XORI32:
14444 mips32_op = OPC_XORI;
14445 goto do_logici;
14446 case ANDI32:
14447 mips32_op = OPC_ANDI;
14448 do_logici:
d75c135e 14449 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14450 break;
14451
14452 /* Set less than immediate */
14453 case SLTI32:
14454 mips32_op = OPC_SLTI;
14455 goto do_slti;
14456 case SLTIU32:
14457 mips32_op = OPC_SLTIU;
14458 do_slti:
d75c135e 14459 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14460 break;
14461 case JALX32:
9e8f441a 14462 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14463 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14464 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14465 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14466 break;
65935f07
YK
14467 case JALS32: /* BOVC, BEQC, BEQZALC */
14468 if (ctx->insn_flags & ISA_MIPS32R6) {
14469 if (rs >= rt) {
14470 /* BOVC */
14471 mips32_op = OPC_BOVC;
14472 } else if (rs < rt && rs == 0) {
14473 /* BEQZALC */
14474 mips32_op = OPC_BEQZALC;
14475 } else {
14476 /* BEQC */
14477 mips32_op = OPC_BEQC;
14478 }
14479 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14480 } else {
14481 /* JALS32 */
14482 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14483 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14484 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14485 }
3c824109 14486 break;
65935f07
YK
14487 case BEQ32: /* BC */
14488 if (ctx->insn_flags & ISA_MIPS32R6) {
14489 /* BC */
14490 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14491 sextract32(ctx->opcode << 1, 0, 27));
14492 } else {
14493 /* BEQ32 */
14494 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14495 }
3c824109 14496 break;
65935f07
YK
14497 case BNE32: /* BALC */
14498 if (ctx->insn_flags & ISA_MIPS32R6) {
14499 /* BALC */
14500 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14501 sextract32(ctx->opcode << 1, 0, 27));
14502 } else {
14503 /* BNE32 */
14504 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14505 }
3c824109 14506 break;
65935f07
YK
14507 case J32: /* BGTZC, BLTZC, BLTC */
14508 if (ctx->insn_flags & ISA_MIPS32R6) {
14509 if (rs == 0 && rt != 0) {
14510 /* BGTZC */
14511 mips32_op = OPC_BGTZC;
14512 } else if (rs != 0 && rt != 0 && rs == rt) {
14513 /* BLTZC */
14514 mips32_op = OPC_BLTZC;
14515 } else {
14516 /* BLTC */
14517 mips32_op = OPC_BLTC;
14518 }
14519 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14520 } else {
14521 /* J32 */
14522 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14523 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14524 }
3c824109 14525 break;
65935f07
YK
14526 case JAL32: /* BLEZC, BGEZC, BGEC */
14527 if (ctx->insn_flags & ISA_MIPS32R6) {
14528 if (rs == 0 && rt != 0) {
14529 /* BLEZC */
14530 mips32_op = OPC_BLEZC;
14531 } else if (rs != 0 && rt != 0 && rs == rt) {
14532 /* BGEZC */
14533 mips32_op = OPC_BGEZC;
14534 } else {
14535 /* BGEC */
14536 mips32_op = OPC_BGEC;
14537 }
14538 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14539 } else {
14540 /* JAL32 */
14541 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14542 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14543 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14544 }
3c824109
NF
14545 break;
14546 /* Floating point (COP1) */
14547 case LWC132:
14548 mips32_op = OPC_LWC1;
14549 goto do_cop1;
14550 case LDC132:
14551 mips32_op = OPC_LDC1;
14552 goto do_cop1;
14553 case SWC132:
14554 mips32_op = OPC_SWC1;
14555 goto do_cop1;
14556 case SDC132:
14557 mips32_op = OPC_SDC1;
14558 do_cop1:
5ab5c041 14559 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 14560 break;
ab39ee45
YK
14561 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14562 if (ctx->insn_flags & ISA_MIPS32R6) {
14563 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14564 switch ((ctx->opcode >> 16) & 0x1f) {
14565 case ADDIUPC_00 ... ADDIUPC_07:
14566 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14567 break;
14568 case AUIPC:
14569 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14570 break;
14571 case ALUIPC:
14572 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14573 break;
14574 case LWPC_08 ... LWPC_0F:
14575 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14576 break;
14577 default:
14578 generate_exception(ctx, EXCP_RI);
14579 break;
14580 }
14581 } else {
14582 /* ADDIUPC */
3c824109
NF
14583 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14584 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14585
14586 gen_addiupc(ctx, reg, offset, 0, 0);
14587 }
14588 break;
65935f07
YK
14589 case BNVC: /* BNEC, BNEZALC */
14590 check_insn(ctx, ISA_MIPS32R6);
14591 if (rs >= rt) {
14592 /* BNVC */
14593 mips32_op = OPC_BNVC;
14594 } else if (rs < rt && rs == 0) {
14595 /* BNEZALC */
14596 mips32_op = OPC_BNEZALC;
14597 } else {
14598 /* BNEC */
14599 mips32_op = OPC_BNEC;
14600 }
14601 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14602 break;
14603 case R6_BNEZC: /* JIALC */
14604 check_insn(ctx, ISA_MIPS32R6);
14605 if (rt != 0) {
14606 /* BNEZC */
14607 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14608 sextract32(ctx->opcode << 1, 0, 22));
14609 } else {
14610 /* JIALC */
14611 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14612 }
14613 break;
14614 case R6_BEQZC: /* JIC */
14615 check_insn(ctx, ISA_MIPS32R6);
14616 if (rt != 0) {
14617 /* BEQZC */
14618 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14619 sextract32(ctx->opcode << 1, 0, 22));
14620 } else {
14621 /* JIC */
14622 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14623 }
14624 break;
14625 case BLEZALC: /* BGEZALC, BGEUC */
14626 check_insn(ctx, ISA_MIPS32R6);
14627 if (rs == 0 && rt != 0) {
14628 /* BLEZALC */
14629 mips32_op = OPC_BLEZALC;
14630 } else if (rs != 0 && rt != 0 && rs == rt) {
14631 /* BGEZALC */
14632 mips32_op = OPC_BGEZALC;
14633 } else {
14634 /* BGEUC */
14635 mips32_op = OPC_BGEUC;
14636 }
14637 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14638 break;
14639 case BGTZALC: /* BLTZALC, BLTUC */
14640 check_insn(ctx, ISA_MIPS32R6);
14641 if (rs == 0 && rt != 0) {
14642 /* BGTZALC */
14643 mips32_op = OPC_BGTZALC;
14644 } else if (rs != 0 && rt != 0 && rs == rt) {
14645 /* BLTZALC */
14646 mips32_op = OPC_BLTZALC;
14647 } else {
14648 /* BLTUC */
14649 mips32_op = OPC_BLTUC;
14650 }
14651 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14652 break;
3c824109
NF
14653 /* Loads and stores */
14654 case LB32:
14655 mips32_op = OPC_LB;
5c13fdfd 14656 goto do_ld;
3c824109
NF
14657 case LBU32:
14658 mips32_op = OPC_LBU;
5c13fdfd 14659 goto do_ld;
3c824109
NF
14660 case LH32:
14661 mips32_op = OPC_LH;
5c13fdfd 14662 goto do_ld;
3c824109
NF
14663 case LHU32:
14664 mips32_op = OPC_LHU;
5c13fdfd 14665 goto do_ld;
3c824109
NF
14666 case LW32:
14667 mips32_op = OPC_LW;
5c13fdfd 14668 goto do_ld;
3c824109
NF
14669#ifdef TARGET_MIPS64
14670 case LD32:
d9224450
MR
14671 check_insn(ctx, ISA_MIPS3);
14672 check_mips_64(ctx);
3c824109 14673 mips32_op = OPC_LD;
5c13fdfd 14674 goto do_ld;
3c824109 14675 case SD32:
d9224450
MR
14676 check_insn(ctx, ISA_MIPS3);
14677 check_mips_64(ctx);
3c824109 14678 mips32_op = OPC_SD;
5c13fdfd 14679 goto do_st;
3c824109
NF
14680#endif
14681 case SB32:
14682 mips32_op = OPC_SB;
5c13fdfd 14683 goto do_st;
3c824109
NF
14684 case SH32:
14685 mips32_op = OPC_SH;
5c13fdfd 14686 goto do_st;
3c824109
NF
14687 case SW32:
14688 mips32_op = OPC_SW;
5c13fdfd
AJ
14689 goto do_st;
14690 do_ld:
d75c135e 14691 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
14692 break;
14693 do_st:
14694 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14695 break;
14696 default:
14697 generate_exception(ctx, EXCP_RI);
14698 break;
14699 }
14700}
14701
240ce26a 14702static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14703{
14704 uint32_t op;
14705
14706 /* make sure instructions are on a halfword boundary */
14707 if (ctx->pc & 0x1) {
14708 env->CP0_BadVAddr = ctx->pc;
14709 generate_exception(ctx, EXCP_AdEL);
14710 ctx->bstate = BS_STOP;
14711 return 2;
14712 }
14713
14714 op = (ctx->opcode >> 10) & 0x3f;
14715 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
14716 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14717 switch (op & 0x7) { /* MSB-3..MSB-5 */
14718 case 0:
14719 /* POOL32A, POOL32B, POOL32I, POOL32C */
14720 case 4:
14721 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14722 case 5:
14723 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14724 case 6:
14725 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14726 case 7:
14727 /* LB32, LH32, LWC132, LDC132, LW32 */
14728 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
14729 generate_exception(ctx, EXCP_RI);
14730 /* Just stop translation; the user is confused. */
14731 ctx->bstate = BS_STOP;
14732 return 2;
14733 }
14734 break;
b231c103
YK
14735 case 1:
14736 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14737 case 2:
14738 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14739 case 3:
14740 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14741 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
14742 generate_exception(ctx, EXCP_RI);
14743 /* Just stop translation; the user is confused. */
14744 ctx->bstate = BS_STOP;
14745 return 2;
14746 }
14747 break;
3c824109
NF
14748 }
14749 }
b231c103 14750
3c824109
NF
14751 switch (op) {
14752 case POOL16A:
14753 {
14754 int rd = mmreg(uMIPS_RD(ctx->opcode));
14755 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14756 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14757 uint32_t opc = 0;
14758
14759 switch (ctx->opcode & 0x1) {
14760 case ADDU16:
14761 opc = OPC_ADDU;
14762 break;
14763 case SUBU16:
14764 opc = OPC_SUBU;
14765 break;
14766 }
ed7ce6c0
YK
14767 if (ctx->insn_flags & ISA_MIPS32R6) {
14768 /* In the Release 6 the register number location in
14769 * the instruction encoding has changed.
14770 */
14771 gen_arith(ctx, opc, rs1, rd, rs2);
14772 } else {
14773 gen_arith(ctx, opc, rd, rs1, rs2);
14774 }
3c824109
NF
14775 }
14776 break;
14777 case POOL16B:
14778 {
14779 int rd = mmreg(uMIPS_RD(ctx->opcode));
14780 int rs = mmreg(uMIPS_RS(ctx->opcode));
14781 int amount = (ctx->opcode >> 1) & 0x7;
14782 uint32_t opc = 0;
14783 amount = amount == 0 ? 8 : amount;
14784
14785 switch (ctx->opcode & 0x1) {
14786 case SLL16:
14787 opc = OPC_SLL;
14788 break;
14789 case SRL16:
14790 opc = OPC_SRL;
14791 break;
14792 }
14793
d75c135e 14794 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14795 }
14796 break;
14797 case POOL16C:
ed7ce6c0
YK
14798 if (ctx->insn_flags & ISA_MIPS32R6) {
14799 gen_pool16c_r6_insn(ctx);
14800 } else {
14801 gen_pool16c_insn(ctx);
14802 }
3c824109
NF
14803 break;
14804 case LWGP16:
14805 {
14806 int rd = mmreg(uMIPS_RD(ctx->opcode));
14807 int rb = 28; /* GP */
14808 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14809
d75c135e 14810 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14811 }
14812 break;
14813 case POOL16F:
9e8f441a 14814 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14815 if (ctx->opcode & 1) {
14816 generate_exception(ctx, EXCP_RI);
14817 } else {
14818 /* MOVEP */
14819 int enc_dest = uMIPS_RD(ctx->opcode);
14820 int enc_rt = uMIPS_RS2(ctx->opcode);
14821 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 14822 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
14823 }
14824 break;
14825 case LBU16:
14826 {
14827 int rd = mmreg(uMIPS_RD(ctx->opcode));
14828 int rb = mmreg(uMIPS_RS(ctx->opcode));
14829 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14830 offset = (offset == 0xf ? -1 : offset);
14831
d75c135e 14832 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14833 }
14834 break;
14835 case LHU16:
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) << 1;
14840
d75c135e 14841 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14842 }
14843 break;
14844 case LWSP16:
14845 {
14846 int rd = (ctx->opcode >> 5) & 0x1f;
14847 int rb = 29; /* SP */
14848 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14849
d75c135e 14850 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14851 }
14852 break;
14853 case LW16:
14854 {
14855 int rd = mmreg(uMIPS_RD(ctx->opcode));
14856 int rb = mmreg(uMIPS_RS(ctx->opcode));
14857 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14858
d75c135e 14859 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14860 }
14861 break;
14862 case SB16:
14863 {
14864 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14865 int rb = mmreg(uMIPS_RS(ctx->opcode));
14866 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14867
5c13fdfd 14868 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14869 }
14870 break;
14871 case SH16:
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) << 1;
14876
5c13fdfd 14877 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14878 }
14879 break;
14880 case SWSP16:
14881 {
14882 int rd = (ctx->opcode >> 5) & 0x1f;
14883 int rb = 29; /* SP */
14884 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14885
5c13fdfd 14886 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14887 }
14888 break;
14889 case SW16:
14890 {
14891 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14892 int rb = mmreg(uMIPS_RS(ctx->opcode));
14893 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14894
5c13fdfd 14895 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14896 }
14897 break;
14898 case MOVE16:
14899 {
14900 int rd = uMIPS_RD5(ctx->opcode);
14901 int rs = uMIPS_RS5(ctx->opcode);
14902
7215d7e7 14903 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14904 }
14905 break;
14906 case ANDI16:
d75c135e 14907 gen_andi16(ctx);
3c824109
NF
14908 break;
14909 case POOL16D:
14910 switch (ctx->opcode & 0x1) {
14911 case ADDIUS5:
d75c135e 14912 gen_addius5(ctx);
3c824109
NF
14913 break;
14914 case ADDIUSP:
d75c135e 14915 gen_addiusp(ctx);
3c824109
NF
14916 break;
14917 }
14918 break;
14919 case POOL16E:
14920 switch (ctx->opcode & 0x1) {
14921 case ADDIUR2:
d75c135e 14922 gen_addiur2(ctx);
3c824109
NF
14923 break;
14924 case ADDIUR1SP:
d75c135e 14925 gen_addiur1sp(ctx);
3c824109
NF
14926 break;
14927 }
14928 break;
65935f07 14929 case B16: /* BC16 */
3c824109 14930 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
14931 sextract32(ctx->opcode, 0, 10) << 1,
14932 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 14933 break;
65935f07
YK
14934 case BNEZ16: /* BNEZC16 */
14935 case BEQZ16: /* BEQZC16 */
3c824109
NF
14936 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14937 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
14938 0, sextract32(ctx->opcode, 0, 7) << 1,
14939 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
14940
3c824109
NF
14941 break;
14942 case LI16:
14943 {
14944 int reg = mmreg(uMIPS_RD(ctx->opcode));
14945 int imm = ZIMM(ctx->opcode, 0, 7);
14946
14947 imm = (imm == 0x7f ? -1 : imm);
14948 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14949 }
14950 break;
3c824109 14951 case RES_29:
3c824109 14952 case RES_31:
3c824109
NF
14953 case RES_39:
14954 generate_exception(ctx, EXCP_RI);
14955 break;
14956 default:
f60eeb0c 14957 decode_micromips32_opc(env, ctx);
3c824109
NF
14958 return 4;
14959 }
14960
14961 return 2;
14962}
14963
14964/* SmartMIPS extension to MIPS32 */
14965
14966#if defined(TARGET_MIPS64)
14967
14968/* MDMX extension to MIPS64 */
14969
14970#endif
14971
9b1a1d68 14972/* MIPSDSP functions. */
d75c135e 14973static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14974 int rd, int base, int offset)
14975{
9b1a1d68
JL
14976 TCGv t0;
14977
9b1a1d68
JL
14978 check_dsp(ctx);
14979 t0 = tcg_temp_new();
14980
14981 if (base == 0) {
14982 gen_load_gpr(t0, offset);
14983 } else if (offset == 0) {
14984 gen_load_gpr(t0, base);
14985 } else {
14986 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14987 }
14988
9b1a1d68
JL
14989 switch (opc) {
14990 case OPC_LBUX:
5f68f5ae 14991 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 14992 gen_store_gpr(t0, rd);
9b1a1d68
JL
14993 break;
14994 case OPC_LHX:
5f68f5ae 14995 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 14996 gen_store_gpr(t0, rd);
9b1a1d68
JL
14997 break;
14998 case OPC_LWX:
5f68f5ae 14999 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15000 gen_store_gpr(t0, rd);
9b1a1d68
JL
15001 break;
15002#if defined(TARGET_MIPS64)
15003 case OPC_LDX:
5f68f5ae 15004 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15005 gen_store_gpr(t0, rd);
9b1a1d68
JL
15006 break;
15007#endif
15008 }
9b1a1d68
JL
15009 tcg_temp_free(t0);
15010}
15011
461c08df
JL
15012static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15013 int ret, int v1, int v2)
15014{
461c08df
JL
15015 TCGv v1_t;
15016 TCGv v2_t;
15017
15018 if (ret == 0) {
15019 /* Treat as NOP. */
461c08df
JL
15020 return;
15021 }
15022
15023 v1_t = tcg_temp_new();
15024 v2_t = tcg_temp_new();
15025
15026 gen_load_gpr(v1_t, v1);
15027 gen_load_gpr(v2_t, v2);
15028
15029 switch (op1) {
15030 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15031 case OPC_MULT_G_2E:
15032 check_dspr2(ctx);
15033 switch (op2) {
15034 case OPC_ADDUH_QB:
15035 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15036 break;
15037 case OPC_ADDUH_R_QB:
15038 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15039 break;
15040 case OPC_ADDQH_PH:
15041 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15042 break;
15043 case OPC_ADDQH_R_PH:
15044 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15045 break;
15046 case OPC_ADDQH_W:
15047 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15048 break;
15049 case OPC_ADDQH_R_W:
15050 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15051 break;
15052 case OPC_SUBUH_QB:
15053 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15054 break;
15055 case OPC_SUBUH_R_QB:
15056 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15057 break;
15058 case OPC_SUBQH_PH:
15059 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15060 break;
15061 case OPC_SUBQH_R_PH:
15062 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15063 break;
15064 case OPC_SUBQH_W:
15065 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15066 break;
15067 case OPC_SUBQH_R_W:
15068 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15069 break;
15070 }
15071 break;
15072 case OPC_ABSQ_S_PH_DSP:
15073 switch (op2) {
15074 case OPC_ABSQ_S_QB:
15075 check_dspr2(ctx);
15076 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15077 break;
15078 case OPC_ABSQ_S_PH:
15079 check_dsp(ctx);
15080 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15081 break;
15082 case OPC_ABSQ_S_W:
15083 check_dsp(ctx);
15084 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15085 break;
15086 case OPC_PRECEQ_W_PHL:
15087 check_dsp(ctx);
15088 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15089 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15090 break;
15091 case OPC_PRECEQ_W_PHR:
15092 check_dsp(ctx);
15093 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15094 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15095 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15096 break;
15097 case OPC_PRECEQU_PH_QBL:
15098 check_dsp(ctx);
15099 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15100 break;
15101 case OPC_PRECEQU_PH_QBR:
15102 check_dsp(ctx);
15103 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15104 break;
15105 case OPC_PRECEQU_PH_QBLA:
15106 check_dsp(ctx);
15107 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15108 break;
15109 case OPC_PRECEQU_PH_QBRA:
15110 check_dsp(ctx);
15111 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15112 break;
15113 case OPC_PRECEU_PH_QBL:
15114 check_dsp(ctx);
15115 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15116 break;
15117 case OPC_PRECEU_PH_QBR:
15118 check_dsp(ctx);
15119 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15120 break;
15121 case OPC_PRECEU_PH_QBLA:
15122 check_dsp(ctx);
15123 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15124 break;
15125 case OPC_PRECEU_PH_QBRA:
15126 check_dsp(ctx);
15127 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15128 break;
15129 }
15130 break;
15131 case OPC_ADDU_QB_DSP:
15132 switch (op2) {
15133 case OPC_ADDQ_PH:
15134 check_dsp(ctx);
15135 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15136 break;
15137 case OPC_ADDQ_S_PH:
15138 check_dsp(ctx);
15139 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15140 break;
15141 case OPC_ADDQ_S_W:
15142 check_dsp(ctx);
15143 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15144 break;
15145 case OPC_ADDU_QB:
15146 check_dsp(ctx);
15147 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15148 break;
15149 case OPC_ADDU_S_QB:
15150 check_dsp(ctx);
15151 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15152 break;
15153 case OPC_ADDU_PH:
15154 check_dspr2(ctx);
15155 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15156 break;
15157 case OPC_ADDU_S_PH:
15158 check_dspr2(ctx);
15159 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15160 break;
15161 case OPC_SUBQ_PH:
15162 check_dsp(ctx);
15163 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15164 break;
15165 case OPC_SUBQ_S_PH:
15166 check_dsp(ctx);
15167 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15168 break;
15169 case OPC_SUBQ_S_W:
15170 check_dsp(ctx);
15171 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15172 break;
15173 case OPC_SUBU_QB:
15174 check_dsp(ctx);
15175 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15176 break;
15177 case OPC_SUBU_S_QB:
15178 check_dsp(ctx);
15179 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15180 break;
15181 case OPC_SUBU_PH:
15182 check_dspr2(ctx);
15183 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15184 break;
15185 case OPC_SUBU_S_PH:
15186 check_dspr2(ctx);
15187 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15188 break;
15189 case OPC_ADDSC:
15190 check_dsp(ctx);
15191 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15192 break;
15193 case OPC_ADDWC:
15194 check_dsp(ctx);
15195 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15196 break;
15197 case OPC_MODSUB:
15198 check_dsp(ctx);
15199 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15200 break;
15201 case OPC_RADDU_W_QB:
15202 check_dsp(ctx);
15203 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15204 break;
15205 }
15206 break;
15207 case OPC_CMPU_EQ_QB_DSP:
15208 switch (op2) {
15209 case OPC_PRECR_QB_PH:
15210 check_dspr2(ctx);
15211 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15212 break;
15213 case OPC_PRECRQ_QB_PH:
15214 check_dsp(ctx);
15215 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15216 break;
15217 case OPC_PRECR_SRA_PH_W:
15218 check_dspr2(ctx);
15219 {
15220 TCGv_i32 sa_t = tcg_const_i32(v2);
15221 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15222 cpu_gpr[ret]);
15223 tcg_temp_free_i32(sa_t);
15224 break;
15225 }
15226 case OPC_PRECR_SRA_R_PH_W:
15227 check_dspr2(ctx);
15228 {
15229 TCGv_i32 sa_t = tcg_const_i32(v2);
15230 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15231 cpu_gpr[ret]);
15232 tcg_temp_free_i32(sa_t);
15233 break;
15234 }
15235 case OPC_PRECRQ_PH_W:
15236 check_dsp(ctx);
15237 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15238 break;
15239 case OPC_PRECRQ_RS_PH_W:
15240 check_dsp(ctx);
15241 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15242 break;
15243 case OPC_PRECRQU_S_QB_PH:
15244 check_dsp(ctx);
15245 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15246 break;
15247 }
15248 break;
15249#ifdef TARGET_MIPS64
15250 case OPC_ABSQ_S_QH_DSP:
15251 switch (op2) {
15252 case OPC_PRECEQ_L_PWL:
15253 check_dsp(ctx);
15254 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15255 break;
15256 case OPC_PRECEQ_L_PWR:
15257 check_dsp(ctx);
15258 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15259 break;
15260 case OPC_PRECEQ_PW_QHL:
15261 check_dsp(ctx);
15262 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15263 break;
15264 case OPC_PRECEQ_PW_QHR:
15265 check_dsp(ctx);
15266 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15267 break;
15268 case OPC_PRECEQ_PW_QHLA:
15269 check_dsp(ctx);
15270 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15271 break;
15272 case OPC_PRECEQ_PW_QHRA:
15273 check_dsp(ctx);
15274 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15275 break;
15276 case OPC_PRECEQU_QH_OBL:
15277 check_dsp(ctx);
15278 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15279 break;
15280 case OPC_PRECEQU_QH_OBR:
15281 check_dsp(ctx);
15282 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15283 break;
15284 case OPC_PRECEQU_QH_OBLA:
15285 check_dsp(ctx);
15286 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15287 break;
15288 case OPC_PRECEQU_QH_OBRA:
15289 check_dsp(ctx);
15290 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15291 break;
15292 case OPC_PRECEU_QH_OBL:
15293 check_dsp(ctx);
15294 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15295 break;
15296 case OPC_PRECEU_QH_OBR:
15297 check_dsp(ctx);
15298 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15299 break;
15300 case OPC_PRECEU_QH_OBLA:
15301 check_dsp(ctx);
15302 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15303 break;
15304 case OPC_PRECEU_QH_OBRA:
15305 check_dsp(ctx);
15306 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15307 break;
15308 case OPC_ABSQ_S_OB:
15309 check_dspr2(ctx);
15310 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15311 break;
15312 case OPC_ABSQ_S_PW:
15313 check_dsp(ctx);
15314 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15315 break;
15316 case OPC_ABSQ_S_QH:
15317 check_dsp(ctx);
15318 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15319 break;
15320 }
15321 break;
15322 case OPC_ADDU_OB_DSP:
15323 switch (op2) {
15324 case OPC_RADDU_L_OB:
15325 check_dsp(ctx);
15326 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15327 break;
15328 case OPC_SUBQ_PW:
15329 check_dsp(ctx);
15330 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15331 break;
15332 case OPC_SUBQ_S_PW:
15333 check_dsp(ctx);
15334 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15335 break;
15336 case OPC_SUBQ_QH:
15337 check_dsp(ctx);
15338 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15339 break;
15340 case OPC_SUBQ_S_QH:
15341 check_dsp(ctx);
15342 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15343 break;
15344 case OPC_SUBU_OB:
15345 check_dsp(ctx);
15346 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15347 break;
15348 case OPC_SUBU_S_OB:
15349 check_dsp(ctx);
15350 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15351 break;
15352 case OPC_SUBU_QH:
15353 check_dspr2(ctx);
15354 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15355 break;
15356 case OPC_SUBU_S_QH:
15357 check_dspr2(ctx);
15358 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15359 break;
15360 case OPC_SUBUH_OB:
15361 check_dspr2(ctx);
15362 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15363 break;
15364 case OPC_SUBUH_R_OB:
15365 check_dspr2(ctx);
15366 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15367 break;
15368 case OPC_ADDQ_PW:
15369 check_dsp(ctx);
15370 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15371 break;
15372 case OPC_ADDQ_S_PW:
15373 check_dsp(ctx);
15374 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15375 break;
15376 case OPC_ADDQ_QH:
15377 check_dsp(ctx);
15378 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15379 break;
15380 case OPC_ADDQ_S_QH:
15381 check_dsp(ctx);
15382 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15383 break;
15384 case OPC_ADDU_OB:
15385 check_dsp(ctx);
15386 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15387 break;
15388 case OPC_ADDU_S_OB:
15389 check_dsp(ctx);
15390 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15391 break;
15392 case OPC_ADDU_QH:
15393 check_dspr2(ctx);
15394 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15395 break;
15396 case OPC_ADDU_S_QH:
15397 check_dspr2(ctx);
15398 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15399 break;
15400 case OPC_ADDUH_OB:
15401 check_dspr2(ctx);
15402 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15403 break;
15404 case OPC_ADDUH_R_OB:
15405 check_dspr2(ctx);
15406 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15407 break;
15408 }
15409 break;
15410 case OPC_CMPU_EQ_OB_DSP:
15411 switch (op2) {
15412 case OPC_PRECR_OB_QH:
15413 check_dspr2(ctx);
15414 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15415 break;
15416 case OPC_PRECR_SRA_QH_PW:
15417 check_dspr2(ctx);
15418 {
15419 TCGv_i32 ret_t = tcg_const_i32(ret);
15420 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15421 tcg_temp_free_i32(ret_t);
15422 break;
15423 }
15424 case OPC_PRECR_SRA_R_QH_PW:
15425 check_dspr2(ctx);
15426 {
15427 TCGv_i32 sa_v = tcg_const_i32(ret);
15428 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15429 tcg_temp_free_i32(sa_v);
15430 break;
15431 }
15432 case OPC_PRECRQ_OB_QH:
15433 check_dsp(ctx);
15434 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15435 break;
15436 case OPC_PRECRQ_PW_L:
15437 check_dsp(ctx);
15438 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15439 break;
15440 case OPC_PRECRQ_QH_PW:
15441 check_dsp(ctx);
15442 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15443 break;
15444 case OPC_PRECRQ_RS_QH_PW:
15445 check_dsp(ctx);
15446 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15447 break;
15448 case OPC_PRECRQU_S_OB_QH:
15449 check_dsp(ctx);
15450 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15451 break;
15452 }
15453 break;
15454#endif
15455 }
15456
15457 tcg_temp_free(v1_t);
15458 tcg_temp_free(v2_t);
461c08df 15459}
9b1a1d68 15460
77c5fa8b
JL
15461static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15462 int ret, int v1, int v2)
15463{
15464 uint32_t op2;
77c5fa8b
JL
15465 TCGv t0;
15466 TCGv v1_t;
15467 TCGv v2_t;
15468
15469 if (ret == 0) {
15470 /* Treat as NOP. */
77c5fa8b
JL
15471 return;
15472 }
15473
15474 t0 = tcg_temp_new();
15475 v1_t = tcg_temp_new();
15476 v2_t = tcg_temp_new();
15477
15478 tcg_gen_movi_tl(t0, v1);
15479 gen_load_gpr(v1_t, v1);
15480 gen_load_gpr(v2_t, v2);
15481
15482 switch (opc) {
15483 case OPC_SHLL_QB_DSP:
15484 {
15485 op2 = MASK_SHLL_QB(ctx->opcode);
15486 switch (op2) {
15487 case OPC_SHLL_QB:
15488 check_dsp(ctx);
15489 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15490 break;
15491 case OPC_SHLLV_QB:
15492 check_dsp(ctx);
15493 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15494 break;
15495 case OPC_SHLL_PH:
15496 check_dsp(ctx);
15497 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15498 break;
15499 case OPC_SHLLV_PH:
15500 check_dsp(ctx);
15501 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15502 break;
15503 case OPC_SHLL_S_PH:
15504 check_dsp(ctx);
15505 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15506 break;
15507 case OPC_SHLLV_S_PH:
15508 check_dsp(ctx);
15509 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15510 break;
15511 case OPC_SHLL_S_W:
15512 check_dsp(ctx);
15513 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15514 break;
15515 case OPC_SHLLV_S_W:
15516 check_dsp(ctx);
15517 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15518 break;
15519 case OPC_SHRL_QB:
15520 check_dsp(ctx);
15521 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15522 break;
15523 case OPC_SHRLV_QB:
15524 check_dsp(ctx);
15525 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15526 break;
15527 case OPC_SHRL_PH:
15528 check_dspr2(ctx);
15529 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15530 break;
15531 case OPC_SHRLV_PH:
15532 check_dspr2(ctx);
15533 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15534 break;
15535 case OPC_SHRA_QB:
15536 check_dspr2(ctx);
15537 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15538 break;
15539 case OPC_SHRA_R_QB:
15540 check_dspr2(ctx);
15541 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15542 break;
15543 case OPC_SHRAV_QB:
15544 check_dspr2(ctx);
15545 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15546 break;
15547 case OPC_SHRAV_R_QB:
15548 check_dspr2(ctx);
15549 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15550 break;
15551 case OPC_SHRA_PH:
15552 check_dsp(ctx);
15553 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15554 break;
15555 case OPC_SHRA_R_PH:
15556 check_dsp(ctx);
15557 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15558 break;
15559 case OPC_SHRAV_PH:
15560 check_dsp(ctx);
15561 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15562 break;
15563 case OPC_SHRAV_R_PH:
15564 check_dsp(ctx);
15565 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15566 break;
15567 case OPC_SHRA_R_W:
15568 check_dsp(ctx);
15569 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15570 break;
15571 case OPC_SHRAV_R_W:
15572 check_dsp(ctx);
15573 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15574 break;
15575 default: /* Invalid */
15576 MIPS_INVAL("MASK SHLL.QB");
15577 generate_exception(ctx, EXCP_RI);
15578 break;
15579 }
15580 break;
15581 }
15582#ifdef TARGET_MIPS64
15583 case OPC_SHLL_OB_DSP:
15584 op2 = MASK_SHLL_OB(ctx->opcode);
15585 switch (op2) {
15586 case OPC_SHLL_PW:
15587 check_dsp(ctx);
15588 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15589 break;
15590 case OPC_SHLLV_PW:
15591 check_dsp(ctx);
15592 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15593 break;
15594 case OPC_SHLL_S_PW:
15595 check_dsp(ctx);
15596 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15597 break;
15598 case OPC_SHLLV_S_PW:
15599 check_dsp(ctx);
15600 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15601 break;
15602 case OPC_SHLL_OB:
15603 check_dsp(ctx);
15604 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15605 break;
15606 case OPC_SHLLV_OB:
15607 check_dsp(ctx);
15608 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15609 break;
15610 case OPC_SHLL_QH:
15611 check_dsp(ctx);
15612 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15613 break;
15614 case OPC_SHLLV_QH:
15615 check_dsp(ctx);
15616 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15617 break;
15618 case OPC_SHLL_S_QH:
15619 check_dsp(ctx);
15620 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15621 break;
15622 case OPC_SHLLV_S_QH:
15623 check_dsp(ctx);
15624 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15625 break;
15626 case OPC_SHRA_OB:
15627 check_dspr2(ctx);
15628 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15629 break;
15630 case OPC_SHRAV_OB:
15631 check_dspr2(ctx);
15632 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15633 break;
15634 case OPC_SHRA_R_OB:
15635 check_dspr2(ctx);
15636 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15637 break;
15638 case OPC_SHRAV_R_OB:
15639 check_dspr2(ctx);
15640 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15641 break;
15642 case OPC_SHRA_PW:
15643 check_dsp(ctx);
15644 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15645 break;
15646 case OPC_SHRAV_PW:
15647 check_dsp(ctx);
15648 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15649 break;
15650 case OPC_SHRA_R_PW:
15651 check_dsp(ctx);
15652 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15653 break;
15654 case OPC_SHRAV_R_PW:
15655 check_dsp(ctx);
15656 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15657 break;
15658 case OPC_SHRA_QH:
15659 check_dsp(ctx);
15660 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15661 break;
15662 case OPC_SHRAV_QH:
15663 check_dsp(ctx);
15664 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15665 break;
15666 case OPC_SHRA_R_QH:
15667 check_dsp(ctx);
15668 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15669 break;
15670 case OPC_SHRAV_R_QH:
15671 check_dsp(ctx);
15672 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15673 break;
15674 case OPC_SHRL_OB:
15675 check_dsp(ctx);
15676 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15677 break;
15678 case OPC_SHRLV_OB:
15679 check_dsp(ctx);
15680 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15681 break;
15682 case OPC_SHRL_QH:
15683 check_dspr2(ctx);
15684 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15685 break;
15686 case OPC_SHRLV_QH:
15687 check_dspr2(ctx);
15688 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15689 break;
15690 default: /* Invalid */
15691 MIPS_INVAL("MASK SHLL.OB");
15692 generate_exception(ctx, EXCP_RI);
15693 break;
15694 }
15695 break;
15696#endif
15697 }
15698
15699 tcg_temp_free(t0);
15700 tcg_temp_free(v1_t);
15701 tcg_temp_free(v2_t);
77c5fa8b
JL
15702}
15703
a22260ae
JL
15704static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15705 int ret, int v1, int v2, int check_ret)
15706{
a22260ae
JL
15707 TCGv_i32 t0;
15708 TCGv v1_t;
15709 TCGv v2_t;
15710
15711 if ((ret == 0) && (check_ret == 1)) {
15712 /* Treat as NOP. */
a22260ae
JL
15713 return;
15714 }
15715
15716 t0 = tcg_temp_new_i32();
15717 v1_t = tcg_temp_new();
15718 v2_t = tcg_temp_new();
15719
15720 tcg_gen_movi_i32(t0, ret);
15721 gen_load_gpr(v1_t, v1);
15722 gen_load_gpr(v2_t, v2);
15723
15724 switch (op1) {
15725 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15726 * the same mask and op1. */
15727 case OPC_MULT_G_2E:
639eadb9 15728 check_dspr2(ctx);
a22260ae
JL
15729 switch (op2) {
15730 case OPC_MUL_PH:
15731 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15732 break;
15733 case OPC_MUL_S_PH:
15734 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15735 break;
15736 case OPC_MULQ_S_W:
15737 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15738 break;
15739 case OPC_MULQ_RS_W:
15740 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15741 break;
15742 }
15743 break;
15744 case OPC_DPA_W_PH_DSP:
15745 switch (op2) {
15746 case OPC_DPAU_H_QBL:
15747 check_dsp(ctx);
15748 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15749 break;
15750 case OPC_DPAU_H_QBR:
15751 check_dsp(ctx);
15752 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15753 break;
15754 case OPC_DPSU_H_QBL:
15755 check_dsp(ctx);
15756 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15757 break;
15758 case OPC_DPSU_H_QBR:
15759 check_dsp(ctx);
15760 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15761 break;
15762 case OPC_DPA_W_PH:
15763 check_dspr2(ctx);
15764 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15765 break;
15766 case OPC_DPAX_W_PH:
15767 check_dspr2(ctx);
15768 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15769 break;
15770 case OPC_DPAQ_S_W_PH:
15771 check_dsp(ctx);
15772 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15773 break;
15774 case OPC_DPAQX_S_W_PH:
15775 check_dspr2(ctx);
15776 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15777 break;
15778 case OPC_DPAQX_SA_W_PH:
15779 check_dspr2(ctx);
15780 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15781 break;
15782 case OPC_DPS_W_PH:
15783 check_dspr2(ctx);
15784 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15785 break;
15786 case OPC_DPSX_W_PH:
15787 check_dspr2(ctx);
15788 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15789 break;
15790 case OPC_DPSQ_S_W_PH:
15791 check_dsp(ctx);
15792 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15793 break;
15794 case OPC_DPSQX_S_W_PH:
15795 check_dspr2(ctx);
15796 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15797 break;
15798 case OPC_DPSQX_SA_W_PH:
15799 check_dspr2(ctx);
15800 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15801 break;
15802 case OPC_MULSAQ_S_W_PH:
15803 check_dsp(ctx);
15804 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15805 break;
15806 case OPC_DPAQ_SA_L_W:
15807 check_dsp(ctx);
15808 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15809 break;
15810 case OPC_DPSQ_SA_L_W:
15811 check_dsp(ctx);
15812 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15813 break;
15814 case OPC_MAQ_S_W_PHL:
15815 check_dsp(ctx);
15816 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15817 break;
15818 case OPC_MAQ_S_W_PHR:
15819 check_dsp(ctx);
15820 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15821 break;
15822 case OPC_MAQ_SA_W_PHL:
15823 check_dsp(ctx);
15824 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15825 break;
15826 case OPC_MAQ_SA_W_PHR:
15827 check_dsp(ctx);
15828 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15829 break;
15830 case OPC_MULSA_W_PH:
15831 check_dspr2(ctx);
15832 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15833 break;
15834 }
15835 break;
15836#ifdef TARGET_MIPS64
15837 case OPC_DPAQ_W_QH_DSP:
15838 {
15839 int ac = ret & 0x03;
15840 tcg_gen_movi_i32(t0, ac);
15841
15842 switch (op2) {
15843 case OPC_DMADD:
15844 check_dsp(ctx);
15845 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15846 break;
15847 case OPC_DMADDU:
15848 check_dsp(ctx);
15849 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15850 break;
15851 case OPC_DMSUB:
15852 check_dsp(ctx);
15853 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15854 break;
15855 case OPC_DMSUBU:
15856 check_dsp(ctx);
15857 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15858 break;
15859 case OPC_DPA_W_QH:
15860 check_dspr2(ctx);
15861 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15862 break;
15863 case OPC_DPAQ_S_W_QH:
15864 check_dsp(ctx);
15865 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15866 break;
15867 case OPC_DPAQ_SA_L_PW:
15868 check_dsp(ctx);
15869 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15870 break;
15871 case OPC_DPAU_H_OBL:
15872 check_dsp(ctx);
15873 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15874 break;
15875 case OPC_DPAU_H_OBR:
15876 check_dsp(ctx);
15877 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15878 break;
15879 case OPC_DPS_W_QH:
15880 check_dspr2(ctx);
15881 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15882 break;
15883 case OPC_DPSQ_S_W_QH:
15884 check_dsp(ctx);
15885 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15886 break;
15887 case OPC_DPSQ_SA_L_PW:
15888 check_dsp(ctx);
15889 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15890 break;
15891 case OPC_DPSU_H_OBL:
15892 check_dsp(ctx);
15893 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15894 break;
15895 case OPC_DPSU_H_OBR:
15896 check_dsp(ctx);
15897 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15898 break;
15899 case OPC_MAQ_S_L_PWL:
15900 check_dsp(ctx);
15901 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15902 break;
15903 case OPC_MAQ_S_L_PWR:
15904 check_dsp(ctx);
15905 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15906 break;
15907 case OPC_MAQ_S_W_QHLL:
15908 check_dsp(ctx);
15909 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15910 break;
15911 case OPC_MAQ_SA_W_QHLL:
15912 check_dsp(ctx);
15913 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15914 break;
15915 case OPC_MAQ_S_W_QHLR:
15916 check_dsp(ctx);
15917 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15918 break;
15919 case OPC_MAQ_SA_W_QHLR:
15920 check_dsp(ctx);
15921 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15922 break;
15923 case OPC_MAQ_S_W_QHRL:
15924 check_dsp(ctx);
15925 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15926 break;
15927 case OPC_MAQ_SA_W_QHRL:
15928 check_dsp(ctx);
15929 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15930 break;
15931 case OPC_MAQ_S_W_QHRR:
15932 check_dsp(ctx);
15933 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15934 break;
15935 case OPC_MAQ_SA_W_QHRR:
15936 check_dsp(ctx);
15937 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15938 break;
15939 case OPC_MULSAQ_S_L_PW:
15940 check_dsp(ctx);
15941 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15942 break;
15943 case OPC_MULSAQ_S_W_QH:
15944 check_dsp(ctx);
15945 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15946 break;
15947 }
15948 }
15949 break;
15950#endif
15951 case OPC_ADDU_QB_DSP:
15952 switch (op2) {
15953 case OPC_MULEU_S_PH_QBL:
15954 check_dsp(ctx);
15955 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15956 break;
15957 case OPC_MULEU_S_PH_QBR:
15958 check_dsp(ctx);
15959 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15960 break;
15961 case OPC_MULQ_RS_PH:
15962 check_dsp(ctx);
15963 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15964 break;
15965 case OPC_MULEQ_S_W_PHL:
15966 check_dsp(ctx);
15967 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15968 break;
15969 case OPC_MULEQ_S_W_PHR:
15970 check_dsp(ctx);
15971 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15972 break;
15973 case OPC_MULQ_S_PH:
15974 check_dspr2(ctx);
15975 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15976 break;
15977 }
15978 break;
15979#ifdef TARGET_MIPS64
15980 case OPC_ADDU_OB_DSP:
15981 switch (op2) {
15982 case OPC_MULEQ_S_PW_QHL:
15983 check_dsp(ctx);
15984 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15985 break;
15986 case OPC_MULEQ_S_PW_QHR:
15987 check_dsp(ctx);
15988 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15989 break;
15990 case OPC_MULEU_S_QH_OBL:
15991 check_dsp(ctx);
15992 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15993 break;
15994 case OPC_MULEU_S_QH_OBR:
15995 check_dsp(ctx);
15996 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15997 break;
15998 case OPC_MULQ_RS_QH:
15999 check_dsp(ctx);
16000 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16001 break;
16002 }
16003 break;
16004#endif
16005 }
16006
16007 tcg_temp_free_i32(t0);
16008 tcg_temp_free(v1_t);
16009 tcg_temp_free(v2_t);
a22260ae
JL
16010}
16011
d75c135e 16012static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16013 int ret, int val)
16014{
1cb6686c
JL
16015 int16_t imm;
16016 TCGv t0;
16017 TCGv val_t;
16018
16019 if (ret == 0) {
16020 /* Treat as NOP. */
1cb6686c
JL
16021 return;
16022 }
16023
16024 t0 = tcg_temp_new();
16025 val_t = tcg_temp_new();
16026 gen_load_gpr(val_t, val);
16027
16028 switch (op1) {
16029 case OPC_ABSQ_S_PH_DSP:
16030 switch (op2) {
16031 case OPC_BITREV:
16032 check_dsp(ctx);
16033 gen_helper_bitrev(cpu_gpr[ret], val_t);
16034 break;
16035 case OPC_REPL_QB:
16036 check_dsp(ctx);
16037 {
16038 target_long result;
16039 imm = (ctx->opcode >> 16) & 0xFF;
16040 result = (uint32_t)imm << 24 |
16041 (uint32_t)imm << 16 |
16042 (uint32_t)imm << 8 |
16043 (uint32_t)imm;
16044 result = (int32_t)result;
16045 tcg_gen_movi_tl(cpu_gpr[ret], result);
16046 }
16047 break;
16048 case OPC_REPLV_QB:
16049 check_dsp(ctx);
16050 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16051 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16052 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16053 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16054 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16055 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16056 break;
16057 case OPC_REPL_PH:
16058 check_dsp(ctx);
16059 {
16060 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16061 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16062 tcg_gen_movi_tl(cpu_gpr[ret], \
16063 (target_long)((int32_t)imm << 16 | \
c4aaba92 16064 (uint16_t)imm));
1cb6686c
JL
16065 }
16066 break;
16067 case OPC_REPLV_PH:
16068 check_dsp(ctx);
16069 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16070 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16071 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16072 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16073 break;
16074 }
16075 break;
16076#ifdef TARGET_MIPS64
16077 case OPC_ABSQ_S_QH_DSP:
16078 switch (op2) {
16079 case OPC_REPL_OB:
16080 check_dsp(ctx);
16081 {
16082 target_long temp;
16083
16084 imm = (ctx->opcode >> 16) & 0xFF;
16085 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16086 temp = (temp << 16) | temp;
16087 temp = (temp << 32) | temp;
16088 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16089 break;
16090 }
16091 case OPC_REPL_PW:
16092 check_dsp(ctx);
16093 {
16094 target_long temp;
16095
16096 imm = (ctx->opcode >> 16) & 0x03FF;
16097 imm = (int16_t)(imm << 6) >> 6;
16098 temp = ((target_long)imm << 32) \
16099 | ((target_long)imm & 0xFFFFFFFF);
16100 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16101 break;
16102 }
16103 case OPC_REPL_QH:
16104 check_dsp(ctx);
16105 {
16106 target_long temp;
16107
16108 imm = (ctx->opcode >> 16) & 0x03FF;
16109 imm = (int16_t)(imm << 6) >> 6;
16110
16111 temp = ((uint64_t)(uint16_t)imm << 48) |
16112 ((uint64_t)(uint16_t)imm << 32) |
16113 ((uint64_t)(uint16_t)imm << 16) |
16114 (uint64_t)(uint16_t)imm;
16115 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16116 break;
16117 }
16118 case OPC_REPLV_OB:
16119 check_dsp(ctx);
16120 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16121 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16122 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16123 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16124 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16125 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16126 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16127 break;
16128 case OPC_REPLV_PW:
16129 check_dsp(ctx);
16130 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16131 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16132 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16133 break;
16134 case OPC_REPLV_QH:
16135 check_dsp(ctx);
16136 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16137 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16138 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16139 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16140 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16141 break;
16142 }
16143 break;
16144#endif
16145 }
16146 tcg_temp_free(t0);
16147 tcg_temp_free(val_t);
1cb6686c
JL
16148}
16149
26690560
JL
16150static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16151 uint32_t op1, uint32_t op2,
16152 int ret, int v1, int v2, int check_ret)
16153{
26690560
JL
16154 TCGv t1;
16155 TCGv v1_t;
16156 TCGv v2_t;
16157
16158 if ((ret == 0) && (check_ret == 1)) {
16159 /* Treat as NOP. */
26690560
JL
16160 return;
16161 }
16162
26690560
JL
16163 t1 = tcg_temp_new();
16164 v1_t = tcg_temp_new();
16165 v2_t = tcg_temp_new();
16166
16167 gen_load_gpr(v1_t, v1);
16168 gen_load_gpr(v2_t, v2);
16169
16170 switch (op1) {
26690560
JL
16171 case OPC_CMPU_EQ_QB_DSP:
16172 switch (op2) {
16173 case OPC_CMPU_EQ_QB:
16174 check_dsp(ctx);
16175 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16176 break;
16177 case OPC_CMPU_LT_QB:
16178 check_dsp(ctx);
16179 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16180 break;
16181 case OPC_CMPU_LE_QB:
16182 check_dsp(ctx);
16183 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16184 break;
16185 case OPC_CMPGU_EQ_QB:
16186 check_dsp(ctx);
16187 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16188 break;
16189 case OPC_CMPGU_LT_QB:
16190 check_dsp(ctx);
16191 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16192 break;
16193 case OPC_CMPGU_LE_QB:
16194 check_dsp(ctx);
16195 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16196 break;
16197 case OPC_CMPGDU_EQ_QB:
16198 check_dspr2(ctx);
16199 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16200 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16201 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16202 tcg_gen_shli_tl(t1, t1, 24);
16203 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16204 break;
16205 case OPC_CMPGDU_LT_QB:
16206 check_dspr2(ctx);
16207 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16208 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16209 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16210 tcg_gen_shli_tl(t1, t1, 24);
16211 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16212 break;
16213 case OPC_CMPGDU_LE_QB:
16214 check_dspr2(ctx);
16215 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16216 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16217 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16218 tcg_gen_shli_tl(t1, t1, 24);
16219 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16220 break;
16221 case OPC_CMP_EQ_PH:
16222 check_dsp(ctx);
16223 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16224 break;
16225 case OPC_CMP_LT_PH:
16226 check_dsp(ctx);
16227 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16228 break;
16229 case OPC_CMP_LE_PH:
16230 check_dsp(ctx);
16231 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16232 break;
16233 case OPC_PICK_QB:
16234 check_dsp(ctx);
16235 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16236 break;
16237 case OPC_PICK_PH:
16238 check_dsp(ctx);
16239 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16240 break;
16241 case OPC_PACKRL_PH:
16242 check_dsp(ctx);
16243 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16244 break;
16245 }
16246 break;
16247#ifdef TARGET_MIPS64
16248 case OPC_CMPU_EQ_OB_DSP:
16249 switch (op2) {
16250 case OPC_CMP_EQ_PW:
16251 check_dsp(ctx);
16252 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16253 break;
16254 case OPC_CMP_LT_PW:
16255 check_dsp(ctx);
16256 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16257 break;
16258 case OPC_CMP_LE_PW:
16259 check_dsp(ctx);
16260 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16261 break;
16262 case OPC_CMP_EQ_QH:
16263 check_dsp(ctx);
16264 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16265 break;
16266 case OPC_CMP_LT_QH:
16267 check_dsp(ctx);
16268 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16269 break;
16270 case OPC_CMP_LE_QH:
16271 check_dsp(ctx);
16272 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16273 break;
16274 case OPC_CMPGDU_EQ_OB:
16275 check_dspr2(ctx);
16276 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16277 break;
16278 case OPC_CMPGDU_LT_OB:
16279 check_dspr2(ctx);
16280 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16281 break;
16282 case OPC_CMPGDU_LE_OB:
16283 check_dspr2(ctx);
16284 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16285 break;
16286 case OPC_CMPGU_EQ_OB:
16287 check_dsp(ctx);
16288 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16289 break;
16290 case OPC_CMPGU_LT_OB:
16291 check_dsp(ctx);
16292 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16293 break;
16294 case OPC_CMPGU_LE_OB:
16295 check_dsp(ctx);
16296 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16297 break;
16298 case OPC_CMPU_EQ_OB:
16299 check_dsp(ctx);
16300 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16301 break;
16302 case OPC_CMPU_LT_OB:
16303 check_dsp(ctx);
16304 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16305 break;
16306 case OPC_CMPU_LE_OB:
16307 check_dsp(ctx);
16308 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16309 break;
16310 case OPC_PACKRL_PW:
16311 check_dsp(ctx);
16312 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16313 break;
16314 case OPC_PICK_OB:
16315 check_dsp(ctx);
16316 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16317 break;
16318 case OPC_PICK_PW:
16319 check_dsp(ctx);
16320 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16321 break;
16322 case OPC_PICK_QH:
16323 check_dsp(ctx);
16324 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16325 break;
16326 }
16327 break;
df6126a7
AJ
16328#endif
16329 }
16330
16331 tcg_temp_free(t1);
16332 tcg_temp_free(v1_t);
16333 tcg_temp_free(v2_t);
df6126a7
AJ
16334}
16335
16336static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16337 uint32_t op1, int rt, int rs, int sa)
16338{
df6126a7
AJ
16339 TCGv t0;
16340
16341 check_dspr2(ctx);
16342
16343 if (rt == 0) {
16344 /* Treat as NOP. */
df6126a7
AJ
16345 return;
16346 }
16347
16348 t0 = tcg_temp_new();
16349 gen_load_gpr(t0, rs);
16350
16351 switch (op1) {
16352 case OPC_APPEND_DSP:
16353 switch (MASK_APPEND(ctx->opcode)) {
16354 case OPC_APPEND:
16355 if (sa != 0) {
16356 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16357 }
16358 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16359 break;
16360 case OPC_PREPEND:
16361 if (sa != 0) {
16362 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16363 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16364 tcg_gen_shli_tl(t0, t0, 32 - sa);
16365 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16366 }
16367 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16368 break;
16369 case OPC_BALIGN:
16370 sa &= 3;
16371 if (sa != 0 && sa != 2) {
16372 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16373 tcg_gen_ext32u_tl(t0, t0);
16374 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16375 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16376 }
16377 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16378 break;
16379 default: /* Invalid */
16380 MIPS_INVAL("MASK APPEND");
16381 generate_exception(ctx, EXCP_RI);
16382 break;
16383 }
16384 break;
16385#ifdef TARGET_MIPS64
26690560 16386 case OPC_DAPPEND_DSP:
df6126a7 16387 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16388 case OPC_DAPPEND:
df6126a7
AJ
16389 if (sa != 0) {
16390 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16391 }
26690560
JL
16392 break;
16393 case OPC_PREPENDD:
df6126a7
AJ
16394 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16395 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16396 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16397 break;
16398 case OPC_PREPENDW:
df6126a7
AJ
16399 if (sa != 0) {
16400 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16401 tcg_gen_shli_tl(t0, t0, 64 - sa);
16402 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16403 }
26690560
JL
16404 break;
16405 case OPC_DBALIGN:
df6126a7
AJ
16406 sa &= 7;
16407 if (sa != 0 && sa != 2 && sa != 4) {
16408 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16409 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16410 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16411 }
26690560
JL
16412 break;
16413 default: /* Invalid */
16414 MIPS_INVAL("MASK DAPPEND");
16415 generate_exception(ctx, EXCP_RI);
16416 break;
16417 }
16418 break;
16419#endif
16420 }
df6126a7 16421 tcg_temp_free(t0);
26690560
JL
16422}
16423
b53371ed
JL
16424static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16425 int ret, int v1, int v2, int check_ret)
16426
16427{
b53371ed
JL
16428 TCGv t0;
16429 TCGv t1;
16430 TCGv v1_t;
16431 TCGv v2_t;
16432 int16_t imm;
16433
16434 if ((ret == 0) && (check_ret == 1)) {
16435 /* Treat as NOP. */
b53371ed
JL
16436 return;
16437 }
16438
16439 t0 = tcg_temp_new();
16440 t1 = tcg_temp_new();
16441 v1_t = tcg_temp_new();
16442 v2_t = tcg_temp_new();
16443
16444 gen_load_gpr(v1_t, v1);
16445 gen_load_gpr(v2_t, v2);
16446
16447 switch (op1) {
16448 case OPC_EXTR_W_DSP:
16449 check_dsp(ctx);
16450 switch (op2) {
16451 case OPC_EXTR_W:
16452 tcg_gen_movi_tl(t0, v2);
16453 tcg_gen_movi_tl(t1, v1);
16454 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16455 break;
16456 case OPC_EXTR_R_W:
16457 tcg_gen_movi_tl(t0, v2);
16458 tcg_gen_movi_tl(t1, v1);
16459 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16460 break;
16461 case OPC_EXTR_RS_W:
16462 tcg_gen_movi_tl(t0, v2);
16463 tcg_gen_movi_tl(t1, v1);
16464 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16465 break;
16466 case OPC_EXTR_S_H:
16467 tcg_gen_movi_tl(t0, v2);
16468 tcg_gen_movi_tl(t1, v1);
16469 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16470 break;
16471 case OPC_EXTRV_S_H:
16472 tcg_gen_movi_tl(t0, v2);
16473 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16474 break;
16475 case OPC_EXTRV_W:
16476 tcg_gen_movi_tl(t0, v2);
16477 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16478 break;
16479 case OPC_EXTRV_R_W:
16480 tcg_gen_movi_tl(t0, v2);
16481 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16482 break;
16483 case OPC_EXTRV_RS_W:
16484 tcg_gen_movi_tl(t0, v2);
16485 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16486 break;
16487 case OPC_EXTP:
16488 tcg_gen_movi_tl(t0, v2);
16489 tcg_gen_movi_tl(t1, v1);
16490 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16491 break;
16492 case OPC_EXTPV:
16493 tcg_gen_movi_tl(t0, v2);
16494 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16495 break;
16496 case OPC_EXTPDP:
16497 tcg_gen_movi_tl(t0, v2);
16498 tcg_gen_movi_tl(t1, v1);
16499 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16500 break;
16501 case OPC_EXTPDPV:
16502 tcg_gen_movi_tl(t0, v2);
16503 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16504 break;
16505 case OPC_SHILO:
16506 imm = (ctx->opcode >> 20) & 0x3F;
16507 tcg_gen_movi_tl(t0, ret);
16508 tcg_gen_movi_tl(t1, imm);
16509 gen_helper_shilo(t0, t1, cpu_env);
16510 break;
16511 case OPC_SHILOV:
16512 tcg_gen_movi_tl(t0, ret);
16513 gen_helper_shilo(t0, v1_t, cpu_env);
16514 break;
16515 case OPC_MTHLIP:
16516 tcg_gen_movi_tl(t0, ret);
16517 gen_helper_mthlip(t0, v1_t, cpu_env);
16518 break;
16519 case OPC_WRDSP:
16520 imm = (ctx->opcode >> 11) & 0x3FF;
16521 tcg_gen_movi_tl(t0, imm);
16522 gen_helper_wrdsp(v1_t, t0, cpu_env);
16523 break;
16524 case OPC_RDDSP:
16525 imm = (ctx->opcode >> 16) & 0x03FF;
16526 tcg_gen_movi_tl(t0, imm);
16527 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16528 break;
16529 }
16530 break;
16531#ifdef TARGET_MIPS64
16532 case OPC_DEXTR_W_DSP:
16533 check_dsp(ctx);
16534 switch (op2) {
16535 case OPC_DMTHLIP:
16536 tcg_gen_movi_tl(t0, ret);
16537 gen_helper_dmthlip(v1_t, t0, cpu_env);
16538 break;
16539 case OPC_DSHILO:
16540 {
16541 int shift = (ctx->opcode >> 19) & 0x7F;
16542 int ac = (ctx->opcode >> 11) & 0x03;
16543 tcg_gen_movi_tl(t0, shift);
16544 tcg_gen_movi_tl(t1, ac);
16545 gen_helper_dshilo(t0, t1, cpu_env);
16546 break;
16547 }
16548 case OPC_DSHILOV:
16549 {
16550 int ac = (ctx->opcode >> 11) & 0x03;
16551 tcg_gen_movi_tl(t0, ac);
16552 gen_helper_dshilo(v1_t, t0, cpu_env);
16553 break;
16554 }
16555 case OPC_DEXTP:
16556 tcg_gen_movi_tl(t0, v2);
16557 tcg_gen_movi_tl(t1, v1);
16558
16559 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16560 break;
16561 case OPC_DEXTPV:
16562 tcg_gen_movi_tl(t0, v2);
16563 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16564 break;
16565 case OPC_DEXTPDP:
16566 tcg_gen_movi_tl(t0, v2);
16567 tcg_gen_movi_tl(t1, v1);
16568 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16569 break;
16570 case OPC_DEXTPDPV:
16571 tcg_gen_movi_tl(t0, v2);
16572 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16573 break;
16574 case OPC_DEXTR_L:
16575 tcg_gen_movi_tl(t0, v2);
16576 tcg_gen_movi_tl(t1, v1);
16577 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16578 break;
16579 case OPC_DEXTR_R_L:
16580 tcg_gen_movi_tl(t0, v2);
16581 tcg_gen_movi_tl(t1, v1);
16582 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16583 break;
16584 case OPC_DEXTR_RS_L:
16585 tcg_gen_movi_tl(t0, v2);
16586 tcg_gen_movi_tl(t1, v1);
16587 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16588 break;
16589 case OPC_DEXTR_W:
16590 tcg_gen_movi_tl(t0, v2);
16591 tcg_gen_movi_tl(t1, v1);
16592 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16593 break;
16594 case OPC_DEXTR_R_W:
16595 tcg_gen_movi_tl(t0, v2);
16596 tcg_gen_movi_tl(t1, v1);
16597 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16598 break;
16599 case OPC_DEXTR_RS_W:
16600 tcg_gen_movi_tl(t0, v2);
16601 tcg_gen_movi_tl(t1, v1);
16602 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16603 break;
16604 case OPC_DEXTR_S_H:
16605 tcg_gen_movi_tl(t0, v2);
16606 tcg_gen_movi_tl(t1, v1);
16607 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16608 break;
16609 case OPC_DEXTRV_S_H:
16610 tcg_gen_movi_tl(t0, v2);
16611 tcg_gen_movi_tl(t1, v1);
16612 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16613 break;
16614 case OPC_DEXTRV_L:
16615 tcg_gen_movi_tl(t0, v2);
16616 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16617 break;
16618 case OPC_DEXTRV_R_L:
16619 tcg_gen_movi_tl(t0, v2);
16620 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16621 break;
16622 case OPC_DEXTRV_RS_L:
16623 tcg_gen_movi_tl(t0, v2);
16624 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16625 break;
16626 case OPC_DEXTRV_W:
16627 tcg_gen_movi_tl(t0, v2);
16628 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16629 break;
16630 case OPC_DEXTRV_R_W:
16631 tcg_gen_movi_tl(t0, v2);
16632 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16633 break;
16634 case OPC_DEXTRV_RS_W:
16635 tcg_gen_movi_tl(t0, v2);
16636 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16637 break;
16638 }
16639 break;
16640#endif
16641 }
16642
16643 tcg_temp_free(t0);
16644 tcg_temp_free(t1);
16645 tcg_temp_free(v1_t);
16646 tcg_temp_free(v2_t);
b53371ed
JL
16647}
16648
9b1a1d68
JL
16649/* End MIPSDSP functions. */
16650
10dc65db
LA
16651static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16652{
4267d3e6 16653 int rs, rt, rd, sa;
b42ee5e1 16654 uint32_t op1, op2;
10dc65db
LA
16655
16656 rs = (ctx->opcode >> 21) & 0x1f;
16657 rt = (ctx->opcode >> 16) & 0x1f;
16658 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16659 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16660
16661 op1 = MASK_SPECIAL(ctx->opcode);
16662 switch (op1) {
d4ea6acd 16663 case OPC_LSA:
1f1b4c00 16664 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16665 break;
b42ee5e1
LA
16666 case OPC_MULT ... OPC_DIVU:
16667 op2 = MASK_R6_MULDIV(ctx->opcode);
16668 switch (op2) {
16669 case R6_OPC_MUL:
16670 case R6_OPC_MUH:
16671 case R6_OPC_MULU:
16672 case R6_OPC_MUHU:
16673 case R6_OPC_DIV:
16674 case R6_OPC_MOD:
16675 case R6_OPC_DIVU:
16676 case R6_OPC_MODU:
16677 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16678 break;
16679 default:
16680 MIPS_INVAL("special_r6 muldiv");
16681 generate_exception(ctx, EXCP_RI);
16682 break;
16683 }
16684 break;
10dc65db
LA
16685 case OPC_SELEQZ:
16686 case OPC_SELNEZ:
16687 gen_cond_move(ctx, op1, rd, rs, rt);
16688 break;
4267d3e6
LA
16689 case R6_OPC_CLO:
16690 case R6_OPC_CLZ:
16691 if (rt == 0 && sa == 1) {
16692 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16693 We need additionally to check other fields */
16694 gen_cl(ctx, op1, rd, rs);
16695 } else {
16696 generate_exception(ctx, EXCP_RI);
16697 }
16698 break;
16699 case R6_OPC_SDBBP:
3b3c1694
LA
16700 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16701 gen_helper_do_semihosting(cpu_env);
faf1f68b 16702 } else {
3b3c1694
LA
16703 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16704 generate_exception(ctx, EXCP_RI);
16705 } else {
16706 generate_exception(ctx, EXCP_DBp);
16707 }
faf1f68b 16708 }
4267d3e6 16709 break;
b42ee5e1 16710#if defined(TARGET_MIPS64)
d4ea6acd
LA
16711 case OPC_DLSA:
16712 check_mips_64(ctx);
1f1b4c00 16713 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16714 break;
4267d3e6
LA
16715 case R6_OPC_DCLO:
16716 case R6_OPC_DCLZ:
16717 if (rt == 0 && sa == 1) {
16718 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16719 We need additionally to check other fields */
16720 check_mips_64(ctx);
16721 gen_cl(ctx, op1, rd, rs);
16722 } else {
16723 generate_exception(ctx, EXCP_RI);
16724 }
16725 break;
b42ee5e1
LA
16726 case OPC_DMULT ... OPC_DDIVU:
16727 op2 = MASK_R6_MULDIV(ctx->opcode);
16728 switch (op2) {
16729 case R6_OPC_DMUL:
16730 case R6_OPC_DMUH:
16731 case R6_OPC_DMULU:
16732 case R6_OPC_DMUHU:
16733 case R6_OPC_DDIV:
16734 case R6_OPC_DMOD:
16735 case R6_OPC_DDIVU:
16736 case R6_OPC_DMODU:
16737 check_mips_64(ctx);
16738 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16739 break;
16740 default:
16741 MIPS_INVAL("special_r6 muldiv");
16742 generate_exception(ctx, EXCP_RI);
16743 break;
16744 }
16745 break;
16746#endif
10dc65db
LA
16747 default: /* Invalid */
16748 MIPS_INVAL("special_r6");
16749 generate_exception(ctx, EXCP_RI);
16750 break;
16751 }
16752}
16753
16754static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16755{
b42ee5e1 16756 int rs, rt, rd, sa;
10dc65db
LA
16757 uint32_t op1;
16758
16759 rs = (ctx->opcode >> 21) & 0x1f;
16760 rt = (ctx->opcode >> 16) & 0x1f;
16761 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16762 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16763
16764 op1 = MASK_SPECIAL(ctx->opcode);
16765 switch (op1) {
16766 case OPC_MOVN: /* Conditional move */
16767 case OPC_MOVZ:
16768 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16769 INSN_LOONGSON2E | INSN_LOONGSON2F);
16770 gen_cond_move(ctx, op1, rd, rs, rt);
16771 break;
16772 case OPC_MFHI: /* Move from HI/LO */
16773 case OPC_MFLO:
16774 gen_HILO(ctx, op1, rs & 3, rd);
16775 break;
16776 case OPC_MTHI:
16777 case OPC_MTLO: /* Move to HI/LO */
16778 gen_HILO(ctx, op1, rd & 3, rs);
16779 break;
16780 case OPC_MOVCI:
16781 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16782 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16783 check_cp1_enabled(ctx);
16784 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16785 (ctx->opcode >> 16) & 1);
16786 } else {
16787 generate_exception_err(ctx, EXCP_CpU, 1);
16788 }
16789 break;
b42ee5e1
LA
16790 case OPC_MULT:
16791 case OPC_MULTU:
16792 if (sa) {
16793 check_insn(ctx, INSN_VR54XX);
16794 op1 = MASK_MUL_VR54XX(ctx->opcode);
16795 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16796 } else {
16797 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16798 }
16799 break;
16800 case OPC_DIV:
16801 case OPC_DIVU:
16802 gen_muldiv(ctx, op1, 0, rs, rt);
16803 break;
16804#if defined(TARGET_MIPS64)
16805 case OPC_DMULT ... OPC_DDIVU:
16806 check_insn(ctx, ISA_MIPS3);
16807 check_mips_64(ctx);
16808 gen_muldiv(ctx, op1, 0, rs, rt);
16809 break;
16810#endif
0aefa333 16811 case OPC_JR:
b231c103 16812 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16813 break;
4267d3e6
LA
16814 case OPC_SPIM:
16815#ifdef MIPS_STRICT_STANDARD
16816 MIPS_INVAL("SPIM");
16817 generate_exception(ctx, EXCP_RI);
16818#else
16819 /* Implemented as RI exception for now. */
16820 MIPS_INVAL("spim (unofficial)");
16821 generate_exception(ctx, EXCP_RI);
16822#endif
16823 break;
10dc65db
LA
16824 default: /* Invalid */
16825 MIPS_INVAL("special_legacy");
16826 generate_exception(ctx, EXCP_RI);
16827 break;
16828 }
16829}
16830
099e5b4d 16831static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16832{
3c824109 16833 int rs, rt, rd, sa;
099e5b4d 16834 uint32_t op1;
3c824109 16835
3c824109
NF
16836 rs = (ctx->opcode >> 21) & 0x1f;
16837 rt = (ctx->opcode >> 16) & 0x1f;
16838 rd = (ctx->opcode >> 11) & 0x1f;
16839 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16840
16841 op1 = MASK_SPECIAL(ctx->opcode);
16842 switch (op1) {
16843 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16844 if (sa == 5 && rd == 0 &&
16845 rs == 0 && rt == 0) { /* PAUSE */
16846 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16847 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
16848 generate_exception(ctx, EXCP_RI);
16849 break;
16850 }
16851 }
16852 /* Fallthrough */
099e5b4d
LA
16853 case OPC_SRA:
16854 gen_shift_imm(ctx, op1, rd, rt, sa);
16855 break;
16856 case OPC_SRL:
16857 switch ((ctx->opcode >> 21) & 0x1f) {
16858 case 1:
16859 /* rotr is decoded as srl on non-R2 CPUs */
16860 if (ctx->insn_flags & ISA_MIPS32R2) {
16861 op1 = OPC_ROTR;
ea63e2c3 16862 }
099e5b4d
LA
16863 /* Fallthrough */
16864 case 0:
16865 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16866 break;
099e5b4d
LA
16867 default:
16868 generate_exception(ctx, EXCP_RI);
ea63e2c3 16869 break;
099e5b4d
LA
16870 }
16871 break;
099e5b4d
LA
16872 case OPC_ADD ... OPC_SUBU:
16873 gen_arith(ctx, op1, rd, rs, rt);
16874 break;
16875 case OPC_SLLV: /* Shifts */
16876 case OPC_SRAV:
16877 gen_shift(ctx, op1, rd, rs, rt);
16878 break;
16879 case OPC_SRLV:
16880 switch ((ctx->opcode >> 6) & 0x1f) {
16881 case 1:
16882 /* rotrv is decoded as srlv on non-R2 CPUs */
16883 if (ctx->insn_flags & ISA_MIPS32R2) {
16884 op1 = OPC_ROTRV;
26135ead 16885 }
099e5b4d
LA
16886 /* Fallthrough */
16887 case 0:
16888 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16889 break;
099e5b4d
LA
16890 default:
16891 generate_exception(ctx, EXCP_RI);
6af0bf9c 16892 break;
099e5b4d
LA
16893 }
16894 break;
16895 case OPC_SLT: /* Set on less than */
16896 case OPC_SLTU:
16897 gen_slt(ctx, op1, rd, rs, rt);
16898 break;
16899 case OPC_AND: /* Logic*/
16900 case OPC_OR:
16901 case OPC_NOR:
16902 case OPC_XOR:
16903 gen_logic(ctx, op1, rd, rs, rt);
16904 break;
0aefa333 16905 case OPC_JALR:
b231c103 16906 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16907 break;
16908 case OPC_TGE ... OPC_TEQ: /* Traps */
16909 case OPC_TNE:
d9224450 16910 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16911 gen_trap(ctx, op1, rs, rt, -1);
16912 break;
d4ea6acd 16913 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16914 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16915 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16916 decode_opc_special_r6(env, ctx);
16917 } else {
16918 /* Pmon entry point, also R4010 selsl */
b48cfdff 16919#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16920 MIPS_INVAL("PMON / selsl");
16921 generate_exception(ctx, EXCP_RI);
b48cfdff 16922#else
d4ea6acd 16923 gen_helper_0e0i(pmon, sa);
b48cfdff 16924#endif
d4ea6acd 16925 }
099e5b4d
LA
16926 break;
16927 case OPC_SYSCALL:
16928 generate_exception(ctx, EXCP_SYSCALL);
16929 ctx->bstate = BS_STOP;
16930 break;
16931 case OPC_BREAK:
16932 generate_exception(ctx, EXCP_BREAK);
16933 break;
099e5b4d 16934 case OPC_SYNC:
d9224450 16935 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16936 /* Treat as NOP. */
16937 break;
4ad40f36 16938
d26bc211 16939#if defined(TARGET_MIPS64)
099e5b4d
LA
16940 /* MIPS64 specific opcodes */
16941 case OPC_DSLL:
16942 case OPC_DSRA:
16943 case OPC_DSLL32:
16944 case OPC_DSRA32:
16945 check_insn(ctx, ISA_MIPS3);
16946 check_mips_64(ctx);
16947 gen_shift_imm(ctx, op1, rd, rt, sa);
16948 break;
16949 case OPC_DSRL:
16950 switch ((ctx->opcode >> 21) & 0x1f) {
16951 case 1:
16952 /* drotr is decoded as dsrl on non-R2 CPUs */
16953 if (ctx->insn_flags & ISA_MIPS32R2) {
16954 op1 = OPC_DROTR;
ea63e2c3 16955 }
099e5b4d
LA
16956 /* Fallthrough */
16957 case 0:
d75c135e 16958 check_insn(ctx, ISA_MIPS3);
e189e748 16959 check_mips_64(ctx);
099e5b4d 16960 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16961 break;
099e5b4d
LA
16962 default:
16963 generate_exception(ctx, EXCP_RI);
460f00c4 16964 break;
099e5b4d
LA
16965 }
16966 break;
16967 case OPC_DSRL32:
16968 switch ((ctx->opcode >> 21) & 0x1f) {
16969 case 1:
16970 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16971 if (ctx->insn_flags & ISA_MIPS32R2) {
16972 op1 = OPC_DROTR32;
ea63e2c3 16973 }
099e5b4d
LA
16974 /* Fallthrough */
16975 case 0:
d75c135e 16976 check_insn(ctx, ISA_MIPS3);
e189e748 16977 check_mips_64(ctx);
099e5b4d 16978 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16979 break;
099e5b4d 16980 default:
6af0bf9c
FB
16981 generate_exception(ctx, EXCP_RI);
16982 break;
16983 }
16984 break;
099e5b4d
LA
16985 case OPC_DADD ... OPC_DSUBU:
16986 check_insn(ctx, ISA_MIPS3);
16987 check_mips_64(ctx);
16988 gen_arith(ctx, op1, rd, rs, rt);
16989 break;
16990 case OPC_DSLLV:
16991 case OPC_DSRAV:
16992 check_insn(ctx, ISA_MIPS3);
16993 check_mips_64(ctx);
16994 gen_shift(ctx, op1, rd, rs, rt);
16995 break;
16996 case OPC_DSRLV:
16997 switch ((ctx->opcode >> 6) & 0x1f) {
16998 case 1:
16999 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17000 if (ctx->insn_flags & ISA_MIPS32R2) {
17001 op1 = OPC_DROTRV;
6af0bf9c 17002 }
099e5b4d
LA
17003 /* Fallthrough */
17004 case 0:
17005 check_insn(ctx, ISA_MIPS3);
e189e748 17006 check_mips_64(ctx);
099e5b4d 17007 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17008 break;
099e5b4d 17009 default:
6af0bf9c
FB
17010 generate_exception(ctx, EXCP_RI);
17011 break;
17012 }
17013 break;
f7685877
YK
17014 case OPC_DLSA:
17015 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17016 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17017 decode_opc_special_r6(env, ctx);
17018 }
17019 break;
099e5b4d 17020#endif
10dc65db
LA
17021 default:
17022 if (ctx->insn_flags & ISA_MIPS32R6) {
17023 decode_opc_special_r6(env, ctx);
17024 } else {
17025 decode_opc_special_legacy(env, ctx);
17026 }
17027 }
17028}
17029
10dc65db 17030static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17031{
17032 int rs, rt, rd;
17033 uint32_t op1;
6c5c1e20 17034
4267d3e6
LA
17035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17036
099e5b4d
LA
17037 rs = (ctx->opcode >> 21) & 0x1f;
17038 rt = (ctx->opcode >> 16) & 0x1f;
17039 rd = (ctx->opcode >> 11) & 0x1f;
17040
17041 op1 = MASK_SPECIAL2(ctx->opcode);
17042 switch (op1) {
17043 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17044 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17045 check_insn(ctx, ISA_MIPS32);
17046 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17047 break;
17048 case OPC_MUL:
099e5b4d
LA
17049 gen_arith(ctx, op1, rd, rs, rt);
17050 break;
fac5a073
LA
17051 case OPC_DIV_G_2F:
17052 case OPC_DIVU_G_2F:
17053 case OPC_MULT_G_2F:
17054 case OPC_MULTU_G_2F:
17055 case OPC_MOD_G_2F:
17056 case OPC_MODU_G_2F:
17057 check_insn(ctx, INSN_LOONGSON2F);
17058 gen_loongson_integer(ctx, op1, rd, rs, rt);
17059 break;
099e5b4d
LA
17060 case OPC_CLO:
17061 case OPC_CLZ:
17062 check_insn(ctx, ISA_MIPS32);
17063 gen_cl(ctx, op1, rd, rs);
17064 break;
17065 case OPC_SDBBP:
3b3c1694
LA
17066 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17067 gen_helper_do_semihosting(cpu_env);
17068 } else {
17069 /* XXX: not clear which exception should be raised
17070 * when in debug mode...
17071 */
17072 check_insn(ctx, ISA_MIPS32);
17073 generate_exception(ctx, EXCP_DBp);
17074 }
099e5b4d 17075 break;
9b1a1d68 17076#if defined(TARGET_MIPS64)
099e5b4d
LA
17077 case OPC_DCLO:
17078 case OPC_DCLZ:
17079 check_insn(ctx, ISA_MIPS64);
17080 check_mips_64(ctx);
17081 gen_cl(ctx, op1, rd, rs);
17082 break;
4267d3e6
LA
17083 case OPC_DMULT_G_2F:
17084 case OPC_DMULTU_G_2F:
17085 case OPC_DDIV_G_2F:
17086 case OPC_DDIVU_G_2F:
17087 case OPC_DMOD_G_2F:
17088 case OPC_DMODU_G_2F:
17089 check_insn(ctx, INSN_LOONGSON2F);
17090 gen_loongson_integer(ctx, op1, rd, rs, rt);
17091 break;
10dc65db 17092#endif
4267d3e6
LA
17093 default: /* Invalid */
17094 MIPS_INVAL("special2_legacy");
17095 generate_exception(ctx, EXCP_RI);
17096 break;
10dc65db
LA
17097 }
17098}
17099
17100static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17101{
15eacb9b
YK
17102 int rs, rt, rd, sa;
17103 uint32_t op1, op2;
10dc65db
LA
17104 int16_t imm;
17105
17106 rs = (ctx->opcode >> 21) & 0x1f;
17107 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17108 rd = (ctx->opcode >> 11) & 0x1f;
17109 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17110 imm = (int16_t)ctx->opcode >> 7;
17111
17112 op1 = MASK_SPECIAL3(ctx->opcode);
17113 switch (op1) {
bf7910c6
LA
17114 case R6_OPC_PREF:
17115 if (rt >= 24) {
17116 /* hint codes 24-31 are reserved and signal RI */
17117 generate_exception(ctx, EXCP_RI);
17118 }
17119 /* Treat as NOP. */
17120 break;
17121 case R6_OPC_CACHE:
17122 /* Treat as NOP. */
17123 break;
10dc65db
LA
17124 case R6_OPC_SC:
17125 gen_st_cond(ctx, op1, rt, rs, imm);
17126 break;
17127 case R6_OPC_LL:
17128 gen_ld(ctx, op1, rt, rs, imm);
17129 break;
15eacb9b
YK
17130 case OPC_BSHFL:
17131 {
17132 if (rd == 0) {
17133 /* Treat as NOP. */
17134 break;
17135 }
15eacb9b
YK
17136 op2 = MASK_BSHFL(ctx->opcode);
17137 switch (op2) {
17138 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17139 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17140 break;
17141 case OPC_BITSWAP:
1f1b4c00 17142 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17143 break;
17144 }
15eacb9b
YK
17145 }
17146 break;
bf7910c6
LA
17147#if defined(TARGET_MIPS64)
17148 case R6_OPC_SCD:
17149 gen_st_cond(ctx, op1, rt, rs, imm);
17150 break;
17151 case R6_OPC_LLD:
17152 gen_ld(ctx, op1, rt, rs, imm);
17153 break;
15eacb9b
YK
17154 case OPC_DBSHFL:
17155 check_mips_64(ctx);
17156 {
17157 if (rd == 0) {
17158 /* Treat as NOP. */
17159 break;
17160 }
15eacb9b
YK
17161 op2 = MASK_DBSHFL(ctx->opcode);
17162 switch (op2) {
17163 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17164 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17165 break;
17166 case OPC_DBITSWAP:
1f1b4c00 17167 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17168 break;
17169 }
1f1b4c00 17170
15eacb9b
YK
17171 }
17172 break;
bf7910c6 17173#endif
10dc65db
LA
17174 default: /* Invalid */
17175 MIPS_INVAL("special3_r6");
17176 generate_exception(ctx, EXCP_RI);
17177 break;
17178 }
17179}
17180
17181static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17182{
fac5a073 17183 int rs, rt, rd;
099e5b4d 17184 uint32_t op1, op2;
099e5b4d
LA
17185
17186 rs = (ctx->opcode >> 21) & 0x1f;
17187 rt = (ctx->opcode >> 16) & 0x1f;
17188 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17189
17190 op1 = MASK_SPECIAL3(ctx->opcode);
17191 switch (op1) {
099e5b4d
LA
17192 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17193 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17194 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17195 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17196 * the same mask and op1. */
17197 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17198 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17199 switch (op2) {
099e5b4d
LA
17200 case OPC_ADDUH_QB:
17201 case OPC_ADDUH_R_QB:
17202 case OPC_ADDQH_PH:
17203 case OPC_ADDQH_R_PH:
17204 case OPC_ADDQH_W:
17205 case OPC_ADDQH_R_W:
17206 case OPC_SUBUH_QB:
17207 case OPC_SUBUH_R_QB:
17208 case OPC_SUBQH_PH:
17209 case OPC_SUBQH_R_PH:
17210 case OPC_SUBQH_W:
17211 case OPC_SUBQH_R_W:
461c08df
JL
17212 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17213 break;
099e5b4d
LA
17214 case OPC_MUL_PH:
17215 case OPC_MUL_S_PH:
17216 case OPC_MULQ_S_W:
17217 case OPC_MULQ_RS_W:
17218 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17219 break;
461c08df 17220 default:
099e5b4d 17221 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
17222 generate_exception(ctx, EXCP_RI);
17223 break;
17224 }
099e5b4d
LA
17225 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17226 gen_loongson_integer(ctx, op1, rd, rs, rt);
17227 } else {
17228 generate_exception(ctx, EXCP_RI);
17229 }
17230 break;
17231 case OPC_LX_DSP:
17232 op2 = MASK_LX(ctx->opcode);
17233 switch (op2) {
17234#if defined(TARGET_MIPS64)
17235 case OPC_LDX:
17236#endif
17237 case OPC_LBUX:
17238 case OPC_LHX:
17239 case OPC_LWX:
17240 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17241 break;
17242 default: /* Invalid */
17243 MIPS_INVAL("MASK LX");
17244 generate_exception(ctx, EXCP_RI);
17245 break;
17246 }
17247 break;
17248 case OPC_ABSQ_S_PH_DSP:
17249 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17250 switch (op2) {
17251 case OPC_ABSQ_S_QB:
17252 case OPC_ABSQ_S_PH:
17253 case OPC_ABSQ_S_W:
17254 case OPC_PRECEQ_W_PHL:
17255 case OPC_PRECEQ_W_PHR:
17256 case OPC_PRECEQU_PH_QBL:
17257 case OPC_PRECEQU_PH_QBR:
17258 case OPC_PRECEQU_PH_QBLA:
17259 case OPC_PRECEQU_PH_QBRA:
17260 case OPC_PRECEU_PH_QBL:
17261 case OPC_PRECEU_PH_QBR:
17262 case OPC_PRECEU_PH_QBLA:
17263 case OPC_PRECEU_PH_QBRA:
17264 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17265 break;
17266 case OPC_BITREV:
17267 case OPC_REPL_QB:
17268 case OPC_REPLV_QB:
17269 case OPC_REPL_PH:
17270 case OPC_REPLV_PH:
17271 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17272 break;
17273 default:
17274 MIPS_INVAL("MASK ABSQ_S.PH");
17275 generate_exception(ctx, EXCP_RI);
17276 break;
17277 }
17278 break;
17279 case OPC_ADDU_QB_DSP:
17280 op2 = MASK_ADDU_QB(ctx->opcode);
17281 switch (op2) {
17282 case OPC_ADDQ_PH:
17283 case OPC_ADDQ_S_PH:
17284 case OPC_ADDQ_S_W:
17285 case OPC_ADDU_QB:
17286 case OPC_ADDU_S_QB:
17287 case OPC_ADDU_PH:
17288 case OPC_ADDU_S_PH:
17289 case OPC_SUBQ_PH:
17290 case OPC_SUBQ_S_PH:
17291 case OPC_SUBQ_S_W:
17292 case OPC_SUBU_QB:
17293 case OPC_SUBU_S_QB:
17294 case OPC_SUBU_PH:
17295 case OPC_SUBU_S_PH:
17296 case OPC_ADDSC:
17297 case OPC_ADDWC:
17298 case OPC_MODSUB:
17299 case OPC_RADDU_W_QB:
17300 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17301 break;
17302 case OPC_MULEU_S_PH_QBL:
17303 case OPC_MULEU_S_PH_QBR:
17304 case OPC_MULQ_RS_PH:
17305 case OPC_MULEQ_S_W_PHL:
17306 case OPC_MULEQ_S_W_PHR:
17307 case OPC_MULQ_S_PH:
17308 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17309 break;
17310 default: /* Invalid */
17311 MIPS_INVAL("MASK ADDU.QB");
17312 generate_exception(ctx, EXCP_RI);
461c08df 17313 break;
461c08df 17314
099e5b4d
LA
17315 }
17316 break;
17317 case OPC_CMPU_EQ_QB_DSP:
17318 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17319 switch (op2) {
17320 case OPC_PRECR_SRA_PH_W:
17321 case OPC_PRECR_SRA_R_PH_W:
17322 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17323 break;
099e5b4d
LA
17324 case OPC_PRECR_QB_PH:
17325 case OPC_PRECRQ_QB_PH:
17326 case OPC_PRECRQ_PH_W:
17327 case OPC_PRECRQ_RS_PH_W:
17328 case OPC_PRECRQU_S_QB_PH:
17329 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17330 break;
099e5b4d
LA
17331 case OPC_CMPU_EQ_QB:
17332 case OPC_CMPU_LT_QB:
17333 case OPC_CMPU_LE_QB:
17334 case OPC_CMP_EQ_PH:
17335 case OPC_CMP_LT_PH:
17336 case OPC_CMP_LE_PH:
17337 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17338 break;
099e5b4d
LA
17339 case OPC_CMPGU_EQ_QB:
17340 case OPC_CMPGU_LT_QB:
17341 case OPC_CMPGU_LE_QB:
17342 case OPC_CMPGDU_EQ_QB:
17343 case OPC_CMPGDU_LT_QB:
17344 case OPC_CMPGDU_LE_QB:
17345 case OPC_PICK_QB:
17346 case OPC_PICK_PH:
17347 case OPC_PACKRL_PH:
17348 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17349 break;
17350 default: /* Invalid */
17351 MIPS_INVAL("MASK CMPU.EQ.QB");
17352 generate_exception(ctx, EXCP_RI);
17353 break;
17354 }
17355 break;
17356 case OPC_SHLL_QB_DSP:
17357 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17358 break;
17359 case OPC_DPA_W_PH_DSP:
17360 op2 = MASK_DPA_W_PH(ctx->opcode);
17361 switch (op2) {
17362 case OPC_DPAU_H_QBL:
17363 case OPC_DPAU_H_QBR:
17364 case OPC_DPSU_H_QBL:
17365 case OPC_DPSU_H_QBR:
17366 case OPC_DPA_W_PH:
17367 case OPC_DPAX_W_PH:
17368 case OPC_DPAQ_S_W_PH:
17369 case OPC_DPAQX_S_W_PH:
17370 case OPC_DPAQX_SA_W_PH:
17371 case OPC_DPS_W_PH:
17372 case OPC_DPSX_W_PH:
17373 case OPC_DPSQ_S_W_PH:
17374 case OPC_DPSQX_S_W_PH:
17375 case OPC_DPSQX_SA_W_PH:
17376 case OPC_MULSAQ_S_W_PH:
17377 case OPC_DPAQ_SA_L_W:
17378 case OPC_DPSQ_SA_L_W:
17379 case OPC_MAQ_S_W_PHL:
17380 case OPC_MAQ_S_W_PHR:
17381 case OPC_MAQ_SA_W_PHL:
17382 case OPC_MAQ_SA_W_PHR:
17383 case OPC_MULSA_W_PH:
17384 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17385 break;
17386 default: /* Invalid */
17387 MIPS_INVAL("MASK DPAW.PH");
17388 generate_exception(ctx, EXCP_RI);
17389 break;
17390 }
17391 break;
17392 case OPC_INSV_DSP:
17393 op2 = MASK_INSV(ctx->opcode);
17394 switch (op2) {
17395 case OPC_INSV:
17396 check_dsp(ctx);
17397 {
17398 TCGv t0, t1;
17399
17400 if (rt == 0) {
099e5b4d
LA
17401 break;
17402 }
17403
17404 t0 = tcg_temp_new();
17405 t1 = tcg_temp_new();
17406
17407 gen_load_gpr(t0, rt);
17408 gen_load_gpr(t1, rs);
17409
17410 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17411
17412 tcg_temp_free(t0);
17413 tcg_temp_free(t1);
a22260ae
JL
17414 break;
17415 }
099e5b4d
LA
17416 default: /* Invalid */
17417 MIPS_INVAL("MASK INSV");
17418 generate_exception(ctx, EXCP_RI);
17419 break;
17420 }
17421 break;
17422 case OPC_APPEND_DSP:
17423 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17424 break;
17425 case OPC_EXTR_W_DSP:
17426 op2 = MASK_EXTR_W(ctx->opcode);
17427 switch (op2) {
17428 case OPC_EXTR_W:
17429 case OPC_EXTR_R_W:
17430 case OPC_EXTR_RS_W:
17431 case OPC_EXTR_S_H:
17432 case OPC_EXTRV_S_H:
17433 case OPC_EXTRV_W:
17434 case OPC_EXTRV_R_W:
17435 case OPC_EXTRV_RS_W:
17436 case OPC_EXTP:
17437 case OPC_EXTPV:
17438 case OPC_EXTPDP:
17439 case OPC_EXTPDPV:
17440 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17441 break;
17442 case OPC_RDDSP:
17443 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17444 break;
17445 case OPC_SHILO:
17446 case OPC_SHILOV:
17447 case OPC_MTHLIP:
17448 case OPC_WRDSP:
17449 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17450 break;
17451 default: /* Invalid */
17452 MIPS_INVAL("MASK EXTR.W");
17453 generate_exception(ctx, EXCP_RI);
17454 break;
17455 }
17456 break;
099e5b4d 17457#if defined(TARGET_MIPS64)
fac5a073
LA
17458 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17459 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17460 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17461 check_insn(ctx, INSN_LOONGSON2E);
17462 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17463 break;
099e5b4d
LA
17464 case OPC_ABSQ_S_QH_DSP:
17465 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17466 switch (op2) {
17467 case OPC_PRECEQ_L_PWL:
17468 case OPC_PRECEQ_L_PWR:
17469 case OPC_PRECEQ_PW_QHL:
17470 case OPC_PRECEQ_PW_QHR:
17471 case OPC_PRECEQ_PW_QHLA:
17472 case OPC_PRECEQ_PW_QHRA:
17473 case OPC_PRECEQU_QH_OBL:
17474 case OPC_PRECEQU_QH_OBR:
17475 case OPC_PRECEQU_QH_OBLA:
17476 case OPC_PRECEQU_QH_OBRA:
17477 case OPC_PRECEU_QH_OBL:
17478 case OPC_PRECEU_QH_OBR:
17479 case OPC_PRECEU_QH_OBLA:
17480 case OPC_PRECEU_QH_OBRA:
17481 case OPC_ABSQ_S_OB:
17482 case OPC_ABSQ_S_PW:
17483 case OPC_ABSQ_S_QH:
17484 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17485 break;
17486 case OPC_REPL_OB:
17487 case OPC_REPL_PW:
17488 case OPC_REPL_QH:
17489 case OPC_REPLV_OB:
17490 case OPC_REPLV_PW:
17491 case OPC_REPLV_QH:
17492 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17493 break;
17494 default: /* Invalid */
17495 MIPS_INVAL("MASK ABSQ_S.QH");
17496 generate_exception(ctx, EXCP_RI);
17497 break;
17498 }
17499 break;
17500 case OPC_ADDU_OB_DSP:
17501 op2 = MASK_ADDU_OB(ctx->opcode);
17502 switch (op2) {
17503 case OPC_RADDU_L_OB:
17504 case OPC_SUBQ_PW:
17505 case OPC_SUBQ_S_PW:
17506 case OPC_SUBQ_QH:
17507 case OPC_SUBQ_S_QH:
17508 case OPC_SUBU_OB:
17509 case OPC_SUBU_S_OB:
17510 case OPC_SUBU_QH:
17511 case OPC_SUBU_S_QH:
17512 case OPC_SUBUH_OB:
17513 case OPC_SUBUH_R_OB:
17514 case OPC_ADDQ_PW:
17515 case OPC_ADDQ_S_PW:
17516 case OPC_ADDQ_QH:
17517 case OPC_ADDQ_S_QH:
17518 case OPC_ADDU_OB:
17519 case OPC_ADDU_S_OB:
17520 case OPC_ADDU_QH:
17521 case OPC_ADDU_S_QH:
17522 case OPC_ADDUH_OB:
17523 case OPC_ADDUH_R_OB:
17524 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17525 break;
099e5b4d
LA
17526 case OPC_MULEQ_S_PW_QHL:
17527 case OPC_MULEQ_S_PW_QHR:
17528 case OPC_MULEU_S_QH_OBL:
17529 case OPC_MULEU_S_QH_OBR:
17530 case OPC_MULQ_RS_QH:
17531 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17532 break;
099e5b4d
LA
17533 default: /* Invalid */
17534 MIPS_INVAL("MASK ADDU.OB");
17535 generate_exception(ctx, EXCP_RI);
26690560 17536 break;
099e5b4d
LA
17537 }
17538 break;
17539 case OPC_CMPU_EQ_OB_DSP:
17540 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17541 switch (op2) {
17542 case OPC_PRECR_SRA_QH_PW:
17543 case OPC_PRECR_SRA_R_QH_PW:
17544 /* Return value is rt. */
17545 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17546 break;
099e5b4d
LA
17547 case OPC_PRECR_OB_QH:
17548 case OPC_PRECRQ_OB_QH:
17549 case OPC_PRECRQ_PW_L:
17550 case OPC_PRECRQ_QH_PW:
17551 case OPC_PRECRQ_RS_QH_PW:
17552 case OPC_PRECRQU_S_OB_QH:
17553 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17554 break;
099e5b4d
LA
17555 case OPC_CMPU_EQ_OB:
17556 case OPC_CMPU_LT_OB:
17557 case OPC_CMPU_LE_OB:
17558 case OPC_CMP_EQ_QH:
17559 case OPC_CMP_LT_QH:
17560 case OPC_CMP_LE_QH:
17561 case OPC_CMP_EQ_PW:
17562 case OPC_CMP_LT_PW:
17563 case OPC_CMP_LE_PW:
17564 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17565 break;
099e5b4d
LA
17566 case OPC_CMPGDU_EQ_OB:
17567 case OPC_CMPGDU_LT_OB:
17568 case OPC_CMPGDU_LE_OB:
17569 case OPC_CMPGU_EQ_OB:
17570 case OPC_CMPGU_LT_OB:
17571 case OPC_CMPGU_LE_OB:
17572 case OPC_PACKRL_PW:
17573 case OPC_PICK_OB:
17574 case OPC_PICK_PW:
17575 case OPC_PICK_QH:
17576 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17577 break;
099e5b4d
LA
17578 default: /* Invalid */
17579 MIPS_INVAL("MASK CMPU_EQ.OB");
17580 generate_exception(ctx, EXCP_RI);
161f85e6 17581 break;
099e5b4d
LA
17582 }
17583 break;
17584 case OPC_DAPPEND_DSP:
17585 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17586 break;
17587 case OPC_DEXTR_W_DSP:
17588 op2 = MASK_DEXTR_W(ctx->opcode);
17589 switch (op2) {
17590 case OPC_DEXTP:
17591 case OPC_DEXTPDP:
17592 case OPC_DEXTPDPV:
17593 case OPC_DEXTPV:
17594 case OPC_DEXTR_L:
17595 case OPC_DEXTR_R_L:
17596 case OPC_DEXTR_RS_L:
17597 case OPC_DEXTR_W:
17598 case OPC_DEXTR_R_W:
17599 case OPC_DEXTR_RS_W:
17600 case OPC_DEXTR_S_H:
17601 case OPC_DEXTRV_L:
17602 case OPC_DEXTRV_R_L:
17603 case OPC_DEXTRV_RS_L:
17604 case OPC_DEXTRV_S_H:
17605 case OPC_DEXTRV_W:
17606 case OPC_DEXTRV_R_W:
17607 case OPC_DEXTRV_RS_W:
17608 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17609 break;
099e5b4d
LA
17610 case OPC_DMTHLIP:
17611 case OPC_DSHILO:
17612 case OPC_DSHILOV:
17613 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17614 break;
099e5b4d
LA
17615 default: /* Invalid */
17616 MIPS_INVAL("MASK EXTR.W");
17617 generate_exception(ctx, EXCP_RI);
461c08df 17618 break;
099e5b4d
LA
17619 }
17620 break;
17621 case OPC_DPAQ_W_QH_DSP:
17622 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17623 switch (op2) {
17624 case OPC_DPAU_H_OBL:
17625 case OPC_DPAU_H_OBR:
17626 case OPC_DPSU_H_OBL:
17627 case OPC_DPSU_H_OBR:
17628 case OPC_DPA_W_QH:
17629 case OPC_DPAQ_S_W_QH:
17630 case OPC_DPS_W_QH:
17631 case OPC_DPSQ_S_W_QH:
17632 case OPC_MULSAQ_S_W_QH:
17633 case OPC_DPAQ_SA_L_PW:
17634 case OPC_DPSQ_SA_L_PW:
17635 case OPC_MULSAQ_S_L_PW:
17636 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17637 break;
17638 case OPC_MAQ_S_W_QHLL:
17639 case OPC_MAQ_S_W_QHLR:
17640 case OPC_MAQ_S_W_QHRL:
17641 case OPC_MAQ_S_W_QHRR:
17642 case OPC_MAQ_SA_W_QHLL:
17643 case OPC_MAQ_SA_W_QHLR:
17644 case OPC_MAQ_SA_W_QHRL:
17645 case OPC_MAQ_SA_W_QHRR:
17646 case OPC_MAQ_S_L_PWL:
17647 case OPC_MAQ_S_L_PWR:
17648 case OPC_DMADD:
17649 case OPC_DMADDU:
17650 case OPC_DMSUB:
17651 case OPC_DMSUBU:
17652 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17653 break;
099e5b4d
LA
17654 default: /* Invalid */
17655 MIPS_INVAL("MASK DPAQ.W.QH");
17656 generate_exception(ctx, EXCP_RI);
b53371ed 17657 break;
099e5b4d
LA
17658 }
17659 break;
17660 case OPC_DINSV_DSP:
17661 op2 = MASK_INSV(ctx->opcode);
17662 switch (op2) {
17663 case OPC_DINSV:
17664 {
17665 TCGv t0, t1;
17666
17667 if (rt == 0) {
a22260ae
JL
17668 break;
17669 }
099e5b4d 17670 check_dsp(ctx);
1cb6686c 17671
099e5b4d
LA
17672 t0 = tcg_temp_new();
17673 t1 = tcg_temp_new();
1cb6686c 17674
099e5b4d
LA
17675 gen_load_gpr(t0, rt);
17676 gen_load_gpr(t1, rs);
1cb6686c 17677
099e5b4d 17678 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17679
099e5b4d
LA
17680 tcg_temp_free(t0);
17681 tcg_temp_free(t1);
77c5fa8b 17682 break;
099e5b4d 17683 }
7a387fff 17684 default: /* Invalid */
099e5b4d 17685 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17686 generate_exception(ctx, EXCP_RI);
17687 break;
17688 }
17689 break;
099e5b4d
LA
17690 case OPC_SHLL_OB_DSP:
17691 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17692 break;
17693#endif
fac5a073
LA
17694 default: /* Invalid */
17695 MIPS_INVAL("special3_legacy");
17696 generate_exception(ctx, EXCP_RI);
17697 break;
17698 }
17699}
17700
17701static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17702{
17703 int rs, rt, rd, sa;
17704 uint32_t op1, op2;
17705
17706 rs = (ctx->opcode >> 21) & 0x1f;
17707 rt = (ctx->opcode >> 16) & 0x1f;
17708 rd = (ctx->opcode >> 11) & 0x1f;
17709 sa = (ctx->opcode >> 6) & 0x1f;
17710
17711 op1 = MASK_SPECIAL3(ctx->opcode);
17712 switch (op1) {
17713 case OPC_EXT:
17714 case OPC_INS:
17715 check_insn(ctx, ISA_MIPS32R2);
17716 gen_bitops(ctx, op1, rt, rs, sa, rd);
17717 break;
17718 case OPC_BSHFL:
fac5a073 17719 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17720 switch (op2) {
17721 case OPC_ALIGN ... OPC_ALIGN_END:
17722 case OPC_BITSWAP:
17723 check_insn(ctx, ISA_MIPS32R6);
17724 decode_opc_special3_r6(env, ctx);
17725 break;
17726 default:
17727 check_insn(ctx, ISA_MIPS32R2);
17728 gen_bshfl(ctx, op2, rt, rd);
17729 break;
17730 }
fac5a073
LA
17731 break;
17732#if defined(TARGET_MIPS64)
17733 case OPC_DEXTM ... OPC_DEXT:
17734 case OPC_DINSM ... OPC_DINS:
17735 check_insn(ctx, ISA_MIPS64R2);
17736 check_mips_64(ctx);
17737 gen_bitops(ctx, op1, rt, rs, sa, rd);
17738 break;
17739 case OPC_DBSHFL:
fac5a073 17740 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17741 switch (op2) {
17742 case OPC_DALIGN ... OPC_DALIGN_END:
17743 case OPC_DBITSWAP:
17744 check_insn(ctx, ISA_MIPS32R6);
17745 decode_opc_special3_r6(env, ctx);
17746 break;
17747 default:
17748 check_insn(ctx, ISA_MIPS64R2);
17749 check_mips_64(ctx);
17750 op2 = MASK_DBSHFL(ctx->opcode);
17751 gen_bshfl(ctx, op2, rt, rd);
17752 break;
17753 }
fac5a073
LA
17754 break;
17755#endif
17756 case OPC_RDHWR:
17757 gen_rdhwr(ctx, rt, rd);
17758 break;
17759 case OPC_FORK:
17760 check_insn(ctx, ASE_MT);
17761 {
17762 TCGv t0 = tcg_temp_new();
17763 TCGv t1 = tcg_temp_new();
17764
17765 gen_load_gpr(t0, rt);
17766 gen_load_gpr(t1, rs);
17767 gen_helper_fork(t0, t1);
17768 tcg_temp_free(t0);
17769 tcg_temp_free(t1);
17770 }
17771 break;
17772 case OPC_YIELD:
17773 check_insn(ctx, ASE_MT);
17774 {
17775 TCGv t0 = tcg_temp_new();
17776
17777 save_cpu_state(ctx, 1);
17778 gen_load_gpr(t0, rs);
17779 gen_helper_yield(t0, cpu_env, t0);
17780 gen_store_gpr(t0, rd);
17781 tcg_temp_free(t0);
17782 }
17783 break;
10dc65db
LA
17784 default:
17785 if (ctx->insn_flags & ISA_MIPS32R6) {
17786 decode_opc_special3_r6(env, ctx);
17787 } else {
17788 decode_opc_special3_legacy(env, ctx);
17789 }
099e5b4d
LA
17790 }
17791}
17792
863f264d
YK
17793/* MIPS SIMD Architecture (MSA) */
17794static inline int check_msa_access(DisasContext *ctx)
17795{
17796 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17797 !(ctx->hflags & MIPS_HFLAG_F64))) {
17798 generate_exception(ctx, EXCP_RI);
17799 return 0;
17800 }
17801
17802 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17803 if (ctx->insn_flags & ASE_MSA) {
17804 generate_exception(ctx, EXCP_MSADIS);
17805 return 0;
17806 } else {
17807 generate_exception(ctx, EXCP_RI);
17808 return 0;
17809 }
17810 }
17811 return 1;
17812}
17813
5692c6e1
YK
17814static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17815{
17816 /* generates tcg ops to check if any element is 0 */
17817 /* Note this function only works with MSA_WRLEN = 128 */
17818 uint64_t eval_zero_or_big = 0;
17819 uint64_t eval_big = 0;
17820 TCGv_i64 t0 = tcg_temp_new_i64();
17821 TCGv_i64 t1 = tcg_temp_new_i64();
17822 switch (df) {
17823 case DF_BYTE:
17824 eval_zero_or_big = 0x0101010101010101ULL;
17825 eval_big = 0x8080808080808080ULL;
17826 break;
17827 case DF_HALF:
17828 eval_zero_or_big = 0x0001000100010001ULL;
17829 eval_big = 0x8000800080008000ULL;
17830 break;
17831 case DF_WORD:
17832 eval_zero_or_big = 0x0000000100000001ULL;
17833 eval_big = 0x8000000080000000ULL;
17834 break;
17835 case DF_DOUBLE:
17836 eval_zero_or_big = 0x0000000000000001ULL;
17837 eval_big = 0x8000000000000000ULL;
17838 break;
17839 }
17840 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17841 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17842 tcg_gen_andi_i64(t0, t0, eval_big);
17843 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17844 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17845 tcg_gen_andi_i64(t1, t1, eval_big);
17846 tcg_gen_or_i64(t0, t0, t1);
17847 /* if all bits are zero then all elements are not zero */
17848 /* if some bit is non-zero then some element is zero */
17849 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17850 tcg_gen_trunc_i64_tl(tresult, t0);
17851 tcg_temp_free_i64(t0);
17852 tcg_temp_free_i64(t1);
17853}
17854
17855static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17856{
17857 uint8_t df = (ctx->opcode >> 21) & 0x3;
17858 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17859 int64_t s16 = (int16_t)ctx->opcode;
17860
17861 check_msa_access(ctx);
17862
17863 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
5692c6e1
YK
17864 generate_exception(ctx, EXCP_RI);
17865 return;
17866 }
17867 switch (op1) {
17868 case OPC_BZ_V:
17869 case OPC_BNZ_V:
17870 {
17871 TCGv_i64 t0 = tcg_temp_new_i64();
17872 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17873 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17874 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17875 tcg_gen_trunc_i64_tl(bcond, t0);
17876 tcg_temp_free_i64(t0);
17877 }
17878 break;
17879 case OPC_BZ_B:
17880 case OPC_BZ_H:
17881 case OPC_BZ_W:
17882 case OPC_BZ_D:
17883 gen_check_zero_element(bcond, df, wt);
17884 break;
17885 case OPC_BNZ_B:
17886 case OPC_BNZ_H:
17887 case OPC_BNZ_W:
17888 case OPC_BNZ_D:
17889 gen_check_zero_element(bcond, df, wt);
17890 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17891 break;
17892 }
17893
17894 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17895
17896 ctx->hflags |= MIPS_HFLAG_BC;
17897 ctx->hflags |= MIPS_HFLAG_BDS32;
17898}
17899
4c789546
YK
17900static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17901{
17902#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17903 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17904 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17905 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17906
17907 TCGv_i32 twd = tcg_const_i32(wd);
17908 TCGv_i32 tws = tcg_const_i32(ws);
17909 TCGv_i32 ti8 = tcg_const_i32(i8);
17910
17911 switch (MASK_MSA_I8(ctx->opcode)) {
17912 case OPC_ANDI_B:
17913 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17914 break;
17915 case OPC_ORI_B:
17916 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17917 break;
17918 case OPC_NORI_B:
17919 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17920 break;
17921 case OPC_XORI_B:
17922 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17923 break;
17924 case OPC_BMNZI_B:
17925 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17926 break;
17927 case OPC_BMZI_B:
17928 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17929 break;
17930 case OPC_BSELI_B:
17931 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17932 break;
17933 case OPC_SHF_B:
17934 case OPC_SHF_H:
17935 case OPC_SHF_W:
17936 {
17937 uint8_t df = (ctx->opcode >> 24) & 0x3;
17938 if (df == DF_DOUBLE) {
17939 generate_exception(ctx, EXCP_RI);
17940 } else {
17941 TCGv_i32 tdf = tcg_const_i32(df);
17942 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17943 tcg_temp_free_i32(tdf);
17944 }
17945 }
17946 break;
17947 default:
17948 MIPS_INVAL("MSA instruction");
17949 generate_exception(ctx, EXCP_RI);
17950 break;
17951 }
17952
17953 tcg_temp_free_i32(twd);
17954 tcg_temp_free_i32(tws);
17955 tcg_temp_free_i32(ti8);
17956}
17957
80e71591
YK
17958static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17959{
17960#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17961 uint8_t df = (ctx->opcode >> 21) & 0x3;
17962 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17963 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17964 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17965 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17966
17967 TCGv_i32 tdf = tcg_const_i32(df);
17968 TCGv_i32 twd = tcg_const_i32(wd);
17969 TCGv_i32 tws = tcg_const_i32(ws);
17970 TCGv_i32 timm = tcg_temp_new_i32();
17971 tcg_gen_movi_i32(timm, u5);
17972
17973 switch (MASK_MSA_I5(ctx->opcode)) {
17974 case OPC_ADDVI_df:
17975 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17976 break;
17977 case OPC_SUBVI_df:
17978 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17979 break;
17980 case OPC_MAXI_S_df:
17981 tcg_gen_movi_i32(timm, s5);
17982 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17983 break;
17984 case OPC_MAXI_U_df:
17985 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17986 break;
17987 case OPC_MINI_S_df:
17988 tcg_gen_movi_i32(timm, s5);
17989 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17990 break;
17991 case OPC_MINI_U_df:
17992 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17993 break;
17994 case OPC_CEQI_df:
17995 tcg_gen_movi_i32(timm, s5);
17996 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17997 break;
17998 case OPC_CLTI_S_df:
17999 tcg_gen_movi_i32(timm, s5);
18000 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18001 break;
18002 case OPC_CLTI_U_df:
18003 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18004 break;
18005 case OPC_CLEI_S_df:
18006 tcg_gen_movi_i32(timm, s5);
18007 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18008 break;
18009 case OPC_CLEI_U_df:
18010 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18011 break;
18012 case OPC_LDI_df:
18013 {
18014 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18015 tcg_gen_movi_i32(timm, s10);
18016 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18017 }
18018 break;
18019 default:
18020 MIPS_INVAL("MSA instruction");
18021 generate_exception(ctx, EXCP_RI);
18022 break;
18023 }
18024
18025 tcg_temp_free_i32(tdf);
18026 tcg_temp_free_i32(twd);
18027 tcg_temp_free_i32(tws);
18028 tcg_temp_free_i32(timm);
18029}
18030
d4cf28de
YK
18031static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18032{
18033#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18034 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18035 uint32_t df = 0, m = 0;
18036 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18037 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18038
18039 TCGv_i32 tdf;
18040 TCGv_i32 tm;
18041 TCGv_i32 twd;
18042 TCGv_i32 tws;
18043
18044 if ((dfm & 0x40) == 0x00) {
18045 m = dfm & 0x3f;
18046 df = DF_DOUBLE;
18047 } else if ((dfm & 0x60) == 0x40) {
18048 m = dfm & 0x1f;
18049 df = DF_WORD;
18050 } else if ((dfm & 0x70) == 0x60) {
18051 m = dfm & 0x0f;
18052 df = DF_HALF;
18053 } else if ((dfm & 0x78) == 0x70) {
18054 m = dfm & 0x7;
18055 df = DF_BYTE;
18056 } else {
18057 generate_exception(ctx, EXCP_RI);
18058 return;
18059 }
18060
18061 tdf = tcg_const_i32(df);
18062 tm = tcg_const_i32(m);
18063 twd = tcg_const_i32(wd);
18064 tws = tcg_const_i32(ws);
18065
18066 switch (MASK_MSA_BIT(ctx->opcode)) {
18067 case OPC_SLLI_df:
18068 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18069 break;
18070 case OPC_SRAI_df:
18071 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18072 break;
18073 case OPC_SRLI_df:
18074 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18075 break;
18076 case OPC_BCLRI_df:
18077 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18078 break;
18079 case OPC_BSETI_df:
18080 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18081 break;
18082 case OPC_BNEGI_df:
18083 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18084 break;
18085 case OPC_BINSLI_df:
18086 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18087 break;
18088 case OPC_BINSRI_df:
18089 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18090 break;
18091 case OPC_SAT_S_df:
18092 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18093 break;
18094 case OPC_SAT_U_df:
18095 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18096 break;
18097 case OPC_SRARI_df:
18098 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18099 break;
18100 case OPC_SRLRI_df:
18101 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18102 break;
18103 default:
18104 MIPS_INVAL("MSA instruction");
18105 generate_exception(ctx, EXCP_RI);
18106 break;
18107 }
18108
18109 tcg_temp_free_i32(tdf);
18110 tcg_temp_free_i32(tm);
18111 tcg_temp_free_i32(twd);
18112 tcg_temp_free_i32(tws);
18113}
18114
28f99f08
YK
18115static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18116{
18117#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18118 uint8_t df = (ctx->opcode >> 21) & 0x3;
18119 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18120 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18121 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18122
18123 TCGv_i32 tdf = tcg_const_i32(df);
18124 TCGv_i32 twd = tcg_const_i32(wd);
18125 TCGv_i32 tws = tcg_const_i32(ws);
18126 TCGv_i32 twt = tcg_const_i32(wt);
18127
18128 switch (MASK_MSA_3R(ctx->opcode)) {
18129 case OPC_SLL_df:
18130 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18131 break;
18132 case OPC_ADDV_df:
18133 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18134 break;
18135 case OPC_CEQ_df:
18136 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18137 break;
18138 case OPC_ADD_A_df:
18139 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18140 break;
18141 case OPC_SUBS_S_df:
18142 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18143 break;
18144 case OPC_MULV_df:
18145 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18146 break;
18147 case OPC_SLD_df:
18148 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18149 break;
18150 case OPC_VSHF_df:
18151 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18152 break;
18153 case OPC_SRA_df:
18154 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18155 break;
18156 case OPC_SUBV_df:
18157 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18158 break;
18159 case OPC_ADDS_A_df:
18160 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18161 break;
18162 case OPC_SUBS_U_df:
18163 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18164 break;
18165 case OPC_MADDV_df:
18166 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18167 break;
18168 case OPC_SPLAT_df:
18169 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18170 break;
18171 case OPC_SRAR_df:
18172 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18173 break;
18174 case OPC_SRL_df:
18175 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18176 break;
18177 case OPC_MAX_S_df:
18178 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18179 break;
18180 case OPC_CLT_S_df:
18181 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18182 break;
18183 case OPC_ADDS_S_df:
18184 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18185 break;
18186 case OPC_SUBSUS_U_df:
18187 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18188 break;
18189 case OPC_MSUBV_df:
18190 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18191 break;
18192 case OPC_PCKEV_df:
18193 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18194 break;
18195 case OPC_SRLR_df:
18196 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18197 break;
18198 case OPC_BCLR_df:
18199 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18200 break;
18201 case OPC_MAX_U_df:
18202 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18203 break;
18204 case OPC_CLT_U_df:
18205 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18206 break;
18207 case OPC_ADDS_U_df:
18208 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18209 break;
18210 case OPC_SUBSUU_S_df:
18211 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18212 break;
18213 case OPC_PCKOD_df:
18214 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18215 break;
18216 case OPC_BSET_df:
18217 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18218 break;
18219 case OPC_MIN_S_df:
18220 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18221 break;
18222 case OPC_CLE_S_df:
18223 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18224 break;
18225 case OPC_AVE_S_df:
18226 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18227 break;
18228 case OPC_ASUB_S_df:
18229 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18230 break;
18231 case OPC_DIV_S_df:
18232 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18233 break;
18234 case OPC_ILVL_df:
18235 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18236 break;
18237 case OPC_BNEG_df:
18238 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18239 break;
18240 case OPC_MIN_U_df:
18241 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18242 break;
18243 case OPC_CLE_U_df:
18244 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18245 break;
18246 case OPC_AVE_U_df:
18247 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18248 break;
18249 case OPC_ASUB_U_df:
18250 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18251 break;
18252 case OPC_DIV_U_df:
18253 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18254 break;
18255 case OPC_ILVR_df:
18256 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18257 break;
18258 case OPC_BINSL_df:
18259 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18260 break;
18261 case OPC_MAX_A_df:
18262 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18263 break;
18264 case OPC_AVER_S_df:
18265 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18266 break;
18267 case OPC_MOD_S_df:
18268 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18269 break;
18270 case OPC_ILVEV_df:
18271 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18272 break;
18273 case OPC_BINSR_df:
18274 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18275 break;
18276 case OPC_MIN_A_df:
18277 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18278 break;
18279 case OPC_AVER_U_df:
18280 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18281 break;
18282 case OPC_MOD_U_df:
18283 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18284 break;
18285 case OPC_ILVOD_df:
18286 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18287 break;
18288
18289 case OPC_DOTP_S_df:
18290 case OPC_DOTP_U_df:
18291 case OPC_DPADD_S_df:
18292 case OPC_DPADD_U_df:
18293 case OPC_DPSUB_S_df:
18294 case OPC_HADD_S_df:
18295 case OPC_DPSUB_U_df:
18296 case OPC_HADD_U_df:
18297 case OPC_HSUB_S_df:
18298 case OPC_HSUB_U_df:
18299 if (df == DF_BYTE) {
18300 generate_exception(ctx, EXCP_RI);
18301 }
18302 switch (MASK_MSA_3R(ctx->opcode)) {
18303 case OPC_DOTP_S_df:
18304 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18305 break;
18306 case OPC_DOTP_U_df:
18307 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18308 break;
18309 case OPC_DPADD_S_df:
18310 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18311 break;
18312 case OPC_DPADD_U_df:
18313 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18314 break;
18315 case OPC_DPSUB_S_df:
18316 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18317 break;
18318 case OPC_HADD_S_df:
18319 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18320 break;
18321 case OPC_DPSUB_U_df:
18322 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18323 break;
18324 case OPC_HADD_U_df:
18325 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18326 break;
18327 case OPC_HSUB_S_df:
18328 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18329 break;
18330 case OPC_HSUB_U_df:
18331 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18332 break;
18333 }
18334 break;
18335 default:
18336 MIPS_INVAL("MSA instruction");
18337 generate_exception(ctx, EXCP_RI);
18338 break;
18339 }
18340 tcg_temp_free_i32(twd);
18341 tcg_temp_free_i32(tws);
18342 tcg_temp_free_i32(twt);
18343 tcg_temp_free_i32(tdf);
18344}
18345
1e608ec1
YK
18346static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18347{
18348#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18349 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18350 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18351 TCGv telm = tcg_temp_new();
18352 TCGv_i32 tsr = tcg_const_i32(source);
18353 TCGv_i32 tdt = tcg_const_i32(dest);
18354
18355 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18356 case OPC_CTCMSA:
18357 gen_load_gpr(telm, source);
18358 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18359 break;
18360 case OPC_CFCMSA:
18361 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18362 gen_store_gpr(telm, dest);
18363 break;
18364 case OPC_MOVE_V:
18365 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18366 break;
18367 default:
18368 MIPS_INVAL("MSA instruction");
18369 generate_exception(ctx, EXCP_RI);
18370 break;
18371 }
18372
18373 tcg_temp_free(telm);
18374 tcg_temp_free_i32(tdt);
18375 tcg_temp_free_i32(tsr);
18376}
18377
18378static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18379 uint32_t n)
18380{
18381#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18382 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18383 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18384
18385 TCGv_i32 tws = tcg_const_i32(ws);
18386 TCGv_i32 twd = tcg_const_i32(wd);
18387 TCGv_i32 tn = tcg_const_i32(n);
18388 TCGv_i32 tdf = tcg_const_i32(df);
18389
18390 switch (MASK_MSA_ELM(ctx->opcode)) {
18391 case OPC_SLDI_df:
18392 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18393 break;
18394 case OPC_SPLATI_df:
18395 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18396 break;
18397 case OPC_INSVE_df:
18398 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18399 break;
18400 case OPC_COPY_S_df:
18401 case OPC_COPY_U_df:
18402 case OPC_INSERT_df:
18403#if !defined(TARGET_MIPS64)
18404 /* Double format valid only for MIPS64 */
18405 if (df == DF_DOUBLE) {
18406 generate_exception(ctx, EXCP_RI);
18407 break;
18408 }
18409#endif
18410 switch (MASK_MSA_ELM(ctx->opcode)) {
18411 case OPC_COPY_S_df:
18412 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18413 break;
18414 case OPC_COPY_U_df:
18415 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18416 break;
18417 case OPC_INSERT_df:
18418 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18419 break;
18420 }
18421 break;
18422 default:
18423 MIPS_INVAL("MSA instruction");
18424 generate_exception(ctx, EXCP_RI);
18425 }
18426 tcg_temp_free_i32(twd);
18427 tcg_temp_free_i32(tws);
18428 tcg_temp_free_i32(tn);
18429 tcg_temp_free_i32(tdf);
18430}
18431
18432static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18433{
18434 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18435 uint32_t df = 0, n = 0;
18436
18437 if ((dfn & 0x30) == 0x00) {
18438 n = dfn & 0x0f;
18439 df = DF_BYTE;
18440 } else if ((dfn & 0x38) == 0x20) {
18441 n = dfn & 0x07;
18442 df = DF_HALF;
18443 } else if ((dfn & 0x3c) == 0x30) {
18444 n = dfn & 0x03;
18445 df = DF_WORD;
18446 } else if ((dfn & 0x3e) == 0x38) {
18447 n = dfn & 0x01;
18448 df = DF_DOUBLE;
18449 } else if (dfn == 0x3E) {
18450 /* CTCMSA, CFCMSA, MOVE.V */
18451 gen_msa_elm_3e(env, ctx);
18452 return;
18453 } else {
18454 generate_exception(ctx, EXCP_RI);
18455 return;
18456 }
18457
18458 gen_msa_elm_df(env, ctx, df, n);
18459}
18460
7d05b9c8
YK
18461static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18462{
18463#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18464 uint8_t df = (ctx->opcode >> 21) & 0x1;
18465 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18466 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18467 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18468
18469 TCGv_i32 twd = tcg_const_i32(wd);
18470 TCGv_i32 tws = tcg_const_i32(ws);
18471 TCGv_i32 twt = tcg_const_i32(wt);
18472 TCGv_i32 tdf = tcg_temp_new_i32();
18473
18474 /* adjust df value for floating-point instruction */
18475 tcg_gen_movi_i32(tdf, df + 2);
18476
18477 switch (MASK_MSA_3RF(ctx->opcode)) {
18478 case OPC_FCAF_df:
18479 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18480 break;
18481 case OPC_FADD_df:
18482 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18483 break;
18484 case OPC_FCUN_df:
18485 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18486 break;
18487 case OPC_FSUB_df:
18488 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18489 break;
18490 case OPC_FCOR_df:
18491 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18492 break;
18493 case OPC_FCEQ_df:
18494 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18495 break;
18496 case OPC_FMUL_df:
18497 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18498 break;
18499 case OPC_FCUNE_df:
18500 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18501 break;
18502 case OPC_FCUEQ_df:
18503 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18504 break;
18505 case OPC_FDIV_df:
18506 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18507 break;
18508 case OPC_FCNE_df:
18509 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18510 break;
18511 case OPC_FCLT_df:
18512 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18513 break;
18514 case OPC_FMADD_df:
18515 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18516 break;
18517 case OPC_MUL_Q_df:
18518 tcg_gen_movi_i32(tdf, df + 1);
18519 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18520 break;
18521 case OPC_FCULT_df:
18522 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18523 break;
18524 case OPC_FMSUB_df:
18525 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18526 break;
18527 case OPC_MADD_Q_df:
18528 tcg_gen_movi_i32(tdf, df + 1);
18529 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18530 break;
18531 case OPC_FCLE_df:
18532 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18533 break;
18534 case OPC_MSUB_Q_df:
18535 tcg_gen_movi_i32(tdf, df + 1);
18536 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18537 break;
18538 case OPC_FCULE_df:
18539 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18540 break;
18541 case OPC_FEXP2_df:
18542 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18543 break;
18544 case OPC_FSAF_df:
18545 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18546 break;
18547 case OPC_FEXDO_df:
18548 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18549 break;
18550 case OPC_FSUN_df:
18551 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18552 break;
18553 case OPC_FSOR_df:
18554 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18555 break;
18556 case OPC_FSEQ_df:
18557 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18558 break;
18559 case OPC_FTQ_df:
18560 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18561 break;
18562 case OPC_FSUNE_df:
18563 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18564 break;
18565 case OPC_FSUEQ_df:
18566 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18567 break;
18568 case OPC_FSNE_df:
18569 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18570 break;
18571 case OPC_FSLT_df:
18572 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18573 break;
18574 case OPC_FMIN_df:
18575 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18576 break;
18577 case OPC_MULR_Q_df:
18578 tcg_gen_movi_i32(tdf, df + 1);
18579 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18580 break;
18581 case OPC_FSULT_df:
18582 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18583 break;
18584 case OPC_FMIN_A_df:
18585 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18586 break;
18587 case OPC_MADDR_Q_df:
18588 tcg_gen_movi_i32(tdf, df + 1);
18589 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18590 break;
18591 case OPC_FSLE_df:
18592 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18593 break;
18594 case OPC_FMAX_df:
18595 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18596 break;
18597 case OPC_MSUBR_Q_df:
18598 tcg_gen_movi_i32(tdf, df + 1);
18599 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18600 break;
18601 case OPC_FSULE_df:
18602 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18603 break;
18604 case OPC_FMAX_A_df:
18605 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18606 break;
18607 default:
18608 MIPS_INVAL("MSA instruction");
18609 generate_exception(ctx, EXCP_RI);
18610 break;
18611 }
18612
18613 tcg_temp_free_i32(twd);
18614 tcg_temp_free_i32(tws);
18615 tcg_temp_free_i32(twt);
18616 tcg_temp_free_i32(tdf);
18617}
18618
cbe50b9a
YK
18619static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18620{
18621#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18622 (op & (0x7 << 18)))
18623 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18624 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18625 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18626 uint8_t df = (ctx->opcode >> 16) & 0x3;
18627 TCGv_i32 twd = tcg_const_i32(wd);
18628 TCGv_i32 tws = tcg_const_i32(ws);
18629 TCGv_i32 twt = tcg_const_i32(wt);
18630 TCGv_i32 tdf = tcg_const_i32(df);
18631
18632 switch (MASK_MSA_2R(ctx->opcode)) {
18633 case OPC_FILL_df:
18634#if !defined(TARGET_MIPS64)
18635 /* Double format valid only for MIPS64 */
18636 if (df == DF_DOUBLE) {
18637 generate_exception(ctx, EXCP_RI);
18638 break;
18639 }
18640#endif
18641 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18642 break;
18643 case OPC_PCNT_df:
18644 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18645 break;
18646 case OPC_NLOC_df:
18647 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18648 break;
18649 case OPC_NLZC_df:
18650 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18651 break;
18652 default:
18653 MIPS_INVAL("MSA instruction");
18654 generate_exception(ctx, EXCP_RI);
18655 break;
18656 }
18657
18658 tcg_temp_free_i32(twd);
18659 tcg_temp_free_i32(tws);
18660 tcg_temp_free_i32(twt);
18661 tcg_temp_free_i32(tdf);
18662}
18663
3bdeb688
YK
18664static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18665{
18666#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18667 (op & (0xf << 17)))
18668 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18669 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18670 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18671 uint8_t df = (ctx->opcode >> 16) & 0x1;
18672 TCGv_i32 twd = tcg_const_i32(wd);
18673 TCGv_i32 tws = tcg_const_i32(ws);
18674 TCGv_i32 twt = tcg_const_i32(wt);
18675 /* adjust df value for floating-point instruction */
18676 TCGv_i32 tdf = tcg_const_i32(df + 2);
18677
18678 switch (MASK_MSA_2RF(ctx->opcode)) {
18679 case OPC_FCLASS_df:
18680 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18681 break;
18682 case OPC_FTRUNC_S_df:
18683 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18684 break;
18685 case OPC_FTRUNC_U_df:
18686 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18687 break;
18688 case OPC_FSQRT_df:
18689 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18690 break;
18691 case OPC_FRSQRT_df:
18692 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18693 break;
18694 case OPC_FRCP_df:
18695 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18696 break;
18697 case OPC_FRINT_df:
18698 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18699 break;
18700 case OPC_FLOG2_df:
18701 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18702 break;
18703 case OPC_FEXUPL_df:
18704 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18705 break;
18706 case OPC_FEXUPR_df:
18707 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18708 break;
18709 case OPC_FFQL_df:
18710 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18711 break;
18712 case OPC_FFQR_df:
18713 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18714 break;
18715 case OPC_FTINT_S_df:
18716 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18717 break;
18718 case OPC_FTINT_U_df:
18719 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18720 break;
18721 case OPC_FFINT_S_df:
18722 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18723 break;
18724 case OPC_FFINT_U_df:
18725 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18726 break;
18727 }
18728
18729 tcg_temp_free_i32(twd);
18730 tcg_temp_free_i32(tws);
18731 tcg_temp_free_i32(twt);
18732 tcg_temp_free_i32(tdf);
18733}
18734
cbe50b9a
YK
18735static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18736{
18737#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18738 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18739 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18740 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18741 TCGv_i32 twd = tcg_const_i32(wd);
18742 TCGv_i32 tws = tcg_const_i32(ws);
18743 TCGv_i32 twt = tcg_const_i32(wt);
18744
18745 switch (MASK_MSA_VEC(ctx->opcode)) {
18746 case OPC_AND_V:
18747 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18748 break;
18749 case OPC_OR_V:
18750 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18751 break;
18752 case OPC_NOR_V:
18753 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18754 break;
18755 case OPC_XOR_V:
18756 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18757 break;
18758 case OPC_BMNZ_V:
18759 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18760 break;
18761 case OPC_BMZ_V:
18762 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18763 break;
18764 case OPC_BSEL_V:
18765 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18766 break;
18767 default:
18768 MIPS_INVAL("MSA instruction");
18769 generate_exception(ctx, EXCP_RI);
18770 break;
18771 }
18772
18773 tcg_temp_free_i32(twd);
18774 tcg_temp_free_i32(tws);
18775 tcg_temp_free_i32(twt);
18776}
18777
18778static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18779{
18780 switch (MASK_MSA_VEC(ctx->opcode)) {
18781 case OPC_AND_V:
18782 case OPC_OR_V:
18783 case OPC_NOR_V:
18784 case OPC_XOR_V:
18785 case OPC_BMNZ_V:
18786 case OPC_BMZ_V:
18787 case OPC_BSEL_V:
18788 gen_msa_vec_v(env, ctx);
18789 break;
18790 case OPC_MSA_2R:
18791 gen_msa_2r(env, ctx);
18792 break;
3bdeb688
YK
18793 case OPC_MSA_2RF:
18794 gen_msa_2rf(env, ctx);
18795 break;
cbe50b9a
YK
18796 default:
18797 MIPS_INVAL("MSA instruction");
18798 generate_exception(ctx, EXCP_RI);
18799 break;
18800 }
18801}
18802
4c789546
YK
18803static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18804{
18805 uint32_t opcode = ctx->opcode;
18806 check_insn(ctx, ASE_MSA);
18807 check_msa_access(ctx);
18808
18809 switch (MASK_MSA_MINOR(opcode)) {
18810 case OPC_MSA_I8_00:
18811 case OPC_MSA_I8_01:
18812 case OPC_MSA_I8_02:
18813 gen_msa_i8(env, ctx);
18814 break;
80e71591
YK
18815 case OPC_MSA_I5_06:
18816 case OPC_MSA_I5_07:
18817 gen_msa_i5(env, ctx);
18818 break;
d4cf28de
YK
18819 case OPC_MSA_BIT_09:
18820 case OPC_MSA_BIT_0A:
18821 gen_msa_bit(env, ctx);
18822 break;
28f99f08
YK
18823 case OPC_MSA_3R_0D:
18824 case OPC_MSA_3R_0E:
18825 case OPC_MSA_3R_0F:
18826 case OPC_MSA_3R_10:
18827 case OPC_MSA_3R_11:
18828 case OPC_MSA_3R_12:
18829 case OPC_MSA_3R_13:
18830 case OPC_MSA_3R_14:
18831 case OPC_MSA_3R_15:
18832 gen_msa_3r(env, ctx);
18833 break;
1e608ec1
YK
18834 case OPC_MSA_ELM:
18835 gen_msa_elm(env, ctx);
18836 break;
7d05b9c8
YK
18837 case OPC_MSA_3RF_1A:
18838 case OPC_MSA_3RF_1B:
18839 case OPC_MSA_3RF_1C:
18840 gen_msa_3rf(env, ctx);
18841 break;
cbe50b9a
YK
18842 case OPC_MSA_VEC:
18843 gen_msa_vec(env, ctx);
18844 break;
f7685877
YK
18845 case OPC_LD_B:
18846 case OPC_LD_H:
18847 case OPC_LD_W:
18848 case OPC_LD_D:
18849 case OPC_ST_B:
18850 case OPC_ST_H:
18851 case OPC_ST_W:
18852 case OPC_ST_D:
18853 {
18854 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18855 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18856 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18857 uint8_t df = (ctx->opcode >> 0) & 0x3;
18858
f7685877 18859 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
18860 TCGv taddr = tcg_temp_new();
18861 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
18862
18863 switch (MASK_MSA_MINOR(opcode)) {
18864 case OPC_LD_B:
adc370a4
YK
18865 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18866 break;
f7685877 18867 case OPC_LD_H:
adc370a4
YK
18868 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18869 break;
f7685877 18870 case OPC_LD_W:
adc370a4
YK
18871 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18872 break;
f7685877 18873 case OPC_LD_D:
adc370a4 18874 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
18875 break;
18876 case OPC_ST_B:
adc370a4
YK
18877 gen_helper_msa_st_b(cpu_env, twd, taddr);
18878 break;
f7685877 18879 case OPC_ST_H:
adc370a4
YK
18880 gen_helper_msa_st_h(cpu_env, twd, taddr);
18881 break;
f7685877 18882 case OPC_ST_W:
adc370a4
YK
18883 gen_helper_msa_st_w(cpu_env, twd, taddr);
18884 break;
f7685877 18885 case OPC_ST_D:
adc370a4 18886 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
18887 break;
18888 }
18889
18890 tcg_temp_free_i32(twd);
adc370a4 18891 tcg_temp_free(taddr);
f7685877
YK
18892 }
18893 break;
4c789546
YK
18894 default:
18895 MIPS_INVAL("MSA instruction");
18896 generate_exception(ctx, EXCP_RI);
18897 break;
18898 }
18899
18900}
18901
d2bfa6e6 18902static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18903{
18904 int32_t offset;
18905 int rs, rt, rd, sa;
18906 uint32_t op, op1;
18907 int16_t imm;
18908
18909 /* make sure instructions are on a word boundary */
18910 if (ctx->pc & 0x3) {
18911 env->CP0_BadVAddr = ctx->pc;
aea14095 18912 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
62c68869 18913 ctx->bstate = BS_STOP;
099e5b4d
LA
18914 return;
18915 }
18916
18917 /* Handle blikely not taken case */
18918 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18919 TCGLabel *l1 = gen_new_label();
099e5b4d 18920
099e5b4d
LA
18921 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18922 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18923 gen_goto_tb(ctx, 1, ctx->pc + 4);
18924 gen_set_label(l1);
18925 }
18926
18927 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18928 tcg_gen_debug_insn_start(ctx->pc);
18929 }
18930
18931 op = MASK_OP_MAJOR(ctx->opcode);
18932 rs = (ctx->opcode >> 21) & 0x1f;
18933 rt = (ctx->opcode >> 16) & 0x1f;
18934 rd = (ctx->opcode >> 11) & 0x1f;
18935 sa = (ctx->opcode >> 6) & 0x1f;
18936 imm = (int16_t)ctx->opcode;
18937 switch (op) {
18938 case OPC_SPECIAL:
18939 decode_opc_special(env, ctx);
18940 break;
18941 case OPC_SPECIAL2:
4267d3e6 18942 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18943 break;
18944 case OPC_SPECIAL3:
18945 decode_opc_special3(env, ctx);
18946 break;
7a387fff
TS
18947 case OPC_REGIMM:
18948 op1 = MASK_REGIMM(ctx->opcode);
18949 switch (op1) {
fecd2646
LA
18950 case OPC_BLTZL: /* REGIMM branches */
18951 case OPC_BGEZL:
18952 case OPC_BLTZALL:
18953 case OPC_BGEZALL:
d9224450 18954 check_insn(ctx, ISA_MIPS2);
fecd2646 18955 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18956 /* Fallthrough */
fecd2646
LA
18957 case OPC_BLTZ:
18958 case OPC_BGEZ:
b231c103 18959 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18960 break;
fecd2646
LA
18961 case OPC_BLTZAL:
18962 case OPC_BGEZAL:
0aefa333
YK
18963 if (ctx->insn_flags & ISA_MIPS32R6) {
18964 if (rs == 0) {
18965 /* OPC_NAL, OPC_BAL */
b231c103 18966 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
18967 } else {
18968 generate_exception(ctx, EXCP_RI);
18969 }
18970 } else {
b231c103 18971 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18972 }
c9602061 18973 break;
7a387fff
TS
18974 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18975 case OPC_TNEI:
d9224450 18976 check_insn(ctx, ISA_MIPS2);
fecd2646 18977 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18978 gen_trap(ctx, op1, rs, -1, imm);
18979 break;
18980 case OPC_SYNCI:
d75c135e 18981 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18982 /* Break the TB to be able to sync copied instructions
18983 immediately */
18984 ctx->bstate = BS_STOP;
6af0bf9c 18985 break;
e45a93e2
JL
18986 case OPC_BPOSGE32: /* MIPS DSP branch */
18987#if defined(TARGET_MIPS64)
18988 case OPC_BPOSGE64:
18989#endif
18990 check_dsp(ctx);
b231c103 18991 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18992 break;
d4ea6acd
LA
18993#if defined(TARGET_MIPS64)
18994 case OPC_DAHI:
18995 check_insn(ctx, ISA_MIPS32R6);
18996 check_mips_64(ctx);
18997 if (rs != 0) {
18998 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18999 }
d4ea6acd
LA
19000 break;
19001 case OPC_DATI:
19002 check_insn(ctx, ISA_MIPS32R6);
19003 check_mips_64(ctx);
19004 if (rs != 0) {
19005 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19006 }
d4ea6acd
LA
19007 break;
19008#endif
6af0bf9c 19009 default: /* Invalid */
923617a3 19010 MIPS_INVAL("regimm");
6af0bf9c
FB
19011 generate_exception(ctx, EXCP_RI);
19012 break;
19013 }
19014 break;
7a387fff 19015 case OPC_CP0:
387a8fe5 19016 check_cp0_enabled(ctx);
7a387fff 19017 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19018 switch (op1) {
7a387fff
TS
19019 case OPC_MFC0:
19020 case OPC_MTC0:
ead9360e
TS
19021 case OPC_MFTR:
19022 case OPC_MTTR:
5204ea79
LA
19023 case OPC_MFHC0:
19024 case OPC_MTHC0:
d26bc211 19025#if defined(TARGET_MIPS64)
7a387fff
TS
19026 case OPC_DMFC0:
19027 case OPC_DMTC0:
19028#endif
f1aa6320 19029#ifndef CONFIG_USER_ONLY
932e71cd 19030 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19031#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19032 break;
19033 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19034#ifndef CONFIG_USER_ONLY
932e71cd 19035 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19036#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19037 break;
19038 case OPC_MFMC0:
8706c382 19039#ifndef CONFIG_USER_ONLY
932e71cd 19040 {
099e5b4d 19041 uint32_t op2;
35fbce2c 19042 TCGv t0 = tcg_temp_new();
6c5c1e20 19043
0eaef5aa 19044 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19045 switch (op2) {
19046 case OPC_DMT:
d75c135e 19047 check_insn(ctx, ASE_MT);
9ed5726c 19048 gen_helper_dmt(t0);
35fbce2c 19049 gen_store_gpr(t0, rt);
6c5c1e20
TS
19050 break;
19051 case OPC_EMT:
d75c135e 19052 check_insn(ctx, ASE_MT);
9ed5726c 19053 gen_helper_emt(t0);
35fbce2c 19054 gen_store_gpr(t0, rt);
da80682b 19055 break;
6c5c1e20 19056 case OPC_DVPE:
d75c135e 19057 check_insn(ctx, ASE_MT);
895c2d04 19058 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19059 gen_store_gpr(t0, rt);
6c5c1e20
TS
19060 break;
19061 case OPC_EVPE:
d75c135e 19062 check_insn(ctx, ASE_MT);
895c2d04 19063 gen_helper_evpe(t0, cpu_env);
35fbce2c 19064 gen_store_gpr(t0, rt);
6c5c1e20
TS
19065 break;
19066 case OPC_DI:
d75c135e 19067 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19068 save_cpu_state(ctx, 1);
895c2d04 19069 gen_helper_di(t0, cpu_env);
35fbce2c 19070 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19071 /* Stop translation as we may have switched
19072 the execution mode. */
6c5c1e20
TS
19073 ctx->bstate = BS_STOP;
19074 break;
19075 case OPC_EI:
d75c135e 19076 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19077 save_cpu_state(ctx, 1);
895c2d04 19078 gen_helper_ei(t0, cpu_env);
35fbce2c 19079 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19080 /* Stop translation as we may have switched
19081 the execution mode. */
6c5c1e20
TS
19082 ctx->bstate = BS_STOP;
19083 break;
19084 default: /* Invalid */
19085 MIPS_INVAL("mfmc0");
19086 generate_exception(ctx, EXCP_RI);
19087 break;
19088 }
6c5c1e20 19089 tcg_temp_free(t0);
7a387fff 19090 }
0eaef5aa 19091#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19092 break;
7a387fff 19093 case OPC_RDPGPR:
d75c135e 19094 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19095 gen_load_srsgpr(rt, rd);
ead9360e 19096 break;
7a387fff 19097 case OPC_WRPGPR:
d75c135e 19098 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19099 gen_store_srsgpr(rt, rd);
38121543 19100 break;
6af0bf9c 19101 default:
923617a3 19102 MIPS_INVAL("cp0");
7a387fff 19103 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
19104 break;
19105 }
19106 break;
31837be3
YK
19107 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19108 if (ctx->insn_flags & ISA_MIPS32R6) {
19109 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19110 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19111 } else {
19112 /* OPC_ADDI */
19113 /* Arithmetic with immediate opcode */
19114 gen_arith_imm(ctx, op, rt, rs, imm);
19115 }
19116 break;
324d9e32 19117 case OPC_ADDIU:
d75c135e 19118 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19119 break;
324d9e32
AJ
19120 case OPC_SLTI: /* Set on less than with immediate opcode */
19121 case OPC_SLTIU:
d75c135e 19122 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19123 break;
19124 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19125 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19126 case OPC_ORI:
19127 case OPC_XORI:
d75c135e 19128 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19129 break;
7a387fff
TS
19130 case OPC_J ... OPC_JAL: /* Jump */
19131 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19132 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19133 break;
31837be3
YK
19134 /* Branch */
19135 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19136 if (ctx->insn_flags & ISA_MIPS32R6) {
19137 if (rt == 0) {
19138 generate_exception(ctx, EXCP_RI);
19139 break;
19140 }
19141 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19142 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19143 } else {
19144 /* OPC_BLEZL */
b231c103 19145 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19146 }
19147 break;
19148 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19149 if (ctx->insn_flags & ISA_MIPS32R6) {
19150 if (rt == 0) {
19151 generate_exception(ctx, EXCP_RI);
19152 break;
19153 }
19154 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19155 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19156 } else {
19157 /* OPC_BGTZL */
b231c103 19158 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19159 }
19160 break;
19161 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19162 if (rt == 0) {
19163 /* OPC_BLEZ */
b231c103 19164 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19165 } else {
19166 check_insn(ctx, ISA_MIPS32R6);
19167 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19168 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19169 }
19170 break;
19171 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19172 if (rt == 0) {
19173 /* OPC_BGTZ */
b231c103 19174 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19175 } else {
19176 check_insn(ctx, ISA_MIPS32R6);
19177 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19178 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19179 }
19180 break;
19181 case OPC_BEQL:
19182 case OPC_BNEL:
d9224450 19183 check_insn(ctx, ISA_MIPS2);
fecd2646 19184 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19185 /* Fallthrough */
31837be3
YK
19186 case OPC_BEQ:
19187 case OPC_BNE:
b231c103 19188 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19189 break;
d9224450
MR
19190 case OPC_LL: /* Load and stores */
19191 check_insn(ctx, ISA_MIPS2);
19192 /* Fallthrough */
19193 case OPC_LWL:
fecd2646
LA
19194 case OPC_LWR:
19195 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19196 /* Fallthrough */
fecd2646
LA
19197 case OPC_LB ... OPC_LH:
19198 case OPC_LW ... OPC_LHU:
d75c135e 19199 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19200 break;
fecd2646 19201 case OPC_SWL:
7a387fff 19202 case OPC_SWR:
fecd2646 19203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19204 /* fall through */
fecd2646
LA
19205 case OPC_SB ... OPC_SH:
19206 case OPC_SW:
5c13fdfd 19207 gen_st(ctx, op, rt, rs, imm);
7a387fff 19208 break;
d66c7132 19209 case OPC_SC:
d9224450 19210 check_insn(ctx, ISA_MIPS2);
4368b29a 19211 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19212 gen_st_cond(ctx, op, rt, rs, imm);
19213 break;
7a387fff 19214 case OPC_CACHE:
bf7910c6 19215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19216 check_cp0_enabled(ctx);
d75c135e 19217 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 19218 /* Treat as NOP. */
34ae7b51 19219 break;
7a387fff 19220 case OPC_PREF:
bf7910c6 19221 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19222 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19223 /* Treat as NOP. */
6af0bf9c 19224 break;
4ad40f36 19225
923617a3 19226 /* Floating point (COP1). */
7a387fff
TS
19227 case OPC_LWC1:
19228 case OPC_LDC1:
19229 case OPC_SWC1:
19230 case OPC_SDC1:
5ab5c041 19231 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19232 break;
19233
7a387fff 19234 case OPC_CP1:
5692c6e1
YK
19235 op1 = MASK_CP1(ctx->opcode);
19236
19237 switch (op1) {
19238 case OPC_MFHC1:
19239 case OPC_MTHC1:
5e755519 19240 check_cp1_enabled(ctx);
5692c6e1
YK
19241 check_insn(ctx, ISA_MIPS32R2);
19242 case OPC_MFC1:
19243 case OPC_CFC1:
19244 case OPC_MTC1:
19245 case OPC_CTC1:
19246 check_cp1_enabled(ctx);
19247 gen_cp1(ctx, op1, rt, rd);
19248 break;
d26bc211 19249#if defined(TARGET_MIPS64)
5692c6e1
YK
19250 case OPC_DMFC1:
19251 case OPC_DMTC1:
19252 check_cp1_enabled(ctx);
19253 check_insn(ctx, ISA_MIPS3);
d9224450 19254 check_mips_64(ctx);
5692c6e1
YK
19255 gen_cp1(ctx, op1, rt, rd);
19256 break;
e189e748 19257#endif
5692c6e1
YK
19258 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19259 check_cp1_enabled(ctx);
19260 if (ctx->insn_flags & ISA_MIPS32R6) {
19261 /* OPC_BC1EQZ */
31837be3 19262 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19263 rt, imm << 2, 4);
5692c6e1
YK
19264 } else {
19265 /* OPC_BC1ANY2 */
b8aa4598 19266 check_cop1x(ctx);
d75c135e 19267 check_insn(ctx, ASE_MIPS3D);
d75c135e 19268 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19269 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19270 }
19271 break;
19272 case OPC_BC1NEZ:
19273 check_cp1_enabled(ctx);
19274 check_insn(ctx, ISA_MIPS32R6);
19275 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19276 rt, imm << 2, 4);
5692c6e1
YK
19277 break;
19278 case OPC_BC1ANY4:
19279 check_cp1_enabled(ctx);
19280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19281 check_cop1x(ctx);
19282 check_insn(ctx, ASE_MIPS3D);
19283 /* fall through */
19284 case OPC_BC1:
19285 check_cp1_enabled(ctx);
19286 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19287 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19288 (rt >> 2) & 0x7, imm << 2);
19289 break;
19290 case OPC_PS_FMT:
e29c9628 19291 check_ps(ctx);
b6f3b233 19292 /* fall through */
5692c6e1
YK
19293 case OPC_S_FMT:
19294 case OPC_D_FMT:
19295 check_cp1_enabled(ctx);
19296 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19297 (imm >> 8) & 0x7);
19298 break;
19299 case OPC_W_FMT:
19300 case OPC_L_FMT:
19301 {
19302 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19303 check_cp1_enabled(ctx);
19304 if (ctx->insn_flags & ISA_MIPS32R6) {
19305 switch (r6_op) {
19306 case R6_OPC_CMP_AF_S:
19307 case R6_OPC_CMP_UN_S:
19308 case R6_OPC_CMP_EQ_S:
19309 case R6_OPC_CMP_UEQ_S:
19310 case R6_OPC_CMP_LT_S:
19311 case R6_OPC_CMP_ULT_S:
19312 case R6_OPC_CMP_LE_S:
19313 case R6_OPC_CMP_ULE_S:
19314 case R6_OPC_CMP_SAF_S:
19315 case R6_OPC_CMP_SUN_S:
19316 case R6_OPC_CMP_SEQ_S:
19317 case R6_OPC_CMP_SEUQ_S:
19318 case R6_OPC_CMP_SLT_S:
19319 case R6_OPC_CMP_SULT_S:
19320 case R6_OPC_CMP_SLE_S:
19321 case R6_OPC_CMP_SULE_S:
19322 case R6_OPC_CMP_OR_S:
19323 case R6_OPC_CMP_UNE_S:
19324 case R6_OPC_CMP_NE_S:
19325 case R6_OPC_CMP_SOR_S:
19326 case R6_OPC_CMP_SUNE_S:
19327 case R6_OPC_CMP_SNE_S:
19328 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19329 break;
19330 case R6_OPC_CMP_AF_D:
19331 case R6_OPC_CMP_UN_D:
19332 case R6_OPC_CMP_EQ_D:
19333 case R6_OPC_CMP_UEQ_D:
19334 case R6_OPC_CMP_LT_D:
19335 case R6_OPC_CMP_ULT_D:
19336 case R6_OPC_CMP_LE_D:
19337 case R6_OPC_CMP_ULE_D:
19338 case R6_OPC_CMP_SAF_D:
19339 case R6_OPC_CMP_SUN_D:
19340 case R6_OPC_CMP_SEQ_D:
19341 case R6_OPC_CMP_SEUQ_D:
19342 case R6_OPC_CMP_SLT_D:
19343 case R6_OPC_CMP_SULT_D:
19344 case R6_OPC_CMP_SLE_D:
19345 case R6_OPC_CMP_SULE_D:
19346 case R6_OPC_CMP_OR_D:
19347 case R6_OPC_CMP_UNE_D:
19348 case R6_OPC_CMP_NE_D:
19349 case R6_OPC_CMP_SOR_D:
19350 case R6_OPC_CMP_SUNE_D:
19351 case R6_OPC_CMP_SNE_D:
19352 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19353 break;
19354 default:
d2bfa6e6
MR
19355 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19356 rt, rd, sa, (imm >> 8) & 0x7);
19357
5692c6e1 19358 break;
3f493883 19359 }
5692c6e1
YK
19360 } else {
19361 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19362 (imm >> 8) & 0x7);
36d23958 19363 }
5692c6e1
YK
19364 break;
19365 }
19366 case OPC_BZ_V:
19367 case OPC_BNZ_V:
19368 case OPC_BZ_B:
19369 case OPC_BZ_H:
19370 case OPC_BZ_W:
19371 case OPC_BZ_D:
19372 case OPC_BNZ_B:
19373 case OPC_BNZ_H:
19374 case OPC_BNZ_W:
19375 case OPC_BNZ_D:
19376 check_insn(ctx, ASE_MSA);
19377 gen_msa_branch(env, ctx, op1);
19378 break;
19379 default:
19380 MIPS_INVAL("cp1");
19381 generate_exception(ctx, EXCP_RI);
19382 break;
6ea83fed 19383 }
4ad40f36
FB
19384 break;
19385
31837be3
YK
19386 /* Compact branches [R6] and COP2 [non-R6] */
19387 case OPC_BC: /* OPC_LWC2 */
19388 case OPC_BALC: /* OPC_SWC2 */
19389 if (ctx->insn_flags & ISA_MIPS32R6) {
19390 /* OPC_BC, OPC_BALC */
19391 gen_compute_compact_branch(ctx, op, 0, 0,
19392 sextract32(ctx->opcode << 2, 0, 28));
19393 } else {
19394 /* OPC_LWC2, OPC_SWC2 */
19395 /* COP2: Not implemented. */
19396 generate_exception_err(ctx, EXCP_CpU, 2);
19397 }
19398 break;
19399 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19400 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19401 if (ctx->insn_flags & ISA_MIPS32R6) {
19402 if (rs != 0) {
19403 /* OPC_BEQZC, OPC_BNEZC */
19404 gen_compute_compact_branch(ctx, op, rs, 0,
19405 sextract32(ctx->opcode << 2, 0, 23));
19406 } else {
19407 /* OPC_JIC, OPC_JIALC */
19408 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19409 }
19410 } else {
19411 /* OPC_LWC2, OPC_SWC2 */
19412 /* COP2: Not implemented. */
19413 generate_exception_err(ctx, EXCP_CpU, 2);
19414 }
4ad40f36 19415 break;
bd277fa1 19416 case OPC_CP2:
d75c135e 19417 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19418 /* Note that these instructions use different fields. */
19419 gen_loongson_multimedia(ctx, sa, rd, rt);
19420 break;
4ad40f36 19421
7a387fff 19422 case OPC_CP3:
fecd2646 19423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19424 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19425 check_cp1_enabled(ctx);
36d23958
TS
19426 op1 = MASK_CP3(ctx->opcode);
19427 switch (op1) {
d9224450
MR
19428 case OPC_LUXC1:
19429 case OPC_SUXC1:
19430 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19431 /* Fallthrough */
5a5012ec
TS
19432 case OPC_LWXC1:
19433 case OPC_LDXC1:
5a5012ec
TS
19434 case OPC_SWXC1:
19435 case OPC_SDXC1:
d9224450 19436 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19437 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19438 break;
e0c84da7 19439 case OPC_PREFX:
d9224450 19440 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19441 /* Treat as NOP. */
e0c84da7 19442 break;
5a5012ec 19443 case OPC_ALNV_PS:
d9224450
MR
19444 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19445 /* Fallthrough */
5a5012ec
TS
19446 case OPC_MADD_S:
19447 case OPC_MADD_D:
19448 case OPC_MADD_PS:
19449 case OPC_MSUB_S:
19450 case OPC_MSUB_D:
19451 case OPC_MSUB_PS:
19452 case OPC_NMADD_S:
19453 case OPC_NMADD_D:
19454 case OPC_NMADD_PS:
19455 case OPC_NMSUB_S:
19456 case OPC_NMSUB_D:
19457 case OPC_NMSUB_PS:
d9224450 19458 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19459 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19460 break;
36d23958 19461 default:
923617a3 19462 MIPS_INVAL("cp3");
e397ee33 19463 generate_exception (ctx, EXCP_RI);
36d23958
TS
19464 break;
19465 }
19466 } else {
e397ee33 19467 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19468 }
4ad40f36
FB
19469 break;
19470
d26bc211 19471#if defined(TARGET_MIPS64)
7a387fff 19472 /* MIPS64 opcodes */
7a387fff 19473 case OPC_LDL ... OPC_LDR:
bf7910c6 19474 case OPC_LLD:
fecd2646 19475 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19476 /* fall through */
fecd2646 19477 case OPC_LWU:
7a387fff 19478 case OPC_LD:
d75c135e 19479 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19480 check_mips_64(ctx);
d75c135e 19481 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19482 break;
19483 case OPC_SDL ... OPC_SDR:
fecd2646 19484 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19485 /* fall through */
7a387fff 19486 case OPC_SD:
d75c135e 19487 check_insn(ctx, ISA_MIPS3);
e189e748 19488 check_mips_64(ctx);
5c13fdfd 19489 gen_st(ctx, op, rt, rs, imm);
7a387fff 19490 break;
d66c7132 19491 case OPC_SCD:
bf7910c6 19492 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19493 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19494 check_mips_64(ctx);
19495 gen_st_cond(ctx, op, rt, rs, imm);
19496 break;
31837be3
YK
19497 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19498 if (ctx->insn_flags & ISA_MIPS32R6) {
19499 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19500 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19501 } else {
19502 /* OPC_DADDI */
19503 check_insn(ctx, ISA_MIPS3);
19504 check_mips_64(ctx);
19505 gen_arith_imm(ctx, op, rt, rs, imm);
19506 }
19507 break;
324d9e32 19508 case OPC_DADDIU:
d75c135e 19509 check_insn(ctx, ISA_MIPS3);
e189e748 19510 check_mips_64(ctx);
d75c135e 19511 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19512 break;
31837be3
YK
19513#else
19514 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19515 if (ctx->insn_flags & ISA_MIPS32R6) {
19516 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19517 } else {
19518 MIPS_INVAL("major opcode");
19519 generate_exception(ctx, EXCP_RI);
19520 }
19521 break;
6af0bf9c 19522#endif
d4ea6acd
LA
19523 case OPC_DAUI: /* OPC_JALX */
19524 if (ctx->insn_flags & ISA_MIPS32R6) {
19525#if defined(TARGET_MIPS64)
19526 /* OPC_DAUI */
19527 check_mips_64(ctx);
19528 if (rt != 0) {
19529 TCGv t0 = tcg_temp_new();
19530 gen_load_gpr(t0, rs);
19531 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19532 tcg_temp_free(t0);
19533 }
d4ea6acd
LA
19534#else
19535 generate_exception(ctx, EXCP_RI);
19536 MIPS_INVAL("major opcode");
19537#endif
19538 } else {
19539 /* OPC_JALX */
19540 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19541 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19542 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19543 }
364d4831 19544 break;
4c789546 19545 case OPC_MSA: /* OPC_MDMX */
7a387fff 19546 /* MDMX: Not implemented. */
4c789546 19547 gen_msa(env, ctx);
d4ea6acd
LA
19548 break;
19549 case OPC_PCREL:
19550 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 19551 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 19552 break;
6af0bf9c 19553 default: /* Invalid */
923617a3 19554 MIPS_INVAL("major opcode");
6af0bf9c
FB
19555 generate_exception(ctx, EXCP_RI);
19556 break;
19557 }
6af0bf9c
FB
19558}
19559
2cfc5f17 19560static inline void
6429db34
AF
19561gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19562 bool search_pc)
6af0bf9c 19563{
ed2803da 19564 CPUState *cs = CPU(cpu);
6429db34 19565 CPUMIPSState *env = &cpu->env;
278d0702 19566 DisasContext ctx;
6af0bf9c 19567 target_ulong pc_start;
fe237291 19568 target_ulong next_page_start;
a1d1bb31 19569 CPUBreakpoint *bp;
6af0bf9c 19570 int j, lj = -1;
2e70f6ef
PB
19571 int num_insns;
19572 int max_insns;
c9602061 19573 int insn_bytes;
339cd2a8 19574 int is_slot;
6af0bf9c 19575
93fcfe39
AL
19576 if (search_pc)
19577 qemu_log("search pc %d\n", search_pc);
4ad40f36 19578
6af0bf9c 19579 pc_start = tb->pc;
fe237291 19580 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19581 ctx.pc = pc_start;
4ad40f36 19582 ctx.saved_pc = -1;
ed2803da 19583 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19584 ctx.insn_flags = env->insn_flags;
5ab5c041 19585 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19586 ctx.tb = tb;
19587 ctx.bstate = BS_NONE;
e98c0d17 19588 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19589 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19590 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19591 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19592 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
19593 ctx.PAMask = env->PAMask;
19594 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19595 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
4ad40f36 19596 /* Restore delay slot state from the tb context. */
c068688b 19597 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19598 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
19599 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19600 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
fd4a04eb 19601 restore_cpu_state(env, &ctx);
932e71cd 19602#ifdef CONFIG_USER_ONLY
0eaef5aa 19603 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19604#else
0eaef5aa 19605 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19606#endif
be3a8c53
YK
19607 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19608 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19609 num_insns = 0;
19610 max_insns = tb->cflags & CF_COUNT_MASK;
19611 if (max_insns == 0)
19612 max_insns = CF_COUNT_MASK;
d12d51d5 19613 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19614 gen_tb_start(tb);
faf7aaa9 19615 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
19616 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19617 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 19618 if (bp->pc == ctx.pc) {
278d0702 19619 save_cpu_state(&ctx, 1);
4ad40f36 19620 ctx.bstate = BS_BRANCH;
895c2d04 19621 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
19622 /* Include the breakpoint location or the tb won't
19623 * be flushed when it must be. */
19624 ctx.pc += 4;
4ad40f36
FB
19625 goto done_generating;
19626 }
19627 }
19628 }
19629
6af0bf9c 19630 if (search_pc) {
fe700adb 19631 j = tcg_op_buf_count();
6af0bf9c
FB
19632 if (lj < j) {
19633 lj++;
19634 while (lj < j)
ab1103de 19635 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 19636 }
25983cad 19637 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 19638 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 19639 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 19640 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 19641 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 19642 }
2e70f6ef
PB
19643 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19644 gen_io_start();
c9602061 19645
339cd2a8 19646 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19647 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19648 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19649 insn_bytes = 4;
240ce26a 19650 decode_opc(env, &ctx);
d75c135e 19651 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19652 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19653 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19654 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19655 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19656 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
19657 } else {
19658 generate_exception(&ctx, EXCP_RI);
3c824109 19659 ctx.bstate = BS_STOP;
c9602061
NF
19660 break;
19661 }
31837be3 19662
b231c103 19663 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19664 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19665 MIPS_HFLAG_FBNSLOT))) {
19666 /* force to generate branch as there is neither delay nor
19667 forbidden slot */
19668 is_slot = 1;
b231c103 19669 }
65935f07
YK
19670 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19671 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19672 /* Force to generate branch as microMIPS R6 doesn't restrict
19673 branches in the forbidden slot. */
19674 is_slot = 1;
19675 }
b231c103 19676 }
339cd2a8 19677 if (is_slot) {
31837be3 19678 gen_branch(&ctx, insn_bytes);
c9602061
NF
19679 }
19680 ctx.pc += insn_bytes;
19681
2e70f6ef 19682 num_insns++;
4ad40f36 19683
7b270ef2
NF
19684 /* Execute a branch and its delay slot as a single instruction.
19685 This is what GDB expects and is consistent with what the
19686 hardware does (e.g. if a delay slot instruction faults, the
19687 reported PC is the PC of the branch). */
ed2803da 19688 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19689 break;
ed2803da 19690 }
4ad40f36 19691
fe237291 19692 if (ctx.pc >= next_page_start) {
6af0bf9c 19693 break;
fe237291 19694 }
4ad40f36 19695
fe700adb 19696 if (tcg_op_buf_full()) {
faf7aaa9 19697 break;
efd7f486 19698 }
faf7aaa9 19699
2e70f6ef
PB
19700 if (num_insns >= max_insns)
19701 break;
1b530a6d
AJ
19702
19703 if (singlestep)
19704 break;
6af0bf9c 19705 }
ed2803da 19706 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19707 gen_io_end();
ed2803da
AF
19708 }
19709 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19710 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
895c2d04 19711 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 19712 } else {
6958549d 19713 switch (ctx.bstate) {
16c00cb2 19714 case BS_STOP:
df1561e2
TS
19715 gen_goto_tb(&ctx, 0, ctx.pc);
19716 break;
16c00cb2 19717 case BS_NONE:
278d0702 19718 save_cpu_state(&ctx, 0);
16c00cb2
TS
19719 gen_goto_tb(&ctx, 0, ctx.pc);
19720 break;
5a5012ec 19721 case BS_EXCP:
57fec1fe 19722 tcg_gen_exit_tb(0);
16c00cb2 19723 break;
5a5012ec
TS
19724 case BS_BRANCH:
19725 default:
19726 break;
6958549d 19727 }
6af0bf9c 19728 }
4ad40f36 19729done_generating:
806f352d 19730 gen_tb_end(tb, num_insns);
0a7df5da 19731
6af0bf9c 19732 if (search_pc) {
fe700adb 19733 j = tcg_op_buf_count();
6af0bf9c
FB
19734 lj++;
19735 while (lj <= j)
ab1103de 19736 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
19737 } else {
19738 tb->size = ctx.pc - pc_start;
2e70f6ef 19739 tb->icount = num_insns;
6af0bf9c
FB
19740 }
19741#ifdef DEBUG_DISAS
d12d51d5 19742 LOG_DISAS("\n");
8fec2b8c 19743 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19744 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 19745 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19746 qemu_log("\n");
6af0bf9c
FB
19747 }
19748#endif
6af0bf9c
FB
19749}
19750
7db13fae 19751void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19752{
6429db34 19753 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
19754}
19755
7db13fae 19756void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19757{
6429db34 19758 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
19759}
19760
7db13fae 19761static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19762 int flags)
6ea83fed
FB
19763{
19764 int i;
5e755519 19765 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19766
2a5612e6
SW
19767#define printfpr(fp) \
19768 do { \
19769 if (is_fpu64) \
19770 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19771 " fd:%13g fs:%13g psu: %13g\n", \
19772 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19773 (double)(fp)->fd, \
19774 (double)(fp)->fs[FP_ENDIAN_IDX], \
19775 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19776 else { \
19777 fpr_t tmp; \
19778 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19779 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19780 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19781 " fd:%13g fs:%13g psu:%13g\n", \
19782 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19783 (double)tmp.fd, \
19784 (double)tmp.fs[FP_ENDIAN_IDX], \
19785 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19786 } \
6ea83fed
FB
19787 } while(0)
19788
5a5012ec 19789
9a78eead
SW
19790 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19791 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19792 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19793 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19794 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19795 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19796 }
19797
19798#undef printfpr
19799}
19800
878096ee
AF
19801void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19802 int flags)
6af0bf9c 19803{
878096ee
AF
19804 MIPSCPU *cpu = MIPS_CPU(cs);
19805 CPUMIPSState *env = &cpu->env;
6af0bf9c 19806 int i;
3b46e624 19807
a7200c9f
SW
19808 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19809 " LO=0x" TARGET_FMT_lx " ds %04x "
19810 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19811 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19812 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19813 for (i = 0; i < 32; i++) {
19814 if ((i & 3) == 0)
19815 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19816 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19817 if ((i & 3) == 3)
19818 cpu_fprintf(f, "\n");
19819 }
568b600d 19820
3594c774 19821 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19822 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
19823 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19824 PRIx64 "\n",
5499b6ff 19825 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19826 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19827 env->CP0_Config2, env->CP0_Config3);
19828 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19829 env->CP0_Config4, env->CP0_Config5);
5e755519 19830 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19831 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
19832}
19833
78ce64f4 19834void mips_tcg_init(void)
39454628 19835{
f01be154 19836 int i;
39454628
TS
19837 static int inited;
19838
19839 /* Initialize various static tables. */
19840 if (inited)
6958549d 19841 return;
39454628 19842
a7812ae4 19843 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19844 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19845 for (i = 1; i < 32; i++)
a7812ae4 19846 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19847 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19848 regnames[i]);
d73ee8a2 19849
863f264d
YK
19850 for (i = 0; i < 32; i++) {
19851 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19852 msa_wr_d[i * 2] =
19853 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
19854 /* The scalar floating-point unit (FPU) registers are mapped on
19855 * the MSA vector registers. */
19856 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19857 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19858 msa_wr_d[i * 2 + 1] =
19859 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19860 }
19861
a7812ae4 19862 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19863 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19864 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19865 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19866 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19867 regnames_HI[i]);
a7812ae4 19868 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19869 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19870 regnames_LO[i]);
4b2eb8d2 19871 }
a7812ae4 19872 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19873 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19874 "DSPControl");
1ba74fb8 19875 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19876 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19877 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19878 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19879 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19880 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19881
a7812ae4 19882 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19883 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19884 "fcr0");
19885 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19886 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19887 "fcr31");
39454628
TS
19888
19889 inited = 1;
19890}
19891
aaed909a
FB
19892#include "translate_init.c"
19893
30bf942d 19894MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19895{
0f71a709 19896 MIPSCPU *cpu;
6af0bf9c 19897 CPUMIPSState *env;
c227f099 19898 const mips_def_t *def;
6af0bf9c 19899
aaed909a
FB
19900 def = cpu_mips_find_by_name(cpu_model);
19901 if (!def)
19902 return NULL;
0f71a709
AF
19903 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19904 env = &cpu->env;
aaed909a
FB
19905 env->cpu_model = def;
19906
51cc2e78
BS
19907#ifndef CONFIG_USER_ONLY
19908 mmu_init(env, def);
19909#endif
19910 fpu_init(env, def);
19911 mvp_init(env, def);
c1caf1d9
AF
19912
19913 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19914
30bf942d 19915 return cpu;
6ae81775
TS
19916}
19917
1bba0dc9 19918void cpu_state_reset(CPUMIPSState *env)
6ae81775 19919{
55e5c285
AF
19920 MIPSCPU *cpu = mips_env_get_cpu(env);
19921 CPUState *cs = CPU(cpu);
6ae81775 19922
51cc2e78
BS
19923 /* Reset registers to their default values */
19924 env->CP0_PRid = env->cpu_model->CP0_PRid;
19925 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19926#ifdef TARGET_WORDS_BIGENDIAN
19927 env->CP0_Config0 |= (1 << CP0C0_BE);
19928#endif
19929 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19930 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19931 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19932 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19933 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19934 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19935 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19936 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19937 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19938 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19939 << env->cpu_model->CP0_LLAddr_shift;
19940 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19941 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19942 env->CCRes = env->cpu_model->CCRes;
19943 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19944 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19945 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19946 env->current_tc = 0;
19947 env->SEGBITS = env->cpu_model->SEGBITS;
19948 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19949#if defined(TARGET_MIPS64)
19950 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19951 env->SEGMask |= 3ULL << 62;
19952 }
19953#endif
19954 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
19955 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19956 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19957 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19958 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19959 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19960 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19961 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19962 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19963 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19964 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19965 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19966 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19967 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19968 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19969 env->insn_flags = env->cpu_model->insn_flags;
19970
0eaef5aa 19971#if defined(CONFIG_USER_ONLY)
03e6e501 19972 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19973# ifdef TARGET_MIPS64
19974 /* Enable 64-bit register mode. */
19975 env->CP0_Status |= (1 << CP0St_PX);
19976# endif
19977# ifdef TARGET_ABI_MIPSN64
19978 /* Enable 64-bit address mode. */
19979 env->CP0_Status |= (1 << CP0St_UX);
19980# endif
94159135
MI
19981 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19982 hardware registers. */
19983 env->CP0_HWREna |= 0x0000000F;
91a75935 19984 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19985 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19986 }
6f0af304
PJ
19987 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19988 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19989 }
4d66261f
PJ
19990# if defined(TARGET_MIPS64)
19991 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19992 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19993 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19994 env->CP0_Status |= (1 << CP0St_FR);
19995 }
4d66261f 19996# endif
932e71cd
AJ
19997#else
19998 if (env->hflags & MIPS_HFLAG_BMASK) {
19999 /* If the exception was raised from a delay slot,
20000 come back to the jump. */
c3577479
MR
20001 env->CP0_ErrorEPC = (env->active_tc.PC
20002 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20003 } else {
932e71cd
AJ
20004 env->CP0_ErrorEPC = env->active_tc.PC;
20005 }
20006 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
20007 env->CP0_Random = env->tlb->nb_tlb - 1;
20008 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20009 env->CP0_Wired = 0;
0a2672b7
JH
20010 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20011 if (kvm_enabled()) {
20012 env->CP0_EBase |= 0x40000000;
20013 } else {
20014 env->CP0_EBase |= 0x80000000;
20015 }
932e71cd
AJ
20016 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20017 /* vectored interrupts not implemented, timer on int 7,
20018 no performance counters. */
20019 env->CP0_IntCtl = 0xe0000000;
20020 {
20021 int i;
20022
20023 for (i = 0; i < 7; i++) {
20024 env->CP0_WatchLo[i] = 0;
20025 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20026 }
932e71cd
AJ
20027 env->CP0_WatchLo[7] = 0;
20028 env->CP0_WatchHi[7] = 0;
fd88b6ab 20029 }
932e71cd
AJ
20030 /* Count register increments in debug mode, EJTAG version 1 */
20031 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20032
4b69c7e2
JH
20033 cpu_mips_store_count(env, 1);
20034
9e56e756
EI
20035 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20036 int i;
20037
20038 /* Only TC0 on VPE 0 starts as active. */
20039 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20040 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20041 env->tcs[i].CP0_TCHalt = 1;
20042 }
20043 env->active_tc.CP0_TCHalt = 1;
259186a7 20044 cs->halted = 1;
9e56e756 20045
55e5c285 20046 if (cs->cpu_index == 0) {
9e56e756
EI
20047 /* VPE0 starts up enabled. */
20048 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20049 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20050
20051 /* TC0 starts up unhalted. */
259186a7 20052 cs->halted = 0;
9e56e756
EI
20053 env->active_tc.CP0_TCHalt = 0;
20054 env->tcs[0].CP0_TCHalt = 0;
20055 /* With thread 0 active. */
20056 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20057 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20058 }
20059 }
51cc2e78 20060#endif
ddc584bd
LA
20061 if ((env->insn_flags & ISA_MIPS32R6) &&
20062 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20063 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20064 env->CP0_Status |= (1 << CP0St_FR);
20065 }
20066
863f264d
YK
20067 /* MSA */
20068 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20069 msa_reset(env);
20070 }
20071
03e6e501 20072 compute_hflags(env);
bb962386
MR
20073 restore_rounding_mode(env);
20074 restore_flush_mode(env);
e117f526 20075 restore_pamask(env);
27103424 20076 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20077
20078 if (semihosting_get_argc()) {
20079 /* UHI interface can be used to obtain argc and argv */
20080 env->active_tc.gpr[4] = -1;
20081 }
6af0bf9c 20082}
d2856f1a 20083
7db13fae 20084void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 20085{
25983cad 20086 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
20087 env->hflags &= ~MIPS_HFLAG_BMASK;
20088 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
20089 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20090 case MIPS_HFLAG_BR:
20091 break;
20092 case MIPS_HFLAG_BC:
20093 case MIPS_HFLAG_BL:
20094 case MIPS_HFLAG_B:
20095 env->btarget = gen_opc_btarget[pc_pos];
20096 break;
20097 }
d2856f1a 20098}