]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
mips: move hw/mips/cputimer.c to target/mips/
[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
c684822a 24#include "qemu/osdep.h"
6af0bf9c 25#include "cpu.h"
76cad711 26#include "disas/disas.h"
63c91552 27#include "exec/exec-all.h"
57fec1fe 28#include "tcg-op.h"
f08b6170 29#include "exec/cpu_ldst.h"
d3d93c6c 30#include "hw/mips/cpudevs.h"
6af0bf9c 31
2ef6175a
RH
32#include "exec/helper-proto.h"
33#include "exec/helper-gen.h"
3b3c1694 34#include "exec/semihost.h"
a7812ae4 35
b44a7fb1 36#include "target/mips/trace.h"
a7e30d84 37#include "trace-tcg.h"
508127e2 38#include "exec/log.h"
a7e30d84 39
fb7729e2 40#define MIPS_DEBUG_DISAS 0
6af0bf9c 41
7a387fff
TS
42/* MIPS major opcodes */
43#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
44
45enum {
46 /* indirect opcode tables */
7a387fff
TS
47 OPC_SPECIAL = (0x00 << 26),
48 OPC_REGIMM = (0x01 << 26),
49 OPC_CP0 = (0x10 << 26),
50 OPC_CP1 = (0x11 << 26),
51 OPC_CP2 = (0x12 << 26),
52 OPC_CP3 = (0x13 << 26),
53 OPC_SPECIAL2 = (0x1C << 26),
54 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 55 /* arithmetic with immediate */
7a387fff
TS
56 OPC_ADDI = (0x08 << 26),
57 OPC_ADDIU = (0x09 << 26),
58 OPC_SLTI = (0x0A << 26),
59 OPC_SLTIU = (0x0B << 26),
324d9e32 60 /* logic with immediate */
7a387fff
TS
61 OPC_ANDI = (0x0C << 26),
62 OPC_ORI = (0x0D << 26),
63 OPC_XORI = (0x0E << 26),
64 OPC_LUI = (0x0F << 26),
324d9e32 65 /* arithmetic with immediate */
7a387fff
TS
66 OPC_DADDI = (0x18 << 26),
67 OPC_DADDIU = (0x19 << 26),
e37e863f 68 /* Jump and branches */
7a387fff
TS
69 OPC_J = (0x02 << 26),
70 OPC_JAL = (0x03 << 26),
71 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
72 OPC_BEQL = (0x14 << 26),
73 OPC_BNE = (0x05 << 26),
74 OPC_BNEL = (0x15 << 26),
75 OPC_BLEZ = (0x06 << 26),
76 OPC_BLEZL = (0x16 << 26),
77 OPC_BGTZ = (0x07 << 26),
78 OPC_BGTZL = (0x17 << 26),
b231c103 79 OPC_JALX = (0x1D << 26),
d4ea6acd 80 OPC_DAUI = (0x1D << 26),
e37e863f 81 /* Load and stores */
7a387fff
TS
82 OPC_LDL = (0x1A << 26),
83 OPC_LDR = (0x1B << 26),
84 OPC_LB = (0x20 << 26),
85 OPC_LH = (0x21 << 26),
86 OPC_LWL = (0x22 << 26),
87 OPC_LW = (0x23 << 26),
364d4831 88 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
89 OPC_LBU = (0x24 << 26),
90 OPC_LHU = (0x25 << 26),
91 OPC_LWR = (0x26 << 26),
92 OPC_LWU = (0x27 << 26),
93 OPC_SB = (0x28 << 26),
94 OPC_SH = (0x29 << 26),
95 OPC_SWL = (0x2A << 26),
96 OPC_SW = (0x2B << 26),
97 OPC_SDL = (0x2C << 26),
98 OPC_SDR = (0x2D << 26),
99 OPC_SWR = (0x2E << 26),
100 OPC_LL = (0x30 << 26),
101 OPC_LLD = (0x34 << 26),
102 OPC_LD = (0x37 << 26),
364d4831 103 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
104 OPC_SC = (0x38 << 26),
105 OPC_SCD = (0x3C << 26),
106 OPC_SD = (0x3F << 26),
e37e863f 107 /* Floating point load/store */
7a387fff
TS
108 OPC_LWC1 = (0x31 << 26),
109 OPC_LWC2 = (0x32 << 26),
110 OPC_LDC1 = (0x35 << 26),
111 OPC_LDC2 = (0x36 << 26),
112 OPC_SWC1 = (0x39 << 26),
113 OPC_SWC2 = (0x3A << 26),
114 OPC_SDC1 = (0x3D << 26),
115 OPC_SDC2 = (0x3E << 26),
31837be3
YK
116 /* Compact Branches */
117 OPC_BLEZALC = (0x06 << 26),
118 OPC_BGEZALC = (0x06 << 26),
119 OPC_BGEUC = (0x06 << 26),
120 OPC_BGTZALC = (0x07 << 26),
121 OPC_BLTZALC = (0x07 << 26),
122 OPC_BLTUC = (0x07 << 26),
123 OPC_BOVC = (0x08 << 26),
124 OPC_BEQZALC = (0x08 << 26),
125 OPC_BEQC = (0x08 << 26),
126 OPC_BLEZC = (0x16 << 26),
127 OPC_BGEZC = (0x16 << 26),
128 OPC_BGEC = (0x16 << 26),
129 OPC_BGTZC = (0x17 << 26),
130 OPC_BLTZC = (0x17 << 26),
131 OPC_BLTC = (0x17 << 26),
132 OPC_BNVC = (0x18 << 26),
133 OPC_BNEZALC = (0x18 << 26),
134 OPC_BNEC = (0x18 << 26),
135 OPC_BC = (0x32 << 26),
136 OPC_BEQZC = (0x36 << 26),
137 OPC_JIC = (0x36 << 26),
138 OPC_BALC = (0x3A << 26),
139 OPC_BNEZC = (0x3E << 26),
140 OPC_JIALC = (0x3E << 26),
7a387fff
TS
141 /* MDMX ASE specific */
142 OPC_MDMX = (0x1E << 26),
239dfebe
YK
143 /* MSA ASE, same as MDMX */
144 OPC_MSA = OPC_MDMX,
e37e863f 145 /* Cache and prefetch */
7a387fff
TS
146 OPC_CACHE = (0x2F << 26),
147 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
148 /* PC-relative address computation / loads */
149 OPC_PCREL = (0x3B << 26),
150};
151
152/* PC-relative address computation / loads */
153#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
154#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
155enum {
156 /* Instructions determined by bits 19 and 20 */
157 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
158 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
159 OPC_LWUPC = OPC_PCREL | (2 << 19),
160
161 /* Instructions determined by bits 16 ... 20 */
162 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
163 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
164
165 /* Other */
166 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
167};
168
169/* MIPS special opcodes */
7a387fff
TS
170#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
171
e37e863f
FB
172enum {
173 /* Shifts */
7a387fff 174 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
175 /* NOP is SLL r0, r0, 0 */
176 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
177 /* EHB is SLL r0, r0, 3 */
178 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 179 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
180 OPC_SRA = 0x03 | OPC_SPECIAL,
181 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 182 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 183 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
184 OPC_SRAV = 0x07 | OPC_SPECIAL,
185 OPC_DSLLV = 0x14 | OPC_SPECIAL,
186 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 187 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
188 OPC_DSRAV = 0x17 | OPC_SPECIAL,
189 OPC_DSLL = 0x38 | OPC_SPECIAL,
190 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 191 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
192 OPC_DSRA = 0x3B | OPC_SPECIAL,
193 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
194 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 195 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 196 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 197 /* Multiplication / division */
7a387fff
TS
198 OPC_MULT = 0x18 | OPC_SPECIAL,
199 OPC_MULTU = 0x19 | OPC_SPECIAL,
200 OPC_DIV = 0x1A | OPC_SPECIAL,
201 OPC_DIVU = 0x1B | OPC_SPECIAL,
202 OPC_DMULT = 0x1C | OPC_SPECIAL,
203 OPC_DMULTU = 0x1D | OPC_SPECIAL,
204 OPC_DDIV = 0x1E | OPC_SPECIAL,
205 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 206
e37e863f 207 /* 2 registers arithmetic / logic */
7a387fff
TS
208 OPC_ADD = 0x20 | OPC_SPECIAL,
209 OPC_ADDU = 0x21 | OPC_SPECIAL,
210 OPC_SUB = 0x22 | OPC_SPECIAL,
211 OPC_SUBU = 0x23 | OPC_SPECIAL,
212 OPC_AND = 0x24 | OPC_SPECIAL,
213 OPC_OR = 0x25 | OPC_SPECIAL,
214 OPC_XOR = 0x26 | OPC_SPECIAL,
215 OPC_NOR = 0x27 | OPC_SPECIAL,
216 OPC_SLT = 0x2A | OPC_SPECIAL,
217 OPC_SLTU = 0x2B | OPC_SPECIAL,
218 OPC_DADD = 0x2C | OPC_SPECIAL,
219 OPC_DADDU = 0x2D | OPC_SPECIAL,
220 OPC_DSUB = 0x2E | OPC_SPECIAL,
221 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 222 /* Jumps */
7a387fff
TS
223 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
224 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 225 /* Traps */
7a387fff
TS
226 OPC_TGE = 0x30 | OPC_SPECIAL,
227 OPC_TGEU = 0x31 | OPC_SPECIAL,
228 OPC_TLT = 0x32 | OPC_SPECIAL,
229 OPC_TLTU = 0x33 | OPC_SPECIAL,
230 OPC_TEQ = 0x34 | OPC_SPECIAL,
231 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 232 /* HI / LO registers load & stores */
7a387fff
TS
233 OPC_MFHI = 0x10 | OPC_SPECIAL,
234 OPC_MTHI = 0x11 | OPC_SPECIAL,
235 OPC_MFLO = 0x12 | OPC_SPECIAL,
236 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 237 /* Conditional moves */
7a387fff
TS
238 OPC_MOVZ = 0x0A | OPC_SPECIAL,
239 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 240
b691d9d2
LA
241 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
242 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
243
7a387fff 244 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
245
246 /* Special */
a0d700e4 247 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
248 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
249 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 250 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
251 OPC_SYNC = 0x0F | OPC_SPECIAL,
252
7a387fff
TS
253 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
254 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
255 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
256 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
257};
258
b42ee5e1
LA
259/* R6 Multiply and Divide instructions have the same Opcode
260 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
261#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
262
263enum {
264 R6_OPC_MUL = OPC_MULT | (2 << 6),
265 R6_OPC_MUH = OPC_MULT | (3 << 6),
266 R6_OPC_MULU = OPC_MULTU | (2 << 6),
267 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
268 R6_OPC_DIV = OPC_DIV | (2 << 6),
269 R6_OPC_MOD = OPC_DIV | (3 << 6),
270 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
271 R6_OPC_MODU = OPC_DIVU | (3 << 6),
272
273 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
274 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
275 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
276 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
277 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
278 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
279 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
280 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
281
282 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
283 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
284 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
285 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
286 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
287
288 OPC_LSA = 0x05 | OPC_SPECIAL,
289 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
290};
291
e9c71dd1
TS
292/* Multiplication variants of the vr54xx. */
293#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
294
295enum {
296 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
297 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
298 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
299 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
300 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
301 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
303 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
305 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
306 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
307 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
308 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
309 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
310};
311
7a387fff
TS
312/* REGIMM (rt field) opcodes */
313#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
314
315enum {
316 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
317 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
318 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
319 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
320 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
321 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
322 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
323 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
324 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
325 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
326 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
327 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
328 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
329 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 330 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 331 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
332
333 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
334 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
335};
336
7a387fff
TS
337/* Special2 opcodes */
338#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
339
e37e863f 340enum {
7a387fff
TS
341 /* Multiply & xxx operations */
342 OPC_MADD = 0x00 | OPC_SPECIAL2,
343 OPC_MADDU = 0x01 | OPC_SPECIAL2,
344 OPC_MUL = 0x02 | OPC_SPECIAL2,
345 OPC_MSUB = 0x04 | OPC_SPECIAL2,
346 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
347 /* Loongson 2F */
348 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
349 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
350 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
351 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
352 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
353 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
354 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
355 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
356 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
357 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
358 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
359 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 360 /* Misc */
7a387fff
TS
361 OPC_CLZ = 0x20 | OPC_SPECIAL2,
362 OPC_CLO = 0x21 | OPC_SPECIAL2,
363 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
364 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 365 /* Special */
7a387fff
TS
366 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
367};
368
369/* Special3 opcodes */
370#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
371
372enum {
373 OPC_EXT = 0x00 | OPC_SPECIAL3,
374 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
375 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
376 OPC_DEXT = 0x03 | OPC_SPECIAL3,
377 OPC_INS = 0x04 | OPC_SPECIAL3,
378 OPC_DINSM = 0x05 | OPC_SPECIAL3,
379 OPC_DINSU = 0x06 | OPC_SPECIAL3,
380 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
381 OPC_FORK = 0x08 | OPC_SPECIAL3,
382 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
383 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
384 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
385 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
386
387 /* Loongson 2E */
388 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
389 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
390 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
391 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
392 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
393 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
394 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
395 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
396 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
397 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
398 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
399 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
400
401 /* MIPS DSP Load */
402 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
403 /* MIPS DSP Arithmetic */
404 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 405 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 406 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 407 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
408 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
409 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
410 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 411 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
412 /* MIPS DSP GPR-Based Shift Sub-class */
413 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 414 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
415 /* MIPS DSP Multiply Sub-class insns */
416 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
417 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
418 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 419 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
420 /* DSP Bit/Manipulation Sub-class */
421 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 422 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 423 /* MIPS DSP Append Sub-class */
26690560 424 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 425 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
426 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
427 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 428 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 429
76964147
JH
430 /* EVA */
431 OPC_LWLE = 0x19 | OPC_SPECIAL3,
432 OPC_LWRE = 0x1A | OPC_SPECIAL3,
433 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
434 OPC_SBE = 0x1C | OPC_SPECIAL3,
435 OPC_SHE = 0x1D | OPC_SPECIAL3,
436 OPC_SCE = 0x1E | OPC_SPECIAL3,
437 OPC_SWE = 0x1F | OPC_SPECIAL3,
438 OPC_SWLE = 0x21 | OPC_SPECIAL3,
439 OPC_SWRE = 0x22 | OPC_SPECIAL3,
440 OPC_PREFE = 0x23 | OPC_SPECIAL3,
441 OPC_LBUE = 0x28 | OPC_SPECIAL3,
442 OPC_LHUE = 0x29 | OPC_SPECIAL3,
443 OPC_LBE = 0x2C | OPC_SPECIAL3,
444 OPC_LHE = 0x2D | OPC_SPECIAL3,
445 OPC_LLE = 0x2E | OPC_SPECIAL3,
446 OPC_LWE = 0x2F | OPC_SPECIAL3,
447
4368b29a 448 /* R6 */
bf7910c6
LA
449 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
450 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
451 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
452 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
453 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
454 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
455};
456
7a387fff
TS
457/* BSHFL opcodes */
458#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
459
e37e863f 460enum {
15eacb9b
YK
461 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
462 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
463 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
464 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
465 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
466 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
467};
468
7a387fff
TS
469/* DBSHFL opcodes */
470#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
471
e37e863f 472enum {
15eacb9b
YK
473 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
474 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
475 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
476 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
477 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
478};
479
e45a93e2
JL
480/* MIPS DSP REGIMM opcodes */
481enum {
482 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 483 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
484};
485
9b1a1d68
JL
486#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
487/* MIPS DSP Load */
488enum {
489 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
490 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
491 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 492 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
493};
494
461c08df
JL
495#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
496enum {
497 /* MIPS DSP Arithmetic Sub-class */
498 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
499 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
500 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
501 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
502 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
503 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
504 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
505 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
506 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
507 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
508 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
509 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
510 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
514 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
515 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
516 /* MIPS DSP Multiply Sub-class insns */
517 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
518 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
519 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
520 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
521 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
522 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
523};
524
525#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
526#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527enum {
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
530 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
531 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
532 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
533 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
534 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
535 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
538 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
539 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
541 /* MIPS DSP Multiply Sub-class insns */
542 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
543 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
544 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
546};
547
548#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
549enum {
550 /* MIPS DSP Arithmetic Sub-class */
551 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
552 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
553 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
554 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
555 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
556 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
564 /* DSP Bit/Manipulation Sub-class */
565 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
570};
571
572#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
573enum {
574 /* MIPS DSP Arithmetic Sub-class */
575 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
580 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
582 /* DSP Compare-Pick Sub-class */
583 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
584 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
585 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 598};
a22260ae 599
77c5fa8b
JL
600#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
601enum {
602 /* MIPS DSP GPR-Based Shift Sub-class */
603 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
607 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
608 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
625};
461c08df 626
a22260ae
JL
627#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
628enum {
629 /* MIPS DSP Multiply Sub-class insns */
630 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
633 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
634 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
635 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
644 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
647 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
652};
653
1cb6686c
JL
654#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
655enum {
656 /* DSP Bit/Manipulation Sub-class */
657 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
658};
659
26690560
JL
660#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
661enum {
df6126a7 662 /* MIPS DSP Append Sub-class */
26690560
JL
663 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
664 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
665 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
666};
667
b53371ed
JL
668#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
670 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
671 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
672 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
673 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
674 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
675 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
676 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
683 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
684 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
685 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
686 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
687 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
688};
689
461c08df
JL
690#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
691enum {
692 /* MIPS DSP Arithmetic Sub-class */
693 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
710 /* DSP Bit/Manipulation Sub-class */
711 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 717};
461c08df 718
461c08df
JL
719#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
720enum {
a22260ae
JL
721 /* MIPS DSP Multiply Sub-class insns */
722 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
723 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
724 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
725 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
726 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
727 /* MIPS DSP Arithmetic Sub-class */
728 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
729 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
730 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
731 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
732 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
733 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
739 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
740 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
741 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
742 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
743 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
749};
461c08df 750
461c08df
JL
751#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
752enum {
26690560
JL
753 /* DSP Compare-Pick Sub-class */
754 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
773 /* MIPS DSP Arithmetic Sub-class */
774 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
782};
461c08df 783
26690560
JL
784#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
785enum {
df6126a7 786 /* DSP Append Sub-class */
26690560
JL
787 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
788 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
789 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
790 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
791};
26690560 792
b53371ed
JL
793#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
794enum {
795 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
796 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
797 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
798 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
799 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
800 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
801 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
802 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
817};
818
1cb6686c
JL
819#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
820enum {
821 /* DSP Bit/Manipulation Sub-class */
822 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
823};
1cb6686c 824
a22260ae
JL
825#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
826enum {
827 /* MIPS DSP Multiply Sub-class insns */
828 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
854};
a22260ae 855
77c5fa8b
JL
856#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
857enum {
858 /* MIPS DSP GPR-Based Shift Sub-class */
859 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
885};
77c5fa8b 886
7a387fff
TS
887/* Coprocessor 0 (rs field) */
888#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
889
6ea83fed 890enum {
7a387fff
TS
891 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
892 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 893 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
894 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
895 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 896 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 897 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
898 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
899 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 900 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
901 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
902 OPC_C0 = (0x10 << 21) | OPC_CP0,
903 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
904 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 905};
7a387fff
TS
906
907/* MFMC0 opcodes */
b48cfdff 908#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
909
910enum {
ead9360e
TS
911 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
912 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
913 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
914 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
915 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
916 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
917 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
918 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
919};
920
921/* Coprocessor 0 (with rs == C0) */
922#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
923
924enum {
925 OPC_TLBR = 0x01 | OPC_C0,
926 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
927 OPC_TLBINV = 0x03 | OPC_C0,
928 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
929 OPC_TLBWR = 0x06 | OPC_C0,
930 OPC_TLBP = 0x08 | OPC_C0,
931 OPC_RFE = 0x10 | OPC_C0,
932 OPC_ERET = 0x18 | OPC_C0,
933 OPC_DERET = 0x1F | OPC_C0,
934 OPC_WAIT = 0x20 | OPC_C0,
935};
936
937/* Coprocessor 1 (rs field) */
938#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
939
bf4120ad
NF
940/* Values for the fmt field in FP instructions */
941enum {
942 /* 0 - 15 are reserved */
e459440a
AJ
943 FMT_S = 16, /* single fp */
944 FMT_D = 17, /* double fp */
945 FMT_E = 18, /* extended fp */
946 FMT_Q = 19, /* quad fp */
947 FMT_W = 20, /* 32-bit fixed */
948 FMT_L = 21, /* 64-bit fixed */
949 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
950 /* 23 - 31 are reserved */
951};
952
7a387fff
TS
953enum {
954 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
955 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
956 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 957 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
958 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
959 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
960 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 961 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 962 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
963 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
964 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
965 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
966 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
967 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
968 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
969 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
970 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
971 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
972 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
973 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
974 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
975 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
976 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
977 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
978 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
979 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
980 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
981 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
982 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
983 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
984};
985
5a5012ec
TS
986#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
987#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
988
7a387fff
TS
989enum {
990 OPC_BC1F = (0x00 << 16) | OPC_BC1,
991 OPC_BC1T = (0x01 << 16) | OPC_BC1,
992 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
993 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
994};
995
5a5012ec
TS
996enum {
997 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
998 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
999};
1000
1001enum {
1002 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1003 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1004};
7a387fff
TS
1005
1006#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1007
1008enum {
1009 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1010 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1011 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1012 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1013 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1014 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1015 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1016 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1017 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1018 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1019 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1020};
1021
bd277fa1
RH
1022#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1023
1024enum {
1025 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1026 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1027 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1028 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1029 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1030 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1031 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1032 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1033
1034 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1035 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1036 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1037 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1038 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1039 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1040 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1041 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1042
1043 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1044 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1045 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1046 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1047 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1048 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1049 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1050 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1051
1052 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1053 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1054 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1055 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1056 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1057 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1058 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1059 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1060
1061 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1062 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1063 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1064 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1065 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1066 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1067
1068 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1069 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1070 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1071 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1072 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1073 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1074
1075 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1076 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1077 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1078 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1079 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1080 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1081
1082 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1083 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1084 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1085 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1086 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1087 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1088
1089 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1090 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1091 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1092 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1093 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1094 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1095
1096 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1097 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1098 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1099 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1100 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1101 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1102
1103 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1104 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1105 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1106 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1107 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1108 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1109
1110 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1111 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1112 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1113 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1114 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1115 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1116};
1117
1118
e0c84da7
TS
1119#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1120
1121enum {
1122 OPC_LWXC1 = 0x00 | OPC_CP3,
1123 OPC_LDXC1 = 0x01 | OPC_CP3,
1124 OPC_LUXC1 = 0x05 | OPC_CP3,
1125 OPC_SWXC1 = 0x08 | OPC_CP3,
1126 OPC_SDXC1 = 0x09 | OPC_CP3,
1127 OPC_SUXC1 = 0x0D | OPC_CP3,
1128 OPC_PREFX = 0x0F | OPC_CP3,
1129 OPC_ALNV_PS = 0x1E | OPC_CP3,
1130 OPC_MADD_S = 0x20 | OPC_CP3,
1131 OPC_MADD_D = 0x21 | OPC_CP3,
1132 OPC_MADD_PS = 0x26 | OPC_CP3,
1133 OPC_MSUB_S = 0x28 | OPC_CP3,
1134 OPC_MSUB_D = 0x29 | OPC_CP3,
1135 OPC_MSUB_PS = 0x2E | OPC_CP3,
1136 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1137 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1138 OPC_NMADD_PS= 0x36 | OPC_CP3,
1139 OPC_NMSUB_S = 0x38 | OPC_CP3,
1140 OPC_NMSUB_D = 0x39 | OPC_CP3,
1141 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1142};
1143
239dfebe
YK
1144/* MSA Opcodes */
1145#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1146enum {
1147 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1148 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1149 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1150 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1151 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1152 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1153 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1154 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1155 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1156 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1157 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1158 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1159 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1160 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1161 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1162 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1163 OPC_MSA_ELM = 0x19 | OPC_MSA,
1164 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1165 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1166 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1167 OPC_MSA_VEC = 0x1E | OPC_MSA,
1168
1169 /* MI10 instruction */
1170 OPC_LD_B = (0x20) | OPC_MSA,
1171 OPC_LD_H = (0x21) | OPC_MSA,
1172 OPC_LD_W = (0x22) | OPC_MSA,
1173 OPC_LD_D = (0x23) | OPC_MSA,
1174 OPC_ST_B = (0x24) | OPC_MSA,
1175 OPC_ST_H = (0x25) | OPC_MSA,
1176 OPC_ST_W = (0x26) | OPC_MSA,
1177 OPC_ST_D = (0x27) | OPC_MSA,
1178};
1179
1180enum {
1181 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1182 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1183 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1184 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1185 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1186 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1187 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1188 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1189 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1190 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1191 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1192 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1193 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1194
1195 /* I8 instruction */
1196 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1197 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1198 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1199 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1200 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1201 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1202 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1203 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1204 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1205 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1206
1207 /* VEC/2R/2RF instruction */
1208 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1209 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1210 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1211 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1212 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1213 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1214 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1215
1216 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1217 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1218
1219 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1220 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1221 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1222 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1223 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1224
1225 /* 2RF instruction df(bit 16) = _w, _d */
1226 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1227 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1228 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1229 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1230 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1231 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1232 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1233 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1234 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1235 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1236 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1237 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1238 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1239 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1240 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1241 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1242
1243 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1244 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1245 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1246 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1247 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1248 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1249 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1250 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1251 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1252 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1253 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1254 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1255 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1256 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1257 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1258 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1259 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1260 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1261 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1262 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1263 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1264 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1265 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1266 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1267 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1268 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1269 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1270 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1271 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1272 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1273 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1274 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1275 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1276 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1277 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1278 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1279 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1280 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1281 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1282 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1283 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1284 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1285 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1286 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1287 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1288 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1289 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1290 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1291 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1292 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1293 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1294 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1295 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1296 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1297 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1298 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1299 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1300 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1301 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1303 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1304 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1305 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1306 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1307
1308 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1309 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1310 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1311 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1312 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1313 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1314 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1315 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1316 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1317 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1318
1319 /* 3RF instruction _df(bit 21) = _w, _d */
1320 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1321 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1322 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1323 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1324 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1325 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1326 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1327 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1328 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1329 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1330 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1331 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1333 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1334 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1336 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1337 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1338 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1339 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1340 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1341 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1342 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1343 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1345 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1346 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1347 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1348 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1349 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1350 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1351 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1352 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1353 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1354 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1355 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1356 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1357 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1358 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1359 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1360 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1361
1362 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1363 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1364 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1365 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1366 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1367 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1368 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1369 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1370 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1371 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1372 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1373 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1374 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1375};
1376
39454628 1377/* global register indices */
1bcea73e 1378static TCGv_env cpu_env;
a7812ae4 1379static TCGv cpu_gpr[32], cpu_PC;
340fff72 1380static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1381static TCGv cpu_dspctrl, btarget, bcond;
1382static TCGv_i32 hflags;
a7812ae4 1383static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1384static TCGv_i64 fpu_f64[32];
863f264d 1385static TCGv_i64 msa_wr_d[64];
aa0bf00b 1386
022c62cb 1387#include "exec/gen-icount.h"
2e70f6ef 1388
895c2d04 1389#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1390 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1391 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1392 tcg_temp_free_i32(helper_tmp); \
1393 } while(0)
be24bb4f 1394
895c2d04 1395#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1396 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1397 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1398 tcg_temp_free_i32(helper_tmp); \
1399 } while(0)
be24bb4f 1400
895c2d04
BS
1401#define gen_helper_1e0i(name, ret, arg1) do { \
1402 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1403 gen_helper_##name(ret, cpu_env, helper_tmp); \
1404 tcg_temp_free_i32(helper_tmp); \
1405 } while(0)
1406
1407#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1408 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1409 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1410 tcg_temp_free_i32(helper_tmp); \
1411 } while(0)
1412
1413#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1414 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1415 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1416 tcg_temp_free_i32(helper_tmp); \
1417 } while(0)
1418
1419#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1420 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1421 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1422 tcg_temp_free_i32(helper_tmp); \
1423 } while(0)
be24bb4f 1424
895c2d04 1425#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1426 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1427 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1428 tcg_temp_free_i32(helper_tmp); \
1429 } while(0)
c239529e 1430
8e9ade68
TS
1431typedef struct DisasContext {
1432 struct TranslationBlock *tb;
1433 target_ulong pc, saved_pc;
1434 uint32_t opcode;
7b270ef2 1435 int singlestep_enabled;
d75c135e 1436 int insn_flags;
5ab5c041 1437 int32_t CP0_Config1;
8e9ade68
TS
1438 /* Routine used to access memory */
1439 int mem_idx;
be3a8c53 1440 TCGMemOp default_tcg_memop_mask;
8e9ade68
TS
1441 uint32_t hflags, saved_hflags;
1442 int bstate;
1443 target_ulong btarget;
d279279e 1444 bool ulri;
e98c0d17 1445 int kscrexist;
7207c7f9 1446 bool rxi;
9456c2fb 1447 int ie;
aea14095
LA
1448 bool bi;
1449 bool bp;
5204ea79
LA
1450 uint64_t PAMask;
1451 bool mvh;
76964147 1452 bool eva;
cec56a73 1453 bool sc;
5204ea79 1454 int CP0_LLAddr_shift;
e29c9628 1455 bool ps;
01bc435b 1456 bool vp;
c870e3f5 1457 bool cmgcr;
f6d4dd81 1458 bool mrp;
87552089 1459 bool nan2008;
6be77480 1460 bool abs2008;
8e9ade68
TS
1461} DisasContext;
1462
1463enum {
1464 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1465 * exception condition */
8e9ade68
TS
1466 BS_STOP = 1, /* We want to stop translation for any reason */
1467 BS_BRANCH = 2, /* We reached a branch condition */
1468 BS_EXCP = 3, /* We reached an exception condition */
1469};
1470
d73ee8a2
RH
1471static const char * const regnames[] = {
1472 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1473 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1474 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1475 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1476};
6af0bf9c 1477
d73ee8a2
RH
1478static const char * const regnames_HI[] = {
1479 "HI0", "HI1", "HI2", "HI3",
1480};
4b2eb8d2 1481
d73ee8a2
RH
1482static const char * const regnames_LO[] = {
1483 "LO0", "LO1", "LO2", "LO3",
1484};
4b2eb8d2 1485
d73ee8a2
RH
1486static const char * const fregnames[] = {
1487 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1488 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1489 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1490 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1491};
958fb4a9 1492
863f264d
YK
1493static const char * const msaregnames[] = {
1494 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1495 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1496 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1497 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1498 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1499 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1500 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1501 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1502 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1503 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1504 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1505 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1506 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1507 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1508 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1509 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1510};
1511
9d68ac14 1512#define LOG_DISAS(...) \
fb7729e2
RH
1513 do { \
1514 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1515 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1516 } \
1517 } while (0)
1518
9d68ac14 1519#define MIPS_INVAL(op) \
fb7729e2
RH
1520 do { \
1521 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1522 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1523 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1524 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1525 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1526 } \
1527 } while (0)
958fb4a9 1528
8e9ade68
TS
1529/* General purpose registers moves. */
1530static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1531{
8e9ade68
TS
1532 if (reg == 0)
1533 tcg_gen_movi_tl(t, 0);
1534 else
4b2eb8d2 1535 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1536}
1537
8e9ade68 1538static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1539{
8e9ade68 1540 if (reg != 0)
4b2eb8d2 1541 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1542}
1543
8e9ade68 1544/* Moves to/from shadow registers. */
be24bb4f 1545static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1546{
d9bea114 1547 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1548
1549 if (from == 0)
d9bea114 1550 tcg_gen_movi_tl(t0, 0);
8e9ade68 1551 else {
d9bea114 1552 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1553 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1554
7db13fae 1555 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1556 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1557 tcg_gen_andi_i32(t2, t2, 0xf);
1558 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1559 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1560 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1561
d9bea114 1562 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1563 tcg_temp_free_ptr(addr);
d9bea114 1564 tcg_temp_free_i32(t2);
8e9ade68 1565 }
d9bea114
AJ
1566 gen_store_gpr(t0, to);
1567 tcg_temp_free(t0);
aaa9128a
TS
1568}
1569
be24bb4f 1570static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1571{
be24bb4f 1572 if (to != 0) {
d9bea114
AJ
1573 TCGv t0 = tcg_temp_new();
1574 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1575 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1576
d9bea114 1577 gen_load_gpr(t0, from);
7db13fae 1578 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1579 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1580 tcg_gen_andi_i32(t2, t2, 0xf);
1581 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1582 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1583 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1584
d9bea114 1585 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1586 tcg_temp_free_ptr(addr);
d9bea114
AJ
1587 tcg_temp_free_i32(t2);
1588 tcg_temp_free(t0);
8e9ade68 1589 }
aaa9128a
TS
1590}
1591
eab9944c
LA
1592/* Tests */
1593static inline void gen_save_pc(target_ulong pc)
1594{
1595 tcg_gen_movi_tl(cpu_PC, pc);
1596}
1597
1598static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1599{
1600 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1601 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1602 gen_save_pc(ctx->pc);
1603 ctx->saved_pc = ctx->pc;
1604 }
1605 if (ctx->hflags != ctx->saved_hflags) {
1606 tcg_gen_movi_i32(hflags, ctx->hflags);
1607 ctx->saved_hflags = ctx->hflags;
1608 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1609 case MIPS_HFLAG_BR:
1610 break;
1611 case MIPS_HFLAG_BC:
1612 case MIPS_HFLAG_BL:
1613 case MIPS_HFLAG_B:
1614 tcg_gen_movi_tl(btarget, ctx->btarget);
1615 break;
1616 }
1617 }
1618}
1619
1620static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1621{
1622 ctx->saved_hflags = ctx->hflags;
1623 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1624 case MIPS_HFLAG_BR:
1625 break;
1626 case MIPS_HFLAG_BC:
1627 case MIPS_HFLAG_BL:
1628 case MIPS_HFLAG_B:
1629 ctx->btarget = env->btarget;
1630 break;
1631 }
1632}
1633
1634static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1635{
1636 TCGv_i32 texcp = tcg_const_i32(excp);
1637 TCGv_i32 terr = tcg_const_i32(err);
1638 save_cpu_state(ctx, 1);
1639 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1640 tcg_temp_free_i32(terr);
1641 tcg_temp_free_i32(texcp);
9c708c7f 1642 ctx->bstate = BS_EXCP;
eab9944c
LA
1643}
1644
1645static inline void generate_exception(DisasContext *ctx, int excp)
1646{
eab9944c
LA
1647 gen_helper_0e0i(raise_exception, excp);
1648}
1649
9c708c7f
PD
1650static inline void generate_exception_end(DisasContext *ctx, int excp)
1651{
1652 generate_exception_err(ctx, excp, 0);
1653}
1654
aaa9128a 1655/* Floating point register moves. */
7c979afd 1656static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1657{
7c979afd
LA
1658 if (ctx->hflags & MIPS_HFLAG_FRE) {
1659 generate_exception(ctx, EXCP_RI);
1660 }
ecc7b3aa 1661 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1662}
1663
7c979afd 1664static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1665{
7c979afd
LA
1666 TCGv_i64 t64;
1667 if (ctx->hflags & MIPS_HFLAG_FRE) {
1668 generate_exception(ctx, EXCP_RI);
1669 }
1670 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1671 tcg_gen_extu_i32_i64(t64, t);
1672 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1673 tcg_temp_free_i64(t64);
6d066274
AJ
1674}
1675
7f6613ce 1676static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1677{
7f6613ce 1678 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1679 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1680 } else {
7c979afd 1681 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1682 }
6d066274
AJ
1683}
1684
7f6613ce 1685static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1686{
7f6613ce
PJ
1687 if (ctx->hflags & MIPS_HFLAG_F64) {
1688 TCGv_i64 t64 = tcg_temp_new_i64();
1689 tcg_gen_extu_i32_i64(t64, t);
1690 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1691 tcg_temp_free_i64(t64);
1692 } else {
7c979afd 1693 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1694 }
aa0bf00b 1695}
6ea83fed 1696
d73ee8a2 1697static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1698{
f364515c 1699 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1700 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1701 } else {
d73ee8a2 1702 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1703 }
1704}
6ea83fed 1705
d73ee8a2 1706static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1707{
f364515c 1708 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1709 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1710 } else {
d73ee8a2
RH
1711 TCGv_i64 t0;
1712 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1713 t0 = tcg_temp_new_i64();
6d066274 1714 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1715 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1716 tcg_temp_free_i64(t0);
aa0bf00b
TS
1717 }
1718}
6ea83fed 1719
d94536f4 1720static inline int get_fp_bit (int cc)
a16336e4 1721{
d94536f4
AJ
1722 if (cc)
1723 return 24 + cc;
1724 else
1725 return 23;
a16336e4
TS
1726}
1727
48d38ca5 1728/* Addresses computation */
941694d0 1729static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1730{
941694d0 1731 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1732
1733#if defined(TARGET_MIPS64)
01f72885 1734 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1735 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1736 }
1737#endif
4ad40f36
FB
1738}
1739
31837be3
YK
1740/* Addresses computation (translation time) */
1741static target_long addr_add(DisasContext *ctx, target_long base,
1742 target_long offset)
1743{
1744 target_long sum = base + offset;
1745
1746#if defined(TARGET_MIPS64)
1747 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1748 sum = (int32_t)sum;
1749 }
1750#endif
1751 return sum;
1752}
1753
71f303cd 1754/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1755static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1756{
1757#if defined(TARGET_MIPS64)
71f303cd
RH
1758 tcg_gen_ext32s_i64(ret, arg);
1759#else
1760 tcg_gen_extrl_i64_i32(ret, arg);
1761#endif
1762}
1763
1764/* Sign-extract the high 32-bits to a target_long. */
1765static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1766{
1767#if defined(TARGET_MIPS64)
1768 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1769#else
71f303cd 1770 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1771#endif
1772}
1773
356265ae 1774static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1775{
fe253235 1776 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1777 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1778}
1779
356265ae 1780static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1781{
fe253235 1782 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1783 generate_exception_err(ctx, EXCP_CpU, 1);
1784}
1785
b8aa4598
TS
1786/* Verify that the processor is running with COP1X instructions enabled.
1787 This is associated with the nabla symbol in the MIPS32 and MIPS64
1788 opcode tables. */
1789
356265ae 1790static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1791{
1792 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1793 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1794}
1795
1796/* Verify that the processor is running with 64-bit floating-point
1797 operations enabled. */
1798
356265ae 1799static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1800{
b8aa4598 1801 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1802 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1803}
1804
1805/*
1806 * Verify if floating point register is valid; an operation is not defined
1807 * if bit 0 of any register specification is set and the FR bit in the
1808 * Status register equals zero, since the register numbers specify an
1809 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1810 * in the Status register equals one, both even and odd register numbers
1811 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1812 *
1813 * Multiple 64 bit wide registers can be checked by calling
1814 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1815 */
356265ae 1816static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1817{
fe253235 1818 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1819 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1820}
1821
853c3240
JL
1822/* Verify that the processor is running with DSP instructions enabled.
1823 This is enabled by CP0 Status register MX(24) bit.
1824 */
1825
1826static inline void check_dsp(DisasContext *ctx)
1827{
1828 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1829 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1830 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1831 } else {
9c708c7f 1832 generate_exception_end(ctx, EXCP_RI);
ad153f15 1833 }
853c3240
JL
1834 }
1835}
1836
1837static inline void check_dspr2(DisasContext *ctx)
1838{
1839 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1840 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1841 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1842 } else {
9c708c7f 1843 generate_exception_end(ctx, EXCP_RI);
ad153f15 1844 }
853c3240
JL
1845 }
1846}
1847
3a95e3a7 1848/* This code generates a "reserved instruction" exception if the
e189e748 1849 CPU does not support the instruction set corresponding to flags. */
d75c135e 1850static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1851{
d75c135e 1852 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1853 generate_exception_end(ctx, EXCP_RI);
d75c135e 1854 }
3a95e3a7
TS
1855}
1856
fecd2646
LA
1857/* This code generates a "reserved instruction" exception if the
1858 CPU has corresponding flag set which indicates that the instruction
1859 has been removed. */
1860static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1861{
1862 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1863 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1864 }
1865}
1866
e29c9628
YK
1867/* This code generates a "reserved instruction" exception if the
1868 CPU does not support 64-bit paired-single (PS) floating point data type */
1869static inline void check_ps(DisasContext *ctx)
1870{
1871 if (unlikely(!ctx->ps)) {
1872 generate_exception(ctx, EXCP_RI);
1873 }
1874 check_cp1_64bitmode(ctx);
1875}
1876
c7986fd6 1877#ifdef TARGET_MIPS64
e189e748
TS
1878/* This code generates a "reserved instruction" exception if 64-bit
1879 instructions are not enabled. */
356265ae 1880static inline void check_mips_64(DisasContext *ctx)
e189e748 1881{
fe253235 1882 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1883 generate_exception_end(ctx, EXCP_RI);
e189e748 1884}
c7986fd6 1885#endif
e189e748 1886
5204ea79
LA
1887#ifndef CONFIG_USER_ONLY
1888static inline void check_mvh(DisasContext *ctx)
1889{
1890 if (unlikely(!ctx->mvh)) {
1891 generate_exception(ctx, EXCP_RI);
1892 }
1893}
1894#endif
1895
8153667c
NF
1896/* Define small wrappers for gen_load_fpr* so that we have a uniform
1897 calling interface for 32 and 64-bit FPRs. No sense in changing
1898 all callers for gen_load_fpr32 when we need the CTX parameter for
1899 this one use. */
7c979afd 1900#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1901#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1902#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1903static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1904 int ft, int fs, int cc) \
1905{ \
1906 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1907 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1908 switch (ifmt) { \
1909 case FMT_PS: \
e29c9628 1910 check_ps(ctx); \
8153667c
NF
1911 break; \
1912 case FMT_D: \
1913 if (abs) { \
1914 check_cop1x(ctx); \
1915 } \
1916 check_cp1_registers(ctx, fs | ft); \
1917 break; \
1918 case FMT_S: \
1919 if (abs) { \
1920 check_cop1x(ctx); \
1921 } \
1922 break; \
1923 } \
1924 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1925 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1926 switch (n) { \
895c2d04
BS
1927 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1928 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1929 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1930 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1931 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1932 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1933 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1934 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1935 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1936 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1937 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1938 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1939 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1940 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1941 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1942 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1943 default: abort(); \
1944 } \
1945 tcg_temp_free_i##bits (fp0); \
1946 tcg_temp_free_i##bits (fp1); \
1947}
1948
1949FOP_CONDS(, 0, d, FMT_D, 64)
1950FOP_CONDS(abs, 1, d, FMT_D, 64)
1951FOP_CONDS(, 0, s, FMT_S, 32)
1952FOP_CONDS(abs, 1, s, FMT_S, 32)
1953FOP_CONDS(, 0, ps, FMT_PS, 64)
1954FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1955#undef FOP_CONDS
3f493883
YK
1956
1957#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1958static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1959 int ft, int fs, int fd) \
1960{ \
1961 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1962 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1963 if (ifmt == FMT_D) { \
3f493883 1964 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1965 } \
1966 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1967 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1968 switch (n) { \
1969 case 0: \
1970 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1971 break; \
1972 case 1: \
1973 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1974 break; \
1975 case 2: \
1976 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1977 break; \
1978 case 3: \
1979 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 4: \
1982 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 5: \
1985 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 6: \
1988 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 7: \
1991 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 8: \
1994 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 9: \
1997 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 10: \
2000 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 11: \
2003 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 12: \
2006 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 13: \
2009 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 case 14: \
2012 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2013 break; \
2014 case 15: \
2015 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2016 break; \
2017 case 17: \
2018 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2019 break; \
2020 case 18: \
2021 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2022 break; \
2023 case 19: \
2024 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2025 break; \
2026 case 25: \
2027 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2028 break; \
2029 case 26: \
2030 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2031 break; \
2032 case 27: \
2033 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2034 break; \
2035 default: \
2036 abort(); \
2037 } \
2038 STORE; \
2039 tcg_temp_free_i ## bits (fp0); \
2040 tcg_temp_free_i ## bits (fp1); \
2041}
2042
2043FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2044FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2045#undef FOP_CONDNS
8153667c
NF
2046#undef gen_ldcmp_fpr32
2047#undef gen_ldcmp_fpr64
2048
958fb4a9 2049/* load/store instructions. */
e7139c44 2050#ifdef CONFIG_USER_ONLY
d9bea114 2051#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2052static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2053 DisasContext *ctx) \
d9bea114
AJ
2054{ \
2055 TCGv t0 = tcg_temp_new(); \
2056 tcg_gen_mov_tl(t0, arg1); \
2057 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2058 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2059 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2060 tcg_temp_free(t0); \
aaa9128a 2061}
e7139c44
AJ
2062#else
2063#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2064static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2065 DisasContext *ctx) \
e7139c44 2066{ \
dd4096cd 2067 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2068}
2069#endif
aaa9128a
TS
2070OP_LD_ATOMIC(ll,ld32s);
2071#if defined(TARGET_MIPS64)
2072OP_LD_ATOMIC(lld,ld64);
2073#endif
2074#undef OP_LD_ATOMIC
2075
590bc601
PB
2076#ifdef CONFIG_USER_ONLY
2077#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2078static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2079 DisasContext *ctx) \
590bc601
PB
2080{ \
2081 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2082 TCGLabel *l1 = gen_new_label(); \
2083 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2084 \
2085 tcg_gen_andi_tl(t0, arg2, almask); \
2086 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2087 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2088 generate_exception(ctx, EXCP_AdES); \
2089 gen_set_label(l1); \
7db13fae 2090 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2091 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2092 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2093 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2094 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2095 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2096 gen_set_label(l2); \
2097 tcg_gen_movi_tl(t0, 0); \
2098 gen_store_gpr(t0, rt); \
2099 tcg_temp_free(t0); \
2100}
2101#else
2102#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2103static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2104 DisasContext *ctx) \
590bc601
PB
2105{ \
2106 TCGv t0 = tcg_temp_new(); \
dd4096cd 2107 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 2108 gen_store_gpr(t0, rt); \
590bc601
PB
2109 tcg_temp_free(t0); \
2110}
2111#endif
590bc601 2112OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2113#if defined(TARGET_MIPS64)
590bc601 2114OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2115#endif
2116#undef OP_ST_ATOMIC
2117
662d7485
NF
2118static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2119 int base, int16_t offset)
2120{
2121 if (base == 0) {
2122 tcg_gen_movi_tl(addr, offset);
2123 } else if (offset == 0) {
2124 gen_load_gpr(addr, base);
2125 } else {
2126 tcg_gen_movi_tl(addr, offset);
2127 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2128 }
2129}
2130
364d4831
NF
2131static target_ulong pc_relative_pc (DisasContext *ctx)
2132{
2133 target_ulong pc = ctx->pc;
2134
2135 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2136 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2137
2138 pc -= branch_bytes;
2139 }
2140
2141 pc &= ~(target_ulong)3;
2142 return pc;
2143}
2144
5c13fdfd 2145/* Load */
d75c135e
AJ
2146static void gen_ld(DisasContext *ctx, uint32_t opc,
2147 int rt, int base, int16_t offset)
6af0bf9c 2148{
fc40787a 2149 TCGv t0, t1, t2;
dd4096cd 2150 int mem_idx = ctx->mem_idx;
afa88c3a 2151
d75c135e 2152 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2153 /* Loongson CPU uses a load to zero register for prefetch.
2154 We emulate it as a NOP. On other CPU we must perform the
2155 actual memory access. */
afa88c3a
AJ
2156 return;
2157 }
6af0bf9c 2158
afa88c3a 2159 t0 = tcg_temp_new();
662d7485 2160 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2161
6af0bf9c 2162 switch (opc) {
d26bc211 2163#if defined(TARGET_MIPS64)
6e473128 2164 case OPC_LWU:
dd4096cd 2165 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2166 ctx->default_tcg_memop_mask);
78723684 2167 gen_store_gpr(t0, rt);
6e473128 2168 break;
6af0bf9c 2169 case OPC_LD:
dd4096cd 2170 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2171 ctx->default_tcg_memop_mask);
78723684 2172 gen_store_gpr(t0, rt);
6af0bf9c 2173 break;
7a387fff 2174 case OPC_LLD:
bf7910c6 2175 case R6_OPC_LLD:
dd4096cd 2176 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2177 gen_store_gpr(t0, rt);
7a387fff 2178 break;
6af0bf9c 2179 case OPC_LDL:
3cee3050 2180 t1 = tcg_temp_new();
908680c6
AJ
2181 /* Do a byte access to possibly trigger a page
2182 fault with the unaligned address. */
dd4096cd 2183 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2184 tcg_gen_andi_tl(t1, t0, 7);
2185#ifndef TARGET_WORDS_BIGENDIAN
2186 tcg_gen_xori_tl(t1, t1, 7);
2187#endif
2188 tcg_gen_shli_tl(t1, t1, 3);
2189 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2190 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2191 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2192 t2 = tcg_const_tl(-1);
2193 tcg_gen_shl_tl(t2, t2, t1);
78723684 2194 gen_load_gpr(t1, rt);
eb02cc3f 2195 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2196 tcg_temp_free(t2);
2197 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2198 tcg_temp_free(t1);
fc40787a 2199 gen_store_gpr(t0, rt);
6af0bf9c 2200 break;
6af0bf9c 2201 case OPC_LDR:
3cee3050 2202 t1 = tcg_temp_new();
908680c6
AJ
2203 /* Do a byte access to possibly trigger a page
2204 fault with the unaligned address. */
dd4096cd 2205 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2206 tcg_gen_andi_tl(t1, t0, 7);
2207#ifdef TARGET_WORDS_BIGENDIAN
2208 tcg_gen_xori_tl(t1, t1, 7);
2209#endif
2210 tcg_gen_shli_tl(t1, t1, 3);
2211 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2212 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2213 tcg_gen_shr_tl(t0, t0, t1);
2214 tcg_gen_xori_tl(t1, t1, 63);
2215 t2 = tcg_const_tl(0xfffffffffffffffeull);
2216 tcg_gen_shl_tl(t2, t2, t1);
78723684 2217 gen_load_gpr(t1, rt);
fc40787a
AJ
2218 tcg_gen_and_tl(t1, t1, t2);
2219 tcg_temp_free(t2);
2220 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2221 tcg_temp_free(t1);
fc40787a 2222 gen_store_gpr(t0, rt);
6af0bf9c 2223 break;
364d4831 2224 case OPC_LDPC:
3cee3050 2225 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2226 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2227 tcg_temp_free(t1);
dd4096cd 2228 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2229 gen_store_gpr(t0, rt);
2230 break;
6af0bf9c 2231#endif
364d4831 2232 case OPC_LWPC:
3cee3050 2233 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2234 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2235 tcg_temp_free(t1);
dd4096cd 2236 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2237 gen_store_gpr(t0, rt);
2238 break;
76964147
JH
2239 case OPC_LWE:
2240 mem_idx = MIPS_HFLAG_UM;
2241 /* fall through */
6af0bf9c 2242 case OPC_LW:
dd4096cd 2243 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2244 ctx->default_tcg_memop_mask);
78723684 2245 gen_store_gpr(t0, rt);
6af0bf9c 2246 break;
76964147
JH
2247 case OPC_LHE:
2248 mem_idx = MIPS_HFLAG_UM;
2249 /* fall through */
6af0bf9c 2250 case OPC_LH:
dd4096cd 2251 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2252 ctx->default_tcg_memop_mask);
78723684 2253 gen_store_gpr(t0, rt);
6af0bf9c 2254 break;
76964147
JH
2255 case OPC_LHUE:
2256 mem_idx = MIPS_HFLAG_UM;
2257 /* fall through */
6af0bf9c 2258 case OPC_LHU:
dd4096cd 2259 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2260 ctx->default_tcg_memop_mask);
78723684 2261 gen_store_gpr(t0, rt);
6af0bf9c 2262 break;
76964147
JH
2263 case OPC_LBE:
2264 mem_idx = MIPS_HFLAG_UM;
2265 /* fall through */
6af0bf9c 2266 case OPC_LB:
dd4096cd 2267 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2268 gen_store_gpr(t0, rt);
6af0bf9c 2269 break;
76964147
JH
2270 case OPC_LBUE:
2271 mem_idx = MIPS_HFLAG_UM;
2272 /* fall through */
6af0bf9c 2273 case OPC_LBU:
dd4096cd 2274 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2275 gen_store_gpr(t0, rt);
6af0bf9c 2276 break;
76964147
JH
2277 case OPC_LWLE:
2278 mem_idx = MIPS_HFLAG_UM;
2279 /* fall through */
6af0bf9c 2280 case OPC_LWL:
3cee3050 2281 t1 = tcg_temp_new();
908680c6
AJ
2282 /* Do a byte access to possibly trigger a page
2283 fault with the unaligned address. */
dd4096cd 2284 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2285 tcg_gen_andi_tl(t1, t0, 3);
2286#ifndef TARGET_WORDS_BIGENDIAN
2287 tcg_gen_xori_tl(t1, t1, 3);
2288#endif
2289 tcg_gen_shli_tl(t1, t1, 3);
2290 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2291 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2292 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2293 t2 = tcg_const_tl(-1);
2294 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2295 gen_load_gpr(t1, rt);
eb02cc3f 2296 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2297 tcg_temp_free(t2);
2298 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2299 tcg_temp_free(t1);
fc40787a
AJ
2300 tcg_gen_ext32s_tl(t0, t0);
2301 gen_store_gpr(t0, rt);
6af0bf9c 2302 break;
76964147
JH
2303 case OPC_LWRE:
2304 mem_idx = MIPS_HFLAG_UM;
2305 /* fall through */
6af0bf9c 2306 case OPC_LWR:
3cee3050 2307 t1 = tcg_temp_new();
908680c6
AJ
2308 /* Do a byte access to possibly trigger a page
2309 fault with the unaligned address. */
dd4096cd 2310 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2311 tcg_gen_andi_tl(t1, t0, 3);
2312#ifdef TARGET_WORDS_BIGENDIAN
2313 tcg_gen_xori_tl(t1, t1, 3);
2314#endif
2315 tcg_gen_shli_tl(t1, t1, 3);
2316 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2317 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2318 tcg_gen_shr_tl(t0, t0, t1);
2319 tcg_gen_xori_tl(t1, t1, 31);
2320 t2 = tcg_const_tl(0xfffffffeull);
2321 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2322 gen_load_gpr(t1, rt);
fc40787a
AJ
2323 tcg_gen_and_tl(t1, t1, t2);
2324 tcg_temp_free(t2);
2325 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2326 tcg_temp_free(t1);
c728154b 2327 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2328 gen_store_gpr(t0, rt);
6af0bf9c 2329 break;
76964147
JH
2330 case OPC_LLE:
2331 mem_idx = MIPS_HFLAG_UM;
2332 /* fall through */
6af0bf9c 2333 case OPC_LL:
4368b29a 2334 case R6_OPC_LL:
dd4096cd 2335 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2336 gen_store_gpr(t0, rt);
6af0bf9c 2337 break;
d66c7132 2338 }
d66c7132 2339 tcg_temp_free(t0);
d66c7132
AJ
2340}
2341
5c13fdfd
AJ
2342/* Store */
2343static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2344 int base, int16_t offset)
2345{
5c13fdfd
AJ
2346 TCGv t0 = tcg_temp_new();
2347 TCGv t1 = tcg_temp_new();
dd4096cd 2348 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2349
2350 gen_base_offset_addr(ctx, t0, base, offset);
2351 gen_load_gpr(t1, rt);
2352 switch (opc) {
2353#if defined(TARGET_MIPS64)
2354 case OPC_SD:
dd4096cd 2355 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2356 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2357 break;
2358 case OPC_SDL:
dd4096cd 2359 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2360 break;
2361 case OPC_SDR:
dd4096cd 2362 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2363 break;
2364#endif
76964147
JH
2365 case OPC_SWE:
2366 mem_idx = MIPS_HFLAG_UM;
2367 /* fall through */
5c13fdfd 2368 case OPC_SW:
dd4096cd 2369 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2370 ctx->default_tcg_memop_mask);
5c13fdfd 2371 break;
76964147
JH
2372 case OPC_SHE:
2373 mem_idx = MIPS_HFLAG_UM;
2374 /* fall through */
5c13fdfd 2375 case OPC_SH:
dd4096cd 2376 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2377 ctx->default_tcg_memop_mask);
5c13fdfd 2378 break;
76964147
JH
2379 case OPC_SBE:
2380 mem_idx = MIPS_HFLAG_UM;
2381 /* fall through */
5c13fdfd 2382 case OPC_SB:
dd4096cd 2383 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2384 break;
76964147
JH
2385 case OPC_SWLE:
2386 mem_idx = MIPS_HFLAG_UM;
2387 /* fall through */
5c13fdfd 2388 case OPC_SWL:
dd4096cd 2389 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2390 break;
76964147
JH
2391 case OPC_SWRE:
2392 mem_idx = MIPS_HFLAG_UM;
2393 /* fall through */
5c13fdfd 2394 case OPC_SWR:
dd4096cd 2395 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2396 break;
2397 }
5c13fdfd
AJ
2398 tcg_temp_free(t0);
2399 tcg_temp_free(t1);
2400}
2401
2402
d66c7132
AJ
2403/* Store conditional */
2404static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2405 int base, int16_t offset)
2406{
d66c7132 2407 TCGv t0, t1;
dd4096cd 2408 int mem_idx = ctx->mem_idx;
d66c7132 2409
2d2826b9 2410#ifdef CONFIG_USER_ONLY
d66c7132 2411 t0 = tcg_temp_local_new();
d66c7132 2412 t1 = tcg_temp_local_new();
2d2826b9
AJ
2413#else
2414 t0 = tcg_temp_new();
2415 t1 = tcg_temp_new();
2416#endif
2417 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2418 gen_load_gpr(t1, rt);
2419 switch (opc) {
2420#if defined(TARGET_MIPS64)
2421 case OPC_SCD:
bf7910c6 2422 case R6_OPC_SCD:
dd4096cd 2423 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
2424 break;
2425#endif
76964147
JH
2426 case OPC_SCE:
2427 mem_idx = MIPS_HFLAG_UM;
2428 /* fall through */
6af0bf9c 2429 case OPC_SC:
4368b29a 2430 case R6_OPC_SC:
dd4096cd 2431 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 2432 break;
6af0bf9c 2433 }
78723684 2434 tcg_temp_free(t1);
d66c7132 2435 tcg_temp_free(t0);
6af0bf9c
FB
2436}
2437
6ea83fed 2438/* Load and store */
7a387fff 2439static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2440 int base, int16_t offset)
6ea83fed 2441{
4e2474d6 2442 TCGv t0 = tcg_temp_new();
6ea83fed 2443
662d7485 2444 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2445 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2446 memory access. */
6ea83fed
FB
2447 switch (opc) {
2448 case OPC_LWC1:
b6d96bed 2449 {
a7812ae4 2450 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2451 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2452 ctx->default_tcg_memop_mask);
7c979afd 2453 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2454 tcg_temp_free_i32(fp0);
b6d96bed 2455 }
6ea83fed
FB
2456 break;
2457 case OPC_SWC1:
b6d96bed 2458 {
a7812ae4 2459 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2460 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2461 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2462 ctx->default_tcg_memop_mask);
a7812ae4 2463 tcg_temp_free_i32(fp0);
b6d96bed 2464 }
6ea83fed
FB
2465 break;
2466 case OPC_LDC1:
b6d96bed 2467 {
a7812ae4 2468 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2469 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2470 ctx->default_tcg_memop_mask);
b6d96bed 2471 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2472 tcg_temp_free_i64(fp0);
b6d96bed 2473 }
6ea83fed
FB
2474 break;
2475 case OPC_SDC1:
b6d96bed 2476 {
a7812ae4 2477 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2478 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2479 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2480 ctx->default_tcg_memop_mask);
a7812ae4 2481 tcg_temp_free_i64(fp0);
b6d96bed 2482 }
6ea83fed
FB
2483 break;
2484 default:
9d68ac14 2485 MIPS_INVAL("flt_ldst");
9c708c7f 2486 generate_exception_end(ctx, EXCP_RI);
78723684 2487 goto out;
6ea83fed 2488 }
78723684
TS
2489 out:
2490 tcg_temp_free(t0);
6ea83fed 2491}
6ea83fed 2492
5ab5c041
AJ
2493static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2494 int rs, int16_t imm)
26ebe468 2495{
5ab5c041 2496 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2497 check_cp1_enabled(ctx);
d9224450
MR
2498 switch (op) {
2499 case OPC_LDC1:
2500 case OPC_SDC1:
2501 check_insn(ctx, ISA_MIPS2);
2502 /* Fallthrough */
2503 default:
2504 gen_flt_ldst(ctx, op, rt, rs, imm);
2505 }
26ebe468
NF
2506 } else {
2507 generate_exception_err(ctx, EXCP_CpU, 1);
2508 }
2509}
2510
6af0bf9c 2511/* Arithmetic with immediate operand */
d75c135e
AJ
2512static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2513 int rt, int rs, int16_t imm)
6af0bf9c 2514{
324d9e32 2515 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2516
7a387fff 2517 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2518 /* If no destination, treat it as a NOP.
2519 For addi, we must generate the overflow exception when needed. */
324d9e32 2520 return;
6af0bf9c
FB
2521 }
2522 switch (opc) {
2523 case OPC_ADDI:
48d38ca5 2524 {
324d9e32
AJ
2525 TCGv t0 = tcg_temp_local_new();
2526 TCGv t1 = tcg_temp_new();
2527 TCGv t2 = tcg_temp_new();
42a268c2 2528 TCGLabel *l1 = gen_new_label();
48d38ca5 2529
324d9e32
AJ
2530 gen_load_gpr(t1, rs);
2531 tcg_gen_addi_tl(t0, t1, uimm);
2532 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2533
324d9e32
AJ
2534 tcg_gen_xori_tl(t1, t1, ~uimm);
2535 tcg_gen_xori_tl(t2, t0, uimm);
2536 tcg_gen_and_tl(t1, t1, t2);
2537 tcg_temp_free(t2);
2538 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2539 tcg_temp_free(t1);
48d38ca5
TS
2540 /* operands of same sign, result different sign */
2541 generate_exception(ctx, EXCP_OVERFLOW);
2542 gen_set_label(l1);
78723684 2543 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2544 gen_store_gpr(t0, rt);
2545 tcg_temp_free(t0);
48d38ca5 2546 }
6af0bf9c
FB
2547 break;
2548 case OPC_ADDIU:
324d9e32
AJ
2549 if (rs != 0) {
2550 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2551 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2552 } else {
2553 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2554 }
6af0bf9c 2555 break;
d26bc211 2556#if defined(TARGET_MIPS64)
7a387fff 2557 case OPC_DADDI:
48d38ca5 2558 {
324d9e32
AJ
2559 TCGv t0 = tcg_temp_local_new();
2560 TCGv t1 = tcg_temp_new();
2561 TCGv t2 = tcg_temp_new();
42a268c2 2562 TCGLabel *l1 = gen_new_label();
48d38ca5 2563
324d9e32
AJ
2564 gen_load_gpr(t1, rs);
2565 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2566
324d9e32
AJ
2567 tcg_gen_xori_tl(t1, t1, ~uimm);
2568 tcg_gen_xori_tl(t2, t0, uimm);
2569 tcg_gen_and_tl(t1, t1, t2);
2570 tcg_temp_free(t2);
2571 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2572 tcg_temp_free(t1);
48d38ca5
TS
2573 /* operands of same sign, result different sign */
2574 generate_exception(ctx, EXCP_OVERFLOW);
2575 gen_set_label(l1);
324d9e32
AJ
2576 gen_store_gpr(t0, rt);
2577 tcg_temp_free(t0);
48d38ca5 2578 }
7a387fff
TS
2579 break;
2580 case OPC_DADDIU:
324d9e32
AJ
2581 if (rs != 0) {
2582 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2583 } else {
2584 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2585 }
7a387fff
TS
2586 break;
2587#endif
324d9e32 2588 }
324d9e32
AJ
2589}
2590
2591/* Logic with immediate operand */
d75c135e 2592static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2593 int rt, int rs, int16_t imm)
324d9e32
AJ
2594{
2595 target_ulong uimm;
324d9e32
AJ
2596
2597 if (rt == 0) {
2598 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2599 return;
2600 }
2601 uimm = (uint16_t)imm;
2602 switch (opc) {
6af0bf9c 2603 case OPC_ANDI:
324d9e32
AJ
2604 if (likely(rs != 0))
2605 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2606 else
2607 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2608 break;
2609 case OPC_ORI:
324d9e32
AJ
2610 if (rs != 0)
2611 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2612 else
2613 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2614 break;
2615 case OPC_XORI:
324d9e32
AJ
2616 if (likely(rs != 0))
2617 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2618 else
2619 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2620 break;
2621 case OPC_LUI:
d4ea6acd
LA
2622 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2623 /* OPC_AUI */
2624 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2625 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2626 } else {
2627 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2628 }
7c2c3ea3
EJ
2629 break;
2630
2631 default:
6af0bf9c 2632 break;
324d9e32 2633 }
324d9e32
AJ
2634}
2635
2636/* Set on less than with immediate operand */
d75c135e 2637static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2638 int rt, int rs, int16_t imm)
324d9e32
AJ
2639{
2640 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2641 TCGv t0;
2642
2643 if (rt == 0) {
2644 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2645 return;
2646 }
2647 t0 = tcg_temp_new();
2648 gen_load_gpr(t0, rs);
2649 switch (opc) {
2650 case OPC_SLTI:
e68dd28f 2651 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2652 break;
2653 case OPC_SLTIU:
e68dd28f 2654 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2655 break;
2656 }
324d9e32
AJ
2657 tcg_temp_free(t0);
2658}
2659
2660/* Shifts with immediate operand */
d75c135e 2661static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2662 int rt, int rs, int16_t imm)
2663{
2664 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2665 TCGv t0;
2666
2667 if (rt == 0) {
2668 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2669 return;
2670 }
2671
2672 t0 = tcg_temp_new();
2673 gen_load_gpr(t0, rs);
2674 switch (opc) {
6af0bf9c 2675 case OPC_SLL:
78723684 2676 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2677 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2678 break;
2679 case OPC_SRA:
324d9e32 2680 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2681 break;
2682 case OPC_SRL:
ea63e2c3
NF
2683 if (uimm != 0) {
2684 tcg_gen_ext32u_tl(t0, t0);
2685 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2686 } else {
2687 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2688 }
ea63e2c3
NF
2689 break;
2690 case OPC_ROTR:
2691 if (uimm != 0) {
2692 TCGv_i32 t1 = tcg_temp_new_i32();
2693
2694 tcg_gen_trunc_tl_i32(t1, t0);
2695 tcg_gen_rotri_i32(t1, t1, uimm);
2696 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2697 tcg_temp_free_i32(t1);
3399e30f
NF
2698 } else {
2699 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2700 }
7a387fff 2701 break;
d26bc211 2702#if defined(TARGET_MIPS64)
7a387fff 2703 case OPC_DSLL:
324d9e32 2704 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2705 break;
2706 case OPC_DSRA:
324d9e32 2707 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2708 break;
2709 case OPC_DSRL:
ea63e2c3 2710 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2711 break;
2712 case OPC_DROTR:
2713 if (uimm != 0) {
2714 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2715 } else {
2716 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2717 }
7a387fff
TS
2718 break;
2719 case OPC_DSLL32:
324d9e32 2720 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2721 break;
2722 case OPC_DSRA32:
324d9e32 2723 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2724 break;
2725 case OPC_DSRL32:
ea63e2c3 2726 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2727 break;
2728 case OPC_DROTR32:
2729 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2730 break;
7a387fff 2731#endif
6af0bf9c 2732 }
78723684 2733 tcg_temp_free(t0);
6af0bf9c
FB
2734}
2735
2736/* Arithmetic */
d75c135e
AJ
2737static void gen_arith(DisasContext *ctx, uint32_t opc,
2738 int rd, int rs, int rt)
6af0bf9c 2739{
7a387fff
TS
2740 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2741 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2742 /* If no destination, treat it as a NOP.
2743 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2744 return;
185f0762 2745 }
460f00c4 2746
6af0bf9c
FB
2747 switch (opc) {
2748 case OPC_ADD:
48d38ca5 2749 {
460f00c4
AJ
2750 TCGv t0 = tcg_temp_local_new();
2751 TCGv t1 = tcg_temp_new();
2752 TCGv t2 = tcg_temp_new();
42a268c2 2753 TCGLabel *l1 = gen_new_label();
48d38ca5 2754
460f00c4
AJ
2755 gen_load_gpr(t1, rs);
2756 gen_load_gpr(t2, rt);
2757 tcg_gen_add_tl(t0, t1, t2);
2758 tcg_gen_ext32s_tl(t0, t0);
2759 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2760 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2761 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2762 tcg_temp_free(t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764 tcg_temp_free(t1);
48d38ca5
TS
2765 /* operands of same sign, result different sign */
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
460f00c4
AJ
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
48d38ca5 2770 }
6af0bf9c
FB
2771 break;
2772 case OPC_ADDU:
460f00c4
AJ
2773 if (rs != 0 && rt != 0) {
2774 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2776 } else if (rs == 0 && rt != 0) {
2777 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2778 } else if (rs != 0 && rt == 0) {
2779 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2780 } else {
2781 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2782 }
6af0bf9c
FB
2783 break;
2784 case OPC_SUB:
48d38ca5 2785 {
460f00c4
AJ
2786 TCGv t0 = tcg_temp_local_new();
2787 TCGv t1 = tcg_temp_new();
2788 TCGv t2 = tcg_temp_new();
42a268c2 2789 TCGLabel *l1 = gen_new_label();
48d38ca5 2790
460f00c4
AJ
2791 gen_load_gpr(t1, rs);
2792 gen_load_gpr(t2, rt);
2793 tcg_gen_sub_tl(t0, t1, t2);
2794 tcg_gen_ext32s_tl(t0, t0);
2795 tcg_gen_xor_tl(t2, t1, t2);
2796 tcg_gen_xor_tl(t1, t0, t1);
2797 tcg_gen_and_tl(t1, t1, t2);
2798 tcg_temp_free(t2);
2799 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2800 tcg_temp_free(t1);
31e3104f 2801 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2802 generate_exception(ctx, EXCP_OVERFLOW);
2803 gen_set_label(l1);
460f00c4
AJ
2804 gen_store_gpr(t0, rd);
2805 tcg_temp_free(t0);
48d38ca5 2806 }
6af0bf9c
FB
2807 break;
2808 case OPC_SUBU:
460f00c4
AJ
2809 if (rs != 0 && rt != 0) {
2810 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2811 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2812 } else if (rs == 0 && rt != 0) {
2813 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2814 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2815 } else if (rs != 0 && rt == 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2817 } else {
2818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2819 }
6af0bf9c 2820 break;
d26bc211 2821#if defined(TARGET_MIPS64)
7a387fff 2822 case OPC_DADD:
48d38ca5 2823 {
460f00c4
AJ
2824 TCGv t0 = tcg_temp_local_new();
2825 TCGv t1 = tcg_temp_new();
2826 TCGv t2 = tcg_temp_new();
42a268c2 2827 TCGLabel *l1 = gen_new_label();
48d38ca5 2828
460f00c4
AJ
2829 gen_load_gpr(t1, rs);
2830 gen_load_gpr(t2, rt);
2831 tcg_gen_add_tl(t0, t1, t2);
2832 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2833 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2834 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2835 tcg_temp_free(t2);
2836 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2837 tcg_temp_free(t1);
48d38ca5
TS
2838 /* operands of same sign, result different sign */
2839 generate_exception(ctx, EXCP_OVERFLOW);
2840 gen_set_label(l1);
460f00c4
AJ
2841 gen_store_gpr(t0, rd);
2842 tcg_temp_free(t0);
48d38ca5 2843 }
7a387fff
TS
2844 break;
2845 case OPC_DADDU:
460f00c4
AJ
2846 if (rs != 0 && rt != 0) {
2847 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2848 } else if (rs == 0 && rt != 0) {
2849 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2850 } else if (rs != 0 && rt == 0) {
2851 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2852 } else {
2853 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2854 }
7a387fff
TS
2855 break;
2856 case OPC_DSUB:
48d38ca5 2857 {
460f00c4
AJ
2858 TCGv t0 = tcg_temp_local_new();
2859 TCGv t1 = tcg_temp_new();
2860 TCGv t2 = tcg_temp_new();
42a268c2 2861 TCGLabel *l1 = gen_new_label();
48d38ca5 2862
460f00c4
AJ
2863 gen_load_gpr(t1, rs);
2864 gen_load_gpr(t2, rt);
2865 tcg_gen_sub_tl(t0, t1, t2);
2866 tcg_gen_xor_tl(t2, t1, t2);
2867 tcg_gen_xor_tl(t1, t0, t1);
2868 tcg_gen_and_tl(t1, t1, t2);
2869 tcg_temp_free(t2);
2870 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2871 tcg_temp_free(t1);
31e3104f 2872 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2873 generate_exception(ctx, EXCP_OVERFLOW);
2874 gen_set_label(l1);
460f00c4
AJ
2875 gen_store_gpr(t0, rd);
2876 tcg_temp_free(t0);
48d38ca5 2877 }
7a387fff
TS
2878 break;
2879 case OPC_DSUBU:
460f00c4
AJ
2880 if (rs != 0 && rt != 0) {
2881 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2882 } else if (rs == 0 && rt != 0) {
2883 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2884 } else if (rs != 0 && rt == 0) {
2885 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2886 } else {
2887 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2888 }
7a387fff
TS
2889 break;
2890#endif
460f00c4
AJ
2891 case OPC_MUL:
2892 if (likely(rs != 0 && rt != 0)) {
2893 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2894 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2895 } else {
2896 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2897 }
6af0bf9c 2898 break;
460f00c4 2899 }
460f00c4
AJ
2900}
2901
2902/* Conditional move */
d75c135e 2903static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2904 int rd, int rs, int rt)
460f00c4 2905{
acf12465 2906 TCGv t0, t1, t2;
460f00c4
AJ
2907
2908 if (rd == 0) {
acf12465 2909 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2910 return;
2911 }
2912
acf12465
AJ
2913 t0 = tcg_temp_new();
2914 gen_load_gpr(t0, rt);
2915 t1 = tcg_const_tl(0);
2916 t2 = tcg_temp_new();
2917 gen_load_gpr(t2, rs);
460f00c4
AJ
2918 switch (opc) {
2919 case OPC_MOVN:
acf12465 2920 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2921 break;
460f00c4 2922 case OPC_MOVZ:
acf12465 2923 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2924 break;
b691d9d2
LA
2925 case OPC_SELNEZ:
2926 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2927 break;
2928 case OPC_SELEQZ:
2929 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2930 break;
460f00c4 2931 }
acf12465
AJ
2932 tcg_temp_free(t2);
2933 tcg_temp_free(t1);
2934 tcg_temp_free(t0);
460f00c4
AJ
2935}
2936
2937/* Logic */
d75c135e 2938static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2939 int rd, int rs, int rt)
460f00c4 2940{
460f00c4
AJ
2941 if (rd == 0) {
2942 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2943 return;
2944 }
2945
2946 switch (opc) {
6af0bf9c 2947 case OPC_AND:
460f00c4
AJ
2948 if (likely(rs != 0 && rt != 0)) {
2949 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2950 } else {
2951 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2952 }
6af0bf9c
FB
2953 break;
2954 case OPC_NOR:
460f00c4
AJ
2955 if (rs != 0 && rt != 0) {
2956 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2957 } else if (rs == 0 && rt != 0) {
2958 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2959 } else if (rs != 0 && rt == 0) {
2960 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2961 } else {
2962 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2963 }
6af0bf9c
FB
2964 break;
2965 case OPC_OR:
460f00c4
AJ
2966 if (likely(rs != 0 && rt != 0)) {
2967 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2968 } else if (rs == 0 && rt != 0) {
2969 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2970 } else if (rs != 0 && rt == 0) {
2971 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2972 } else {
2973 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2974 }
6af0bf9c
FB
2975 break;
2976 case OPC_XOR:
460f00c4
AJ
2977 if (likely(rs != 0 && rt != 0)) {
2978 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2979 } else if (rs == 0 && rt != 0) {
2980 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2981 } else if (rs != 0 && rt == 0) {
2982 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2983 } else {
2984 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2985 }
6af0bf9c 2986 break;
460f00c4 2987 }
460f00c4
AJ
2988}
2989
2990/* Set on lower than */
d75c135e 2991static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2992 int rd, int rs, int rt)
460f00c4 2993{
460f00c4
AJ
2994 TCGv t0, t1;
2995
2996 if (rd == 0) {
2997 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2998 return;
2999 }
3000
3001 t0 = tcg_temp_new();
3002 t1 = tcg_temp_new();
3003 gen_load_gpr(t0, rs);
3004 gen_load_gpr(t1, rt);
3005 switch (opc) {
3006 case OPC_SLT:
e68dd28f 3007 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 3008 break;
460f00c4 3009 case OPC_SLTU:
e68dd28f 3010 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3011 break;
3012 }
460f00c4
AJ
3013 tcg_temp_free(t0);
3014 tcg_temp_free(t1);
3015}
20c4c97c 3016
460f00c4 3017/* Shifts */
d75c135e
AJ
3018static void gen_shift(DisasContext *ctx, uint32_t opc,
3019 int rd, int rs, int rt)
460f00c4 3020{
460f00c4 3021 TCGv t0, t1;
20c4c97c 3022
460f00c4
AJ
3023 if (rd == 0) {
3024 /* If no destination, treat it as a NOP.
3025 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
3026 return;
3027 }
3028
3029 t0 = tcg_temp_new();
3030 t1 = tcg_temp_new();
3031 gen_load_gpr(t0, rs);
3032 gen_load_gpr(t1, rt);
3033 switch (opc) {
6af0bf9c 3034 case OPC_SLLV:
78723684
TS
3035 tcg_gen_andi_tl(t0, t0, 0x1f);
3036 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3037 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3038 break;
3039 case OPC_SRAV:
78723684 3040 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3041 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3042 break;
3043 case OPC_SRLV:
ea63e2c3
NF
3044 tcg_gen_ext32u_tl(t1, t1);
3045 tcg_gen_andi_tl(t0, t0, 0x1f);
3046 tcg_gen_shr_tl(t0, t1, t0);
3047 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
3048 break;
3049 case OPC_ROTRV:
3050 {
3051 TCGv_i32 t2 = tcg_temp_new_i32();
3052 TCGv_i32 t3 = tcg_temp_new_i32();
3053
3054 tcg_gen_trunc_tl_i32(t2, t0);
3055 tcg_gen_trunc_tl_i32(t3, t1);
3056 tcg_gen_andi_i32(t2, t2, 0x1f);
3057 tcg_gen_rotr_i32(t2, t3, t2);
3058 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3059 tcg_temp_free_i32(t2);
3060 tcg_temp_free_i32(t3);
5a63bcb2 3061 }
7a387fff 3062 break;
d26bc211 3063#if defined(TARGET_MIPS64)
7a387fff 3064 case OPC_DSLLV:
78723684 3065 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3066 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3067 break;
3068 case OPC_DSRAV:
78723684 3069 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3070 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3071 break;
3072 case OPC_DSRLV:
ea63e2c3
NF
3073 tcg_gen_andi_tl(t0, t0, 0x3f);
3074 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3075 break;
3076 case OPC_DROTRV:
3077 tcg_gen_andi_tl(t0, t0, 0x3f);
3078 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3079 break;
7a387fff 3080#endif
6af0bf9c 3081 }
78723684
TS
3082 tcg_temp_free(t0);
3083 tcg_temp_free(t1);
6af0bf9c
FB
3084}
3085
3086/* Arithmetic on HI/LO registers */
26135ead 3087static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3088{
6af0bf9c 3089 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3090 /* Treat as NOP. */
a1f6684d 3091 return;
6af0bf9c 3092 }
4133498f 3093
4133498f
JL
3094 if (acc != 0) {
3095 check_dsp(ctx);
3096 }
3097
6af0bf9c
FB
3098 switch (opc) {
3099 case OPC_MFHI:
4133498f
JL
3100#if defined(TARGET_MIPS64)
3101 if (acc != 0) {
3102 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3103 } else
3104#endif
3105 {
3106 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3107 }
6af0bf9c
FB
3108 break;
3109 case OPC_MFLO:
4133498f
JL
3110#if defined(TARGET_MIPS64)
3111 if (acc != 0) {
3112 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3113 } else
3114#endif
3115 {
3116 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3117 }
6af0bf9c
FB
3118 break;
3119 case OPC_MTHI:
4133498f
JL
3120 if (reg != 0) {
3121#if defined(TARGET_MIPS64)
3122 if (acc != 0) {
3123 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3124 } else
3125#endif
3126 {
3127 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3128 }
3129 } else {
3130 tcg_gen_movi_tl(cpu_HI[acc], 0);
3131 }
6af0bf9c
FB
3132 break;
3133 case OPC_MTLO:
4133498f
JL
3134 if (reg != 0) {
3135#if defined(TARGET_MIPS64)
3136 if (acc != 0) {
3137 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3138 } else
3139#endif
3140 {
3141 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3142 }
3143 } else {
3144 tcg_gen_movi_tl(cpu_LO[acc], 0);
3145 }
6af0bf9c 3146 break;
6af0bf9c 3147 }
6af0bf9c
FB
3148}
3149
d4ea6acd
LA
3150static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3151 TCGMemOp memop)
3152{
3153 TCGv t0 = tcg_const_tl(addr);
3154 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3155 gen_store_gpr(t0, reg);
3156 tcg_temp_free(t0);
3157}
3158
ab39ee45
YK
3159static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3160 int rs)
d4ea6acd
LA
3161{
3162 target_long offset;
3163 target_long addr;
3164
ab39ee45 3165 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3166 case OPC_ADDIUPC:
3167 if (rs != 0) {
3168 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3169 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3170 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3171 }
3172 break;
3173 case R6_OPC_LWPC:
3174 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3175 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3176 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3177 break;
3178#if defined(TARGET_MIPS64)
3179 case OPC_LWUPC:
3180 check_mips_64(ctx);
3181 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3182 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3183 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3184 break;
3185#endif
3186 default:
ab39ee45 3187 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3188 case OPC_AUIPC:
3189 if (rs != 0) {
ab39ee45
YK
3190 offset = sextract32(ctx->opcode, 0, 16) << 16;
3191 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3192 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3193 }
3194 break;
3195 case OPC_ALUIPC:
3196 if (rs != 0) {
ab39ee45
YK
3197 offset = sextract32(ctx->opcode, 0, 16) << 16;
3198 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3199 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3200 }
3201 break;
3202#if defined(TARGET_MIPS64)
3203 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3204 case R6_OPC_LDPC + (1 << 16):
3205 case R6_OPC_LDPC + (2 << 16):
3206 case R6_OPC_LDPC + (3 << 16):
3207 check_mips_64(ctx);
3208 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3209 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3210 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3211 break;
3212#endif
3213 default:
3214 MIPS_INVAL("OPC_PCREL");
9c708c7f 3215 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3216 break;
3217 }
3218 break;
3219 }
3220}
3221
b42ee5e1
LA
3222static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3223{
b42ee5e1
LA
3224 TCGv t0, t1;
3225
3226 if (rd == 0) {
3227 /* Treat as NOP. */
b42ee5e1
LA
3228 return;
3229 }
3230
3231 t0 = tcg_temp_new();
3232 t1 = tcg_temp_new();
3233
3234 gen_load_gpr(t0, rs);
3235 gen_load_gpr(t1, rt);
3236
3237 switch (opc) {
3238 case R6_OPC_DIV:
3239 {
3240 TCGv t2 = tcg_temp_new();
3241 TCGv t3 = tcg_temp_new();
3242 tcg_gen_ext32s_tl(t0, t0);
3243 tcg_gen_ext32s_tl(t1, t1);
3244 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3245 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3246 tcg_gen_and_tl(t2, t2, t3);
3247 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3248 tcg_gen_or_tl(t2, t2, t3);
3249 tcg_gen_movi_tl(t3, 0);
3250 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3251 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3252 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3253 tcg_temp_free(t3);
3254 tcg_temp_free(t2);
3255 }
b42ee5e1
LA
3256 break;
3257 case R6_OPC_MOD:
3258 {
3259 TCGv t2 = tcg_temp_new();
3260 TCGv t3 = tcg_temp_new();
3261 tcg_gen_ext32s_tl(t0, t0);
3262 tcg_gen_ext32s_tl(t1, t1);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3265 tcg_gen_and_tl(t2, t2, t3);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267 tcg_gen_or_tl(t2, t2, t3);
3268 tcg_gen_movi_tl(t3, 0);
3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3271 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3272 tcg_temp_free(t3);
3273 tcg_temp_free(t2);
3274 }
b42ee5e1
LA
3275 break;
3276 case R6_OPC_DIVU:
3277 {
3278 TCGv t2 = tcg_const_tl(0);
3279 TCGv t3 = tcg_const_tl(1);
3280 tcg_gen_ext32u_tl(t0, t0);
3281 tcg_gen_ext32u_tl(t1, t1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3284 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3285 tcg_temp_free(t3);
3286 tcg_temp_free(t2);
3287 }
b42ee5e1
LA
3288 break;
3289 case R6_OPC_MODU:
3290 {
3291 TCGv t2 = tcg_const_tl(0);
3292 TCGv t3 = tcg_const_tl(1);
3293 tcg_gen_ext32u_tl(t0, t0);
3294 tcg_gen_ext32u_tl(t1, t1);
3295 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3296 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3297 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3298 tcg_temp_free(t3);
3299 tcg_temp_free(t2);
3300 }
b42ee5e1
LA
3301 break;
3302 case R6_OPC_MUL:
3303 {
3304 TCGv_i32 t2 = tcg_temp_new_i32();
3305 TCGv_i32 t3 = tcg_temp_new_i32();
3306 tcg_gen_trunc_tl_i32(t2, t0);
3307 tcg_gen_trunc_tl_i32(t3, t1);
3308 tcg_gen_mul_i32(t2, t2, t3);
3309 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3310 tcg_temp_free_i32(t2);
3311 tcg_temp_free_i32(t3);
3312 }
b42ee5e1
LA
3313 break;
3314 case R6_OPC_MUH:
3315 {
3316 TCGv_i32 t2 = tcg_temp_new_i32();
3317 TCGv_i32 t3 = tcg_temp_new_i32();
3318 tcg_gen_trunc_tl_i32(t2, t0);
3319 tcg_gen_trunc_tl_i32(t3, t1);
3320 tcg_gen_muls2_i32(t2, t3, t2, t3);
3321 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3322 tcg_temp_free_i32(t2);
3323 tcg_temp_free_i32(t3);
3324 }
b42ee5e1
LA
3325 break;
3326 case R6_OPC_MULU:
3327 {
3328 TCGv_i32 t2 = tcg_temp_new_i32();
3329 TCGv_i32 t3 = tcg_temp_new_i32();
3330 tcg_gen_trunc_tl_i32(t2, t0);
3331 tcg_gen_trunc_tl_i32(t3, t1);
3332 tcg_gen_mul_i32(t2, t2, t3);
3333 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3334 tcg_temp_free_i32(t2);
3335 tcg_temp_free_i32(t3);
3336 }
b42ee5e1
LA
3337 break;
3338 case R6_OPC_MUHU:
3339 {
3340 TCGv_i32 t2 = tcg_temp_new_i32();
3341 TCGv_i32 t3 = tcg_temp_new_i32();
3342 tcg_gen_trunc_tl_i32(t2, t0);
3343 tcg_gen_trunc_tl_i32(t3, t1);
3344 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3345 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3346 tcg_temp_free_i32(t2);
3347 tcg_temp_free_i32(t3);
3348 }
b42ee5e1
LA
3349 break;
3350#if defined(TARGET_MIPS64)
3351 case R6_OPC_DDIV:
3352 {
3353 TCGv t2 = tcg_temp_new();
3354 TCGv t3 = tcg_temp_new();
3355 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3356 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3357 tcg_gen_and_tl(t2, t2, t3);
3358 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3359 tcg_gen_or_tl(t2, t2, t3);
3360 tcg_gen_movi_tl(t3, 0);
3361 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3362 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3363 tcg_temp_free(t3);
3364 tcg_temp_free(t2);
3365 }
b42ee5e1
LA
3366 break;
3367 case R6_OPC_DMOD:
3368 {
3369 TCGv t2 = tcg_temp_new();
3370 TCGv t3 = tcg_temp_new();
3371 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3372 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3373 tcg_gen_and_tl(t2, t2, t3);
3374 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3375 tcg_gen_or_tl(t2, t2, t3);
3376 tcg_gen_movi_tl(t3, 0);
3377 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3378 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3379 tcg_temp_free(t3);
3380 tcg_temp_free(t2);
3381 }
b42ee5e1
LA
3382 break;
3383 case R6_OPC_DDIVU:
3384 {
3385 TCGv t2 = tcg_const_tl(0);
3386 TCGv t3 = tcg_const_tl(1);
3387 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3388 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3389 tcg_temp_free(t3);
3390 tcg_temp_free(t2);
3391 }
b42ee5e1
LA
3392 break;
3393 case R6_OPC_DMODU:
3394 {
3395 TCGv t2 = tcg_const_tl(0);
3396 TCGv t3 = tcg_const_tl(1);
3397 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3398 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3399 tcg_temp_free(t3);
3400 tcg_temp_free(t2);
3401 }
b42ee5e1
LA
3402 break;
3403 case R6_OPC_DMUL:
3404 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3405 break;
3406 case R6_OPC_DMUH:
3407 {
3408 TCGv t2 = tcg_temp_new();
3409 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3410 tcg_temp_free(t2);
3411 }
b42ee5e1
LA
3412 break;
3413 case R6_OPC_DMULU:
3414 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3415 break;
3416 case R6_OPC_DMUHU:
3417 {
3418 TCGv t2 = tcg_temp_new();
3419 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3420 tcg_temp_free(t2);
3421 }
b42ee5e1
LA
3422 break;
3423#endif
3424 default:
9d68ac14 3425 MIPS_INVAL("r6 mul/div");
9c708c7f 3426 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3427 goto out;
3428 }
b42ee5e1
LA
3429 out:
3430 tcg_temp_free(t0);
3431 tcg_temp_free(t1);
3432}
3433
26135ead
RS
3434static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3435 int acc, int rs, int rt)
6af0bf9c 3436{
d45f89f4
AJ
3437 TCGv t0, t1;
3438
51127181
AJ
3439 t0 = tcg_temp_new();
3440 t1 = tcg_temp_new();
6af0bf9c 3441
78723684
TS
3442 gen_load_gpr(t0, rs);
3443 gen_load_gpr(t1, rt);
51127181 3444
26135ead
RS
3445 if (acc != 0) {
3446 check_dsp(ctx);
3447 }
3448
6af0bf9c
FB
3449 switch (opc) {
3450 case OPC_DIV:
48d38ca5 3451 {
51127181
AJ
3452 TCGv t2 = tcg_temp_new();
3453 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3454 tcg_gen_ext32s_tl(t0, t0);
3455 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3456 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3457 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3458 tcg_gen_and_tl(t2, t2, t3);
3459 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3460 tcg_gen_or_tl(t2, t2, t3);
3461 tcg_gen_movi_tl(t3, 0);
3462 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3463 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3464 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3465 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3466 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3467 tcg_temp_free(t3);
3468 tcg_temp_free(t2);
48d38ca5 3469 }
6af0bf9c
FB
3470 break;
3471 case OPC_DIVU:
48d38ca5 3472 {
51127181
AJ
3473 TCGv t2 = tcg_const_tl(0);
3474 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3475 tcg_gen_ext32u_tl(t0, t0);
3476 tcg_gen_ext32u_tl(t1, t1);
51127181 3477 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3478 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3479 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3480 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3481 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3482 tcg_temp_free(t3);
3483 tcg_temp_free(t2);
48d38ca5 3484 }
6af0bf9c
FB
3485 break;
3486 case OPC_MULT:
214c465f 3487 {
ce1dd5d1
RH
3488 TCGv_i32 t2 = tcg_temp_new_i32();
3489 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3490 tcg_gen_trunc_tl_i32(t2, t0);
3491 tcg_gen_trunc_tl_i32(t3, t1);
3492 tcg_gen_muls2_i32(t2, t3, t2, t3);
3493 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3494 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3495 tcg_temp_free_i32(t2);
3496 tcg_temp_free_i32(t3);
214c465f 3497 }
6af0bf9c
FB
3498 break;
3499 case OPC_MULTU:
214c465f 3500 {
ce1dd5d1
RH
3501 TCGv_i32 t2 = tcg_temp_new_i32();
3502 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3503 tcg_gen_trunc_tl_i32(t2, t0);
3504 tcg_gen_trunc_tl_i32(t3, t1);
3505 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3506 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3507 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3508 tcg_temp_free_i32(t2);
3509 tcg_temp_free_i32(t3);
214c465f 3510 }
6af0bf9c 3511 break;
d26bc211 3512#if defined(TARGET_MIPS64)
7a387fff 3513 case OPC_DDIV:
48d38ca5 3514 {
51127181
AJ
3515 TCGv t2 = tcg_temp_new();
3516 TCGv t3 = tcg_temp_new();
3517 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3518 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3519 tcg_gen_and_tl(t2, t2, t3);
3520 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3521 tcg_gen_or_tl(t2, t2, t3);
3522 tcg_gen_movi_tl(t3, 0);
3523 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3524 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3525 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3526 tcg_temp_free(t3);
3527 tcg_temp_free(t2);
48d38ca5 3528 }
7a387fff
TS
3529 break;
3530 case OPC_DDIVU:
48d38ca5 3531 {
51127181
AJ
3532 TCGv t2 = tcg_const_tl(0);
3533 TCGv t3 = tcg_const_tl(1);
3534 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3535 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3536 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3537 tcg_temp_free(t3);
3538 tcg_temp_free(t2);
48d38ca5 3539 }
7a387fff
TS
3540 break;
3541 case OPC_DMULT:
26135ead 3542 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3543 break;
3544 case OPC_DMULTU:
26135ead 3545 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3546 break;
3547#endif
6af0bf9c 3548 case OPC_MADD:
214c465f 3549 {
d45f89f4
AJ
3550 TCGv_i64 t2 = tcg_temp_new_i64();
3551 TCGv_i64 t3 = tcg_temp_new_i64();
3552
3553 tcg_gen_ext_tl_i64(t2, t0);
3554 tcg_gen_ext_tl_i64(t3, t1);
3555 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3556 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3557 tcg_gen_add_i64(t2, t2, t3);
3558 tcg_temp_free_i64(t3);
71f303cd
RH
3559 gen_move_low32(cpu_LO[acc], t2);
3560 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3561 tcg_temp_free_i64(t2);
214c465f 3562 }
6af0bf9c
FB
3563 break;
3564 case OPC_MADDU:
4133498f 3565 {
d45f89f4
AJ
3566 TCGv_i64 t2 = tcg_temp_new_i64();
3567 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3568
78723684
TS
3569 tcg_gen_ext32u_tl(t0, t0);
3570 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3571 tcg_gen_extu_tl_i64(t2, t0);
3572 tcg_gen_extu_tl_i64(t3, t1);
3573 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3574 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3575 tcg_gen_add_i64(t2, t2, t3);
3576 tcg_temp_free_i64(t3);
71f303cd
RH
3577 gen_move_low32(cpu_LO[acc], t2);
3578 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3579 tcg_temp_free_i64(t2);
214c465f 3580 }
6af0bf9c
FB
3581 break;
3582 case OPC_MSUB:
214c465f 3583 {
d45f89f4
AJ
3584 TCGv_i64 t2 = tcg_temp_new_i64();
3585 TCGv_i64 t3 = tcg_temp_new_i64();
3586
3587 tcg_gen_ext_tl_i64(t2, t0);
3588 tcg_gen_ext_tl_i64(t3, t1);
3589 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3590 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3591 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3592 tcg_temp_free_i64(t3);
71f303cd
RH
3593 gen_move_low32(cpu_LO[acc], t2);
3594 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3595 tcg_temp_free_i64(t2);
214c465f 3596 }
6af0bf9c
FB
3597 break;
3598 case OPC_MSUBU:
214c465f 3599 {
d45f89f4
AJ
3600 TCGv_i64 t2 = tcg_temp_new_i64();
3601 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3602
78723684
TS
3603 tcg_gen_ext32u_tl(t0, t0);
3604 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3605 tcg_gen_extu_tl_i64(t2, t0);
3606 tcg_gen_extu_tl_i64(t3, t1);
3607 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3608 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3609 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3610 tcg_temp_free_i64(t3);
71f303cd
RH
3611 gen_move_low32(cpu_LO[acc], t2);
3612 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3613 tcg_temp_free_i64(t2);
214c465f 3614 }
6af0bf9c
FB
3615 break;
3616 default:
9d68ac14 3617 MIPS_INVAL("mul/div");
9c708c7f 3618 generate_exception_end(ctx, EXCP_RI);
78723684 3619 goto out;
6af0bf9c 3620 }
78723684
TS
3621 out:
3622 tcg_temp_free(t0);
3623 tcg_temp_free(t1);
6af0bf9c
FB
3624}
3625
e9c71dd1
TS
3626static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3627 int rd, int rs, int rt)
3628{
f157bfe1
AJ
3629 TCGv t0 = tcg_temp_new();
3630 TCGv t1 = tcg_temp_new();
e9c71dd1 3631
6c5c1e20
TS
3632 gen_load_gpr(t0, rs);
3633 gen_load_gpr(t1, rt);
e9c71dd1
TS
3634
3635 switch (opc) {
3636 case OPC_VR54XX_MULS:
895c2d04 3637 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3638 break;
e9c71dd1 3639 case OPC_VR54XX_MULSU:
895c2d04 3640 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3641 break;
e9c71dd1 3642 case OPC_VR54XX_MACC:
895c2d04 3643 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3644 break;
e9c71dd1 3645 case OPC_VR54XX_MACCU:
895c2d04 3646 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3647 break;
e9c71dd1 3648 case OPC_VR54XX_MSAC:
895c2d04 3649 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3650 break;
e9c71dd1 3651 case OPC_VR54XX_MSACU:
895c2d04 3652 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3653 break;
e9c71dd1 3654 case OPC_VR54XX_MULHI:
895c2d04 3655 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3656 break;
e9c71dd1 3657 case OPC_VR54XX_MULHIU:
895c2d04 3658 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3659 break;
e9c71dd1 3660 case OPC_VR54XX_MULSHI:
895c2d04 3661 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3662 break;
e9c71dd1 3663 case OPC_VR54XX_MULSHIU:
895c2d04 3664 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3665 break;
e9c71dd1 3666 case OPC_VR54XX_MACCHI:
895c2d04 3667 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3668 break;
e9c71dd1 3669 case OPC_VR54XX_MACCHIU:
895c2d04 3670 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3671 break;
e9c71dd1 3672 case OPC_VR54XX_MSACHI:
895c2d04 3673 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3674 break;
e9c71dd1 3675 case OPC_VR54XX_MSACHIU:
895c2d04 3676 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3677 break;
e9c71dd1
TS
3678 default:
3679 MIPS_INVAL("mul vr54xx");
9c708c7f 3680 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3681 goto out;
e9c71dd1 3682 }
6c5c1e20 3683 gen_store_gpr(t0, rd);
6c5c1e20
TS
3684
3685 out:
3686 tcg_temp_free(t0);
3687 tcg_temp_free(t1);
e9c71dd1
TS
3688}
3689
7a387fff 3690static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3691 int rd, int rs)
3692{
20e1fb52 3693 TCGv t0;
6c5c1e20 3694
6af0bf9c 3695 if (rd == 0) {
ead9360e 3696 /* Treat as NOP. */
20e1fb52 3697 return;
6af0bf9c 3698 }
1a0196c5 3699 t0 = cpu_gpr[rd];
6c5c1e20 3700 gen_load_gpr(t0, rs);
1a0196c5 3701
6af0bf9c
FB
3702 switch (opc) {
3703 case OPC_CLO:
4267d3e6 3704 case R6_OPC_CLO:
1a0196c5
RH
3705#if defined(TARGET_MIPS64)
3706 case OPC_DCLO:
3707 case R6_OPC_DCLO:
3708#endif
3709 tcg_gen_not_tl(t0, t0);
6af0bf9c 3710 break;
1a0196c5
RH
3711 }
3712
3713 switch (opc) {
3714 case OPC_CLO:
3715 case R6_OPC_CLO:
6af0bf9c 3716 case OPC_CLZ:
4267d3e6 3717 case R6_OPC_CLZ:
1a0196c5
RH
3718 tcg_gen_ext32u_tl(t0, t0);
3719 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3720 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3721 break;
d26bc211 3722#if defined(TARGET_MIPS64)
7a387fff 3723 case OPC_DCLO:
4267d3e6 3724 case R6_OPC_DCLO:
7a387fff 3725 case OPC_DCLZ:
4267d3e6 3726 case R6_OPC_DCLZ:
1a0196c5 3727 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3728 break;
3729#endif
6af0bf9c 3730 }
6af0bf9c
FB
3731}
3732
161f85e6 3733/* Godson integer instructions */
bd277fa1
RH
3734static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3735 int rd, int rs, int rt)
161f85e6 3736{
161f85e6
AJ
3737 TCGv t0, t1;
3738
3739 if (rd == 0) {
3740 /* Treat as NOP. */
161f85e6
AJ
3741 return;
3742 }
3743
3744 switch (opc) {
3745 case OPC_MULT_G_2E:
3746 case OPC_MULT_G_2F:
3747 case OPC_MULTU_G_2E:
3748 case OPC_MULTU_G_2F:
3749#if defined(TARGET_MIPS64)
3750 case OPC_DMULT_G_2E:
3751 case OPC_DMULT_G_2F:
3752 case OPC_DMULTU_G_2E:
3753 case OPC_DMULTU_G_2F:
3754#endif
3755 t0 = tcg_temp_new();
3756 t1 = tcg_temp_new();
3757 break;
3758 default:
3759 t0 = tcg_temp_local_new();
3760 t1 = tcg_temp_local_new();
3761 break;
3762 }
3763
3764 gen_load_gpr(t0, rs);
3765 gen_load_gpr(t1, rt);
3766
3767 switch (opc) {
3768 case OPC_MULT_G_2E:
3769 case OPC_MULT_G_2F:
3770 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3771 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3772 break;
3773 case OPC_MULTU_G_2E:
3774 case OPC_MULTU_G_2F:
3775 tcg_gen_ext32u_tl(t0, t0);
3776 tcg_gen_ext32u_tl(t1, t1);
3777 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3778 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3779 break;
3780 case OPC_DIV_G_2E:
3781 case OPC_DIV_G_2F:
3782 {
42a268c2
RH
3783 TCGLabel *l1 = gen_new_label();
3784 TCGLabel *l2 = gen_new_label();
3785 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3786 tcg_gen_ext32s_tl(t0, t0);
3787 tcg_gen_ext32s_tl(t1, t1);
3788 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3790 tcg_gen_br(l3);
3791 gen_set_label(l1);
3792 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3793 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3794 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3795 tcg_gen_br(l3);
3796 gen_set_label(l2);
3797 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3798 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3799 gen_set_label(l3);
3800 }
161f85e6
AJ
3801 break;
3802 case OPC_DIVU_G_2E:
3803 case OPC_DIVU_G_2F:
3804 {
42a268c2
RH
3805 TCGLabel *l1 = gen_new_label();
3806 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3807 tcg_gen_ext32u_tl(t0, t0);
3808 tcg_gen_ext32u_tl(t1, t1);
3809 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3810 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3811 tcg_gen_br(l2);
3812 gen_set_label(l1);
3813 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3814 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3815 gen_set_label(l2);
3816 }
161f85e6
AJ
3817 break;
3818 case OPC_MOD_G_2E:
3819 case OPC_MOD_G_2F:
3820 {
42a268c2
RH
3821 TCGLabel *l1 = gen_new_label();
3822 TCGLabel *l2 = gen_new_label();
3823 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3824 tcg_gen_ext32u_tl(t0, t0);
3825 tcg_gen_ext32u_tl(t1, t1);
3826 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3827 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3828 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3829 gen_set_label(l1);
3830 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3831 tcg_gen_br(l3);
3832 gen_set_label(l2);
3833 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3834 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3835 gen_set_label(l3);
3836 }
161f85e6
AJ
3837 break;
3838 case OPC_MODU_G_2E:
3839 case OPC_MODU_G_2F:
3840 {
42a268c2
RH
3841 TCGLabel *l1 = gen_new_label();
3842 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3843 tcg_gen_ext32u_tl(t0, t0);
3844 tcg_gen_ext32u_tl(t1, t1);
3845 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3846 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3847 tcg_gen_br(l2);
3848 gen_set_label(l1);
3849 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3850 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3851 gen_set_label(l2);
3852 }
161f85e6
AJ
3853 break;
3854#if defined(TARGET_MIPS64)
3855 case OPC_DMULT_G_2E:
3856 case OPC_DMULT_G_2F:
3857 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3858 break;
3859 case OPC_DMULTU_G_2E:
3860 case OPC_DMULTU_G_2F:
3861 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3862 break;
3863 case OPC_DDIV_G_2E:
3864 case OPC_DDIV_G_2F:
3865 {
42a268c2
RH
3866 TCGLabel *l1 = gen_new_label();
3867 TCGLabel *l2 = gen_new_label();
3868 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3869 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3870 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3871 tcg_gen_br(l3);
3872 gen_set_label(l1);
3873 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3874 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3875 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3876 tcg_gen_br(l3);
3877 gen_set_label(l2);
3878 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3879 gen_set_label(l3);
3880 }
161f85e6
AJ
3881 break;
3882 case OPC_DDIVU_G_2E:
3883 case OPC_DDIVU_G_2F:
3884 {
42a268c2
RH
3885 TCGLabel *l1 = gen_new_label();
3886 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3887 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3888 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3889 tcg_gen_br(l2);
3890 gen_set_label(l1);
3891 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3892 gen_set_label(l2);
3893 }
161f85e6
AJ
3894 break;
3895 case OPC_DMOD_G_2E:
3896 case OPC_DMOD_G_2F:
3897 {
42a268c2
RH
3898 TCGLabel *l1 = gen_new_label();
3899 TCGLabel *l2 = gen_new_label();
3900 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3901 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3902 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3903 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3904 gen_set_label(l1);
3905 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3906 tcg_gen_br(l3);
3907 gen_set_label(l2);
3908 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3909 gen_set_label(l3);
3910 }
161f85e6
AJ
3911 break;
3912 case OPC_DMODU_G_2E:
3913 case OPC_DMODU_G_2F:
3914 {
42a268c2
RH
3915 TCGLabel *l1 = gen_new_label();
3916 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3917 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3918 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3919 tcg_gen_br(l2);
3920 gen_set_label(l1);
3921 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3922 gen_set_label(l2);
3923 }
161f85e6
AJ
3924 break;
3925#endif
3926 }
3927
161f85e6
AJ
3928 tcg_temp_free(t0);
3929 tcg_temp_free(t1);
3930}
3931
bd277fa1
RH
3932/* Loongson multimedia instructions */
3933static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3934{
bd277fa1
RH
3935 uint32_t opc, shift_max;
3936 TCGv_i64 t0, t1;
3937
3938 opc = MASK_LMI(ctx->opcode);
3939 switch (opc) {
3940 case OPC_ADD_CP2:
3941 case OPC_SUB_CP2:
3942 case OPC_DADD_CP2:
3943 case OPC_DSUB_CP2:
3944 t0 = tcg_temp_local_new_i64();
3945 t1 = tcg_temp_local_new_i64();
3946 break;
3947 default:
3948 t0 = tcg_temp_new_i64();
3949 t1 = tcg_temp_new_i64();
3950 break;
3951 }
3952
b5a587b6 3953 check_cp1_enabled(ctx);
bd277fa1
RH
3954 gen_load_fpr64(ctx, t0, rs);
3955 gen_load_fpr64(ctx, t1, rt);
3956
3957#define LMI_HELPER(UP, LO) \
9d68ac14 3958 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3959#define LMI_HELPER_1(UP, LO) \
9d68ac14 3960 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3961#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3962 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3963
3964 switch (opc) {
3965 LMI_HELPER(PADDSH, paddsh);
3966 LMI_HELPER(PADDUSH, paddush);
3967 LMI_HELPER(PADDH, paddh);
3968 LMI_HELPER(PADDW, paddw);
3969 LMI_HELPER(PADDSB, paddsb);
3970 LMI_HELPER(PADDUSB, paddusb);
3971 LMI_HELPER(PADDB, paddb);
3972
3973 LMI_HELPER(PSUBSH, psubsh);
3974 LMI_HELPER(PSUBUSH, psubush);
3975 LMI_HELPER(PSUBH, psubh);
3976 LMI_HELPER(PSUBW, psubw);
3977 LMI_HELPER(PSUBSB, psubsb);
3978 LMI_HELPER(PSUBUSB, psubusb);
3979 LMI_HELPER(PSUBB, psubb);
3980
3981 LMI_HELPER(PSHUFH, pshufh);
3982 LMI_HELPER(PACKSSWH, packsswh);
3983 LMI_HELPER(PACKSSHB, packsshb);
3984 LMI_HELPER(PACKUSHB, packushb);
3985
3986 LMI_HELPER(PUNPCKLHW, punpcklhw);
3987 LMI_HELPER(PUNPCKHHW, punpckhhw);
3988 LMI_HELPER(PUNPCKLBH, punpcklbh);
3989 LMI_HELPER(PUNPCKHBH, punpckhbh);
3990 LMI_HELPER(PUNPCKLWD, punpcklwd);
3991 LMI_HELPER(PUNPCKHWD, punpckhwd);
3992
3993 LMI_HELPER(PAVGH, pavgh);
3994 LMI_HELPER(PAVGB, pavgb);
3995 LMI_HELPER(PMAXSH, pmaxsh);
3996 LMI_HELPER(PMINSH, pminsh);
3997 LMI_HELPER(PMAXUB, pmaxub);
3998 LMI_HELPER(PMINUB, pminub);
3999
4000 LMI_HELPER(PCMPEQW, pcmpeqw);
4001 LMI_HELPER(PCMPGTW, pcmpgtw);
4002 LMI_HELPER(PCMPEQH, pcmpeqh);
4003 LMI_HELPER(PCMPGTH, pcmpgth);
4004 LMI_HELPER(PCMPEQB, pcmpeqb);
4005 LMI_HELPER(PCMPGTB, pcmpgtb);
4006
4007 LMI_HELPER(PSLLW, psllw);
4008 LMI_HELPER(PSLLH, psllh);
4009 LMI_HELPER(PSRLW, psrlw);
4010 LMI_HELPER(PSRLH, psrlh);
4011 LMI_HELPER(PSRAW, psraw);
4012 LMI_HELPER(PSRAH, psrah);
4013
4014 LMI_HELPER(PMULLH, pmullh);
4015 LMI_HELPER(PMULHH, pmulhh);
4016 LMI_HELPER(PMULHUH, pmulhuh);
4017 LMI_HELPER(PMADDHW, pmaddhw);
4018
4019 LMI_HELPER(PASUBUB, pasubub);
4020 LMI_HELPER_1(BIADD, biadd);
4021 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4022
4023 LMI_DIRECT(PADDD, paddd, add);
4024 LMI_DIRECT(PSUBD, psubd, sub);
4025 LMI_DIRECT(XOR_CP2, xor, xor);
4026 LMI_DIRECT(NOR_CP2, nor, nor);
4027 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 4028 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 4029
9099a36b
H
4030 case OPC_PANDN:
4031 tcg_gen_andc_i64(t0, t1, t0);
4032 break;
4033
bd277fa1
RH
4034 case OPC_PINSRH_0:
4035 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4036 break;
4037 case OPC_PINSRH_1:
4038 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4039 break;
4040 case OPC_PINSRH_2:
4041 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4042 break;
4043 case OPC_PINSRH_3:
4044 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4045 break;
4046
4047 case OPC_PEXTRH:
4048 tcg_gen_andi_i64(t1, t1, 3);
4049 tcg_gen_shli_i64(t1, t1, 4);
4050 tcg_gen_shr_i64(t0, t0, t1);
4051 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4052 break;
4053
4054 case OPC_ADDU_CP2:
4055 tcg_gen_add_i64(t0, t0, t1);
4056 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4057 break;
4058 case OPC_SUBU_CP2:
4059 tcg_gen_sub_i64(t0, t0, t1);
4060 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4061 break;
4062
4063 case OPC_SLL_CP2:
bd277fa1
RH
4064 shift_max = 32;
4065 goto do_shift;
4066 case OPC_SRL_CP2:
bd277fa1
RH
4067 shift_max = 32;
4068 goto do_shift;
4069 case OPC_SRA_CP2:
bd277fa1
RH
4070 shift_max = 32;
4071 goto do_shift;
4072 case OPC_DSLL_CP2:
bd277fa1
RH
4073 shift_max = 64;
4074 goto do_shift;
4075 case OPC_DSRL_CP2:
bd277fa1
RH
4076 shift_max = 64;
4077 goto do_shift;
4078 case OPC_DSRA_CP2:
bd277fa1
RH
4079 shift_max = 64;
4080 goto do_shift;
4081 do_shift:
4082 /* Make sure shift count isn't TCG undefined behaviour. */
4083 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4084
4085 switch (opc) {
4086 case OPC_SLL_CP2:
4087 case OPC_DSLL_CP2:
4088 tcg_gen_shl_i64(t0, t0, t1);
4089 break;
4090 case OPC_SRA_CP2:
4091 case OPC_DSRA_CP2:
4092 /* Since SRA is UndefinedResult without sign-extended inputs,
4093 we can treat SRA and DSRA the same. */
4094 tcg_gen_sar_i64(t0, t0, t1);
4095 break;
4096 case OPC_SRL_CP2:
4097 /* We want to shift in zeros for SRL; zero-extend first. */
4098 tcg_gen_ext32u_i64(t0, t0);
4099 /* FALLTHRU */
4100 case OPC_DSRL_CP2:
4101 tcg_gen_shr_i64(t0, t0, t1);
4102 break;
4103 }
4104
4105 if (shift_max == 32) {
4106 tcg_gen_ext32s_i64(t0, t0);
4107 }
4108
4109 /* Shifts larger than MAX produce zero. */
4110 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4111 tcg_gen_neg_i64(t1, t1);
4112 tcg_gen_and_i64(t0, t0, t1);
4113 break;
4114
4115 case OPC_ADD_CP2:
4116 case OPC_DADD_CP2:
4117 {
4118 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4119 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4120
4121 tcg_gen_mov_i64(t2, t0);
4122 tcg_gen_add_i64(t0, t1, t2);
4123 if (opc == OPC_ADD_CP2) {
4124 tcg_gen_ext32s_i64(t0, t0);
4125 }
4126 tcg_gen_xor_i64(t1, t1, t2);
4127 tcg_gen_xor_i64(t2, t2, t0);
4128 tcg_gen_andc_i64(t1, t2, t1);
4129 tcg_temp_free_i64(t2);
4130 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4131 generate_exception(ctx, EXCP_OVERFLOW);
4132 gen_set_label(lab);
bd277fa1
RH
4133 break;
4134 }
4135
4136 case OPC_SUB_CP2:
4137 case OPC_DSUB_CP2:
4138 {
4139 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4140 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4141
4142 tcg_gen_mov_i64(t2, t0);
4143 tcg_gen_sub_i64(t0, t1, t2);
4144 if (opc == OPC_SUB_CP2) {
4145 tcg_gen_ext32s_i64(t0, t0);
4146 }
4147 tcg_gen_xor_i64(t1, t1, t2);
4148 tcg_gen_xor_i64(t2, t2, t0);
4149 tcg_gen_and_i64(t1, t1, t2);
4150 tcg_temp_free_i64(t2);
4151 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4152 generate_exception(ctx, EXCP_OVERFLOW);
4153 gen_set_label(lab);
bd277fa1
RH
4154 break;
4155 }
4156
4157 case OPC_PMULUW:
4158 tcg_gen_ext32u_i64(t0, t0);
4159 tcg_gen_ext32u_i64(t1, t1);
4160 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4161 break;
4162
4163 case OPC_SEQU_CP2:
4164 case OPC_SEQ_CP2:
4165 case OPC_SLTU_CP2:
4166 case OPC_SLT_CP2:
4167 case OPC_SLEU_CP2:
4168 case OPC_SLE_CP2:
4169 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4170 FD field is the CC field? */
4171 default:
9d68ac14 4172 MIPS_INVAL("loongson_cp2");
9c708c7f 4173 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4174 return;
4175 }
4176
4177#undef LMI_HELPER
4178#undef LMI_DIRECT
4179
4180 gen_store_fpr64(ctx, t0, rd);
4181
bd277fa1
RH
4182 tcg_temp_free_i64(t0);
4183 tcg_temp_free_i64(t1);
4184}
4185
6af0bf9c 4186/* Traps */
7a387fff 4187static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4188 int rs, int rt, int16_t imm)
4189{
4190 int cond;
cdc0faa6 4191 TCGv t0 = tcg_temp_new();
1ba74fb8 4192 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4193
4194 cond = 0;
4195 /* Load needed operands */
4196 switch (opc) {
4197 case OPC_TEQ:
4198 case OPC_TGE:
4199 case OPC_TGEU:
4200 case OPC_TLT:
4201 case OPC_TLTU:
4202 case OPC_TNE:
4203 /* Compare two registers */
4204 if (rs != rt) {
be24bb4f
TS
4205 gen_load_gpr(t0, rs);
4206 gen_load_gpr(t1, rt);
6af0bf9c
FB
4207 cond = 1;
4208 }
179e32bb 4209 break;
6af0bf9c
FB
4210 case OPC_TEQI:
4211 case OPC_TGEI:
4212 case OPC_TGEIU:
4213 case OPC_TLTI:
4214 case OPC_TLTIU:
4215 case OPC_TNEI:
4216 /* Compare register to immediate */
4217 if (rs != 0 || imm != 0) {
be24bb4f
TS
4218 gen_load_gpr(t0, rs);
4219 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4220 cond = 1;
4221 }
4222 break;
4223 }
4224 if (cond == 0) {
4225 switch (opc) {
4226 case OPC_TEQ: /* rs == rs */
4227 case OPC_TEQI: /* r0 == 0 */
4228 case OPC_TGE: /* rs >= rs */
4229 case OPC_TGEI: /* r0 >= 0 */
4230 case OPC_TGEU: /* rs >= rs unsigned */
4231 case OPC_TGEIU: /* r0 >= 0 unsigned */
4232 /* Always trap */
9c708c7f 4233 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4234 break;
4235 case OPC_TLT: /* rs < rs */
4236 case OPC_TLTI: /* r0 < 0 */
4237 case OPC_TLTU: /* rs < rs unsigned */
4238 case OPC_TLTIU: /* r0 < 0 unsigned */
4239 case OPC_TNE: /* rs != rs */
4240 case OPC_TNEI: /* r0 != 0 */
ead9360e 4241 /* Never trap: treat as NOP. */
cdc0faa6 4242 break;
6af0bf9c
FB
4243 }
4244 } else {
42a268c2 4245 TCGLabel *l1 = gen_new_label();
cdc0faa6 4246
6af0bf9c
FB
4247 switch (opc) {
4248 case OPC_TEQ:
4249 case OPC_TEQI:
cdc0faa6 4250 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4251 break;
4252 case OPC_TGE:
4253 case OPC_TGEI:
cdc0faa6 4254 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4255 break;
4256 case OPC_TGEU:
4257 case OPC_TGEIU:
cdc0faa6 4258 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4259 break;
4260 case OPC_TLT:
4261 case OPC_TLTI:
cdc0faa6 4262 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4263 break;
4264 case OPC_TLTU:
4265 case OPC_TLTIU:
cdc0faa6 4266 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4267 break;
4268 case OPC_TNE:
4269 case OPC_TNEI:
cdc0faa6 4270 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4271 break;
6af0bf9c 4272 }
cdc0faa6 4273 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4274 gen_set_label(l1);
4275 }
be24bb4f
TS
4276 tcg_temp_free(t0);
4277 tcg_temp_free(t1);
6af0bf9c
FB
4278}
4279
90aa39a1
SF
4280static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4281{
4282 if (unlikely(ctx->singlestep_enabled)) {
4283 return false;
4284 }
4285
4286#ifndef CONFIG_USER_ONLY
4287 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4288#else
4289 return true;
4290#endif
4291}
4292
356265ae 4293static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4294{
90aa39a1 4295 if (use_goto_tb(ctx, dest)) {
57fec1fe 4296 tcg_gen_goto_tb(n);
9b9e4393 4297 gen_save_pc(dest);
90aa39a1 4298 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
6e256c93 4299 } else {
9b9e4393 4300 gen_save_pc(dest);
7b270ef2
NF
4301 if (ctx->singlestep_enabled) {
4302 save_cpu_state(ctx, 0);
9c708c7f 4303 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4304 }
d9a9acde 4305 tcg_gen_lookup_and_goto_ptr(cpu_PC);
6e256c93 4306 }
c53be334
FB
4307}
4308
6af0bf9c 4309/* Branches (before delay slot) */
7a387fff 4310static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4311 int insn_bytes,
b231c103
YK
4312 int rs, int rt, int32_t offset,
4313 int delayslot_size)
6af0bf9c 4314{
d077b6f7 4315 target_ulong btgt = -1;
3ad4bb2d 4316 int blink = 0;
2fdbad25 4317 int bcond_compute = 0;
1ba74fb8
AJ
4318 TCGv t0 = tcg_temp_new();
4319 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4320
4321 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4322#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4323 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4324 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4325#endif
9c708c7f 4326 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4327 goto out;
3ad4bb2d 4328 }
6af0bf9c 4329
6af0bf9c
FB
4330 /* Load needed operands */
4331 switch (opc) {
4332 case OPC_BEQ:
4333 case OPC_BEQL:
4334 case OPC_BNE:
4335 case OPC_BNEL:
4336 /* Compare two registers */
4337 if (rs != rt) {
6c5c1e20
TS
4338 gen_load_gpr(t0, rs);
4339 gen_load_gpr(t1, rt);
2fdbad25 4340 bcond_compute = 1;
6af0bf9c 4341 }
7dca4ad0 4342 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4343 break;
4344 case OPC_BGEZ:
4345 case OPC_BGEZAL:
4346 case OPC_BGEZALL:
4347 case OPC_BGEZL:
4348 case OPC_BGTZ:
4349 case OPC_BGTZL:
4350 case OPC_BLEZ:
4351 case OPC_BLEZL:
4352 case OPC_BLTZ:
4353 case OPC_BLTZAL:
4354 case OPC_BLTZALL:
4355 case OPC_BLTZL:
4356 /* Compare to zero */
4357 if (rs != 0) {
6c5c1e20 4358 gen_load_gpr(t0, rs);
2fdbad25 4359 bcond_compute = 1;
6af0bf9c 4360 }
7dca4ad0 4361 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4362 break;
e45a93e2
JL
4363 case OPC_BPOSGE32:
4364#if defined(TARGET_MIPS64)
4365 case OPC_BPOSGE64:
4366 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4367#else
4368 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4369#endif
4370 bcond_compute = 1;
4371 btgt = ctx->pc + insn_bytes + offset;
4372 break;
6af0bf9c
FB
4373 case OPC_J:
4374 case OPC_JAL:
364d4831 4375 case OPC_JALX:
6af0bf9c 4376 /* Jump to immediate */
7dca4ad0 4377 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4378 break;
4379 case OPC_JR:
4380 case OPC_JALR:
4381 /* Jump to register */
7a387fff
TS
4382 if (offset != 0 && offset != 16) {
4383 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4384 others are reserved. */
923617a3 4385 MIPS_INVAL("jump hint");
9c708c7f 4386 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4387 goto out;
6af0bf9c 4388 }
d077b6f7 4389 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4390 break;
4391 default:
4392 MIPS_INVAL("branch/jump");
9c708c7f 4393 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4394 goto out;
6af0bf9c 4395 }
2fdbad25 4396 if (bcond_compute == 0) {
6af0bf9c
FB
4397 /* No condition to be computed */
4398 switch (opc) {
4399 case OPC_BEQ: /* rx == rx */
4400 case OPC_BEQL: /* rx == rx likely */
4401 case OPC_BGEZ: /* 0 >= 0 */
4402 case OPC_BGEZL: /* 0 >= 0 likely */
4403 case OPC_BLEZ: /* 0 <= 0 */
4404 case OPC_BLEZL: /* 0 <= 0 likely */
4405 /* Always take */
4ad40f36 4406 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4407 break;
4408 case OPC_BGEZAL: /* 0 >= 0 */
4409 case OPC_BGEZALL: /* 0 >= 0 likely */
4410 /* Always take and link */
4411 blink = 31;
4ad40f36 4412 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4413 break;
4414 case OPC_BNE: /* rx != rx */
4415 case OPC_BGTZ: /* 0 > 0 */
4416 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4417 /* Treat as NOP. */
6c5c1e20 4418 goto out;
eeef26cd 4419 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4420 /* Handle as an unconditional branch to get correct delay
4421 slot checking. */
4422 blink = 31;
b231c103 4423 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4424 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4425 break;
eeef26cd 4426 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4427 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4428 /* Skip the instruction in the delay slot */
9898128f 4429 ctx->pc += 4;
6c5c1e20 4430 goto out;
6af0bf9c
FB
4431 case OPC_BNEL: /* rx != rx likely */
4432 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4433 case OPC_BLTZL: /* 0 < 0 likely */
4434 /* Skip the instruction in the delay slot */
9898128f 4435 ctx->pc += 4;
6c5c1e20 4436 goto out;
6af0bf9c 4437 case OPC_J:
4ad40f36 4438 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4439 break;
364d4831
NF
4440 case OPC_JALX:
4441 ctx->hflags |= MIPS_HFLAG_BX;
4442 /* Fallthrough */
6af0bf9c
FB
4443 case OPC_JAL:
4444 blink = 31;
4ad40f36 4445 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4446 break;
4447 case OPC_JR:
4ad40f36 4448 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4449 break;
4450 case OPC_JALR:
4451 blink = rt;
4ad40f36 4452 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4453 break;
4454 default:
4455 MIPS_INVAL("branch/jump");
9c708c7f 4456 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4457 goto out;
6af0bf9c
FB
4458 }
4459 } else {
4460 switch (opc) {
4461 case OPC_BEQ:
e68dd28f 4462 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4463 goto not_likely;
4464 case OPC_BEQL:
e68dd28f 4465 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4466 goto likely;
4467 case OPC_BNE:
e68dd28f 4468 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4469 goto not_likely;
4470 case OPC_BNEL:
e68dd28f 4471 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4472 goto likely;
4473 case OPC_BGEZ:
e68dd28f 4474 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4475 goto not_likely;
4476 case OPC_BGEZL:
e68dd28f 4477 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4478 goto likely;
4479 case OPC_BGEZAL:
e68dd28f 4480 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4481 blink = 31;
4482 goto not_likely;
4483 case OPC_BGEZALL:
e68dd28f 4484 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4485 blink = 31;
6af0bf9c
FB
4486 goto likely;
4487 case OPC_BGTZ:
e68dd28f 4488 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4489 goto not_likely;
4490 case OPC_BGTZL:
e68dd28f 4491 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4492 goto likely;
4493 case OPC_BLEZ:
e68dd28f 4494 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4495 goto not_likely;
4496 case OPC_BLEZL:
e68dd28f 4497 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4498 goto likely;
4499 case OPC_BLTZ:
e68dd28f 4500 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4501 goto not_likely;
4502 case OPC_BLTZL:
e68dd28f 4503 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4504 goto likely;
e45a93e2
JL
4505 case OPC_BPOSGE32:
4506 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4507 goto not_likely;
4508#if defined(TARGET_MIPS64)
4509 case OPC_BPOSGE64:
4510 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4511 goto not_likely;
4512#endif
6af0bf9c 4513 case OPC_BLTZAL:
e68dd28f 4514 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4515 blink = 31;
6af0bf9c 4516 not_likely:
4ad40f36 4517 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4518 break;
4519 case OPC_BLTZALL:
e68dd28f 4520 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4521 blink = 31;
6af0bf9c 4522 likely:
4ad40f36 4523 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4524 break;
c53f4a62
TS
4525 default:
4526 MIPS_INVAL("conditional branch/jump");
9c708c7f 4527 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4528 goto out;
6af0bf9c 4529 }
6af0bf9c 4530 }
9b9e4393 4531
d077b6f7 4532 ctx->btarget = btgt;
b231c103
YK
4533
4534 switch (delayslot_size) {
4535 case 2:
4536 ctx->hflags |= MIPS_HFLAG_BDS16;
4537 break;
4538 case 4:
4539 ctx->hflags |= MIPS_HFLAG_BDS32;
4540 break;
4541 }
4542
6af0bf9c 4543 if (blink > 0) {
b231c103 4544 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4545 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4546
364d4831 4547 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4548 }
6c5c1e20
TS
4549
4550 out:
364d4831
NF
4551 if (insn_bytes == 2)
4552 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4553 tcg_temp_free(t0);
4554 tcg_temp_free(t1);
6af0bf9c
FB
4555}
4556
7a387fff
TS
4557/* special3 bitfield operations */
4558static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4559 int rs, int lsb, int msb)
7a387fff 4560{
a7812ae4
PB
4561 TCGv t0 = tcg_temp_new();
4562 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4563
4564 gen_load_gpr(t1, rs);
7a387fff
TS
4565 switch (opc) {
4566 case OPC_EXT:
b7f26e52 4567 if (lsb + msb > 31) {
7a387fff 4568 goto fail;
b7f26e52 4569 }
505ad7c2 4570 if (msb != 31) {
6eebb7a4 4571 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 4572 } else {
6eebb7a4
RH
4573 /* The two checks together imply that lsb == 0,
4574 so this is a simple sign-extension. */
4575 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 4576 }
7a387fff 4577 break;
c6d6dd7c 4578#if defined(TARGET_MIPS64)
7a387fff 4579 case OPC_DEXTU:
b7f26e52
RH
4580 lsb += 32;
4581 goto do_dext;
4582 case OPC_DEXTM:
4583 msb += 32;
4584 goto do_dext;
7a387fff 4585 case OPC_DEXT:
b7f26e52
RH
4586 do_dext:
4587 if (lsb + msb > 63) {
4588 goto fail;
4589 }
6eebb7a4 4590 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 4591 break;
c6d6dd7c 4592#endif
7a387fff 4593 case OPC_INS:
b7f26e52 4594 if (lsb > msb) {
7a387fff 4595 goto fail;
b7f26e52 4596 }
6c5c1e20 4597 gen_load_gpr(t0, rt);
e0d002f1 4598 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4599 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4600 break;
c6d6dd7c 4601#if defined(TARGET_MIPS64)
7a387fff 4602 case OPC_DINSU:
b7f26e52
RH
4603 lsb += 32;
4604 /* FALLTHRU */
4605 case OPC_DINSM:
4606 msb += 32;
4607 /* FALLTHRU */
7a387fff 4608 case OPC_DINS:
b7f26e52
RH
4609 if (lsb > msb) {
4610 goto fail;
4611 }
6c5c1e20 4612 gen_load_gpr(t0, rt);
e0d002f1 4613 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4614 break;
c6d6dd7c 4615#endif
7a387fff
TS
4616 default:
4617fail:
4618 MIPS_INVAL("bitops");
9c708c7f 4619 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4620 tcg_temp_free(t0);
4621 tcg_temp_free(t1);
7a387fff
TS
4622 return;
4623 }
6c5c1e20
TS
4624 gen_store_gpr(t0, rt);
4625 tcg_temp_free(t0);
4626 tcg_temp_free(t1);
7a387fff
TS
4627}
4628
49bcf33c
AJ
4629static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4630{
3a55fa47 4631 TCGv t0;
49bcf33c 4632
3a55fa47
AJ
4633 if (rd == 0) {
4634 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4635 return;
4636 }
4637
4638 t0 = tcg_temp_new();
4639 gen_load_gpr(t0, rt);
49bcf33c
AJ
4640 switch (op2) {
4641 case OPC_WSBH:
3a55fa47
AJ
4642 {
4643 TCGv t1 = tcg_temp_new();
06a57e5c 4644 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
4645
4646 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4647 tcg_gen_and_tl(t1, t1, t2);
4648 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4649 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4650 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 4651 tcg_temp_free(t2);
3a55fa47
AJ
4652 tcg_temp_free(t1);
4653 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4654 }
49bcf33c
AJ
4655 break;
4656 case OPC_SEB:
3a55fa47 4657 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4658 break;
4659 case OPC_SEH:
3a55fa47 4660 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4661 break;
4662#if defined(TARGET_MIPS64)
4663 case OPC_DSBH:
3a55fa47
AJ
4664 {
4665 TCGv t1 = tcg_temp_new();
06a57e5c 4666 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
4667
4668 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4669 tcg_gen_and_tl(t1, t1, t2);
4670 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4671 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4672 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4673 tcg_temp_free(t2);
3a55fa47
AJ
4674 tcg_temp_free(t1);
4675 }
49bcf33c
AJ
4676 break;
4677 case OPC_DSHD:
3a55fa47
AJ
4678 {
4679 TCGv t1 = tcg_temp_new();
06a57e5c 4680 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
4681
4682 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
4683 tcg_gen_and_tl(t1, t1, t2);
4684 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4685 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
4686 tcg_gen_or_tl(t0, t0, t1);
4687 tcg_gen_shri_tl(t1, t0, 32);
4688 tcg_gen_shli_tl(t0, t0, 32);
4689 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4690 tcg_temp_free(t2);
3a55fa47
AJ
4691 tcg_temp_free(t1);
4692 }
49bcf33c
AJ
4693 break;
4694#endif
4695 default:
4696 MIPS_INVAL("bsfhl");
9c708c7f 4697 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4698 tcg_temp_free(t0);
49bcf33c
AJ
4699 return;
4700 }
49bcf33c 4701 tcg_temp_free(t0);
49bcf33c
AJ
4702}
4703
1f1b4c00
YK
4704static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4705 int imm2)
4706{
4707 TCGv t0;
4708 TCGv t1;
4709 if (rd == 0) {
4710 /* Treat as NOP. */
4711 return;
4712 }
4713 t0 = tcg_temp_new();
4714 t1 = tcg_temp_new();
4715 gen_load_gpr(t0, rs);
4716 gen_load_gpr(t1, rt);
4717 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4718 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4719 if (opc == OPC_LSA) {
4720 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4721 }
4722
4723 tcg_temp_free(t1);
4724 tcg_temp_free(t0);
4725
4726 return;
4727}
4728
4729static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4730 int bp)
284b731a 4731{
1f1b4c00
YK
4732 TCGv t0;
4733 if (rd == 0) {
4734 /* Treat as NOP. */
4735 return;
4736 }
4737 t0 = tcg_temp_new();
4738 gen_load_gpr(t0, rt);
4739 if (bp == 0) {
51243852
MD
4740 switch (opc) {
4741 case OPC_ALIGN:
4742 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4743 break;
4744#if defined(TARGET_MIPS64)
4745 case OPC_DALIGN:
4746 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4747 break;
4748#endif
4749 }
1f1b4c00
YK
4750 } else {
4751 TCGv t1 = tcg_temp_new();
4752 gen_load_gpr(t1, rs);
4753 switch (opc) {
4754 case OPC_ALIGN:
4755 {
4756 TCGv_i64 t2 = tcg_temp_new_i64();
4757 tcg_gen_concat_tl_i64(t2, t1, t0);
4758 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4759 gen_move_low32(cpu_gpr[rd], t2);
4760 tcg_temp_free_i64(t2);
4761 }
4762 break;
284b731a 4763#if defined(TARGET_MIPS64)
1f1b4c00
YK
4764 case OPC_DALIGN:
4765 tcg_gen_shli_tl(t0, t0, 8 * bp);
4766 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4767 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4768 break;
284b731a 4769#endif
1f1b4c00
YK
4770 }
4771 tcg_temp_free(t1);
4772 }
4773
4774 tcg_temp_free(t0);
4775}
4776
4777static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4778{
4779 TCGv t0;
4780 if (rd == 0) {
4781 /* Treat as NOP. */
4782 return;
4783 }
4784 t0 = tcg_temp_new();
4785 gen_load_gpr(t0, rt);
4786 switch (opc) {
4787 case OPC_BITSWAP:
4788 gen_helper_bitswap(cpu_gpr[rd], t0);
4789 break;
4790#if defined(TARGET_MIPS64)
4791 case OPC_DBITSWAP:
4792 gen_helper_dbitswap(cpu_gpr[rd], t0);
4793 break;
4794#endif
4795 }
4796 tcg_temp_free(t0);
284b731a
LA
4797}
4798
1f1b4c00
YK
4799#ifndef CONFIG_USER_ONLY
4800/* CP0 (MMU and control) */
5204ea79
LA
4801static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4802{
4803 TCGv_i64 t0 = tcg_temp_new_i64();
4804 TCGv_i64 t1 = tcg_temp_new_i64();
4805
4806 tcg_gen_ext_tl_i64(t0, arg);
4807 tcg_gen_ld_i64(t1, cpu_env, off);
4808#if defined(TARGET_MIPS64)
4809 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4810#else
4811 tcg_gen_concat32_i64(t1, t1, t0);
4812#endif
4813 tcg_gen_st_i64(t1, cpu_env, off);
4814 tcg_temp_free_i64(t1);
4815 tcg_temp_free_i64(t0);
4816}
4817
4818static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4819{
4820 TCGv_i64 t0 = tcg_temp_new_i64();
4821 TCGv_i64 t1 = tcg_temp_new_i64();
4822
4823 tcg_gen_ext_tl_i64(t0, arg);
4824 tcg_gen_ld_i64(t1, cpu_env, off);
4825 tcg_gen_concat32_i64(t1, t1, t0);
4826 tcg_gen_st_i64(t1, cpu_env, off);
4827 tcg_temp_free_i64(t1);
4828 tcg_temp_free_i64(t0);
4829}
4830
4831static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4832{
4833 TCGv_i64 t0 = tcg_temp_new_i64();
4834
4835 tcg_gen_ld_i64(t0, cpu_env, off);
4836#if defined(TARGET_MIPS64)
4837 tcg_gen_shri_i64(t0, t0, 30);
4838#else
4839 tcg_gen_shri_i64(t0, t0, 32);
4840#endif
4841 gen_move_low32(arg, t0);
4842 tcg_temp_free_i64(t0);
4843}
4844
4845static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4846{
4847 TCGv_i64 t0 = tcg_temp_new_i64();
4848
4849 tcg_gen_ld_i64(t0, cpu_env, off);
4850 tcg_gen_shri_i64(t0, t0, 32 + shift);
4851 gen_move_low32(arg, t0);
4852 tcg_temp_free_i64(t0);
4853}
4854
d9bea114 4855static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4856{
d9bea114 4857 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4858
d9bea114
AJ
4859 tcg_gen_ld_i32(t0, cpu_env, off);
4860 tcg_gen_ext_i32_tl(arg, t0);
4861 tcg_temp_free_i32(t0);
4f57689a
TS
4862}
4863
d9bea114 4864static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4865{
d9bea114
AJ
4866 tcg_gen_ld_tl(arg, cpu_env, off);
4867 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4868}
4869
d9bea114 4870static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4871{
d9bea114 4872 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4873
d9bea114
AJ
4874 tcg_gen_trunc_tl_i32(t0, arg);
4875 tcg_gen_st_i32(t0, cpu_env, off);
4876 tcg_temp_free_i32(t0);
f1aa6320
TS
4877}
4878
c98d3d79
YK
4879#define CP0_CHECK(c) \
4880 do { \
4881 if (!(c)) { \
4882 goto cp0_unimplemented; \
4883 } \
4884 } while (0)
4885
5204ea79
LA
4886static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4887{
4888 const char *rn = "invalid";
4889
c98d3d79 4890 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4891
4892 switch (reg) {
4893 case 2:
4894 switch (sel) {
4895 case 0:
4896 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4897 rn = "EntryLo0";
4898 break;
4899 default:
c98d3d79 4900 goto cp0_unimplemented;
5204ea79
LA
4901 }
4902 break;
4903 case 3:
4904 switch (sel) {
4905 case 0:
4906 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4907 rn = "EntryLo1";
4908 break;
4909 default:
c98d3d79 4910 goto cp0_unimplemented;
5204ea79
LA
4911 }
4912 break;
4913 case 17:
4914 switch (sel) {
4915 case 0:
4916 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4917 ctx->CP0_LLAddr_shift);
4918 rn = "LLAddr";
4919 break;
f6d4dd81
YK
4920 case 1:
4921 CP0_CHECK(ctx->mrp);
4922 gen_helper_mfhc0_maar(arg, cpu_env);
4923 rn = "MAAR";
4924 break;
5204ea79 4925 default:
c98d3d79 4926 goto cp0_unimplemented;
5204ea79
LA
4927 }
4928 break;
4929 case 28:
4930 switch (sel) {
4931 case 0:
4932 case 2:
4933 case 4:
4934 case 6:
4935 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4936 rn = "TagLo";
4937 break;
4938 default:
c98d3d79 4939 goto cp0_unimplemented;
5204ea79
LA
4940 }
4941 break;
4942 default:
c98d3d79 4943 goto cp0_unimplemented;
5204ea79 4944 }
b44a7fb1 4945 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
4946 return;
4947
c98d3d79 4948cp0_unimplemented:
965447ee 4949 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
4950 tcg_gen_movi_tl(arg, 0);
4951}
4952
4953static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4954{
4955 const char *rn = "invalid";
4956 uint64_t mask = ctx->PAMask >> 36;
4957
c98d3d79 4958 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4959
4960 switch (reg) {
4961 case 2:
4962 switch (sel) {
4963 case 0:
4964 tcg_gen_andi_tl(arg, arg, mask);
4965 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4966 rn = "EntryLo0";
4967 break;
4968 default:
c98d3d79 4969 goto cp0_unimplemented;
5204ea79
LA
4970 }
4971 break;
4972 case 3:
4973 switch (sel) {
4974 case 0:
4975 tcg_gen_andi_tl(arg, arg, mask);
4976 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4977 rn = "EntryLo1";
4978 break;
4979 default:
c98d3d79 4980 goto cp0_unimplemented;
5204ea79
LA
4981 }
4982 break;
4983 case 17:
4984 switch (sel) {
4985 case 0:
4986 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4987 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4988 relevant for modern MIPS cores supporting MTHC0, therefore
4989 treating MTHC0 to LLAddr as NOP. */
4990 rn = "LLAddr";
4991 break;
f6d4dd81
YK
4992 case 1:
4993 CP0_CHECK(ctx->mrp);
4994 gen_helper_mthc0_maar(cpu_env, arg);
4995 rn = "MAAR";
4996 break;
5204ea79 4997 default:
c98d3d79 4998 goto cp0_unimplemented;
5204ea79
LA
4999 }
5000 break;
5001 case 28:
5002 switch (sel) {
5003 case 0:
5004 case 2:
5005 case 4:
5006 case 6:
5007 tcg_gen_andi_tl(arg, arg, mask);
5008 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5009 rn = "TagLo";
5010 break;
5011 default:
c98d3d79 5012 goto cp0_unimplemented;
5204ea79
LA
5013 }
5014 break;
5015 default:
c98d3d79 5016 goto cp0_unimplemented;
5204ea79 5017 }
b44a7fb1 5018 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 5019
c98d3d79 5020cp0_unimplemented:
965447ee 5021 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5022}
5023
e98c0d17
LA
5024static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5025{
5026 if (ctx->insn_flags & ISA_MIPS32R6) {
5027 tcg_gen_movi_tl(arg, 0);
5028 } else {
5029 tcg_gen_movi_tl(arg, ~0);
5030 }
5031}
5032
d75c135e 5033static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5034{
7a387fff 5035 const char *rn = "invalid";
873eb012 5036
e189e748 5037 if (sel != 0)
d75c135e 5038 check_insn(ctx, ISA_MIPS32);
e189e748 5039
873eb012
TS
5040 switch (reg) {
5041 case 0:
7a387fff
TS
5042 switch (sel) {
5043 case 0:
7db13fae 5044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
5045 rn = "Index";
5046 break;
5047 case 1:
f31b035a 5048 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5049 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 5050 rn = "MVPControl";
ead9360e 5051 break;
7a387fff 5052 case 2:
f31b035a 5053 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5054 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 5055 rn = "MVPConf0";
ead9360e 5056 break;
7a387fff 5057 case 3:
f31b035a 5058 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5059 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 5060 rn = "MVPConf1";
ead9360e 5061 break;
01bc435b
YK
5062 case 4:
5063 CP0_CHECK(ctx->vp);
5064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5065 rn = "VPControl";
5066 break;
7a387fff 5067 default:
f31b035a 5068 goto cp0_unimplemented;
7a387fff 5069 }
873eb012
TS
5070 break;
5071 case 1:
7a387fff
TS
5072 switch (sel) {
5073 case 0:
f31b035a 5074 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5075 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5076 rn = "Random";
2423f660 5077 break;
7a387fff 5078 case 1:
f31b035a 5079 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5081 rn = "VPEControl";
ead9360e 5082 break;
7a387fff 5083 case 2:
f31b035a 5084 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5086 rn = "VPEConf0";
ead9360e 5087 break;
7a387fff 5088 case 3:
f31b035a 5089 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5091 rn = "VPEConf1";
ead9360e 5092 break;
7a387fff 5093 case 4:
f31b035a 5094 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5095 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5096 rn = "YQMask";
ead9360e 5097 break;
7a387fff 5098 case 5:
f31b035a 5099 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5100 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5101 rn = "VPESchedule";
ead9360e 5102 break;
7a387fff 5103 case 6:
f31b035a 5104 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5105 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5106 rn = "VPEScheFBack";
ead9360e 5107 break;
7a387fff 5108 case 7:
f31b035a 5109 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5110 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5111 rn = "VPEOpt";
ead9360e 5112 break;
7a387fff 5113 default:
f31b035a 5114 goto cp0_unimplemented;
7a387fff 5115 }
873eb012
TS
5116 break;
5117 case 2:
7a387fff
TS
5118 switch (sel) {
5119 case 0:
284b731a
LA
5120 {
5121 TCGv_i64 tmp = tcg_temp_new_i64();
5122 tcg_gen_ld_i64(tmp, cpu_env,
5123 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5124#if defined(TARGET_MIPS64)
284b731a
LA
5125 if (ctx->rxi) {
5126 /* Move RI/XI fields to bits 31:30 */
5127 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5128 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5129 }
7207c7f9 5130#endif
284b731a
LA
5131 gen_move_low32(arg, tmp);
5132 tcg_temp_free_i64(tmp);
5133 }
2423f660
TS
5134 rn = "EntryLo0";
5135 break;
7a387fff 5136 case 1:
f31b035a 5137 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5138 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5139 rn = "TCStatus";
ead9360e 5140 break;
7a387fff 5141 case 2:
f31b035a 5142 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5143 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5144 rn = "TCBind";
ead9360e 5145 break;
7a387fff 5146 case 3:
f31b035a 5147 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5148 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5149 rn = "TCRestart";
ead9360e 5150 break;
7a387fff 5151 case 4:
f31b035a 5152 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5153 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5154 rn = "TCHalt";
ead9360e 5155 break;
7a387fff 5156 case 5:
f31b035a 5157 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5158 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5159 rn = "TCContext";
ead9360e 5160 break;
7a387fff 5161 case 6:
f31b035a 5162 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5163 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5164 rn = "TCSchedule";
ead9360e 5165 break;
7a387fff 5166 case 7:
f31b035a 5167 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5168 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5169 rn = "TCScheFBack";
ead9360e 5170 break;
7a387fff 5171 default:
f31b035a 5172 goto cp0_unimplemented;
7a387fff 5173 }
873eb012
TS
5174 break;
5175 case 3:
7a387fff
TS
5176 switch (sel) {
5177 case 0:
284b731a
LA
5178 {
5179 TCGv_i64 tmp = tcg_temp_new_i64();
5180 tcg_gen_ld_i64(tmp, cpu_env,
5181 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5182#if defined(TARGET_MIPS64)
284b731a
LA
5183 if (ctx->rxi) {
5184 /* Move RI/XI fields to bits 31:30 */
5185 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5186 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5187 }
7207c7f9 5188#endif
284b731a
LA
5189 gen_move_low32(arg, tmp);
5190 tcg_temp_free_i64(tmp);
5191 }
2423f660
TS
5192 rn = "EntryLo1";
5193 break;
01bc435b
YK
5194 case 1:
5195 CP0_CHECK(ctx->vp);
5196 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5197 rn = "GlobalNumber";
5198 break;
7a387fff 5199 default:
f31b035a 5200 goto cp0_unimplemented;
1579a72e 5201 }
873eb012
TS
5202 break;
5203 case 4:
7a387fff
TS
5204 switch (sel) {
5205 case 0:
7db13fae 5206 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5207 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5208 rn = "Context";
5209 break;
7a387fff 5210 case 1:
d9bea114 5211// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5212 rn = "ContextConfig";
f31b035a 5213 goto cp0_unimplemented;
d279279e 5214 case 2:
f31b035a 5215 CP0_CHECK(ctx->ulri);
e40df9a8
JH
5216 tcg_gen_ld_tl(arg, cpu_env,
5217 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5218 tcg_gen_ext32s_tl(arg, arg);
f31b035a 5219 rn = "UserLocal";
d279279e 5220 break;
7a387fff 5221 default:
f31b035a 5222 goto cp0_unimplemented;
1579a72e 5223 }
873eb012
TS
5224 break;
5225 case 5:
7a387fff
TS
5226 switch (sel) {
5227 case 0:
7db13fae 5228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5229 rn = "PageMask";
5230 break;
7a387fff 5231 case 1:
d75c135e 5232 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5234 rn = "PageGrain";
5235 break;
cec56a73
JH
5236 case 2:
5237 CP0_CHECK(ctx->sc);
5238 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5239 tcg_gen_ext32s_tl(arg, arg);
5240 rn = "SegCtl0";
5241 break;
5242 case 3:
5243 CP0_CHECK(ctx->sc);
5244 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5245 tcg_gen_ext32s_tl(arg, arg);
5246 rn = "SegCtl1";
5247 break;
5248 case 4:
5249 CP0_CHECK(ctx->sc);
5250 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5251 tcg_gen_ext32s_tl(arg, arg);
5252 rn = "SegCtl2";
5253 break;
7a387fff 5254 default:
f31b035a 5255 goto cp0_unimplemented;
1579a72e 5256 }
873eb012
TS
5257 break;
5258 case 6:
7a387fff
TS
5259 switch (sel) {
5260 case 0:
7db13fae 5261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5262 rn = "Wired";
5263 break;
7a387fff 5264 case 1:
d75c135e 5265 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5267 rn = "SRSConf0";
ead9360e 5268 break;
7a387fff 5269 case 2:
d75c135e 5270 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5272 rn = "SRSConf1";
ead9360e 5273 break;
7a387fff 5274 case 3:
d75c135e 5275 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5277 rn = "SRSConf2";
ead9360e 5278 break;
7a387fff 5279 case 4:
d75c135e 5280 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5282 rn = "SRSConf3";
ead9360e 5283 break;
7a387fff 5284 case 5:
d75c135e 5285 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5287 rn = "SRSConf4";
ead9360e 5288 break;
7a387fff 5289 default:
f31b035a 5290 goto cp0_unimplemented;
1579a72e 5291 }
873eb012 5292 break;
8c0fdd85 5293 case 7:
7a387fff
TS
5294 switch (sel) {
5295 case 0:
d75c135e 5296 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5298 rn = "HWREna";
5299 break;
7a387fff 5300 default:
f31b035a 5301 goto cp0_unimplemented;
1579a72e 5302 }
8c0fdd85 5303 break;
873eb012 5304 case 8:
7a387fff
TS
5305 switch (sel) {
5306 case 0:
7db13fae 5307 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5308 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5309 rn = "BadVAddr";
2423f660 5310 break;
aea14095 5311 case 1:
f31b035a
LA
5312 CP0_CHECK(ctx->bi);
5313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5314 rn = "BadInstr";
aea14095
LA
5315 break;
5316 case 2:
f31b035a
LA
5317 CP0_CHECK(ctx->bp);
5318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5319 rn = "BadInstrP";
aea14095 5320 break;
7a387fff 5321 default:
f31b035a 5322 goto cp0_unimplemented;
aea14095 5323 }
873eb012
TS
5324 break;
5325 case 9:
7a387fff
TS
5326 switch (sel) {
5327 case 0:
2e70f6ef 5328 /* Mark as an IO operation because we read the time. */
bd79255d 5329 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5330 gen_io_start();
bd79255d 5331 }
895c2d04 5332 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5333 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5334 gen_io_end();
2e70f6ef 5335 }
55807224 5336 /* Break the TB to be able to take timer interrupts immediately
b74cddcb
JH
5337 after reading count. BS_STOP isn't sufficient, we need to ensure
5338 we break completely out of translated code. */
5339 gen_save_pc(ctx->pc + 4);
5340 ctx->bstate = BS_EXCP;
2423f660
TS
5341 rn = "Count";
5342 break;
5343 /* 6,7 are implementation dependent */
7a387fff 5344 default:
f31b035a 5345 goto cp0_unimplemented;
2423f660 5346 }
873eb012
TS
5347 break;
5348 case 10:
7a387fff
TS
5349 switch (sel) {
5350 case 0:
7db13fae 5351 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5352 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5353 rn = "EntryHi";
5354 break;
7a387fff 5355 default:
f31b035a 5356 goto cp0_unimplemented;
1579a72e 5357 }
873eb012
TS
5358 break;
5359 case 11:
7a387fff
TS
5360 switch (sel) {
5361 case 0:
7db13fae 5362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5363 rn = "Compare";
5364 break;
5365 /* 6,7 are implementation dependent */
7a387fff 5366 default:
f31b035a 5367 goto cp0_unimplemented;
2423f660 5368 }
873eb012
TS
5369 break;
5370 case 12:
7a387fff
TS
5371 switch (sel) {
5372 case 0:
7db13fae 5373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5374 rn = "Status";
5375 break;
7a387fff 5376 case 1:
d75c135e 5377 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5379 rn = "IntCtl";
5380 break;
7a387fff 5381 case 2:
d75c135e 5382 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5384 rn = "SRSCtl";
5385 break;
7a387fff 5386 case 3:
d75c135e 5387 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5389 rn = "SRSMap";
fd88b6ab 5390 break;
7a387fff 5391 default:
f31b035a 5392 goto cp0_unimplemented;
7a387fff 5393 }
873eb012
TS
5394 break;
5395 case 13:
7a387fff
TS
5396 switch (sel) {
5397 case 0:
7db13fae 5398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5399 rn = "Cause";
5400 break;
7a387fff 5401 default:
f31b035a 5402 goto cp0_unimplemented;
7a387fff 5403 }
873eb012
TS
5404 break;
5405 case 14:
7a387fff
TS
5406 switch (sel) {
5407 case 0:
7db13fae 5408 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5409 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5410 rn = "EPC";
5411 break;
7a387fff 5412 default:
f31b035a 5413 goto cp0_unimplemented;
1579a72e 5414 }
873eb012
TS
5415 break;
5416 case 15:
7a387fff
TS
5417 switch (sel) {
5418 case 0:
7db13fae 5419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5420 rn = "PRid";
5421 break;
7a387fff 5422 case 1:
d75c135e 5423 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
5424 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5425 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5426 rn = "EBase";
5427 break;
c870e3f5
YK
5428 case 3:
5429 check_insn(ctx, ISA_MIPS32R2);
5430 CP0_CHECK(ctx->cmgcr);
5431 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5432 tcg_gen_ext32s_tl(arg, arg);
5433 rn = "CMGCRBase";
5434 break;
7a387fff 5435 default:
f31b035a 5436 goto cp0_unimplemented;
7a387fff 5437 }
873eb012
TS
5438 break;
5439 case 16:
5440 switch (sel) {
5441 case 0:
7db13fae 5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5443 rn = "Config";
5444 break;
5445 case 1:
7db13fae 5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5447 rn = "Config1";
5448 break;
7a387fff 5449 case 2:
7db13fae 5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5451 rn = "Config2";
5452 break;
5453 case 3:
7db13fae 5454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5455 rn = "Config3";
5456 break;
b4160af1
PJ
5457 case 4:
5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5459 rn = "Config4";
5460 break;
b4dd99a3
PJ
5461 case 5:
5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5463 rn = "Config5";
5464 break;
e397ee33
TS
5465 /* 6,7 are implementation dependent */
5466 case 6:
7db13fae 5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5468 rn = "Config6";
5469 break;
5470 case 7:
7db13fae 5471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5472 rn = "Config7";
5473 break;
873eb012 5474 default:
f31b035a 5475 goto cp0_unimplemented;
873eb012
TS
5476 }
5477 break;
5478 case 17:
7a387fff
TS
5479 switch (sel) {
5480 case 0:
895c2d04 5481 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5482 rn = "LLAddr";
5483 break;
f6d4dd81
YK
5484 case 1:
5485 CP0_CHECK(ctx->mrp);
5486 gen_helper_mfc0_maar(arg, cpu_env);
5487 rn = "MAAR";
5488 break;
5489 case 2:
5490 CP0_CHECK(ctx->mrp);
5491 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5492 rn = "MAARI";
5493 break;
7a387fff 5494 default:
f31b035a 5495 goto cp0_unimplemented;
7a387fff 5496 }
873eb012
TS
5497 break;
5498 case 18:
7a387fff 5499 switch (sel) {
fd88b6ab 5500 case 0 ... 7:
895c2d04 5501 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5502 rn = "WatchLo";
5503 break;
7a387fff 5504 default:
f31b035a 5505 goto cp0_unimplemented;
7a387fff 5506 }
873eb012
TS
5507 break;
5508 case 19:
7a387fff 5509 switch (sel) {
fd88b6ab 5510 case 0 ...7:
895c2d04 5511 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5512 rn = "WatchHi";
5513 break;
7a387fff 5514 default:
f31b035a 5515 goto cp0_unimplemented;
7a387fff 5516 }
873eb012 5517 break;
8c0fdd85 5518 case 20:
7a387fff
TS
5519 switch (sel) {
5520 case 0:
d26bc211 5521#if defined(TARGET_MIPS64)
d75c135e 5522 check_insn(ctx, ISA_MIPS3);
7db13fae 5523 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5524 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5525 rn = "XContext";
5526 break;
703eaf37 5527#endif
7a387fff 5528 default:
f31b035a 5529 goto cp0_unimplemented;
7a387fff 5530 }
8c0fdd85
TS
5531 break;
5532 case 21:
7a387fff 5533 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5534 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5535 switch (sel) {
5536 case 0:
7db13fae 5537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5538 rn = "Framemask";
5539 break;
7a387fff 5540 default:
f31b035a 5541 goto cp0_unimplemented;
7a387fff 5542 }
8c0fdd85
TS
5543 break;
5544 case 22:
d9bea114 5545 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5546 rn = "'Diagnostic"; /* implementation dependent */
5547 break;
873eb012 5548 case 23:
7a387fff
TS
5549 switch (sel) {
5550 case 0:
895c2d04 5551 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5552 rn = "Debug";
5553 break;
7a387fff 5554 case 1:
d9bea114 5555// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 5556 rn = "TraceControl";
3570d7f6 5557 goto cp0_unimplemented;
7a387fff 5558 case 2:
d9bea114 5559// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 5560 rn = "TraceControl2";
3570d7f6 5561 goto cp0_unimplemented;
7a387fff 5562 case 3:
d9bea114 5563// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 5564 rn = "UserTraceData";
3570d7f6 5565 goto cp0_unimplemented;
7a387fff 5566 case 4:
d9bea114 5567// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 5568 rn = "TraceBPC";
3570d7f6 5569 goto cp0_unimplemented;
7a387fff 5570 default:
f31b035a 5571 goto cp0_unimplemented;
7a387fff 5572 }
873eb012
TS
5573 break;
5574 case 24:
7a387fff
TS
5575 switch (sel) {
5576 case 0:
f0b3f3ae 5577 /* EJTAG support */
7db13fae 5578 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5579 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5580 rn = "DEPC";
5581 break;
7a387fff 5582 default:
f31b035a 5583 goto cp0_unimplemented;
7a387fff 5584 }
873eb012 5585 break;
8c0fdd85 5586 case 25:
7a387fff
TS
5587 switch (sel) {
5588 case 0:
7db13fae 5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5590 rn = "Performance0";
7a387fff
TS
5591 break;
5592 case 1:
d9bea114 5593// gen_helper_mfc0_performance1(arg);
2423f660 5594 rn = "Performance1";
3570d7f6 5595 goto cp0_unimplemented;
7a387fff 5596 case 2:
d9bea114 5597// gen_helper_mfc0_performance2(arg);
2423f660 5598 rn = "Performance2";
3570d7f6 5599 goto cp0_unimplemented;
7a387fff 5600 case 3:
d9bea114 5601// gen_helper_mfc0_performance3(arg);
2423f660 5602 rn = "Performance3";
3570d7f6 5603 goto cp0_unimplemented;
7a387fff 5604 case 4:
d9bea114 5605// gen_helper_mfc0_performance4(arg);
2423f660 5606 rn = "Performance4";
3570d7f6 5607 goto cp0_unimplemented;
7a387fff 5608 case 5:
d9bea114 5609// gen_helper_mfc0_performance5(arg);
2423f660 5610 rn = "Performance5";
3570d7f6 5611 goto cp0_unimplemented;
7a387fff 5612 case 6:
d9bea114 5613// gen_helper_mfc0_performance6(arg);
2423f660 5614 rn = "Performance6";
3570d7f6 5615 goto cp0_unimplemented;
7a387fff 5616 case 7:
d9bea114 5617// gen_helper_mfc0_performance7(arg);
2423f660 5618 rn = "Performance7";
3570d7f6 5619 goto cp0_unimplemented;
7a387fff 5620 default:
f31b035a 5621 goto cp0_unimplemented;
7a387fff 5622 }
8c0fdd85
TS
5623 break;
5624 case 26:
0d74a222
LA
5625 switch (sel) {
5626 case 0:
5627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5628 rn = "ErrCtl";
5629 break;
5630 default:
5631 goto cp0_unimplemented;
5632 }
da80682b 5633 break;
8c0fdd85 5634 case 27:
7a387fff 5635 switch (sel) {
7a387fff 5636 case 0 ... 3:
d9bea114 5637 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5638 rn = "CacheErr";
5639 break;
7a387fff 5640 default:
f31b035a 5641 goto cp0_unimplemented;
7a387fff 5642 }
8c0fdd85 5643 break;
873eb012
TS
5644 case 28:
5645 switch (sel) {
5646 case 0:
7a387fff
TS
5647 case 2:
5648 case 4:
5649 case 6:
284b731a
LA
5650 {
5651 TCGv_i64 tmp = tcg_temp_new_i64();
5652 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5653 gen_move_low32(arg, tmp);
5654 tcg_temp_free_i64(tmp);
5655 }
873eb012
TS
5656 rn = "TagLo";
5657 break;
5658 case 1:
7a387fff
TS
5659 case 3:
5660 case 5:
5661 case 7:
7db13fae 5662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5663 rn = "DataLo";
5664 break;
5665 default:
f31b035a 5666 goto cp0_unimplemented;
873eb012
TS
5667 }
5668 break;
8c0fdd85 5669 case 29:
7a387fff
TS
5670 switch (sel) {
5671 case 0:
5672 case 2:
5673 case 4:
5674 case 6:
7db13fae 5675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5676 rn = "TagHi";
5677 break;
5678 case 1:
5679 case 3:
5680 case 5:
5681 case 7:
7db13fae 5682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5683 rn = "DataHi";
5684 break;
5685 default:
f31b035a 5686 goto cp0_unimplemented;
7a387fff 5687 }
8c0fdd85 5688 break;
873eb012 5689 case 30:
7a387fff
TS
5690 switch (sel) {
5691 case 0:
7db13fae 5692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5693 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5694 rn = "ErrorEPC";
5695 break;
7a387fff 5696 default:
f31b035a 5697 goto cp0_unimplemented;
7a387fff 5698 }
873eb012
TS
5699 break;
5700 case 31:
7a387fff
TS
5701 switch (sel) {
5702 case 0:
f0b3f3ae 5703 /* EJTAG support */
7db13fae 5704 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5705 rn = "DESAVE";
5706 break;
e98c0d17 5707 case 2 ... 7:
f31b035a
LA
5708 CP0_CHECK(ctx->kscrexist & (1 << sel));
5709 tcg_gen_ld_tl(arg, cpu_env,
5710 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5711 tcg_gen_ext32s_tl(arg, arg);
5712 rn = "KScratch";
e98c0d17 5713 break;
7a387fff 5714 default:
f31b035a 5715 goto cp0_unimplemented;
7a387fff 5716 }
873eb012
TS
5717 break;
5718 default:
f31b035a 5719 goto cp0_unimplemented;
873eb012 5720 }
b44a7fb1 5721 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
5722 return;
5723
f31b035a 5724cp0_unimplemented:
965447ee 5725 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5726 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5727}
5728
d75c135e 5729static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5730{
7a387fff
TS
5731 const char *rn = "invalid";
5732
e189e748 5733 if (sel != 0)
d75c135e 5734 check_insn(ctx, ISA_MIPS32);
e189e748 5735
bd79255d 5736 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5737 gen_io_start();
bd79255d 5738 }
2e70f6ef 5739
8c0fdd85
TS
5740 switch (reg) {
5741 case 0:
7a387fff
TS
5742 switch (sel) {
5743 case 0:
895c2d04 5744 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5745 rn = "Index";
5746 break;
5747 case 1:
f31b035a 5748 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5749 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5750 rn = "MVPControl";
ead9360e 5751 break;
7a387fff 5752 case 2:
f31b035a 5753 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5754 /* ignored */
7a387fff 5755 rn = "MVPConf0";
ead9360e 5756 break;
7a387fff 5757 case 3:
f31b035a 5758 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5759 /* ignored */
7a387fff 5760 rn = "MVPConf1";
ead9360e 5761 break;
01bc435b
YK
5762 case 4:
5763 CP0_CHECK(ctx->vp);
5764 /* ignored */
5765 rn = "VPControl";
5766 break;
7a387fff 5767 default:
f31b035a 5768 goto cp0_unimplemented;
7a387fff 5769 }
8c0fdd85
TS
5770 break;
5771 case 1:
7a387fff
TS
5772 switch (sel) {
5773 case 0:
2423f660 5774 /* ignored */
7a387fff 5775 rn = "Random";
2423f660 5776 break;
7a387fff 5777 case 1:
f31b035a 5778 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5779 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5780 rn = "VPEControl";
ead9360e 5781 break;
7a387fff 5782 case 2:
f31b035a 5783 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5784 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5785 rn = "VPEConf0";
ead9360e 5786 break;
7a387fff 5787 case 3:
f31b035a 5788 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5789 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5790 rn = "VPEConf1";
ead9360e 5791 break;
7a387fff 5792 case 4:
f31b035a 5793 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5794 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5795 rn = "YQMask";
ead9360e 5796 break;
7a387fff 5797 case 5:
f31b035a 5798 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5799 tcg_gen_st_tl(arg, cpu_env,
5800 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5801 rn = "VPESchedule";
ead9360e 5802 break;
7a387fff 5803 case 6:
f31b035a 5804 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5805 tcg_gen_st_tl(arg, cpu_env,
5806 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5807 rn = "VPEScheFBack";
ead9360e 5808 break;
7a387fff 5809 case 7:
f31b035a 5810 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5811 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5812 rn = "VPEOpt";
ead9360e 5813 break;
7a387fff 5814 default:
f31b035a 5815 goto cp0_unimplemented;
7a387fff 5816 }
8c0fdd85
TS
5817 break;
5818 case 2:
7a387fff
TS
5819 switch (sel) {
5820 case 0:
895c2d04 5821 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5822 rn = "EntryLo0";
5823 break;
7a387fff 5824 case 1:
f31b035a 5825 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5826 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5827 rn = "TCStatus";
ead9360e 5828 break;
7a387fff 5829 case 2:
f31b035a 5830 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5831 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5832 rn = "TCBind";
ead9360e 5833 break;
7a387fff 5834 case 3:
f31b035a 5835 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5836 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5837 rn = "TCRestart";
ead9360e 5838 break;
7a387fff 5839 case 4:
f31b035a 5840 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5841 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5842 rn = "TCHalt";
ead9360e 5843 break;
7a387fff 5844 case 5:
f31b035a 5845 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5846 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5847 rn = "TCContext";
ead9360e 5848 break;
7a387fff 5849 case 6:
f31b035a 5850 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5851 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5852 rn = "TCSchedule";
ead9360e 5853 break;
7a387fff 5854 case 7:
f31b035a 5855 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5856 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5857 rn = "TCScheFBack";
ead9360e 5858 break;
7a387fff 5859 default:
f31b035a 5860 goto cp0_unimplemented;
7a387fff 5861 }
8c0fdd85
TS
5862 break;
5863 case 3:
7a387fff
TS
5864 switch (sel) {
5865 case 0:
895c2d04 5866 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5867 rn = "EntryLo1";
5868 break;
01bc435b
YK
5869 case 1:
5870 CP0_CHECK(ctx->vp);
5871 /* ignored */
5872 rn = "GlobalNumber";
5873 break;
7a387fff 5874 default:
f31b035a 5875 goto cp0_unimplemented;
876d4b07 5876 }
8c0fdd85
TS
5877 break;
5878 case 4:
7a387fff
TS
5879 switch (sel) {
5880 case 0:
895c2d04 5881 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5882 rn = "Context";
5883 break;
7a387fff 5884 case 1:
895c2d04 5885// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5886 rn = "ContextConfig";
f31b035a 5887 goto cp0_unimplemented;
d279279e 5888 case 2:
f31b035a
LA
5889 CP0_CHECK(ctx->ulri);
5890 tcg_gen_st_tl(arg, cpu_env,
5891 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5892 rn = "UserLocal";
d279279e 5893 break;
7a387fff 5894 default:
f31b035a 5895 goto cp0_unimplemented;
876d4b07 5896 }
8c0fdd85
TS
5897 break;
5898 case 5:
7a387fff
TS
5899 switch (sel) {
5900 case 0:
895c2d04 5901 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5902 rn = "PageMask";
5903 break;
7a387fff 5904 case 1:
d75c135e 5905 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5906 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5907 rn = "PageGrain";
e117f526 5908 ctx->bstate = BS_STOP;
2423f660 5909 break;
cec56a73
JH
5910 case 2:
5911 CP0_CHECK(ctx->sc);
5912 gen_helper_mtc0_segctl0(cpu_env, arg);
5913 rn = "SegCtl0";
5914 break;
5915 case 3:
5916 CP0_CHECK(ctx->sc);
5917 gen_helper_mtc0_segctl1(cpu_env, arg);
5918 rn = "SegCtl1";
5919 break;
5920 case 4:
5921 CP0_CHECK(ctx->sc);
5922 gen_helper_mtc0_segctl2(cpu_env, arg);
5923 rn = "SegCtl2";
5924 break;
7a387fff 5925 default:
f31b035a 5926 goto cp0_unimplemented;
876d4b07 5927 }
8c0fdd85
TS
5928 break;
5929 case 6:
7a387fff
TS
5930 switch (sel) {
5931 case 0:
895c2d04 5932 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5933 rn = "Wired";
5934 break;
7a387fff 5935 case 1:
d75c135e 5936 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5937 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5938 rn = "SRSConf0";
ead9360e 5939 break;
7a387fff 5940 case 2:
d75c135e 5941 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5942 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5943 rn = "SRSConf1";
ead9360e 5944 break;
7a387fff 5945 case 3:
d75c135e 5946 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5947 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5948 rn = "SRSConf2";
ead9360e 5949 break;
7a387fff 5950 case 4:
d75c135e 5951 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5952 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5953 rn = "SRSConf3";
ead9360e 5954 break;
7a387fff 5955 case 5:
d75c135e 5956 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5957 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5958 rn = "SRSConf4";
ead9360e 5959 break;
7a387fff 5960 default:
f31b035a 5961 goto cp0_unimplemented;
876d4b07 5962 }
8c0fdd85
TS
5963 break;
5964 case 7:
7a387fff
TS
5965 switch (sel) {
5966 case 0:
d75c135e 5967 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5968 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5969 ctx->bstate = BS_STOP;
2423f660
TS
5970 rn = "HWREna";
5971 break;
7a387fff 5972 default:
f31b035a 5973 goto cp0_unimplemented;
876d4b07 5974 }
8c0fdd85
TS
5975 break;
5976 case 8:
aea14095
LA
5977 switch (sel) {
5978 case 0:
5979 /* ignored */
5980 rn = "BadVAddr";
5981 break;
5982 case 1:
5983 /* ignored */
5984 rn = "BadInstr";
5985 break;
5986 case 2:
5987 /* ignored */
5988 rn = "BadInstrP";
5989 break;
5990 default:
f31b035a 5991 goto cp0_unimplemented;
aea14095 5992 }
8c0fdd85
TS
5993 break;
5994 case 9:
7a387fff
TS
5995 switch (sel) {
5996 case 0:
895c2d04 5997 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5998 rn = "Count";
5999 break;
876d4b07 6000 /* 6,7 are implementation dependent */
7a387fff 6001 default:
f31b035a 6002 goto cp0_unimplemented;
876d4b07 6003 }
8c0fdd85
TS
6004 break;
6005 case 10:
7a387fff
TS
6006 switch (sel) {
6007 case 0:
895c2d04 6008 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6009 rn = "EntryHi";
6010 break;
7a387fff 6011 default:
f31b035a 6012 goto cp0_unimplemented;
876d4b07 6013 }
8c0fdd85
TS
6014 break;
6015 case 11:
7a387fff
TS
6016 switch (sel) {
6017 case 0:
895c2d04 6018 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6019 rn = "Compare";
6020 break;
6021 /* 6,7 are implementation dependent */
7a387fff 6022 default:
f31b035a 6023 goto cp0_unimplemented;
876d4b07 6024 }
8c0fdd85
TS
6025 break;
6026 case 12:
7a387fff
TS
6027 switch (sel) {
6028 case 0:
867abc7e 6029 save_cpu_state(ctx, 1);
895c2d04 6030 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6031 /* BS_STOP isn't good enough here, hflags may have changed. */
6032 gen_save_pc(ctx->pc + 4);
6033 ctx->bstate = BS_EXCP;
2423f660
TS
6034 rn = "Status";
6035 break;
7a387fff 6036 case 1:
d75c135e 6037 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6038 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6039 /* Stop translation as we may have switched the execution mode */
6040 ctx->bstate = BS_STOP;
2423f660
TS
6041 rn = "IntCtl";
6042 break;
7a387fff 6043 case 2:
d75c135e 6044 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6045 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6046 /* Stop translation as we may have switched the execution mode */
6047 ctx->bstate = BS_STOP;
2423f660
TS
6048 rn = "SRSCtl";
6049 break;
7a387fff 6050 case 3:
d75c135e 6051 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6052 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6053 /* Stop translation as we may have switched the execution mode */
6054 ctx->bstate = BS_STOP;
2423f660 6055 rn = "SRSMap";
fd88b6ab 6056 break;
7a387fff 6057 default:
f31b035a 6058 goto cp0_unimplemented;
876d4b07 6059 }
8c0fdd85
TS
6060 break;
6061 case 13:
7a387fff
TS
6062 switch (sel) {
6063 case 0:
867abc7e 6064 save_cpu_state(ctx, 1);
895c2d04 6065 gen_helper_mtc0_cause(cpu_env, arg);
b74cddcb
JH
6066 /* Stop translation as we may have triggered an interrupt. BS_STOP
6067 * isn't sufficient, we need to ensure we break out of translated
6068 * code to check for pending interrupts. */
6069 gen_save_pc(ctx->pc + 4);
6070 ctx->bstate = BS_EXCP;
2423f660
TS
6071 rn = "Cause";
6072 break;
7a387fff 6073 default:
f31b035a 6074 goto cp0_unimplemented;
876d4b07 6075 }
8c0fdd85
TS
6076 break;
6077 case 14:
7a387fff
TS
6078 switch (sel) {
6079 case 0:
d54a299b 6080 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6081 rn = "EPC";
6082 break;
7a387fff 6083 default:
f31b035a 6084 goto cp0_unimplemented;
876d4b07 6085 }
8c0fdd85
TS
6086 break;
6087 case 15:
7a387fff
TS
6088 switch (sel) {
6089 case 0:
2423f660
TS
6090 /* ignored */
6091 rn = "PRid";
6092 break;
7a387fff 6093 case 1:
d75c135e 6094 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6095 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6096 rn = "EBase";
6097 break;
7a387fff 6098 default:
f31b035a 6099 goto cp0_unimplemented;
1579a72e 6100 }
8c0fdd85
TS
6101 break;
6102 case 16:
6103 switch (sel) {
6104 case 0:
895c2d04 6105 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6106 rn = "Config";
2423f660
TS
6107 /* Stop translation as we may have switched the execution mode */
6108 ctx->bstate = BS_STOP;
7a387fff
TS
6109 break;
6110 case 1:
e397ee33 6111 /* ignored, read only */
7a387fff
TS
6112 rn = "Config1";
6113 break;
6114 case 2:
895c2d04 6115 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6116 rn = "Config2";
2423f660
TS
6117 /* Stop translation as we may have switched the execution mode */
6118 ctx->bstate = BS_STOP;
8c0fdd85 6119 break;
7a387fff 6120 case 3:
90f12d73 6121 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6122 rn = "Config3";
90f12d73
MR
6123 /* Stop translation as we may have switched the execution mode */
6124 ctx->bstate = BS_STOP;
7a387fff 6125 break;
b4160af1
PJ
6126 case 4:
6127 gen_helper_mtc0_config4(cpu_env, arg);
6128 rn = "Config4";
6129 ctx->bstate = BS_STOP;
6130 break;
b4dd99a3
PJ
6131 case 5:
6132 gen_helper_mtc0_config5(cpu_env, arg);
6133 rn = "Config5";
6134 /* Stop translation as we may have switched the execution mode */
6135 ctx->bstate = BS_STOP;
6136 break;
e397ee33
TS
6137 /* 6,7 are implementation dependent */
6138 case 6:
6139 /* ignored */
6140 rn = "Config6";
6141 break;
6142 case 7:
6143 /* ignored */
6144 rn = "Config7";
6145 break;
8c0fdd85
TS
6146 default:
6147 rn = "Invalid config selector";
f31b035a 6148 goto cp0_unimplemented;
8c0fdd85
TS
6149 }
6150 break;
6151 case 17:
7a387fff
TS
6152 switch (sel) {
6153 case 0:
895c2d04 6154 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6155 rn = "LLAddr";
6156 break;
f6d4dd81
YK
6157 case 1:
6158 CP0_CHECK(ctx->mrp);
6159 gen_helper_mtc0_maar(cpu_env, arg);
6160 rn = "MAAR";
6161 break;
6162 case 2:
6163 CP0_CHECK(ctx->mrp);
6164 gen_helper_mtc0_maari(cpu_env, arg);
6165 rn = "MAARI";
6166 break;
7a387fff 6167 default:
f31b035a 6168 goto cp0_unimplemented;
7a387fff 6169 }
8c0fdd85
TS
6170 break;
6171 case 18:
7a387fff 6172 switch (sel) {
fd88b6ab 6173 case 0 ... 7:
895c2d04 6174 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6175 rn = "WatchLo";
6176 break;
7a387fff 6177 default:
f31b035a 6178 goto cp0_unimplemented;
7a387fff 6179 }
8c0fdd85
TS
6180 break;
6181 case 19:
7a387fff 6182 switch (sel) {
fd88b6ab 6183 case 0 ... 7:
895c2d04 6184 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6185 rn = "WatchHi";
6186 break;
7a387fff 6187 default:
f31b035a 6188 goto cp0_unimplemented;
7a387fff 6189 }
8c0fdd85
TS
6190 break;
6191 case 20:
7a387fff
TS
6192 switch (sel) {
6193 case 0:
d26bc211 6194#if defined(TARGET_MIPS64)
d75c135e 6195 check_insn(ctx, ISA_MIPS3);
895c2d04 6196 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6197 rn = "XContext";
6198 break;
703eaf37 6199#endif
7a387fff 6200 default:
f31b035a 6201 goto cp0_unimplemented;
7a387fff 6202 }
8c0fdd85
TS
6203 break;
6204 case 21:
7a387fff 6205 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6206 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6207 switch (sel) {
6208 case 0:
895c2d04 6209 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6210 rn = "Framemask";
6211 break;
7a387fff 6212 default:
f31b035a 6213 goto cp0_unimplemented;
7a387fff
TS
6214 }
6215 break;
8c0fdd85 6216 case 22:
7a387fff
TS
6217 /* ignored */
6218 rn = "Diagnostic"; /* implementation dependent */
2423f660 6219 break;
8c0fdd85 6220 case 23:
7a387fff
TS
6221 switch (sel) {
6222 case 0:
895c2d04 6223 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6224 /* BS_STOP isn't good enough here, hflags may have changed. */
6225 gen_save_pc(ctx->pc + 4);
6226 ctx->bstate = BS_EXCP;
2423f660
TS
6227 rn = "Debug";
6228 break;
7a387fff 6229 case 1:
895c2d04 6230// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6231 rn = "TraceControl";
8487327a
TS
6232 /* Stop translation as we may have switched the execution mode */
6233 ctx->bstate = BS_STOP;
3570d7f6 6234 goto cp0_unimplemented;
7a387fff 6235 case 2:
895c2d04 6236// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6237 rn = "TraceControl2";
8487327a
TS
6238 /* Stop translation as we may have switched the execution mode */
6239 ctx->bstate = BS_STOP;
3570d7f6 6240 goto cp0_unimplemented;
7a387fff 6241 case 3:
8487327a
TS
6242 /* Stop translation as we may have switched the execution mode */
6243 ctx->bstate = BS_STOP;
895c2d04 6244// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6245 rn = "UserTraceData";
8487327a
TS
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx->bstate = BS_STOP;
3570d7f6 6248 goto cp0_unimplemented;
7a387fff 6249 case 4:
895c2d04 6250// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6251 /* Stop translation as we may have switched the execution mode */
6252 ctx->bstate = BS_STOP;
2423f660 6253 rn = "TraceBPC";
3570d7f6 6254 goto cp0_unimplemented;
7a387fff 6255 default:
f31b035a 6256 goto cp0_unimplemented;
7a387fff 6257 }
8c0fdd85
TS
6258 break;
6259 case 24:
7a387fff
TS
6260 switch (sel) {
6261 case 0:
f1aa6320 6262 /* EJTAG support */
d54a299b 6263 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6264 rn = "DEPC";
6265 break;
7a387fff 6266 default:
f31b035a 6267 goto cp0_unimplemented;
7a387fff 6268 }
8c0fdd85
TS
6269 break;
6270 case 25:
7a387fff
TS
6271 switch (sel) {
6272 case 0:
895c2d04 6273 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6274 rn = "Performance0";
6275 break;
7a387fff 6276 case 1:
d9bea114 6277// gen_helper_mtc0_performance1(arg);
2423f660 6278 rn = "Performance1";
3570d7f6 6279 goto cp0_unimplemented;
7a387fff 6280 case 2:
d9bea114 6281// gen_helper_mtc0_performance2(arg);
2423f660 6282 rn = "Performance2";
3570d7f6 6283 goto cp0_unimplemented;
7a387fff 6284 case 3:
d9bea114 6285// gen_helper_mtc0_performance3(arg);
2423f660 6286 rn = "Performance3";
3570d7f6 6287 goto cp0_unimplemented;
7a387fff 6288 case 4:
d9bea114 6289// gen_helper_mtc0_performance4(arg);
2423f660 6290 rn = "Performance4";
3570d7f6 6291 goto cp0_unimplemented;
7a387fff 6292 case 5:
d9bea114 6293// gen_helper_mtc0_performance5(arg);
2423f660 6294 rn = "Performance5";
3570d7f6 6295 goto cp0_unimplemented;
7a387fff 6296 case 6:
d9bea114 6297// gen_helper_mtc0_performance6(arg);
2423f660 6298 rn = "Performance6";
3570d7f6 6299 goto cp0_unimplemented;
7a387fff 6300 case 7:
d9bea114 6301// gen_helper_mtc0_performance7(arg);
2423f660 6302 rn = "Performance7";
3570d7f6 6303 goto cp0_unimplemented;
7a387fff 6304 default:
f31b035a 6305 goto cp0_unimplemented;
7a387fff 6306 }
8c0fdd85
TS
6307 break;
6308 case 26:
0d74a222
LA
6309 switch (sel) {
6310 case 0:
6311 gen_helper_mtc0_errctl(cpu_env, arg);
6312 ctx->bstate = BS_STOP;
6313 rn = "ErrCtl";
6314 break;
6315 default:
6316 goto cp0_unimplemented;
6317 }
2423f660 6318 break;
8c0fdd85 6319 case 27:
7a387fff
TS
6320 switch (sel) {
6321 case 0 ... 3:
2423f660
TS
6322 /* ignored */
6323 rn = "CacheErr";
6324 break;
7a387fff 6325 default:
f31b035a 6326 goto cp0_unimplemented;
7a387fff 6327 }
8c0fdd85
TS
6328 break;
6329 case 28:
6330 switch (sel) {
6331 case 0:
7a387fff
TS
6332 case 2:
6333 case 4:
6334 case 6:
895c2d04 6335 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6336 rn = "TagLo";
6337 break;
7a387fff
TS
6338 case 1:
6339 case 3:
6340 case 5:
6341 case 7:
895c2d04 6342 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6343 rn = "DataLo";
6344 break;
8c0fdd85 6345 default:
f31b035a 6346 goto cp0_unimplemented;
8c0fdd85
TS
6347 }
6348 break;
6349 case 29:
7a387fff
TS
6350 switch (sel) {
6351 case 0:
6352 case 2:
6353 case 4:
6354 case 6:
895c2d04 6355 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6356 rn = "TagHi";
6357 break;
6358 case 1:
6359 case 3:
6360 case 5:
6361 case 7:
895c2d04 6362 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6363 rn = "DataHi";
6364 break;
6365 default:
6366 rn = "invalid sel";
f31b035a 6367 goto cp0_unimplemented;
7a387fff 6368 }
8c0fdd85
TS
6369 break;
6370 case 30:
7a387fff
TS
6371 switch (sel) {
6372 case 0:
d54a299b 6373 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6374 rn = "ErrorEPC";
6375 break;
7a387fff 6376 default:
f31b035a 6377 goto cp0_unimplemented;
7a387fff 6378 }
8c0fdd85
TS
6379 break;
6380 case 31:
7a387fff
TS
6381 switch (sel) {
6382 case 0:
f1aa6320 6383 /* EJTAG support */
7db13fae 6384 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6385 rn = "DESAVE";
6386 break;
e98c0d17 6387 case 2 ... 7:
f31b035a
LA
6388 CP0_CHECK(ctx->kscrexist & (1 << sel));
6389 tcg_gen_st_tl(arg, cpu_env,
6390 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6391 rn = "KScratch";
e98c0d17 6392 break;
7a387fff 6393 default:
f31b035a 6394 goto cp0_unimplemented;
7a387fff 6395 }
8c0fdd85
TS
6396 break;
6397 default:
f31b035a 6398 goto cp0_unimplemented;
8c0fdd85 6399 }
b44a7fb1
PMD
6400 trace_mips_translate_c0("mtc0", rn, reg, sel);
6401
bf20dc07 6402 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6403 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6404 gen_io_end();
b74cddcb
JH
6405 /* BS_STOP isn't sufficient, we need to ensure we break out of
6406 * translated code to check for pending interrupts. */
6407 gen_save_pc(ctx->pc + 4);
6408 ctx->bstate = BS_EXCP;
2e70f6ef 6409 }
8c0fdd85
TS
6410 return;
6411
f31b035a 6412cp0_unimplemented:
965447ee 6413 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6414}
6415
d26bc211 6416#if defined(TARGET_MIPS64)
d75c135e 6417static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6418{
6419 const char *rn = "invalid";
6420
e189e748 6421 if (sel != 0)
d75c135e 6422 check_insn(ctx, ISA_MIPS64);
e189e748 6423
9c2149c8
TS
6424 switch (reg) {
6425 case 0:
6426 switch (sel) {
6427 case 0:
7db13fae 6428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6429 rn = "Index";
6430 break;
6431 case 1:
f31b035a 6432 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6433 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6434 rn = "MVPControl";
ead9360e 6435 break;
9c2149c8 6436 case 2:
f31b035a 6437 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6438 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6439 rn = "MVPConf0";
ead9360e 6440 break;
9c2149c8 6441 case 3:
f31b035a 6442 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6443 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6444 rn = "MVPConf1";
ead9360e 6445 break;
01bc435b
YK
6446 case 4:
6447 CP0_CHECK(ctx->vp);
6448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6449 rn = "VPControl";
6450 break;
9c2149c8 6451 default:
f31b035a 6452 goto cp0_unimplemented;
9c2149c8
TS
6453 }
6454 break;
6455 case 1:
6456 switch (sel) {
6457 case 0:
f31b035a 6458 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6459 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6460 rn = "Random";
2423f660 6461 break;
9c2149c8 6462 case 1:
f31b035a 6463 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6465 rn = "VPEControl";
ead9360e 6466 break;
9c2149c8 6467 case 2:
f31b035a 6468 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6470 rn = "VPEConf0";
ead9360e 6471 break;
9c2149c8 6472 case 3:
f31b035a 6473 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6475 rn = "VPEConf1";
ead9360e 6476 break;
9c2149c8 6477 case 4:
f31b035a 6478 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6479 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6480 rn = "YQMask";
ead9360e 6481 break;
9c2149c8 6482 case 5:
f31b035a 6483 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6485 rn = "VPESchedule";
ead9360e 6486 break;
9c2149c8 6487 case 6:
f31b035a 6488 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6490 rn = "VPEScheFBack";
ead9360e 6491 break;
9c2149c8 6492 case 7:
f31b035a 6493 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6494 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6495 rn = "VPEOpt";
ead9360e 6496 break;
9c2149c8 6497 default:
f31b035a 6498 goto cp0_unimplemented;
9c2149c8
TS
6499 }
6500 break;
6501 case 2:
6502 switch (sel) {
6503 case 0:
7db13fae 6504 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6505 rn = "EntryLo0";
6506 break;
9c2149c8 6507 case 1:
f31b035a 6508 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6509 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6510 rn = "TCStatus";
ead9360e 6511 break;
9c2149c8 6512 case 2:
f31b035a 6513 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6514 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6515 rn = "TCBind";
ead9360e 6516 break;
9c2149c8 6517 case 3:
f31b035a 6518 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6519 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6520 rn = "TCRestart";
ead9360e 6521 break;
9c2149c8 6522 case 4:
f31b035a 6523 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6524 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6525 rn = "TCHalt";
ead9360e 6526 break;
9c2149c8 6527 case 5:
f31b035a 6528 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6529 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6530 rn = "TCContext";
ead9360e 6531 break;
9c2149c8 6532 case 6:
f31b035a 6533 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6534 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6535 rn = "TCSchedule";
ead9360e 6536 break;
9c2149c8 6537 case 7:
f31b035a 6538 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6539 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6540 rn = "TCScheFBack";
ead9360e 6541 break;
9c2149c8 6542 default:
f31b035a 6543 goto cp0_unimplemented;
9c2149c8
TS
6544 }
6545 break;
6546 case 3:
6547 switch (sel) {
6548 case 0:
7db13fae 6549 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6550 rn = "EntryLo1";
6551 break;
01bc435b
YK
6552 case 1:
6553 CP0_CHECK(ctx->vp);
6554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6555 rn = "GlobalNumber";
6556 break;
9c2149c8 6557 default:
f31b035a 6558 goto cp0_unimplemented;
1579a72e 6559 }
9c2149c8
TS
6560 break;
6561 case 4:
6562 switch (sel) {
6563 case 0:
7db13fae 6564 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6565 rn = "Context";
6566 break;
9c2149c8 6567 case 1:
d9bea114 6568// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6569 rn = "ContextConfig";
f31b035a 6570 goto cp0_unimplemented;
d279279e 6571 case 2:
f31b035a
LA
6572 CP0_CHECK(ctx->ulri);
6573 tcg_gen_ld_tl(arg, cpu_env,
6574 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6575 rn = "UserLocal";
d279279e 6576 break;
9c2149c8 6577 default:
f31b035a 6578 goto cp0_unimplemented;
876d4b07 6579 }
9c2149c8
TS
6580 break;
6581 case 5:
6582 switch (sel) {
6583 case 0:
7db13fae 6584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6585 rn = "PageMask";
6586 break;
9c2149c8 6587 case 1:
d75c135e 6588 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6590 rn = "PageGrain";
6591 break;
cec56a73
JH
6592 case 2:
6593 CP0_CHECK(ctx->sc);
6594 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6595 rn = "SegCtl0";
6596 break;
6597 case 3:
6598 CP0_CHECK(ctx->sc);
6599 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6600 rn = "SegCtl1";
6601 break;
6602 case 4:
6603 CP0_CHECK(ctx->sc);
6604 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6605 rn = "SegCtl2";
6606 break;
9c2149c8 6607 default:
f31b035a 6608 goto cp0_unimplemented;
876d4b07 6609 }
9c2149c8
TS
6610 break;
6611 case 6:
6612 switch (sel) {
6613 case 0:
7db13fae 6614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6615 rn = "Wired";
6616 break;
9c2149c8 6617 case 1:
d75c135e 6618 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6620 rn = "SRSConf0";
ead9360e 6621 break;
9c2149c8 6622 case 2:
d75c135e 6623 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6625 rn = "SRSConf1";
ead9360e 6626 break;
9c2149c8 6627 case 3:
d75c135e 6628 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6630 rn = "SRSConf2";
ead9360e 6631 break;
9c2149c8 6632 case 4:
d75c135e 6633 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6635 rn = "SRSConf3";
ead9360e 6636 break;
9c2149c8 6637 case 5:
d75c135e 6638 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6640 rn = "SRSConf4";
ead9360e 6641 break;
9c2149c8 6642 default:
f31b035a 6643 goto cp0_unimplemented;
876d4b07 6644 }
9c2149c8
TS
6645 break;
6646 case 7:
6647 switch (sel) {
6648 case 0:
d75c135e 6649 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6651 rn = "HWREna";
6652 break;
9c2149c8 6653 default:
f31b035a 6654 goto cp0_unimplemented;
876d4b07 6655 }
9c2149c8
TS
6656 break;
6657 case 8:
6658 switch (sel) {
6659 case 0:
7db13fae 6660 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6661 rn = "BadVAddr";
2423f660 6662 break;
aea14095 6663 case 1:
f31b035a
LA
6664 CP0_CHECK(ctx->bi);
6665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6666 rn = "BadInstr";
aea14095
LA
6667 break;
6668 case 2:
f31b035a
LA
6669 CP0_CHECK(ctx->bp);
6670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6671 rn = "BadInstrP";
aea14095 6672 break;
9c2149c8 6673 default:
f31b035a 6674 goto cp0_unimplemented;
876d4b07 6675 }
9c2149c8
TS
6676 break;
6677 case 9:
6678 switch (sel) {
6679 case 0:
2e70f6ef 6680 /* Mark as an IO operation because we read the time. */
bd79255d 6681 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6682 gen_io_start();
bd79255d 6683 }
895c2d04 6684 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6685 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6686 gen_io_end();
2e70f6ef 6687 }
55807224 6688 /* Break the TB to be able to take timer interrupts immediately
b74cddcb
JH
6689 after reading count. BS_STOP isn't sufficient, we need to ensure
6690 we break completely out of translated code. */
6691 gen_save_pc(ctx->pc + 4);
6692 ctx->bstate = BS_EXCP;
2423f660
TS
6693 rn = "Count";
6694 break;
6695 /* 6,7 are implementation dependent */
9c2149c8 6696 default:
f31b035a 6697 goto cp0_unimplemented;
876d4b07 6698 }
9c2149c8
TS
6699 break;
6700 case 10:
6701 switch (sel) {
6702 case 0:
7db13fae 6703 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6704 rn = "EntryHi";
6705 break;
9c2149c8 6706 default:
f31b035a 6707 goto cp0_unimplemented;
876d4b07 6708 }
9c2149c8
TS
6709 break;
6710 case 11:
6711 switch (sel) {
6712 case 0:
7db13fae 6713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6714 rn = "Compare";
6715 break;
876d4b07 6716 /* 6,7 are implementation dependent */
9c2149c8 6717 default:
f31b035a 6718 goto cp0_unimplemented;
876d4b07 6719 }
9c2149c8
TS
6720 break;
6721 case 12:
6722 switch (sel) {
6723 case 0:
7db13fae 6724 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6725 rn = "Status";
6726 break;
9c2149c8 6727 case 1:
d75c135e 6728 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6730 rn = "IntCtl";
6731 break;
9c2149c8 6732 case 2:
d75c135e 6733 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6734 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6735 rn = "SRSCtl";
6736 break;
9c2149c8 6737 case 3:
d75c135e 6738 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6739 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6740 rn = "SRSMap";
6741 break;
9c2149c8 6742 default:
f31b035a 6743 goto cp0_unimplemented;
876d4b07 6744 }
9c2149c8
TS
6745 break;
6746 case 13:
6747 switch (sel) {
6748 case 0:
7db13fae 6749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6750 rn = "Cause";
6751 break;
9c2149c8 6752 default:
f31b035a 6753 goto cp0_unimplemented;
876d4b07 6754 }
9c2149c8
TS
6755 break;
6756 case 14:
6757 switch (sel) {
6758 case 0:
7db13fae 6759 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6760 rn = "EPC";
6761 break;
9c2149c8 6762 default:
f31b035a 6763 goto cp0_unimplemented;
876d4b07 6764 }
9c2149c8
TS
6765 break;
6766 case 15:
6767 switch (sel) {
6768 case 0:
7db13fae 6769 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6770 rn = "PRid";
6771 break;
9c2149c8 6772 case 1:
d75c135e 6773 check_insn(ctx, ISA_MIPS32R2);
74dbf824 6774 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6775 rn = "EBase";
6776 break;
c870e3f5
YK
6777 case 3:
6778 check_insn(ctx, ISA_MIPS32R2);
6779 CP0_CHECK(ctx->cmgcr);
6780 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6781 rn = "CMGCRBase";
6782 break;
9c2149c8 6783 default:
f31b035a 6784 goto cp0_unimplemented;
876d4b07 6785 }
9c2149c8
TS
6786 break;
6787 case 16:
6788 switch (sel) {
6789 case 0:
7db13fae 6790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6791 rn = "Config";
6792 break;
6793 case 1:
7db13fae 6794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6795 rn = "Config1";
6796 break;
6797 case 2:
7db13fae 6798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6799 rn = "Config2";
6800 break;
6801 case 3:
7db13fae 6802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6803 rn = "Config3";
6804 break;
faf1f68b
LA
6805 case 4:
6806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6807 rn = "Config4";
6808 break;
6809 case 5:
6810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6811 rn = "Config5";
6812 break;
9c2149c8 6813 /* 6,7 are implementation dependent */
f0b3f3ae 6814 case 6:
7db13fae 6815 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6816 rn = "Config6";
6817 break;
6818 case 7:
7db13fae 6819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6820 rn = "Config7";
6821 break;
9c2149c8 6822 default:
f31b035a 6823 goto cp0_unimplemented;
9c2149c8
TS
6824 }
6825 break;
6826 case 17:
6827 switch (sel) {
6828 case 0:
895c2d04 6829 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6830 rn = "LLAddr";
6831 break;
f6d4dd81
YK
6832 case 1:
6833 CP0_CHECK(ctx->mrp);
6834 gen_helper_dmfc0_maar(arg, cpu_env);
6835 rn = "MAAR";
6836 break;
6837 case 2:
6838 CP0_CHECK(ctx->mrp);
6839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6840 rn = "MAARI";
6841 break;
9c2149c8 6842 default:
f31b035a 6843 goto cp0_unimplemented;
9c2149c8
TS
6844 }
6845 break;
6846 case 18:
6847 switch (sel) {
fd88b6ab 6848 case 0 ... 7:
895c2d04 6849 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6850 rn = "WatchLo";
6851 break;
9c2149c8 6852 default:
f31b035a 6853 goto cp0_unimplemented;
9c2149c8
TS
6854 }
6855 break;
6856 case 19:
6857 switch (sel) {
fd88b6ab 6858 case 0 ... 7:
895c2d04 6859 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6860 rn = "WatchHi";
6861 break;
9c2149c8 6862 default:
f31b035a 6863 goto cp0_unimplemented;
9c2149c8
TS
6864 }
6865 break;
6866 case 20:
6867 switch (sel) {
6868 case 0:
d75c135e 6869 check_insn(ctx, ISA_MIPS3);
7db13fae 6870 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6871 rn = "XContext";
6872 break;
9c2149c8 6873 default:
f31b035a 6874 goto cp0_unimplemented;
9c2149c8
TS
6875 }
6876 break;
6877 case 21:
6878 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6879 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6880 switch (sel) {
6881 case 0:
7db13fae 6882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6883 rn = "Framemask";
6884 break;
9c2149c8 6885 default:
f31b035a 6886 goto cp0_unimplemented;
9c2149c8
TS
6887 }
6888 break;
6889 case 22:
d9bea114 6890 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6891 rn = "'Diagnostic"; /* implementation dependent */
6892 break;
9c2149c8
TS
6893 case 23:
6894 switch (sel) {
6895 case 0:
895c2d04 6896 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6897 rn = "Debug";
6898 break;
9c2149c8 6899 case 1:
895c2d04 6900// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 6901 rn = "TraceControl";
3570d7f6 6902 goto cp0_unimplemented;
9c2149c8 6903 case 2:
895c2d04 6904// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 6905 rn = "TraceControl2";
3570d7f6 6906 goto cp0_unimplemented;
9c2149c8 6907 case 3:
895c2d04 6908// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 6909 rn = "UserTraceData";
3570d7f6 6910 goto cp0_unimplemented;
9c2149c8 6911 case 4:
895c2d04 6912// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 6913 rn = "TraceBPC";
3570d7f6 6914 goto cp0_unimplemented;
9c2149c8 6915 default:
f31b035a 6916 goto cp0_unimplemented;
9c2149c8
TS
6917 }
6918 break;
6919 case 24:
6920 switch (sel) {
6921 case 0:
f0b3f3ae 6922 /* EJTAG support */
7db13fae 6923 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6924 rn = "DEPC";
6925 break;
9c2149c8 6926 default:
f31b035a 6927 goto cp0_unimplemented;
9c2149c8
TS
6928 }
6929 break;
6930 case 25:
6931 switch (sel) {
6932 case 0:
7db13fae 6933 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6934 rn = "Performance0";
9c2149c8
TS
6935 break;
6936 case 1:
d9bea114 6937// gen_helper_dmfc0_performance1(arg);
2423f660 6938 rn = "Performance1";
3570d7f6 6939 goto cp0_unimplemented;
9c2149c8 6940 case 2:
d9bea114 6941// gen_helper_dmfc0_performance2(arg);
2423f660 6942 rn = "Performance2";
3570d7f6 6943 goto cp0_unimplemented;
9c2149c8 6944 case 3:
d9bea114 6945// gen_helper_dmfc0_performance3(arg);
2423f660 6946 rn = "Performance3";
3570d7f6 6947 goto cp0_unimplemented;
9c2149c8 6948 case 4:
d9bea114 6949// gen_helper_dmfc0_performance4(arg);
2423f660 6950 rn = "Performance4";
3570d7f6 6951 goto cp0_unimplemented;
9c2149c8 6952 case 5:
d9bea114 6953// gen_helper_dmfc0_performance5(arg);
2423f660 6954 rn = "Performance5";
3570d7f6 6955 goto cp0_unimplemented;
9c2149c8 6956 case 6:
d9bea114 6957// gen_helper_dmfc0_performance6(arg);
2423f660 6958 rn = "Performance6";
3570d7f6 6959 goto cp0_unimplemented;
9c2149c8 6960 case 7:
d9bea114 6961// gen_helper_dmfc0_performance7(arg);
2423f660 6962 rn = "Performance7";
3570d7f6 6963 goto cp0_unimplemented;
9c2149c8 6964 default:
f31b035a 6965 goto cp0_unimplemented;
9c2149c8
TS
6966 }
6967 break;
6968 case 26:
0d74a222
LA
6969 switch (sel) {
6970 case 0:
6971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6972 rn = "ErrCtl";
6973 break;
6974 default:
6975 goto cp0_unimplemented;
6976 }
da80682b 6977 break;
9c2149c8
TS
6978 case 27:
6979 switch (sel) {
6980 /* ignored */
6981 case 0 ... 3:
d9bea114 6982 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6983 rn = "CacheErr";
6984 break;
9c2149c8 6985 default:
f31b035a 6986 goto cp0_unimplemented;
9c2149c8
TS
6987 }
6988 break;
6989 case 28:
6990 switch (sel) {
6991 case 0:
6992 case 2:
6993 case 4:
6994 case 6:
7db13fae 6995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6996 rn = "TagLo";
6997 break;
6998 case 1:
6999 case 3:
7000 case 5:
7001 case 7:
7db13fae 7002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7003 rn = "DataLo";
7004 break;
7005 default:
f31b035a 7006 goto cp0_unimplemented;
9c2149c8
TS
7007 }
7008 break;
7009 case 29:
7010 switch (sel) {
7011 case 0:
7012 case 2:
7013 case 4:
7014 case 6:
7db13fae 7015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7016 rn = "TagHi";
7017 break;
7018 case 1:
7019 case 3:
7020 case 5:
7021 case 7:
7db13fae 7022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7023 rn = "DataHi";
7024 break;
7025 default:
f31b035a 7026 goto cp0_unimplemented;
9c2149c8
TS
7027 }
7028 break;
7029 case 30:
7030 switch (sel) {
7031 case 0:
7db13fae 7032 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7033 rn = "ErrorEPC";
7034 break;
9c2149c8 7035 default:
f31b035a 7036 goto cp0_unimplemented;
9c2149c8
TS
7037 }
7038 break;
7039 case 31:
7040 switch (sel) {
7041 case 0:
f0b3f3ae 7042 /* EJTAG support */
7db13fae 7043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7044 rn = "DESAVE";
7045 break;
e98c0d17 7046 case 2 ... 7:
f31b035a
LA
7047 CP0_CHECK(ctx->kscrexist & (1 << sel));
7048 tcg_gen_ld_tl(arg, cpu_env,
7049 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7050 rn = "KScratch";
e98c0d17 7051 break;
9c2149c8 7052 default:
f31b035a 7053 goto cp0_unimplemented;
9c2149c8
TS
7054 }
7055 break;
7056 default:
f31b035a 7057 goto cp0_unimplemented;
9c2149c8 7058 }
b44a7fb1 7059 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7060 return;
7061
f31b035a 7062cp0_unimplemented:
965447ee 7063 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7064 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7065}
7066
d75c135e 7067static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7068{
7069 const char *rn = "invalid";
7070
e189e748 7071 if (sel != 0)
d75c135e 7072 check_insn(ctx, ISA_MIPS64);
e189e748 7073
bd79255d 7074 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 7075 gen_io_start();
bd79255d 7076 }
2e70f6ef 7077
9c2149c8
TS
7078 switch (reg) {
7079 case 0:
7080 switch (sel) {
7081 case 0:
895c2d04 7082 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7083 rn = "Index";
7084 break;
7085 case 1:
f31b035a 7086 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7087 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7088 rn = "MVPControl";
ead9360e 7089 break;
9c2149c8 7090 case 2:
f31b035a 7091 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7092 /* ignored */
9c2149c8 7093 rn = "MVPConf0";
ead9360e 7094 break;
9c2149c8 7095 case 3:
f31b035a 7096 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7097 /* ignored */
9c2149c8 7098 rn = "MVPConf1";
ead9360e 7099 break;
01bc435b
YK
7100 case 4:
7101 CP0_CHECK(ctx->vp);
7102 /* ignored */
7103 rn = "VPControl";
7104 break;
9c2149c8 7105 default:
f31b035a 7106 goto cp0_unimplemented;
9c2149c8
TS
7107 }
7108 break;
7109 case 1:
7110 switch (sel) {
7111 case 0:
2423f660 7112 /* ignored */
9c2149c8 7113 rn = "Random";
2423f660 7114 break;
9c2149c8 7115 case 1:
f31b035a 7116 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7117 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7118 rn = "VPEControl";
ead9360e 7119 break;
9c2149c8 7120 case 2:
f31b035a 7121 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7122 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7123 rn = "VPEConf0";
ead9360e 7124 break;
9c2149c8 7125 case 3:
f31b035a 7126 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7127 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7128 rn = "VPEConf1";
ead9360e 7129 break;
9c2149c8 7130 case 4:
f31b035a 7131 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7132 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7133 rn = "YQMask";
ead9360e 7134 break;
9c2149c8 7135 case 5:
f31b035a 7136 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7137 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7138 rn = "VPESchedule";
ead9360e 7139 break;
9c2149c8 7140 case 6:
f31b035a 7141 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7142 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7143 rn = "VPEScheFBack";
ead9360e 7144 break;
9c2149c8 7145 case 7:
f31b035a 7146 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7147 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7148 rn = "VPEOpt";
ead9360e 7149 break;
9c2149c8 7150 default:
f31b035a 7151 goto cp0_unimplemented;
9c2149c8
TS
7152 }
7153 break;
7154 case 2:
7155 switch (sel) {
7156 case 0:
7207c7f9 7157 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7158 rn = "EntryLo0";
7159 break;
9c2149c8 7160 case 1:
f31b035a 7161 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7162 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7163 rn = "TCStatus";
ead9360e 7164 break;
9c2149c8 7165 case 2:
f31b035a 7166 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7167 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7168 rn = "TCBind";
ead9360e 7169 break;
9c2149c8 7170 case 3:
f31b035a 7171 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7172 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7173 rn = "TCRestart";
ead9360e 7174 break;
9c2149c8 7175 case 4:
f31b035a 7176 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7177 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7178 rn = "TCHalt";
ead9360e 7179 break;
9c2149c8 7180 case 5:
f31b035a 7181 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7182 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7183 rn = "TCContext";
ead9360e 7184 break;
9c2149c8 7185 case 6:
f31b035a 7186 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7187 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7188 rn = "TCSchedule";
ead9360e 7189 break;
9c2149c8 7190 case 7:
f31b035a 7191 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7192 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7193 rn = "TCScheFBack";
ead9360e 7194 break;
9c2149c8 7195 default:
f31b035a 7196 goto cp0_unimplemented;
9c2149c8
TS
7197 }
7198 break;
7199 case 3:
7200 switch (sel) {
7201 case 0:
7207c7f9 7202 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7203 rn = "EntryLo1";
7204 break;
01bc435b
YK
7205 case 1:
7206 CP0_CHECK(ctx->vp);
7207 /* ignored */
7208 rn = "GlobalNumber";
7209 break;
9c2149c8 7210 default:
f31b035a 7211 goto cp0_unimplemented;
876d4b07 7212 }
9c2149c8
TS
7213 break;
7214 case 4:
7215 switch (sel) {
7216 case 0:
895c2d04 7217 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7218 rn = "Context";
7219 break;
9c2149c8 7220 case 1:
895c2d04 7221// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7222 rn = "ContextConfig";
f31b035a 7223 goto cp0_unimplemented;
d279279e 7224 case 2:
f31b035a
LA
7225 CP0_CHECK(ctx->ulri);
7226 tcg_gen_st_tl(arg, cpu_env,
7227 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7228 rn = "UserLocal";
d279279e 7229 break;
9c2149c8 7230 default:
f31b035a 7231 goto cp0_unimplemented;
876d4b07 7232 }
9c2149c8
TS
7233 break;
7234 case 5:
7235 switch (sel) {
7236 case 0:
895c2d04 7237 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7238 rn = "PageMask";
7239 break;
9c2149c8 7240 case 1:
d75c135e 7241 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7242 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7243 rn = "PageGrain";
7244 break;
cec56a73
JH
7245 case 2:
7246 CP0_CHECK(ctx->sc);
7247 gen_helper_mtc0_segctl0(cpu_env, arg);
7248 rn = "SegCtl0";
7249 break;
7250 case 3:
7251 CP0_CHECK(ctx->sc);
7252 gen_helper_mtc0_segctl1(cpu_env, arg);
7253 rn = "SegCtl1";
7254 break;
7255 case 4:
7256 CP0_CHECK(ctx->sc);
7257 gen_helper_mtc0_segctl2(cpu_env, arg);
7258 rn = "SegCtl2";
7259 break;
9c2149c8 7260 default:
f31b035a 7261 goto cp0_unimplemented;
876d4b07 7262 }
9c2149c8
TS
7263 break;
7264 case 6:
7265 switch (sel) {
7266 case 0:
895c2d04 7267 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7268 rn = "Wired";
7269 break;
9c2149c8 7270 case 1:
d75c135e 7271 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7272 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7273 rn = "SRSConf0";
ead9360e 7274 break;
9c2149c8 7275 case 2:
d75c135e 7276 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7277 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7278 rn = "SRSConf1";
ead9360e 7279 break;
9c2149c8 7280 case 3:
d75c135e 7281 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7282 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7283 rn = "SRSConf2";
ead9360e 7284 break;
9c2149c8 7285 case 4:
d75c135e 7286 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7287 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7288 rn = "SRSConf3";
ead9360e 7289 break;
9c2149c8 7290 case 5:
d75c135e 7291 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7292 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7293 rn = "SRSConf4";
ead9360e 7294 break;
9c2149c8 7295 default:
f31b035a 7296 goto cp0_unimplemented;
876d4b07 7297 }
9c2149c8
TS
7298 break;
7299 case 7:
7300 switch (sel) {
7301 case 0:
d75c135e 7302 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7303 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7304 ctx->bstate = BS_STOP;
2423f660
TS
7305 rn = "HWREna";
7306 break;
9c2149c8 7307 default:
f31b035a 7308 goto cp0_unimplemented;
876d4b07 7309 }
9c2149c8
TS
7310 break;
7311 case 8:
aea14095
LA
7312 switch (sel) {
7313 case 0:
7314 /* ignored */
7315 rn = "BadVAddr";
7316 break;
7317 case 1:
7318 /* ignored */
7319 rn = "BadInstr";
7320 break;
7321 case 2:
7322 /* ignored */
7323 rn = "BadInstrP";
7324 break;
7325 default:
f31b035a 7326 goto cp0_unimplemented;
aea14095 7327 }
9c2149c8
TS
7328 break;
7329 case 9:
7330 switch (sel) {
7331 case 0:
895c2d04 7332 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7333 rn = "Count";
7334 break;
876d4b07 7335 /* 6,7 are implementation dependent */
9c2149c8 7336 default:
f31b035a 7337 goto cp0_unimplemented;
876d4b07
TS
7338 }
7339 /* Stop translation as we may have switched the execution mode */
7340 ctx->bstate = BS_STOP;
9c2149c8
TS
7341 break;
7342 case 10:
7343 switch (sel) {
7344 case 0:
895c2d04 7345 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7346 rn = "EntryHi";
7347 break;
9c2149c8 7348 default:
f31b035a 7349 goto cp0_unimplemented;
876d4b07 7350 }
9c2149c8
TS
7351 break;
7352 case 11:
7353 switch (sel) {
7354 case 0:
895c2d04 7355 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7356 rn = "Compare";
7357 break;
876d4b07 7358 /* 6,7 are implementation dependent */
9c2149c8 7359 default:
f31b035a 7360 goto cp0_unimplemented;
876d4b07 7361 }
de9a95f0
AJ
7362 /* Stop translation as we may have switched the execution mode */
7363 ctx->bstate = BS_STOP;
9c2149c8
TS
7364 break;
7365 case 12:
7366 switch (sel) {
7367 case 0:
867abc7e 7368 save_cpu_state(ctx, 1);
895c2d04 7369 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7370 /* BS_STOP isn't good enough here, hflags may have changed. */
7371 gen_save_pc(ctx->pc + 4);
7372 ctx->bstate = BS_EXCP;
2423f660
TS
7373 rn = "Status";
7374 break;
9c2149c8 7375 case 1:
d75c135e 7376 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7377 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7378 /* Stop translation as we may have switched the execution mode */
7379 ctx->bstate = BS_STOP;
2423f660
TS
7380 rn = "IntCtl";
7381 break;
9c2149c8 7382 case 2:
d75c135e 7383 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7384 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7385 /* Stop translation as we may have switched the execution mode */
7386 ctx->bstate = BS_STOP;
2423f660
TS
7387 rn = "SRSCtl";
7388 break;
9c2149c8 7389 case 3:
d75c135e 7390 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7391 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7392 /* Stop translation as we may have switched the execution mode */
7393 ctx->bstate = BS_STOP;
2423f660
TS
7394 rn = "SRSMap";
7395 break;
7396 default:
f31b035a 7397 goto cp0_unimplemented;
876d4b07 7398 }
9c2149c8
TS
7399 break;
7400 case 13:
7401 switch (sel) {
7402 case 0:
867abc7e 7403 save_cpu_state(ctx, 1);
895c2d04 7404 gen_helper_mtc0_cause(cpu_env, arg);
b74cddcb
JH
7405 /* Stop translation as we may have triggered an intetrupt. BS_STOP
7406 * isn't sufficient, we need to ensure we break out of translated
7407 * code to check for pending interrupts. */
7408 gen_save_pc(ctx->pc + 4);
7409 ctx->bstate = BS_EXCP;
2423f660
TS
7410 rn = "Cause";
7411 break;
9c2149c8 7412 default:
f31b035a 7413 goto cp0_unimplemented;
876d4b07 7414 }
9c2149c8
TS
7415 break;
7416 case 14:
7417 switch (sel) {
7418 case 0:
7db13fae 7419 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7420 rn = "EPC";
7421 break;
9c2149c8 7422 default:
f31b035a 7423 goto cp0_unimplemented;
876d4b07 7424 }
9c2149c8
TS
7425 break;
7426 case 15:
7427 switch (sel) {
7428 case 0:
2423f660
TS
7429 /* ignored */
7430 rn = "PRid";
7431 break;
9c2149c8 7432 case 1:
d75c135e 7433 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7434 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7435 rn = "EBase";
7436 break;
9c2149c8 7437 default:
f31b035a 7438 goto cp0_unimplemented;
876d4b07 7439 }
9c2149c8
TS
7440 break;
7441 case 16:
7442 switch (sel) {
7443 case 0:
895c2d04 7444 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7445 rn = "Config";
2423f660
TS
7446 /* Stop translation as we may have switched the execution mode */
7447 ctx->bstate = BS_STOP;
9c2149c8
TS
7448 break;
7449 case 1:
1fc7bf6e 7450 /* ignored, read only */
9c2149c8
TS
7451 rn = "Config1";
7452 break;
7453 case 2:
895c2d04 7454 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7455 rn = "Config2";
2423f660
TS
7456 /* Stop translation as we may have switched the execution mode */
7457 ctx->bstate = BS_STOP;
9c2149c8
TS
7458 break;
7459 case 3:
90f12d73 7460 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7461 rn = "Config3";
90f12d73
MR
7462 /* Stop translation as we may have switched the execution mode */
7463 ctx->bstate = BS_STOP;
9c2149c8 7464 break;
faf1f68b
LA
7465 case 4:
7466 /* currently ignored */
7467 rn = "Config4";
7468 break;
7469 case 5:
7470 gen_helper_mtc0_config5(cpu_env, arg);
7471 rn = "Config5";
7472 /* Stop translation as we may have switched the execution mode */
7473 ctx->bstate = BS_STOP;
7474 break;
9c2149c8
TS
7475 /* 6,7 are implementation dependent */
7476 default:
7477 rn = "Invalid config selector";
f31b035a 7478 goto cp0_unimplemented;
9c2149c8 7479 }
9c2149c8
TS
7480 break;
7481 case 17:
7482 switch (sel) {
7483 case 0:
895c2d04 7484 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7485 rn = "LLAddr";
7486 break;
f6d4dd81
YK
7487 case 1:
7488 CP0_CHECK(ctx->mrp);
7489 gen_helper_mtc0_maar(cpu_env, arg);
7490 rn = "MAAR";
7491 break;
7492 case 2:
7493 CP0_CHECK(ctx->mrp);
7494 gen_helper_mtc0_maari(cpu_env, arg);
7495 rn = "MAARI";
7496 break;
9c2149c8 7497 default:
f31b035a 7498 goto cp0_unimplemented;
9c2149c8
TS
7499 }
7500 break;
7501 case 18:
7502 switch (sel) {
fd88b6ab 7503 case 0 ... 7:
895c2d04 7504 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7505 rn = "WatchLo";
7506 break;
9c2149c8 7507 default:
f31b035a 7508 goto cp0_unimplemented;
9c2149c8
TS
7509 }
7510 break;
7511 case 19:
7512 switch (sel) {
fd88b6ab 7513 case 0 ... 7:
895c2d04 7514 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7515 rn = "WatchHi";
7516 break;
9c2149c8 7517 default:
f31b035a 7518 goto cp0_unimplemented;
9c2149c8
TS
7519 }
7520 break;
7521 case 20:
7522 switch (sel) {
7523 case 0:
d75c135e 7524 check_insn(ctx, ISA_MIPS3);
895c2d04 7525 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7526 rn = "XContext";
7527 break;
9c2149c8 7528 default:
f31b035a 7529 goto cp0_unimplemented;
9c2149c8
TS
7530 }
7531 break;
7532 case 21:
7533 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7534 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7535 switch (sel) {
7536 case 0:
895c2d04 7537 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7538 rn = "Framemask";
7539 break;
9c2149c8 7540 default:
f31b035a 7541 goto cp0_unimplemented;
9c2149c8
TS
7542 }
7543 break;
7544 case 22:
7545 /* ignored */
7546 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7547 break;
9c2149c8
TS
7548 case 23:
7549 switch (sel) {
7550 case 0:
895c2d04 7551 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7552 /* BS_STOP isn't good enough here, hflags may have changed. */
7553 gen_save_pc(ctx->pc + 4);
7554 ctx->bstate = BS_EXCP;
2423f660
TS
7555 rn = "Debug";
7556 break;
9c2149c8 7557 case 1:
895c2d04 7558// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7559 /* Stop translation as we may have switched the execution mode */
7560 ctx->bstate = BS_STOP;
2423f660 7561 rn = "TraceControl";
3570d7f6 7562 goto cp0_unimplemented;
9c2149c8 7563 case 2:
895c2d04 7564// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7565 /* Stop translation as we may have switched the execution mode */
7566 ctx->bstate = BS_STOP;
2423f660 7567 rn = "TraceControl2";
3570d7f6 7568 goto cp0_unimplemented;
9c2149c8 7569 case 3:
895c2d04 7570// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7571 /* Stop translation as we may have switched the execution mode */
7572 ctx->bstate = BS_STOP;
2423f660 7573 rn = "UserTraceData";
3570d7f6 7574 goto cp0_unimplemented;
9c2149c8 7575 case 4:
895c2d04 7576// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7577 /* Stop translation as we may have switched the execution mode */
7578 ctx->bstate = BS_STOP;
2423f660 7579 rn = "TraceBPC";
3570d7f6 7580 goto cp0_unimplemented;
9c2149c8 7581 default:
f31b035a 7582 goto cp0_unimplemented;
9c2149c8 7583 }
9c2149c8
TS
7584 break;
7585 case 24:
7586 switch (sel) {
7587 case 0:
f1aa6320 7588 /* EJTAG support */
7db13fae 7589 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7590 rn = "DEPC";
7591 break;
9c2149c8 7592 default:
f31b035a 7593 goto cp0_unimplemented;
9c2149c8
TS
7594 }
7595 break;
7596 case 25:
7597 switch (sel) {
7598 case 0:
895c2d04 7599 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7600 rn = "Performance0";
7601 break;
9c2149c8 7602 case 1:
895c2d04 7603// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 7604 rn = "Performance1";
3570d7f6 7605 goto cp0_unimplemented;
9c2149c8 7606 case 2:
895c2d04 7607// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 7608 rn = "Performance2";
3570d7f6 7609 goto cp0_unimplemented;
9c2149c8 7610 case 3:
895c2d04 7611// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 7612 rn = "Performance3";
3570d7f6 7613 goto cp0_unimplemented;
9c2149c8 7614 case 4:
895c2d04 7615// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 7616 rn = "Performance4";
3570d7f6 7617 goto cp0_unimplemented;
9c2149c8 7618 case 5:
895c2d04 7619// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 7620 rn = "Performance5";
3570d7f6 7621 goto cp0_unimplemented;
9c2149c8 7622 case 6:
895c2d04 7623// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 7624 rn = "Performance6";
3570d7f6 7625 goto cp0_unimplemented;
9c2149c8 7626 case 7:
895c2d04 7627// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 7628 rn = "Performance7";
3570d7f6 7629 goto cp0_unimplemented;
9c2149c8 7630 default:
f31b035a 7631 goto cp0_unimplemented;
9c2149c8 7632 }
876d4b07 7633 break;
9c2149c8 7634 case 26:
0d74a222
LA
7635 switch (sel) {
7636 case 0:
7637 gen_helper_mtc0_errctl(cpu_env, arg);
7638 ctx->bstate = BS_STOP;
7639 rn = "ErrCtl";
7640 break;
7641 default:
7642 goto cp0_unimplemented;
7643 }
876d4b07 7644 break;
9c2149c8
TS
7645 case 27:
7646 switch (sel) {
7647 case 0 ... 3:
2423f660
TS
7648 /* ignored */
7649 rn = "CacheErr";
7650 break;
9c2149c8 7651 default:
f31b035a 7652 goto cp0_unimplemented;
9c2149c8 7653 }
876d4b07 7654 break;
9c2149c8
TS
7655 case 28:
7656 switch (sel) {
7657 case 0:
7658 case 2:
7659 case 4:
7660 case 6:
895c2d04 7661 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7662 rn = "TagLo";
7663 break;
7664 case 1:
7665 case 3:
7666 case 5:
7667 case 7:
895c2d04 7668 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7669 rn = "DataLo";
7670 break;
7671 default:
f31b035a 7672 goto cp0_unimplemented;
9c2149c8
TS
7673 }
7674 break;
7675 case 29:
7676 switch (sel) {
7677 case 0:
7678 case 2:
7679 case 4:
7680 case 6:
895c2d04 7681 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7682 rn = "TagHi";
7683 break;
7684 case 1:
7685 case 3:
7686 case 5:
7687 case 7:
895c2d04 7688 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7689 rn = "DataHi";
7690 break;
7691 default:
7692 rn = "invalid sel";
f31b035a 7693 goto cp0_unimplemented;
9c2149c8 7694 }
876d4b07 7695 break;
9c2149c8
TS
7696 case 30:
7697 switch (sel) {
7698 case 0:
7db13fae 7699 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7700 rn = "ErrorEPC";
7701 break;
9c2149c8 7702 default:
f31b035a 7703 goto cp0_unimplemented;
9c2149c8
TS
7704 }
7705 break;
7706 case 31:
7707 switch (sel) {
7708 case 0:
f1aa6320 7709 /* EJTAG support */
7db13fae 7710 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7711 rn = "DESAVE";
7712 break;
e98c0d17 7713 case 2 ... 7:
f31b035a
LA
7714 CP0_CHECK(ctx->kscrexist & (1 << sel));
7715 tcg_gen_st_tl(arg, cpu_env,
7716 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7717 rn = "KScratch";
e98c0d17 7718 break;
9c2149c8 7719 default:
f31b035a 7720 goto cp0_unimplemented;
9c2149c8 7721 }
9c2149c8
TS
7722 break;
7723 default:
f31b035a 7724 goto cp0_unimplemented;
9c2149c8 7725 }
b44a7fb1
PMD
7726 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7727
bf20dc07 7728 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7729 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 7730 gen_io_end();
b74cddcb
JH
7731 /* BS_STOP isn't sufficient, we need to ensure we break out of
7732 * translated code to check for pending interrupts. */
7733 gen_save_pc(ctx->pc + 4);
7734 ctx->bstate = BS_EXCP;
2e70f6ef 7735 }
9c2149c8
TS
7736 return;
7737
f31b035a 7738cp0_unimplemented:
965447ee 7739 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7740}
d26bc211 7741#endif /* TARGET_MIPS64 */
9c2149c8 7742
7db13fae 7743static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7744 int u, int sel, int h)
7745{
7746 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7747 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7748
7749 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7750 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7751 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7752 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7753 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7754 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7755 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7756 else if (u == 0) {
7757 switch (rt) {
5a25ce94
EI
7758 case 1:
7759 switch (sel) {
7760 case 1:
895c2d04 7761 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7762 break;
7763 case 2:
895c2d04 7764 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7765 break;
7766 default:
7767 goto die;
7768 break;
7769 }
7770 break;
ead9360e
TS
7771 case 2:
7772 switch (sel) {
7773 case 1:
895c2d04 7774 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7775 break;
7776 case 2:
895c2d04 7777 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7778 break;
7779 case 3:
895c2d04 7780 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7781 break;
7782 case 4:
895c2d04 7783 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7784 break;
7785 case 5:
895c2d04 7786 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7787 break;
7788 case 6:
895c2d04 7789 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7790 break;
7791 case 7:
895c2d04 7792 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7793 break;
7794 default:
d75c135e 7795 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7796 break;
7797 }
7798 break;
7799 case 10:
7800 switch (sel) {
7801 case 0:
895c2d04 7802 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7803 break;
7804 default:
d75c135e 7805 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7806 break;
7807 }
7808 case 12:
7809 switch (sel) {
7810 case 0:
895c2d04 7811 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7812 break;
7813 default:
d75c135e 7814 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7815 break;
7816 }
5a25ce94
EI
7817 case 13:
7818 switch (sel) {
7819 case 0:
895c2d04 7820 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7821 break;
7822 default:
7823 goto die;
7824 break;
7825 }
7826 break;
7827 case 14:
7828 switch (sel) {
7829 case 0:
895c2d04 7830 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7831 break;
7832 default:
7833 goto die;
7834 break;
7835 }
7836 break;
7837 case 15:
7838 switch (sel) {
7839 case 1:
895c2d04 7840 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7841 break;
7842 default:
7843 goto die;
7844 break;
7845 }
7846 break;
7847 case 16:
7848 switch (sel) {
7849 case 0 ... 7:
895c2d04 7850 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7851 break;
7852 default:
7853 goto die;
7854 break;
7855 }
7856 break;
ead9360e
TS
7857 case 23:
7858 switch (sel) {
7859 case 0:
895c2d04 7860 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7861 break;
7862 default:
d75c135e 7863 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7864 break;
7865 }
7866 break;
7867 default:
d75c135e 7868 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7869 }
7870 } else switch (sel) {
7871 /* GPR registers. */
7872 case 0:
895c2d04 7873 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7874 break;
7875 /* Auxiliary CPU registers */
7876 case 1:
7877 switch (rt) {
7878 case 0:
895c2d04 7879 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7880 break;
7881 case 1:
895c2d04 7882 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7883 break;
7884 case 2:
895c2d04 7885 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7886 break;
7887 case 4:
895c2d04 7888 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7889 break;
7890 case 5:
895c2d04 7891 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7892 break;
7893 case 6:
895c2d04 7894 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7895 break;
7896 case 8:
895c2d04 7897 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7898 break;
7899 case 9:
895c2d04 7900 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7901 break;
7902 case 10:
895c2d04 7903 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7904 break;
7905 case 12:
895c2d04 7906 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7907 break;
7908 case 13:
895c2d04 7909 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7910 break;
7911 case 14:
895c2d04 7912 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7913 break;
7914 case 16:
895c2d04 7915 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7916 break;
7917 default:
7918 goto die;
7919 }
7920 break;
7921 /* Floating point (COP1). */
7922 case 2:
7923 /* XXX: For now we support only a single FPU context. */
7924 if (h == 0) {
a7812ae4 7925 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7926
7c979afd 7927 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7928 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7929 tcg_temp_free_i32(fp0);
ead9360e 7930 } else {
a7812ae4 7931 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7932
7f6613ce 7933 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7934 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7935 tcg_temp_free_i32(fp0);
ead9360e
TS
7936 }
7937 break;
7938 case 3:
7939 /* XXX: For now we support only a single FPU context. */
895c2d04 7940 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7941 break;
7942 /* COP2: Not implemented. */
7943 case 4:
7944 case 5:
7945 /* fall through */
7946 default:
7947 goto die;
7948 }
b44a7fb1 7949 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
7950 gen_store_gpr(t0, rd);
7951 tcg_temp_free(t0);
ead9360e
TS
7952 return;
7953
7954die:
1a3fd9c3 7955 tcg_temp_free(t0);
d12d51d5 7956 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7957 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7958}
7959
7db13fae 7960static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7961 int u, int sel, int h)
7962{
7963 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7964 TCGv t0 = tcg_temp_local_new();
ead9360e 7965
1a3fd9c3 7966 gen_load_gpr(t0, rt);
ead9360e 7967 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7968 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7969 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7970 /* NOP */ ;
7971 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7972 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7973 /* NOP */ ;
7974 else if (u == 0) {
7975 switch (rd) {
5a25ce94
EI
7976 case 1:
7977 switch (sel) {
7978 case 1:
895c2d04 7979 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7980 break;
7981 case 2:
895c2d04 7982 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7983 break;
7984 default:
7985 goto die;
7986 break;
7987 }
7988 break;
ead9360e
TS
7989 case 2:
7990 switch (sel) {
7991 case 1:
895c2d04 7992 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7993 break;
7994 case 2:
895c2d04 7995 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7996 break;
7997 case 3:
895c2d04 7998 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7999 break;
8000 case 4:
895c2d04 8001 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8002 break;
8003 case 5:
895c2d04 8004 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8005 break;
8006 case 6:
895c2d04 8007 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8008 break;
8009 case 7:
895c2d04 8010 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8011 break;
8012 default:
d75c135e 8013 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8014 break;
8015 }
8016 break;
8017 case 10:
8018 switch (sel) {
8019 case 0:
895c2d04 8020 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8021 break;
8022 default:
d75c135e 8023 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8024 break;
8025 }
8026 case 12:
8027 switch (sel) {
8028 case 0:
895c2d04 8029 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8030 break;
8031 default:
d75c135e 8032 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8033 break;
8034 }
5a25ce94
EI
8035 case 13:
8036 switch (sel) {
8037 case 0:
895c2d04 8038 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8039 break;
8040 default:
8041 goto die;
8042 break;
8043 }
8044 break;
8045 case 15:
8046 switch (sel) {
8047 case 1:
895c2d04 8048 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8049 break;
8050 default:
8051 goto die;
8052 break;
8053 }
8054 break;
ead9360e
TS
8055 case 23:
8056 switch (sel) {
8057 case 0:
895c2d04 8058 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8059 break;
8060 default:
d75c135e 8061 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8062 break;
8063 }
8064 break;
8065 default:
d75c135e 8066 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8067 }
8068 } else switch (sel) {
8069 /* GPR registers. */
8070 case 0:
895c2d04 8071 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8072 break;
8073 /* Auxiliary CPU registers */
8074 case 1:
8075 switch (rd) {
8076 case 0:
895c2d04 8077 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8078 break;
8079 case 1:
895c2d04 8080 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8081 break;
8082 case 2:
895c2d04 8083 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8084 break;
8085 case 4:
895c2d04 8086 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8087 break;
8088 case 5:
895c2d04 8089 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8090 break;
8091 case 6:
895c2d04 8092 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8093 break;
8094 case 8:
895c2d04 8095 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8096 break;
8097 case 9:
895c2d04 8098 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8099 break;
8100 case 10:
895c2d04 8101 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8102 break;
8103 case 12:
895c2d04 8104 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8105 break;
8106 case 13:
895c2d04 8107 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8108 break;
8109 case 14:
895c2d04 8110 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8111 break;
8112 case 16:
895c2d04 8113 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8114 break;
8115 default:
8116 goto die;
8117 }
8118 break;
8119 /* Floating point (COP1). */
8120 case 2:
8121 /* XXX: For now we support only a single FPU context. */
8122 if (h == 0) {
a7812ae4 8123 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8124
8125 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8126 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8127 tcg_temp_free_i32(fp0);
ead9360e 8128 } else {
a7812ae4 8129 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8130
8131 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8132 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8133 tcg_temp_free_i32(fp0);
ead9360e
TS
8134 }
8135 break;
8136 case 3:
8137 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
8138 {
8139 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8140
8141 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8142 tcg_temp_free_i32(fs_tmp);
8143 }
4cf8a45f
YK
8144 /* Stop translation as we may have changed hflags */
8145 ctx->bstate = BS_STOP;
ead9360e
TS
8146 break;
8147 /* COP2: Not implemented. */
8148 case 4:
8149 case 5:
8150 /* fall through */
8151 default:
8152 goto die;
8153 }
b44a7fb1 8154 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 8155 tcg_temp_free(t0);
ead9360e
TS
8156 return;
8157
8158die:
1a3fd9c3 8159 tcg_temp_free(t0);
d12d51d5 8160 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8161 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8162}
8163
7db13fae 8164static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8165{
287c4b84 8166 const char *opn = "ldst";
6af0bf9c 8167
2e15497c 8168 check_cp0_enabled(ctx);
6af0bf9c
FB
8169 switch (opc) {
8170 case OPC_MFC0:
8171 if (rt == 0) {
ead9360e 8172 /* Treat as NOP. */
6af0bf9c
FB
8173 return;
8174 }
d75c135e 8175 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8176 opn = "mfc0";
8177 break;
8178 case OPC_MTC0:
1a3fd9c3 8179 {
1fc7bf6e 8180 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8181
8182 gen_load_gpr(t0, rt);
d75c135e 8183 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8184 tcg_temp_free(t0);
8185 }
6af0bf9c
FB
8186 opn = "mtc0";
8187 break;
d26bc211 8188#if defined(TARGET_MIPS64)
9c2149c8 8189 case OPC_DMFC0:
d75c135e 8190 check_insn(ctx, ISA_MIPS3);
9c2149c8 8191 if (rt == 0) {
ead9360e 8192 /* Treat as NOP. */
9c2149c8
TS
8193 return;
8194 }
d75c135e 8195 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8196 opn = "dmfc0";
8197 break;
8198 case OPC_DMTC0:
d75c135e 8199 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8200 {
1fc7bf6e 8201 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8202
8203 gen_load_gpr(t0, rt);
d75c135e 8204 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8205 tcg_temp_free(t0);
8206 }
9c2149c8
TS
8207 opn = "dmtc0";
8208 break;
534ce69f 8209#endif
5204ea79
LA
8210 case OPC_MFHC0:
8211 check_mvh(ctx);
8212 if (rt == 0) {
8213 /* Treat as NOP. */
8214 return;
8215 }
8216 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8217 opn = "mfhc0";
8218 break;
8219 case OPC_MTHC0:
8220 check_mvh(ctx);
8221 {
8222 TCGv t0 = tcg_temp_new();
8223 gen_load_gpr(t0, rt);
8224 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8225 tcg_temp_free(t0);
8226 }
8227 opn = "mthc0";
8228 break;
ead9360e 8229 case OPC_MFTR:
d75c135e 8230 check_insn(ctx, ASE_MT);
ead9360e
TS
8231 if (rd == 0) {
8232 /* Treat as NOP. */
8233 return;
8234 }
6c5c1e20 8235 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8236 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8237 opn = "mftr";
8238 break;
8239 case OPC_MTTR:
d75c135e 8240 check_insn(ctx, ASE_MT);
6c5c1e20 8241 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8242 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8243 opn = "mttr";
8244 break;
6af0bf9c 8245 case OPC_TLBWI:
6af0bf9c 8246 opn = "tlbwi";
c01fccd2 8247 if (!env->tlb->helper_tlbwi)
29929e34 8248 goto die;
895c2d04 8249 gen_helper_tlbwi(cpu_env);
6af0bf9c 8250 break;
9456c2fb
LA
8251 case OPC_TLBINV:
8252 opn = "tlbinv";
8253 if (ctx->ie >= 2) {
8254 if (!env->tlb->helper_tlbinv) {
8255 goto die;
8256 }
8257 gen_helper_tlbinv(cpu_env);
8258 } /* treat as nop if TLBINV not supported */
8259 break;
8260 case OPC_TLBINVF:
8261 opn = "tlbinvf";
8262 if (ctx->ie >= 2) {
8263 if (!env->tlb->helper_tlbinvf) {
8264 goto die;
8265 }
8266 gen_helper_tlbinvf(cpu_env);
8267 } /* treat as nop if TLBINV not supported */
8268 break;
6af0bf9c 8269 case OPC_TLBWR:
6af0bf9c 8270 opn = "tlbwr";
c01fccd2 8271 if (!env->tlb->helper_tlbwr)
29929e34 8272 goto die;
895c2d04 8273 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8274 break;
8275 case OPC_TLBP:
6af0bf9c 8276 opn = "tlbp";
c01fccd2 8277 if (!env->tlb->helper_tlbp)
29929e34 8278 goto die;
895c2d04 8279 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8280 break;
8281 case OPC_TLBR:
6af0bf9c 8282 opn = "tlbr";
c01fccd2 8283 if (!env->tlb->helper_tlbr)
29929e34 8284 goto die;
895c2d04 8285 gen_helper_tlbr(cpu_env);
6af0bf9c 8286 break;
ce9782f4 8287 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8288 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8289 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8290 goto die;
ce9782f4
LA
8291 } else {
8292 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8293 if (ctx->opcode & (1 << bit_shift)) {
8294 /* OPC_ERETNC */
8295 opn = "eretnc";
8296 check_insn(ctx, ISA_MIPS32R5);
8297 gen_helper_eretnc(cpu_env);
8298 } else {
8299 /* OPC_ERET */
8300 opn = "eret";
8301 check_insn(ctx, ISA_MIPS2);
8302 gen_helper_eret(cpu_env);
8303 }
8304 ctx->bstate = BS_EXCP;
339cd2a8 8305 }
6af0bf9c
FB
8306 break;
8307 case OPC_DERET:
8308 opn = "deret";
d75c135e 8309 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8310 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8311 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8312 goto die;
8313 }
6af0bf9c 8314 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8315 MIPS_INVAL(opn);
9c708c7f 8316 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8317 } else {
895c2d04 8318 gen_helper_deret(cpu_env);
6af0bf9c
FB
8319 ctx->bstate = BS_EXCP;
8320 }
8321 break;
4ad40f36
FB
8322 case OPC_WAIT:
8323 opn = "wait";
d75c135e 8324 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8325 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8326 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8327 goto die;
8328 }
4ad40f36
FB
8329 /* If we get an exception, we want to restart at next instruction */
8330 ctx->pc += 4;
8331 save_cpu_state(ctx, 1);
8332 ctx->pc -= 4;
895c2d04 8333 gen_helper_wait(cpu_env);
4ad40f36
FB
8334 ctx->bstate = BS_EXCP;
8335 break;
6af0bf9c 8336 default:
29929e34 8337 die:
923617a3 8338 MIPS_INVAL(opn);
9c708c7f 8339 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8340 return;
8341 }
2abf314d 8342 (void)opn; /* avoid a compiler warning */
6af0bf9c 8343}
f1aa6320 8344#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8345
6ea83fed 8346/* CP1 Branches (before delay slot) */
d75c135e
AJ
8347static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8348 int32_t cc, int32_t offset)
6ea83fed
FB
8349{
8350 target_ulong btarget;
a7812ae4 8351 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8352
339cd2a8 8353 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8354 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8355 goto out;
8356 }
8357
e189e748 8358 if (cc != 0)
d75c135e 8359 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8360
6ea83fed
FB
8361 btarget = ctx->pc + 4 + offset;
8362
7a387fff
TS
8363 switch (op) {
8364 case OPC_BC1F:
d94536f4
AJ
8365 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8366 tcg_gen_not_i32(t0, t0);
8367 tcg_gen_andi_i32(t0, t0, 1);
8368 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8369 goto not_likely;
7a387fff 8370 case OPC_BC1FL:
d94536f4
AJ
8371 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8372 tcg_gen_not_i32(t0, t0);
8373 tcg_gen_andi_i32(t0, t0, 1);
8374 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8375 goto likely;
7a387fff 8376 case OPC_BC1T:
d94536f4
AJ
8377 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8378 tcg_gen_andi_i32(t0, t0, 1);
8379 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8380 goto not_likely;
7a387fff 8381 case OPC_BC1TL:
d94536f4
AJ
8382 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8383 tcg_gen_andi_i32(t0, t0, 1);
8384 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8385 likely:
8386 ctx->hflags |= MIPS_HFLAG_BL;
8387 break;
5a5012ec 8388 case OPC_BC1FANY2:
a16336e4 8389 {
d94536f4
AJ
8390 TCGv_i32 t1 = tcg_temp_new_i32();
8391 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8392 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8393 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8394 tcg_temp_free_i32(t1);
d94536f4
AJ
8395 tcg_gen_andi_i32(t0, t0, 1);
8396 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8397 }
5a5012ec
TS
8398 goto not_likely;
8399 case OPC_BC1TANY2:
a16336e4 8400 {
d94536f4
AJ
8401 TCGv_i32 t1 = tcg_temp_new_i32();
8402 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8403 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8404 tcg_gen_or_i32(t0, t0, t1);
8405 tcg_temp_free_i32(t1);
8406 tcg_gen_andi_i32(t0, t0, 1);
8407 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8408 }
5a5012ec
TS
8409 goto not_likely;
8410 case OPC_BC1FANY4:
a16336e4 8411 {
d94536f4
AJ
8412 TCGv_i32 t1 = tcg_temp_new_i32();
8413 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8414 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8415 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8416 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8417 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8418 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8419 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8420 tcg_temp_free_i32(t1);
d94536f4
AJ
8421 tcg_gen_andi_i32(t0, t0, 1);
8422 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8423 }
5a5012ec
TS
8424 goto not_likely;
8425 case OPC_BC1TANY4:
a16336e4 8426 {
d94536f4
AJ
8427 TCGv_i32 t1 = tcg_temp_new_i32();
8428 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8429 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8430 tcg_gen_or_i32(t0, t0, t1);
8431 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8432 tcg_gen_or_i32(t0, t0, t1);
8433 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8434 tcg_gen_or_i32(t0, t0, t1);
8435 tcg_temp_free_i32(t1);
8436 tcg_gen_andi_i32(t0, t0, 1);
8437 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8438 }
5a5012ec
TS
8439 not_likely:
8440 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8441 break;
8442 default:
9d68ac14 8443 MIPS_INVAL("cp1 cond branch");
9c708c7f 8444 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8445 goto out;
6ea83fed 8446 }
6ea83fed 8447 ctx->btarget = btarget;
b231c103 8448 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8449 out:
a7812ae4 8450 tcg_temp_free_i32(t0);
6ea83fed
FB
8451}
8452
31837be3
YK
8453/* R6 CP1 Branches */
8454static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8455 int32_t ft, int32_t offset,
8456 int delayslot_size)
31837be3
YK
8457{
8458 target_ulong btarget;
31837be3
YK
8459 TCGv_i64 t0 = tcg_temp_new_i64();
8460
8461 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8462#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8463 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8464 "\n", ctx->pc);
31837be3 8465#endif
9c708c7f 8466 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8467 goto out;
8468 }
8469
8470 gen_load_fpr64(ctx, t0, ft);
8471 tcg_gen_andi_i64(t0, t0, 1);
8472
8473 btarget = addr_add(ctx, ctx->pc + 4, offset);
8474
8475 switch (op) {
8476 case OPC_BC1EQZ:
8477 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8478 ctx->hflags |= MIPS_HFLAG_BC;
8479 break;
8480 case OPC_BC1NEZ:
8481 /* t0 already set */
31837be3
YK
8482 ctx->hflags |= MIPS_HFLAG_BC;
8483 break;
8484 default:
9d68ac14 8485 MIPS_INVAL("cp1 cond branch");
9c708c7f 8486 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8487 goto out;
8488 }
8489
8490 tcg_gen_trunc_i64_tl(bcond, t0);
8491
31837be3 8492 ctx->btarget = btarget;
65935f07
YK
8493
8494 switch (delayslot_size) {
8495 case 2:
8496 ctx->hflags |= MIPS_HFLAG_BDS16;
8497 break;
8498 case 4:
8499 ctx->hflags |= MIPS_HFLAG_BDS32;
8500 break;
8501 }
31837be3
YK
8502
8503out:
8504 tcg_temp_free_i64(t0);
8505}
8506
6af0bf9c 8507/* Coprocessor 1 (FPU) */
5a5012ec 8508
5a5012ec
TS
8509#define FOP(func, fmt) (((fmt) << 21) | (func))
8510
bf4120ad
NF
8511enum fopcode {
8512 OPC_ADD_S = FOP(0, FMT_S),
8513 OPC_SUB_S = FOP(1, FMT_S),
8514 OPC_MUL_S = FOP(2, FMT_S),
8515 OPC_DIV_S = FOP(3, FMT_S),
8516 OPC_SQRT_S = FOP(4, FMT_S),
8517 OPC_ABS_S = FOP(5, FMT_S),
8518 OPC_MOV_S = FOP(6, FMT_S),
8519 OPC_NEG_S = FOP(7, FMT_S),
8520 OPC_ROUND_L_S = FOP(8, FMT_S),
8521 OPC_TRUNC_L_S = FOP(9, FMT_S),
8522 OPC_CEIL_L_S = FOP(10, FMT_S),
8523 OPC_FLOOR_L_S = FOP(11, FMT_S),
8524 OPC_ROUND_W_S = FOP(12, FMT_S),
8525 OPC_TRUNC_W_S = FOP(13, FMT_S),
8526 OPC_CEIL_W_S = FOP(14, FMT_S),
8527 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8528 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8529 OPC_MOVCF_S = FOP(17, FMT_S),
8530 OPC_MOVZ_S = FOP(18, FMT_S),
8531 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8532 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8533 OPC_RECIP_S = FOP(21, FMT_S),
8534 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8535 OPC_SELNEZ_S = FOP(23, FMT_S),
8536 OPC_MADDF_S = FOP(24, FMT_S),
8537 OPC_MSUBF_S = FOP(25, FMT_S),
8538 OPC_RINT_S = FOP(26, FMT_S),
8539 OPC_CLASS_S = FOP(27, FMT_S),
8540 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8541 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8542 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8543 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8544 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8545 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8546 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8547 OPC_RSQRT2_S = FOP(31, FMT_S),
8548 OPC_CVT_D_S = FOP(33, FMT_S),
8549 OPC_CVT_W_S = FOP(36, FMT_S),
8550 OPC_CVT_L_S = FOP(37, FMT_S),
8551 OPC_CVT_PS_S = FOP(38, FMT_S),
8552 OPC_CMP_F_S = FOP (48, FMT_S),
8553 OPC_CMP_UN_S = FOP (49, FMT_S),
8554 OPC_CMP_EQ_S = FOP (50, FMT_S),
8555 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8556 OPC_CMP_OLT_S = FOP (52, FMT_S),
8557 OPC_CMP_ULT_S = FOP (53, FMT_S),
8558 OPC_CMP_OLE_S = FOP (54, FMT_S),
8559 OPC_CMP_ULE_S = FOP (55, FMT_S),
8560 OPC_CMP_SF_S = FOP (56, FMT_S),
8561 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8562 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8563 OPC_CMP_NGL_S = FOP (59, FMT_S),
8564 OPC_CMP_LT_S = FOP (60, FMT_S),
8565 OPC_CMP_NGE_S = FOP (61, FMT_S),
8566 OPC_CMP_LE_S = FOP (62, FMT_S),
8567 OPC_CMP_NGT_S = FOP (63, FMT_S),
8568
8569 OPC_ADD_D = FOP(0, FMT_D),
8570 OPC_SUB_D = FOP(1, FMT_D),
8571 OPC_MUL_D = FOP(2, FMT_D),
8572 OPC_DIV_D = FOP(3, FMT_D),
8573 OPC_SQRT_D = FOP(4, FMT_D),
8574 OPC_ABS_D = FOP(5, FMT_D),
8575 OPC_MOV_D = FOP(6, FMT_D),
8576 OPC_NEG_D = FOP(7, FMT_D),
8577 OPC_ROUND_L_D = FOP(8, FMT_D),
8578 OPC_TRUNC_L_D = FOP(9, FMT_D),
8579 OPC_CEIL_L_D = FOP(10, FMT_D),
8580 OPC_FLOOR_L_D = FOP(11, FMT_D),
8581 OPC_ROUND_W_D = FOP(12, FMT_D),
8582 OPC_TRUNC_W_D = FOP(13, FMT_D),
8583 OPC_CEIL_W_D = FOP(14, FMT_D),
8584 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8585 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8586 OPC_MOVCF_D = FOP(17, FMT_D),
8587 OPC_MOVZ_D = FOP(18, FMT_D),
8588 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8589 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8590 OPC_RECIP_D = FOP(21, FMT_D),
8591 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8592 OPC_SELNEZ_D = FOP(23, FMT_D),
8593 OPC_MADDF_D = FOP(24, FMT_D),
8594 OPC_MSUBF_D = FOP(25, FMT_D),
8595 OPC_RINT_D = FOP(26, FMT_D),
8596 OPC_CLASS_D = FOP(27, FMT_D),
8597 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8598 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8599 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8600 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8601 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8602 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8603 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8604 OPC_RSQRT2_D = FOP(31, FMT_D),
8605 OPC_CVT_S_D = FOP(32, FMT_D),
8606 OPC_CVT_W_D = FOP(36, FMT_D),
8607 OPC_CVT_L_D = FOP(37, FMT_D),
8608 OPC_CMP_F_D = FOP (48, FMT_D),
8609 OPC_CMP_UN_D = FOP (49, FMT_D),
8610 OPC_CMP_EQ_D = FOP (50, FMT_D),
8611 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8612 OPC_CMP_OLT_D = FOP (52, FMT_D),
8613 OPC_CMP_ULT_D = FOP (53, FMT_D),
8614 OPC_CMP_OLE_D = FOP (54, FMT_D),
8615 OPC_CMP_ULE_D = FOP (55, FMT_D),
8616 OPC_CMP_SF_D = FOP (56, FMT_D),
8617 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8618 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8619 OPC_CMP_NGL_D = FOP (59, FMT_D),
8620 OPC_CMP_LT_D = FOP (60, FMT_D),
8621 OPC_CMP_NGE_D = FOP (61, FMT_D),
8622 OPC_CMP_LE_D = FOP (62, FMT_D),
8623 OPC_CMP_NGT_D = FOP (63, FMT_D),
8624
8625 OPC_CVT_S_W = FOP(32, FMT_W),
8626 OPC_CVT_D_W = FOP(33, FMT_W),
8627 OPC_CVT_S_L = FOP(32, FMT_L),
8628 OPC_CVT_D_L = FOP(33, FMT_L),
8629 OPC_CVT_PS_PW = FOP(38, FMT_W),
8630
8631 OPC_ADD_PS = FOP(0, FMT_PS),
8632 OPC_SUB_PS = FOP(1, FMT_PS),
8633 OPC_MUL_PS = FOP(2, FMT_PS),
8634 OPC_DIV_PS = FOP(3, FMT_PS),
8635 OPC_ABS_PS = FOP(5, FMT_PS),
8636 OPC_MOV_PS = FOP(6, FMT_PS),
8637 OPC_NEG_PS = FOP(7, FMT_PS),
8638 OPC_MOVCF_PS = FOP(17, FMT_PS),
8639 OPC_MOVZ_PS = FOP(18, FMT_PS),
8640 OPC_MOVN_PS = FOP(19, FMT_PS),
8641 OPC_ADDR_PS = FOP(24, FMT_PS),
8642 OPC_MULR_PS = FOP(26, FMT_PS),
8643 OPC_RECIP2_PS = FOP(28, FMT_PS),
8644 OPC_RECIP1_PS = FOP(29, FMT_PS),
8645 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8646 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8647
8648 OPC_CVT_S_PU = FOP(32, FMT_PS),
8649 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8650 OPC_CVT_S_PL = FOP(40, FMT_PS),
8651 OPC_PLL_PS = FOP(44, FMT_PS),
8652 OPC_PLU_PS = FOP(45, FMT_PS),
8653 OPC_PUL_PS = FOP(46, FMT_PS),
8654 OPC_PUU_PS = FOP(47, FMT_PS),
8655 OPC_CMP_F_PS = FOP (48, FMT_PS),
8656 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8657 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8658 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8659 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8660 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8661 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8662 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8663 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8664 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8665 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8666 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8667 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8668 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8669 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8670 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8671};
8672
3f493883
YK
8673enum r6_f_cmp_op {
8674 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8675 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8676 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8677 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8678 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8679 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8680 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8681 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8682 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8683 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8684 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8685 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8686 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8687 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8688 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8689 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8690 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8691 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8692 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8693 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8694 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8695 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8696
8697 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8698 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8699 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8700 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8701 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8702 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8703 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8704 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8705 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8706 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8707 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8708 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8709 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8710 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8711 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8712 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8713 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8714 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8715 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8716 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8717 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8718 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8719};
7a387fff 8720static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8721{
72c3a3ee 8722 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8723
8724 switch (opc) {
8725 case OPC_MFC1:
b6d96bed 8726 {
a7812ae4 8727 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8728
7c979afd 8729 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8730 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8731 tcg_temp_free_i32(fp0);
6958549d 8732 }
6c5c1e20 8733 gen_store_gpr(t0, rt);
6ea83fed
FB
8734 break;
8735 case OPC_MTC1:
6c5c1e20 8736 gen_load_gpr(t0, rt);
b6d96bed 8737 {
a7812ae4 8738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8739
8740 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8741 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8742 tcg_temp_free_i32(fp0);
6958549d 8743 }
6ea83fed
FB
8744 break;
8745 case OPC_CFC1:
895c2d04 8746 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8747 gen_store_gpr(t0, rt);
6ea83fed
FB
8748 break;
8749 case OPC_CTC1:
6c5c1e20 8750 gen_load_gpr(t0, rt);
9c708c7f 8751 save_cpu_state(ctx, 0);
736d120a
PJ
8752 {
8753 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8754
8755 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8756 tcg_temp_free_i32(fs_tmp);
8757 }
4cf8a45f
YK
8758 /* Stop translation as we may have changed hflags */
8759 ctx->bstate = BS_STOP;
6ea83fed 8760 break;
72c3a3ee 8761#if defined(TARGET_MIPS64)
9c2149c8 8762 case OPC_DMFC1:
72c3a3ee 8763 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8764 gen_store_gpr(t0, rt);
5a5012ec 8765 break;
9c2149c8 8766 case OPC_DMTC1:
6c5c1e20 8767 gen_load_gpr(t0, rt);
72c3a3ee 8768 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8769 break;
72c3a3ee 8770#endif
5a5012ec 8771 case OPC_MFHC1:
b6d96bed 8772 {
a7812ae4 8773 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8774
7f6613ce 8775 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8776 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8777 tcg_temp_free_i32(fp0);
6958549d 8778 }
6c5c1e20 8779 gen_store_gpr(t0, rt);
5a5012ec
TS
8780 break;
8781 case OPC_MTHC1:
6c5c1e20 8782 gen_load_gpr(t0, rt);
b6d96bed 8783 {
a7812ae4 8784 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8785
8786 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8787 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8788 tcg_temp_free_i32(fp0);
6958549d 8789 }
5a5012ec 8790 break;
6ea83fed 8791 default:
9d68ac14 8792 MIPS_INVAL("cp1 move");
9c708c7f 8793 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8794 goto out;
6ea83fed 8795 }
6c5c1e20
TS
8796
8797 out:
8798 tcg_temp_free(t0);
6ea83fed
FB
8799}
8800
5a5012ec
TS
8801static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8802{
42a268c2 8803 TCGLabel *l1;
e214b9bb 8804 TCGCond cond;
af58f9ca
AJ
8805 TCGv_i32 t0;
8806
8807 if (rd == 0) {
8808 /* Treat as NOP. */
8809 return;
8810 }
6ea83fed 8811
e214b9bb 8812 if (tf)
e214b9bb 8813 cond = TCG_COND_EQ;
27848470
TS
8814 else
8815 cond = TCG_COND_NE;
8816
af58f9ca
AJ
8817 l1 = gen_new_label();
8818 t0 = tcg_temp_new_i32();
fa31af0e 8819 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8820 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8821 tcg_temp_free_i32(t0);
af58f9ca
AJ
8822 if (rs == 0) {
8823 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8824 } else {
8825 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8826 }
e214b9bb 8827 gen_set_label(l1);
5a5012ec
TS
8828}
8829
7c979afd
LA
8830static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8831 int tf)
a16336e4 8832{
a16336e4 8833 int cond;
cbc37b28 8834 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8835 TCGLabel *l1 = gen_new_label();
a16336e4 8836
a16336e4
TS
8837 if (tf)
8838 cond = TCG_COND_EQ;
8839 else
8840 cond = TCG_COND_NE;
8841
fa31af0e 8842 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8843 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8844 gen_load_fpr32(ctx, t0, fs);
8845 gen_store_fpr32(ctx, t0, fd);
a16336e4 8846 gen_set_label(l1);
cbc37b28 8847 tcg_temp_free_i32(t0);
5a5012ec 8848}
a16336e4 8849
b6d96bed 8850static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8851{
a16336e4 8852 int cond;
cbc37b28
AJ
8853 TCGv_i32 t0 = tcg_temp_new_i32();
8854 TCGv_i64 fp0;
42a268c2 8855 TCGLabel *l1 = gen_new_label();
a16336e4 8856
a16336e4
TS
8857 if (tf)
8858 cond = TCG_COND_EQ;
8859 else
8860 cond = TCG_COND_NE;
8861
fa31af0e 8862 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8863 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8864 tcg_temp_free_i32(t0);
11f94258 8865 fp0 = tcg_temp_new_i64();
9bf3eb2c 8866 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8867 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8868 tcg_temp_free_i64(fp0);
cbc37b28 8869 gen_set_label(l1);
a16336e4
TS
8870}
8871
7f6613ce
PJ
8872static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8873 int cc, int tf)
a16336e4
TS
8874{
8875 int cond;
cbc37b28 8876 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8877 TCGLabel *l1 = gen_new_label();
8878 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8879
8880 if (tf)
8881 cond = TCG_COND_EQ;
8882 else
8883 cond = TCG_COND_NE;
8884
fa31af0e 8885 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8886 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8887 gen_load_fpr32(ctx, t0, fs);
8888 gen_store_fpr32(ctx, t0, fd);
a16336e4 8889 gen_set_label(l1);
9bf3eb2c 8890
fa31af0e 8891 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8892 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8893 gen_load_fpr32h(ctx, t0, fs);
8894 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8895 tcg_temp_free_i32(t0);
a16336e4 8896 gen_set_label(l2);
a16336e4
TS
8897}
8898
e7f16abb
LA
8899static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8900 int fs)
8901{
8902 TCGv_i32 t1 = tcg_const_i32(0);
8903 TCGv_i32 fp0 = tcg_temp_new_i32();
8904 TCGv_i32 fp1 = tcg_temp_new_i32();
8905 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8906 gen_load_fpr32(ctx, fp0, fd);
8907 gen_load_fpr32(ctx, fp1, ft);
8908 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8909
8910 switch (op1) {
8911 case OPC_SEL_S:
8912 tcg_gen_andi_i32(fp0, fp0, 1);
8913 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8914 break;
8915 case OPC_SELEQZ_S:
8916 tcg_gen_andi_i32(fp1, fp1, 1);
8917 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8918 break;
8919 case OPC_SELNEZ_S:
8920 tcg_gen_andi_i32(fp1, fp1, 1);
8921 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8922 break;
8923 default:
8924 MIPS_INVAL("gen_sel_s");
9c708c7f 8925 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8926 break;
8927 }
8928
7c979afd 8929 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8930 tcg_temp_free_i32(fp2);
8931 tcg_temp_free_i32(fp1);
8932 tcg_temp_free_i32(fp0);
8933 tcg_temp_free_i32(t1);
8934}
8935
8936static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8937 int fs)
8938{
8939 TCGv_i64 t1 = tcg_const_i64(0);
8940 TCGv_i64 fp0 = tcg_temp_new_i64();
8941 TCGv_i64 fp1 = tcg_temp_new_i64();
8942 TCGv_i64 fp2 = tcg_temp_new_i64();
8943 gen_load_fpr64(ctx, fp0, fd);
8944 gen_load_fpr64(ctx, fp1, ft);
8945 gen_load_fpr64(ctx, fp2, fs);
8946
8947 switch (op1) {
8948 case OPC_SEL_D:
8949 tcg_gen_andi_i64(fp0, fp0, 1);
8950 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8951 break;
8952 case OPC_SELEQZ_D:
8953 tcg_gen_andi_i64(fp1, fp1, 1);
8954 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8955 break;
8956 case OPC_SELNEZ_D:
8957 tcg_gen_andi_i64(fp1, fp1, 1);
8958 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8959 break;
8960 default:
8961 MIPS_INVAL("gen_sel_d");
9c708c7f 8962 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8963 break;
8964 }
8965
8966 gen_store_fpr64(ctx, fp0, fd);
8967 tcg_temp_free_i64(fp2);
8968 tcg_temp_free_i64(fp1);
8969 tcg_temp_free_i64(fp0);
8970 tcg_temp_free_i64(t1);
8971}
6ea83fed 8972
bf4120ad 8973static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8974 int ft, int fs, int fd, int cc)
6ea83fed 8975{
7a387fff 8976 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8977 switch (op1) {
8978 case OPC_ADD_S:
b6d96bed 8979 {
a7812ae4
PB
8980 TCGv_i32 fp0 = tcg_temp_new_i32();
8981 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8982
7c979afd
LA
8983 gen_load_fpr32(ctx, fp0, fs);
8984 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8985 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8986 tcg_temp_free_i32(fp1);
7c979afd 8987 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8988 tcg_temp_free_i32(fp0);
b6d96bed 8989 }
5a5012ec 8990 break;
bf4120ad 8991 case OPC_SUB_S:
b6d96bed 8992 {
a7812ae4
PB
8993 TCGv_i32 fp0 = tcg_temp_new_i32();
8994 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8995
7c979afd
LA
8996 gen_load_fpr32(ctx, fp0, fs);
8997 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8998 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8999 tcg_temp_free_i32(fp1);
7c979afd 9000 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9001 tcg_temp_free_i32(fp0);
b6d96bed 9002 }
5a5012ec 9003 break;
bf4120ad 9004 case OPC_MUL_S:
b6d96bed 9005 {
a7812ae4
PB
9006 TCGv_i32 fp0 = tcg_temp_new_i32();
9007 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9008
7c979afd
LA
9009 gen_load_fpr32(ctx, fp0, fs);
9010 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9011 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9012 tcg_temp_free_i32(fp1);
7c979afd 9013 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9014 tcg_temp_free_i32(fp0);
b6d96bed 9015 }
5a5012ec 9016 break;
bf4120ad 9017 case OPC_DIV_S:
b6d96bed 9018 {
a7812ae4
PB
9019 TCGv_i32 fp0 = tcg_temp_new_i32();
9020 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9021
7c979afd
LA
9022 gen_load_fpr32(ctx, fp0, fs);
9023 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9024 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9025 tcg_temp_free_i32(fp1);
7c979afd 9026 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9027 tcg_temp_free_i32(fp0);
b6d96bed 9028 }
5a5012ec 9029 break;
bf4120ad 9030 case OPC_SQRT_S:
b6d96bed 9031 {
a7812ae4 9032 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9033
7c979afd 9034 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9035 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9036 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9037 tcg_temp_free_i32(fp0);
b6d96bed 9038 }
5a5012ec 9039 break;
bf4120ad 9040 case OPC_ABS_S:
b6d96bed 9041 {
a7812ae4 9042 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9043
7c979afd 9044 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9045 if (ctx->abs2008) {
9046 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9047 } else {
9048 gen_helper_float_abs_s(fp0, fp0);
9049 }
7c979afd 9050 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9051 tcg_temp_free_i32(fp0);
b6d96bed 9052 }
5a5012ec 9053 break;
bf4120ad 9054 case OPC_MOV_S:
b6d96bed 9055 {
a7812ae4 9056 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9057
7c979afd
LA
9058 gen_load_fpr32(ctx, fp0, fs);
9059 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9060 tcg_temp_free_i32(fp0);
b6d96bed 9061 }
5a5012ec 9062 break;
bf4120ad 9063 case OPC_NEG_S:
b6d96bed 9064 {
a7812ae4 9065 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9066
7c979afd 9067 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9068 if (ctx->abs2008) {
9069 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9070 } else {
9071 gen_helper_float_chs_s(fp0, fp0);
9072 }
7c979afd 9073 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9074 tcg_temp_free_i32(fp0);
b6d96bed 9075 }
5a5012ec 9076 break;
bf4120ad 9077 case OPC_ROUND_L_S:
5e755519 9078 check_cp1_64bitmode(ctx);
b6d96bed 9079 {
a7812ae4
PB
9080 TCGv_i32 fp32 = tcg_temp_new_i32();
9081 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9082
7c979afd 9083 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9084 if (ctx->nan2008) {
9085 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9086 } else {
9087 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9088 }
a7812ae4 9089 tcg_temp_free_i32(fp32);
b6d96bed 9090 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9091 tcg_temp_free_i64(fp64);
b6d96bed 9092 }
5a5012ec 9093 break;
bf4120ad 9094 case OPC_TRUNC_L_S:
5e755519 9095 check_cp1_64bitmode(ctx);
b6d96bed 9096 {
a7812ae4
PB
9097 TCGv_i32 fp32 = tcg_temp_new_i32();
9098 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9099
7c979afd 9100 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9101 if (ctx->nan2008) {
9102 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9103 } else {
9104 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9105 }
a7812ae4 9106 tcg_temp_free_i32(fp32);
b6d96bed 9107 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9108 tcg_temp_free_i64(fp64);
b6d96bed 9109 }
5a5012ec 9110 break;
bf4120ad 9111 case OPC_CEIL_L_S:
5e755519 9112 check_cp1_64bitmode(ctx);
b6d96bed 9113 {
a7812ae4
PB
9114 TCGv_i32 fp32 = tcg_temp_new_i32();
9115 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9116
7c979afd 9117 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9118 if (ctx->nan2008) {
9119 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9120 } else {
9121 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9122 }
a7812ae4 9123 tcg_temp_free_i32(fp32);
b6d96bed 9124 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9125 tcg_temp_free_i64(fp64);
b6d96bed 9126 }
5a5012ec 9127 break;
bf4120ad 9128 case OPC_FLOOR_L_S:
5e755519 9129 check_cp1_64bitmode(ctx);
b6d96bed 9130 {
a7812ae4
PB
9131 TCGv_i32 fp32 = tcg_temp_new_i32();
9132 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9133
7c979afd 9134 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9135 if (ctx->nan2008) {
9136 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9137 } else {
9138 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9139 }
a7812ae4 9140 tcg_temp_free_i32(fp32);
b6d96bed 9141 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9142 tcg_temp_free_i64(fp64);
b6d96bed 9143 }
5a5012ec 9144 break;
bf4120ad 9145 case OPC_ROUND_W_S:
b6d96bed 9146 {
a7812ae4 9147 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9148
7c979afd 9149 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9150 if (ctx->nan2008) {
9151 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9152 } else {
9153 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9154 }
7c979afd 9155 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9156 tcg_temp_free_i32(fp0);
b6d96bed 9157 }
5a5012ec 9158 break;
bf4120ad 9159 case OPC_TRUNC_W_S:
b6d96bed 9160 {
a7812ae4 9161 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9162
7c979afd 9163 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9164 if (ctx->nan2008) {
9165 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9166 } else {
9167 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9168 }
7c979afd 9169 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9170 tcg_temp_free_i32(fp0);
b6d96bed 9171 }
5a5012ec 9172 break;
bf4120ad 9173 case OPC_CEIL_W_S:
b6d96bed 9174 {
a7812ae4 9175 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9176
7c979afd 9177 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9178 if (ctx->nan2008) {
9179 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9180 } else {
9181 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9182 }
7c979afd 9183 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9184 tcg_temp_free_i32(fp0);
b6d96bed 9185 }
5a5012ec 9186 break;
bf4120ad 9187 case OPC_FLOOR_W_S:
b6d96bed 9188 {
a7812ae4 9189 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9190
7c979afd 9191 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9192 if (ctx->nan2008) {
9193 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9194 } else {
9195 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9196 }
7c979afd 9197 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9198 tcg_temp_free_i32(fp0);
b6d96bed 9199 }
5a5012ec 9200 break;
e7f16abb
LA
9201 case OPC_SEL_S:
9202 check_insn(ctx, ISA_MIPS32R6);
9203 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9204 break;
9205 case OPC_SELEQZ_S:
9206 check_insn(ctx, ISA_MIPS32R6);
9207 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9208 break;
9209 case OPC_SELNEZ_S:
9210 check_insn(ctx, ISA_MIPS32R6);
9211 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9212 break;
bf4120ad 9213 case OPC_MOVCF_S:
fecd2646 9214 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9215 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9216 break;
bf4120ad 9217 case OPC_MOVZ_S:
fecd2646 9218 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9219 {
42a268c2 9220 TCGLabel *l1 = gen_new_label();
c9297f4d 9221 TCGv_i32 fp0;
a16336e4 9222
c9297f4d
AJ
9223 if (ft != 0) {
9224 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9225 }
9226 fp0 = tcg_temp_new_i32();
7c979afd
LA
9227 gen_load_fpr32(ctx, fp0, fs);
9228 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9229 tcg_temp_free_i32(fp0);
a16336e4
TS
9230 gen_set_label(l1);
9231 }
5a5012ec 9232 break;
bf4120ad 9233 case OPC_MOVN_S:
fecd2646 9234 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9235 {
42a268c2 9236 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9237 TCGv_i32 fp0;
9238
9239 if (ft != 0) {
9240 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9241 fp0 = tcg_temp_new_i32();
7c979afd
LA
9242 gen_load_fpr32(ctx, fp0, fs);
9243 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9244 tcg_temp_free_i32(fp0);
9245 gen_set_label(l1);
9246 }
a16336e4 9247 }
5a5012ec 9248 break;
bf4120ad 9249 case OPC_RECIP_S:
b6d96bed 9250 {
a7812ae4 9251 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9252
7c979afd 9253 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9254 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9255 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9256 tcg_temp_free_i32(fp0);
b6d96bed 9257 }
57fa1fb3 9258 break;
bf4120ad 9259 case OPC_RSQRT_S:
b6d96bed 9260 {
a7812ae4 9261 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9262
7c979afd 9263 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9264 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9265 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9266 tcg_temp_free_i32(fp0);
b6d96bed 9267 }
57fa1fb3 9268 break;
e7f16abb
LA
9269 case OPC_MADDF_S:
9270 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9271 {
a7812ae4
PB
9272 TCGv_i32 fp0 = tcg_temp_new_i32();
9273 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9274 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9275 gen_load_fpr32(ctx, fp0, fs);
9276 gen_load_fpr32(ctx, fp1, ft);
9277 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9278 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9279 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9280 tcg_temp_free_i32(fp2);
a7812ae4 9281 tcg_temp_free_i32(fp1);
a7812ae4 9282 tcg_temp_free_i32(fp0);
b6d96bed 9283 }
57fa1fb3 9284 break;
e7f16abb
LA
9285 case OPC_MSUBF_S:
9286 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9287 {
a7812ae4 9288 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9289 TCGv_i32 fp1 = tcg_temp_new_i32();
9290 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9291 gen_load_fpr32(ctx, fp0, fs);
9292 gen_load_fpr32(ctx, fp1, ft);
9293 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9294 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9295 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9296 tcg_temp_free_i32(fp2);
9297 tcg_temp_free_i32(fp1);
a7812ae4 9298 tcg_temp_free_i32(fp0);
b6d96bed 9299 }
57fa1fb3 9300 break;
e7f16abb
LA
9301 case OPC_RINT_S:
9302 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9303 {
a7812ae4 9304 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9305 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9306 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9307 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9308 tcg_temp_free_i32(fp0);
b6d96bed 9309 }
57fa1fb3 9310 break;
e7f16abb
LA
9311 case OPC_CLASS_S:
9312 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9313 {
e7f16abb 9314 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9315 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9316 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9317 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9318 tcg_temp_free_i32(fp0);
e7f16abb
LA
9319 }
9320 break;
9321 case OPC_MIN_S: /* OPC_RECIP2_S */
9322 if (ctx->insn_flags & ISA_MIPS32R6) {
9323 /* OPC_MIN_S */
a7812ae4
PB
9324 TCGv_i32 fp0 = tcg_temp_new_i32();
9325 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9326 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9327 gen_load_fpr32(ctx, fp0, fs);
9328 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9329 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9330 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9331 tcg_temp_free_i32(fp2);
9332 tcg_temp_free_i32(fp1);
9333 tcg_temp_free_i32(fp0);
e7f16abb
LA
9334 } else {
9335 /* OPC_RECIP2_S */
9336 check_cp1_64bitmode(ctx);
9337 {
9338 TCGv_i32 fp0 = tcg_temp_new_i32();
9339 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9340
7c979afd
LA
9341 gen_load_fpr32(ctx, fp0, fs);
9342 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9343 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9344 tcg_temp_free_i32(fp1);
7c979afd 9345 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9346 tcg_temp_free_i32(fp0);
9347 }
e7f16abb
LA
9348 }
9349 break;
9350 case OPC_MINA_S: /* OPC_RECIP1_S */
9351 if (ctx->insn_flags & ISA_MIPS32R6) {
9352 /* OPC_MINA_S */
9353 TCGv_i32 fp0 = tcg_temp_new_i32();
9354 TCGv_i32 fp1 = tcg_temp_new_i32();
9355 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9356 gen_load_fpr32(ctx, fp0, fs);
9357 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9358 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9359 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9360 tcg_temp_free_i32(fp2);
9361 tcg_temp_free_i32(fp1);
9362 tcg_temp_free_i32(fp0);
e7f16abb
LA
9363 } else {
9364 /* OPC_RECIP1_S */
9365 check_cp1_64bitmode(ctx);
9366 {
9367 TCGv_i32 fp0 = tcg_temp_new_i32();
9368
7c979afd 9369 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9370 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9371 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9372 tcg_temp_free_i32(fp0);
9373 }
e7f16abb
LA
9374 }
9375 break;
9376 case OPC_MAX_S: /* OPC_RSQRT1_S */
9377 if (ctx->insn_flags & ISA_MIPS32R6) {
9378 /* OPC_MAX_S */
9379 TCGv_i32 fp0 = tcg_temp_new_i32();
9380 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9381 gen_load_fpr32(ctx, fp0, fs);
9382 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9383 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9384 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9385 tcg_temp_free_i32(fp1);
9386 tcg_temp_free_i32(fp0);
e7f16abb
LA
9387 } else {
9388 /* OPC_RSQRT1_S */
9389 check_cp1_64bitmode(ctx);
9390 {
9391 TCGv_i32 fp0 = tcg_temp_new_i32();
9392
7c979afd 9393 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9394 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9395 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9396 tcg_temp_free_i32(fp0);
9397 }
e7f16abb
LA
9398 }
9399 break;
9400 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9401 if (ctx->insn_flags & ISA_MIPS32R6) {
9402 /* OPC_MAXA_S */
9403 TCGv_i32 fp0 = tcg_temp_new_i32();
9404 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9405 gen_load_fpr32(ctx, fp0, fs);
9406 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9407 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9408 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9409 tcg_temp_free_i32(fp1);
a7812ae4 9410 tcg_temp_free_i32(fp0);
e7f16abb
LA
9411 } else {
9412 /* OPC_RSQRT2_S */
9413 check_cp1_64bitmode(ctx);
9414 {
9415 TCGv_i32 fp0 = tcg_temp_new_i32();
9416 TCGv_i32 fp1 = tcg_temp_new_i32();
9417
7c979afd
LA
9418 gen_load_fpr32(ctx, fp0, fs);
9419 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9420 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9421 tcg_temp_free_i32(fp1);
7c979afd 9422 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9423 tcg_temp_free_i32(fp0);
9424 }
b6d96bed 9425 }
57fa1fb3 9426 break;
bf4120ad 9427 case OPC_CVT_D_S:
5e755519 9428 check_cp1_registers(ctx, fd);
b6d96bed 9429 {
a7812ae4
PB
9430 TCGv_i32 fp32 = tcg_temp_new_i32();
9431 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9432
7c979afd 9433 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9434 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9435 tcg_temp_free_i32(fp32);
b6d96bed 9436 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9437 tcg_temp_free_i64(fp64);
b6d96bed 9438 }
5a5012ec 9439 break;
bf4120ad 9440 case OPC_CVT_W_S:
b6d96bed 9441 {
a7812ae4 9442 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9443
7c979afd 9444 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9445 if (ctx->nan2008) {
9446 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9447 } else {
9448 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9449 }
7c979afd 9450 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9451 tcg_temp_free_i32(fp0);
b6d96bed 9452 }
5a5012ec 9453 break;
bf4120ad 9454 case OPC_CVT_L_S:
5e755519 9455 check_cp1_64bitmode(ctx);
b6d96bed 9456 {
a7812ae4
PB
9457 TCGv_i32 fp32 = tcg_temp_new_i32();
9458 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9459
7c979afd 9460 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9461 if (ctx->nan2008) {
9462 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9463 } else {
9464 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9465 }
a7812ae4 9466 tcg_temp_free_i32(fp32);
b6d96bed 9467 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9468 tcg_temp_free_i64(fp64);
b6d96bed 9469 }
5a5012ec 9470 break;
bf4120ad 9471 case OPC_CVT_PS_S:
e29c9628 9472 check_ps(ctx);
b6d96bed 9473 {
a7812ae4
PB
9474 TCGv_i64 fp64 = tcg_temp_new_i64();
9475 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9476 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9477
7c979afd
LA
9478 gen_load_fpr32(ctx, fp32_0, fs);
9479 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9480 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9481 tcg_temp_free_i32(fp32_1);
9482 tcg_temp_free_i32(fp32_0);
36aa55dc 9483 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9484 tcg_temp_free_i64(fp64);
b6d96bed 9485 }
5a5012ec 9486 break;
bf4120ad
NF
9487 case OPC_CMP_F_S:
9488 case OPC_CMP_UN_S:
9489 case OPC_CMP_EQ_S:
9490 case OPC_CMP_UEQ_S:
9491 case OPC_CMP_OLT_S:
9492 case OPC_CMP_ULT_S:
9493 case OPC_CMP_OLE_S:
9494 case OPC_CMP_ULE_S:
9495 case OPC_CMP_SF_S:
9496 case OPC_CMP_NGLE_S:
9497 case OPC_CMP_SEQ_S:
9498 case OPC_CMP_NGL_S:
9499 case OPC_CMP_LT_S:
9500 case OPC_CMP_NGE_S:
9501 case OPC_CMP_LE_S:
9502 case OPC_CMP_NGT_S:
fecd2646 9503 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9504 if (ctx->opcode & (1 << 6)) {
9505 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9506 } else {
9507 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9508 }
5a5012ec 9509 break;
bf4120ad 9510 case OPC_ADD_D:
5e755519 9511 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9512 {
a7812ae4
PB
9513 TCGv_i64 fp0 = tcg_temp_new_i64();
9514 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9515
9516 gen_load_fpr64(ctx, fp0, fs);
9517 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9518 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9519 tcg_temp_free_i64(fp1);
b6d96bed 9520 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9521 tcg_temp_free_i64(fp0);
b6d96bed 9522 }
6ea83fed 9523 break;
bf4120ad 9524 case OPC_SUB_D:
5e755519 9525 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9526 {
a7812ae4
PB
9527 TCGv_i64 fp0 = tcg_temp_new_i64();
9528 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9529
9530 gen_load_fpr64(ctx, fp0, fs);
9531 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9532 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9533 tcg_temp_free_i64(fp1);
b6d96bed 9534 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9535 tcg_temp_free_i64(fp0);
b6d96bed 9536 }
6ea83fed 9537 break;
bf4120ad 9538 case OPC_MUL_D:
5e755519 9539 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9540 {
a7812ae4
PB
9541 TCGv_i64 fp0 = tcg_temp_new_i64();
9542 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9543
9544 gen_load_fpr64(ctx, fp0, fs);
9545 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9546 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9547 tcg_temp_free_i64(fp1);
b6d96bed 9548 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9549 tcg_temp_free_i64(fp0);
b6d96bed 9550 }
6ea83fed 9551 break;
bf4120ad 9552 case OPC_DIV_D:
5e755519 9553 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9554 {
a7812ae4
PB
9555 TCGv_i64 fp0 = tcg_temp_new_i64();
9556 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9557
9558 gen_load_fpr64(ctx, fp0, fs);
9559 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9560 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9561 tcg_temp_free_i64(fp1);
b6d96bed 9562 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9563 tcg_temp_free_i64(fp0);
b6d96bed 9564 }
6ea83fed 9565 break;
bf4120ad 9566 case OPC_SQRT_D:
5e755519 9567 check_cp1_registers(ctx, fs | fd);
b6d96bed 9568 {
a7812ae4 9569 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9570
9571 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9572 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9573 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9574 tcg_temp_free_i64(fp0);
b6d96bed 9575 }
6ea83fed 9576 break;
bf4120ad 9577 case OPC_ABS_D:
5e755519 9578 check_cp1_registers(ctx, fs | fd);
b6d96bed 9579 {
a7812ae4 9580 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9581
9582 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9583 if (ctx->abs2008) {
9584 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9585 } else {
9586 gen_helper_float_abs_d(fp0, fp0);
9587 }
b6d96bed 9588 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9589 tcg_temp_free_i64(fp0);
b6d96bed 9590 }
6ea83fed 9591 break;
bf4120ad 9592 case OPC_MOV_D:
5e755519 9593 check_cp1_registers(ctx, fs | fd);
b6d96bed 9594 {
a7812ae4 9595 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9596
9597 gen_load_fpr64(ctx, fp0, fs);
9598 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9599 tcg_temp_free_i64(fp0);
b6d96bed 9600 }
6ea83fed 9601 break;
bf4120ad 9602 case OPC_NEG_D:
5e755519 9603 check_cp1_registers(ctx, fs | fd);
b6d96bed 9604 {
a7812ae4 9605 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9606
9607 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9608 if (ctx->abs2008) {
9609 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9610 } else {
9611 gen_helper_float_chs_d(fp0, fp0);
9612 }
b6d96bed 9613 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9614 tcg_temp_free_i64(fp0);
b6d96bed 9615 }
6ea83fed 9616 break;
bf4120ad 9617 case OPC_ROUND_L_D:
5e755519 9618 check_cp1_64bitmode(ctx);
b6d96bed 9619 {
a7812ae4 9620 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9621
9622 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9623 if (ctx->nan2008) {
9624 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9625 } else {
9626 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9627 }
b6d96bed 9628 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9629 tcg_temp_free_i64(fp0);
b6d96bed 9630 }
5a5012ec 9631 break;
bf4120ad 9632 case OPC_TRUNC_L_D:
5e755519 9633 check_cp1_64bitmode(ctx);
b6d96bed 9634 {
a7812ae4 9635 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9636
9637 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9638 if (ctx->nan2008) {
9639 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9640 } else {
9641 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9642 }
b6d96bed 9643 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9644 tcg_temp_free_i64(fp0);
b6d96bed 9645 }
5a5012ec 9646 break;
bf4120ad 9647 case OPC_CEIL_L_D:
5e755519 9648 check_cp1_64bitmode(ctx);
b6d96bed 9649 {
a7812ae4 9650 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9651
9652 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9653 if (ctx->nan2008) {
9654 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9655 } else {
9656 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9657 }
b6d96bed 9658 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9659 tcg_temp_free_i64(fp0);
b6d96bed 9660 }
5a5012ec 9661 break;
bf4120ad 9662 case OPC_FLOOR_L_D:
5e755519 9663 check_cp1_64bitmode(ctx);
b6d96bed 9664 {
a7812ae4 9665 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9666
9667 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9668 if (ctx->nan2008) {
9669 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9670 } else {
9671 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9672 }
b6d96bed 9673 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9674 tcg_temp_free_i64(fp0);
b6d96bed 9675 }
5a5012ec 9676 break;
bf4120ad 9677 case OPC_ROUND_W_D:
5e755519 9678 check_cp1_registers(ctx, fs);
b6d96bed 9679 {
a7812ae4
PB
9680 TCGv_i32 fp32 = tcg_temp_new_i32();
9681 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9682
9683 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9684 if (ctx->nan2008) {
9685 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9686 } else {
9687 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9688 }
a7812ae4 9689 tcg_temp_free_i64(fp64);
7c979afd 9690 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9691 tcg_temp_free_i32(fp32);
b6d96bed 9692 }
6ea83fed 9693 break;
bf4120ad 9694 case OPC_TRUNC_W_D:
5e755519 9695 check_cp1_registers(ctx, fs);
b6d96bed 9696 {
a7812ae4
PB
9697 TCGv_i32 fp32 = tcg_temp_new_i32();
9698 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9699
9700 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9701 if (ctx->nan2008) {
9702 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9703 } else {
9704 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9705 }
a7812ae4 9706 tcg_temp_free_i64(fp64);
7c979afd 9707 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9708 tcg_temp_free_i32(fp32);
b6d96bed 9709 }
6ea83fed 9710 break;
bf4120ad 9711 case OPC_CEIL_W_D:
5e755519 9712 check_cp1_registers(ctx, fs);
b6d96bed 9713 {
a7812ae4
PB
9714 TCGv_i32 fp32 = tcg_temp_new_i32();
9715 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9716
9717 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9718 if (ctx->nan2008) {
9719 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9720 } else {
9721 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9722 }
a7812ae4 9723 tcg_temp_free_i64(fp64);
7c979afd 9724 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9725 tcg_temp_free_i32(fp32);
b6d96bed 9726 }
6ea83fed 9727 break;
bf4120ad 9728 case OPC_FLOOR_W_D:
5e755519 9729 check_cp1_registers(ctx, fs);
b6d96bed 9730 {
a7812ae4
PB
9731 TCGv_i32 fp32 = tcg_temp_new_i32();
9732 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9733
9734 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9735 if (ctx->nan2008) {
9736 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9737 } else {
9738 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9739 }
a7812ae4 9740 tcg_temp_free_i64(fp64);
7c979afd 9741 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9742 tcg_temp_free_i32(fp32);
b6d96bed 9743 }
6ea83fed 9744 break;
e7f16abb
LA
9745 case OPC_SEL_D:
9746 check_insn(ctx, ISA_MIPS32R6);
9747 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9748 break;
9749 case OPC_SELEQZ_D:
9750 check_insn(ctx, ISA_MIPS32R6);
9751 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9752 break;
9753 case OPC_SELNEZ_D:
9754 check_insn(ctx, ISA_MIPS32R6);
9755 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9756 break;
bf4120ad 9757 case OPC_MOVCF_D:
fecd2646 9758 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9759 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9760 break;
bf4120ad 9761 case OPC_MOVZ_D:
fecd2646 9762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9763 {
42a268c2 9764 TCGLabel *l1 = gen_new_label();
c9297f4d 9765 TCGv_i64 fp0;
a16336e4 9766
c9297f4d
AJ
9767 if (ft != 0) {
9768 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9769 }
9770 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9771 gen_load_fpr64(ctx, fp0, fs);
9772 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9773 tcg_temp_free_i64(fp0);
a16336e4
TS
9774 gen_set_label(l1);
9775 }
5a5012ec 9776 break;
bf4120ad 9777 case OPC_MOVN_D:
fecd2646 9778 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9779 {
42a268c2 9780 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9781 TCGv_i64 fp0;
9782
9783 if (ft != 0) {
9784 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9785 fp0 = tcg_temp_new_i64();
9786 gen_load_fpr64(ctx, fp0, fs);
9787 gen_store_fpr64(ctx, fp0, fd);
9788 tcg_temp_free_i64(fp0);
9789 gen_set_label(l1);
9790 }
a16336e4 9791 }
6ea83fed 9792 break;
bf4120ad 9793 case OPC_RECIP_D:
ca6c7803 9794 check_cp1_registers(ctx, fs | fd);
b6d96bed 9795 {
a7812ae4 9796 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9797
9798 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9799 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9800 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9801 tcg_temp_free_i64(fp0);
b6d96bed 9802 }
57fa1fb3 9803 break;
bf4120ad 9804 case OPC_RSQRT_D:
ca6c7803 9805 check_cp1_registers(ctx, fs | fd);
b6d96bed 9806 {
a7812ae4 9807 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9808
9809 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9810 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9811 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9812 tcg_temp_free_i64(fp0);
b6d96bed 9813 }
57fa1fb3 9814 break;
e7f16abb
LA
9815 case OPC_MADDF_D:
9816 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9817 {
a7812ae4
PB
9818 TCGv_i64 fp0 = tcg_temp_new_i64();
9819 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9820 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9821 gen_load_fpr64(ctx, fp0, fs);
9822 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9823 gen_load_fpr64(ctx, fp2, fd);
9824 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9825 gen_store_fpr64(ctx, fp2, fd);
9826 tcg_temp_free_i64(fp2);
a7812ae4 9827 tcg_temp_free_i64(fp1);
a7812ae4 9828 tcg_temp_free_i64(fp0);
b6d96bed 9829 }
57fa1fb3 9830 break;
e7f16abb
LA
9831 case OPC_MSUBF_D:
9832 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9833 {
a7812ae4 9834 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9835 TCGv_i64 fp1 = tcg_temp_new_i64();
9836 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9837 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9838 gen_load_fpr64(ctx, fp1, ft);
9839 gen_load_fpr64(ctx, fp2, fd);
9840 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9841 gen_store_fpr64(ctx, fp2, fd);
9842 tcg_temp_free_i64(fp2);
9843 tcg_temp_free_i64(fp1);
a7812ae4 9844 tcg_temp_free_i64(fp0);
b6d96bed 9845 }
57fa1fb3 9846 break;
e7f16abb
LA
9847 case OPC_RINT_D:
9848 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9849 {
a7812ae4 9850 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9851 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9852 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9853 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9854 tcg_temp_free_i64(fp0);
b6d96bed 9855 }
57fa1fb3 9856 break;
e7f16abb
LA
9857 case OPC_CLASS_D:
9858 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9859 {
e7f16abb
LA
9860 TCGv_i64 fp0 = tcg_temp_new_i64();
9861 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9862 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9863 gen_store_fpr64(ctx, fp0, fd);
9864 tcg_temp_free_i64(fp0);
e7f16abb
LA
9865 }
9866 break;
9867 case OPC_MIN_D: /* OPC_RECIP2_D */
9868 if (ctx->insn_flags & ISA_MIPS32R6) {
9869 /* OPC_MIN_D */
a7812ae4
PB
9870 TCGv_i64 fp0 = tcg_temp_new_i64();
9871 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9872 gen_load_fpr64(ctx, fp0, fs);
9873 gen_load_fpr64(ctx, fp1, ft);
9874 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9875 gen_store_fpr64(ctx, fp1, fd);
9876 tcg_temp_free_i64(fp1);
9877 tcg_temp_free_i64(fp0);
e7f16abb
LA
9878 } else {
9879 /* OPC_RECIP2_D */
9880 check_cp1_64bitmode(ctx);
9881 {
9882 TCGv_i64 fp0 = tcg_temp_new_i64();
9883 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9884
e7f16abb
LA
9885 gen_load_fpr64(ctx, fp0, fs);
9886 gen_load_fpr64(ctx, fp1, ft);
9887 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9888 tcg_temp_free_i64(fp1);
9889 gen_store_fpr64(ctx, fp0, fd);
9890 tcg_temp_free_i64(fp0);
9891 }
e7f16abb
LA
9892 }
9893 break;
9894 case OPC_MINA_D: /* OPC_RECIP1_D */
9895 if (ctx->insn_flags & ISA_MIPS32R6) {
9896 /* OPC_MINA_D */
9897 TCGv_i64 fp0 = tcg_temp_new_i64();
9898 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9899 gen_load_fpr64(ctx, fp0, fs);
9900 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9901 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9902 gen_store_fpr64(ctx, fp1, fd);
9903 tcg_temp_free_i64(fp1);
9904 tcg_temp_free_i64(fp0);
e7f16abb
LA
9905 } else {
9906 /* OPC_RECIP1_D */
9907 check_cp1_64bitmode(ctx);
9908 {
9909 TCGv_i64 fp0 = tcg_temp_new_i64();
9910
9911 gen_load_fpr64(ctx, fp0, fs);
9912 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9913 gen_store_fpr64(ctx, fp0, fd);
9914 tcg_temp_free_i64(fp0);
9915 }
e7f16abb
LA
9916 }
9917 break;
9918 case OPC_MAX_D: /* OPC_RSQRT1_D */
9919 if (ctx->insn_flags & ISA_MIPS32R6) {
9920 /* OPC_MAX_D */
9921 TCGv_i64 fp0 = tcg_temp_new_i64();
9922 TCGv_i64 fp1 = tcg_temp_new_i64();
9923 gen_load_fpr64(ctx, fp0, fs);
9924 gen_load_fpr64(ctx, fp1, ft);
9925 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9926 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9927 tcg_temp_free_i64(fp1);
a7812ae4 9928 tcg_temp_free_i64(fp0);
e7f16abb
LA
9929 } else {
9930 /* OPC_RSQRT1_D */
9931 check_cp1_64bitmode(ctx);
9932 {
9933 TCGv_i64 fp0 = tcg_temp_new_i64();
9934
9935 gen_load_fpr64(ctx, fp0, fs);
9936 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9937 gen_store_fpr64(ctx, fp0, fd);
9938 tcg_temp_free_i64(fp0);
9939 }
e7f16abb
LA
9940 }
9941 break;
9942 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9943 if (ctx->insn_flags & ISA_MIPS32R6) {
9944 /* OPC_MAXA_D */
9945 TCGv_i64 fp0 = tcg_temp_new_i64();
9946 TCGv_i64 fp1 = tcg_temp_new_i64();
9947 gen_load_fpr64(ctx, fp0, fs);
9948 gen_load_fpr64(ctx, fp1, ft);
9949 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9950 gen_store_fpr64(ctx, fp1, fd);
9951 tcg_temp_free_i64(fp1);
9952 tcg_temp_free_i64(fp0);
e7f16abb
LA
9953 } else {
9954 /* OPC_RSQRT2_D */
9955 check_cp1_64bitmode(ctx);
9956 {
9957 TCGv_i64 fp0 = tcg_temp_new_i64();
9958 TCGv_i64 fp1 = tcg_temp_new_i64();
9959
9960 gen_load_fpr64(ctx, fp0, fs);
9961 gen_load_fpr64(ctx, fp1, ft);
9962 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9963 tcg_temp_free_i64(fp1);
9964 gen_store_fpr64(ctx, fp0, fd);
9965 tcg_temp_free_i64(fp0);
9966 }
b6d96bed 9967 }
57fa1fb3 9968 break;
bf4120ad
NF
9969 case OPC_CMP_F_D:
9970 case OPC_CMP_UN_D:
9971 case OPC_CMP_EQ_D:
9972 case OPC_CMP_UEQ_D:
9973 case OPC_CMP_OLT_D:
9974 case OPC_CMP_ULT_D:
9975 case OPC_CMP_OLE_D:
9976 case OPC_CMP_ULE_D:
9977 case OPC_CMP_SF_D:
9978 case OPC_CMP_NGLE_D:
9979 case OPC_CMP_SEQ_D:
9980 case OPC_CMP_NGL_D:
9981 case OPC_CMP_LT_D:
9982 case OPC_CMP_NGE_D:
9983 case OPC_CMP_LE_D:
9984 case OPC_CMP_NGT_D:
fecd2646 9985 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9986 if (ctx->opcode & (1 << 6)) {
9987 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9988 } else {
9989 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9990 }
6ea83fed 9991 break;
bf4120ad 9992 case OPC_CVT_S_D:
5e755519 9993 check_cp1_registers(ctx, fs);
b6d96bed 9994 {
a7812ae4
PB
9995 TCGv_i32 fp32 = tcg_temp_new_i32();
9996 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9997
9998 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9999 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10000 tcg_temp_free_i64(fp64);
7c979afd 10001 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10002 tcg_temp_free_i32(fp32);
b6d96bed 10003 }
5a5012ec 10004 break;
bf4120ad 10005 case OPC_CVT_W_D:
5e755519 10006 check_cp1_registers(ctx, fs);
b6d96bed 10007 {
a7812ae4
PB
10008 TCGv_i32 fp32 = tcg_temp_new_i32();
10009 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10010
10011 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10012 if (ctx->nan2008) {
10013 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10014 } else {
10015 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10016 }
a7812ae4 10017 tcg_temp_free_i64(fp64);
7c979afd 10018 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10019 tcg_temp_free_i32(fp32);
b6d96bed 10020 }
5a5012ec 10021 break;
bf4120ad 10022 case OPC_CVT_L_D:
5e755519 10023 check_cp1_64bitmode(ctx);
b6d96bed 10024 {
a7812ae4 10025 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10026
10027 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10028 if (ctx->nan2008) {
10029 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10030 } else {
10031 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10032 }
b6d96bed 10033 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10034 tcg_temp_free_i64(fp0);
b6d96bed 10035 }
5a5012ec 10036 break;
bf4120ad 10037 case OPC_CVT_S_W:
b6d96bed 10038 {
a7812ae4 10039 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10040
7c979afd 10041 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10042 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10043 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10044 tcg_temp_free_i32(fp0);
b6d96bed 10045 }
6ea83fed 10046 break;
bf4120ad 10047 case OPC_CVT_D_W:
5e755519 10048 check_cp1_registers(ctx, fd);
b6d96bed 10049 {
a7812ae4
PB
10050 TCGv_i32 fp32 = tcg_temp_new_i32();
10051 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10052
7c979afd 10053 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10054 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10055 tcg_temp_free_i32(fp32);
b6d96bed 10056 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10057 tcg_temp_free_i64(fp64);
b6d96bed 10058 }
5a5012ec 10059 break;
bf4120ad 10060 case OPC_CVT_S_L:
5e755519 10061 check_cp1_64bitmode(ctx);
b6d96bed 10062 {
a7812ae4
PB
10063 TCGv_i32 fp32 = tcg_temp_new_i32();
10064 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10065
10066 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10067 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10068 tcg_temp_free_i64(fp64);
7c979afd 10069 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10070 tcg_temp_free_i32(fp32);
b6d96bed 10071 }
5a5012ec 10072 break;
bf4120ad 10073 case OPC_CVT_D_L:
5e755519 10074 check_cp1_64bitmode(ctx);
b6d96bed 10075 {
a7812ae4 10076 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10077
10078 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10079 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10080 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10081 tcg_temp_free_i64(fp0);
b6d96bed 10082 }
5a5012ec 10083 break;
bf4120ad 10084 case OPC_CVT_PS_PW:
e29c9628 10085 check_ps(ctx);
b6d96bed 10086 {
a7812ae4 10087 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10088
10089 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10090 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10091 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10092 tcg_temp_free_i64(fp0);
b6d96bed 10093 }
5a5012ec 10094 break;
bf4120ad 10095 case OPC_ADD_PS:
e29c9628 10096 check_ps(ctx);
b6d96bed 10097 {
a7812ae4
PB
10098 TCGv_i64 fp0 = tcg_temp_new_i64();
10099 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10100
10101 gen_load_fpr64(ctx, fp0, fs);
10102 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10103 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10104 tcg_temp_free_i64(fp1);
b6d96bed 10105 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10106 tcg_temp_free_i64(fp0);
b6d96bed 10107 }
6ea83fed 10108 break;
bf4120ad 10109 case OPC_SUB_PS:
e29c9628 10110 check_ps(ctx);
b6d96bed 10111 {
a7812ae4
PB
10112 TCGv_i64 fp0 = tcg_temp_new_i64();
10113 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10114
10115 gen_load_fpr64(ctx, fp0, fs);
10116 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10117 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10118 tcg_temp_free_i64(fp1);
b6d96bed 10119 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10120 tcg_temp_free_i64(fp0);
b6d96bed 10121 }
6ea83fed 10122 break;
bf4120ad 10123 case OPC_MUL_PS:
e29c9628 10124 check_ps(ctx);
b6d96bed 10125 {
a7812ae4
PB
10126 TCGv_i64 fp0 = tcg_temp_new_i64();
10127 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10128
10129 gen_load_fpr64(ctx, fp0, fs);
10130 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10131 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10132 tcg_temp_free_i64(fp1);
b6d96bed 10133 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10134 tcg_temp_free_i64(fp0);
b6d96bed 10135 }
6ea83fed 10136 break;
bf4120ad 10137 case OPC_ABS_PS:
e29c9628 10138 check_ps(ctx);
b6d96bed 10139 {
a7812ae4 10140 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10141
10142 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10143 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10144 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10145 tcg_temp_free_i64(fp0);
b6d96bed 10146 }
6ea83fed 10147 break;
bf4120ad 10148 case OPC_MOV_PS:
e29c9628 10149 check_ps(ctx);
b6d96bed 10150 {
a7812ae4 10151 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10152
10153 gen_load_fpr64(ctx, fp0, fs);
10154 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10155 tcg_temp_free_i64(fp0);
b6d96bed 10156 }
6ea83fed 10157 break;
bf4120ad 10158 case OPC_NEG_PS:
e29c9628 10159 check_ps(ctx);
b6d96bed 10160 {
a7812ae4 10161 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10162
10163 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10164 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10165 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10166 tcg_temp_free_i64(fp0);
b6d96bed 10167 }
6ea83fed 10168 break;
bf4120ad 10169 case OPC_MOVCF_PS:
e29c9628 10170 check_ps(ctx);
7f6613ce 10171 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10172 break;
bf4120ad 10173 case OPC_MOVZ_PS:
e29c9628 10174 check_ps(ctx);
a16336e4 10175 {
42a268c2 10176 TCGLabel *l1 = gen_new_label();
30a3848b 10177 TCGv_i64 fp0;
a16336e4 10178
c9297f4d
AJ
10179 if (ft != 0)
10180 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10181 fp0 = tcg_temp_new_i64();
10182 gen_load_fpr64(ctx, fp0, fs);
10183 gen_store_fpr64(ctx, fp0, fd);
10184 tcg_temp_free_i64(fp0);
a16336e4
TS
10185 gen_set_label(l1);
10186 }
6ea83fed 10187 break;
bf4120ad 10188 case OPC_MOVN_PS:
e29c9628 10189 check_ps(ctx);
a16336e4 10190 {
42a268c2 10191 TCGLabel *l1 = gen_new_label();
30a3848b 10192 TCGv_i64 fp0;
c9297f4d
AJ
10193
10194 if (ft != 0) {
10195 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10196 fp0 = tcg_temp_new_i64();
10197 gen_load_fpr64(ctx, fp0, fs);
10198 gen_store_fpr64(ctx, fp0, fd);
10199 tcg_temp_free_i64(fp0);
10200 gen_set_label(l1);
10201 }
a16336e4 10202 }
6ea83fed 10203 break;
bf4120ad 10204 case OPC_ADDR_PS:
e29c9628 10205 check_ps(ctx);
b6d96bed 10206 {
a7812ae4
PB
10207 TCGv_i64 fp0 = tcg_temp_new_i64();
10208 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10209
10210 gen_load_fpr64(ctx, fp0, ft);
10211 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10212 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10213 tcg_temp_free_i64(fp1);
b6d96bed 10214 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10215 tcg_temp_free_i64(fp0);
b6d96bed 10216 }
fbcc6828 10217 break;
bf4120ad 10218 case OPC_MULR_PS:
e29c9628 10219 check_ps(ctx);
b6d96bed 10220 {
a7812ae4
PB
10221 TCGv_i64 fp0 = tcg_temp_new_i64();
10222 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10223
10224 gen_load_fpr64(ctx, fp0, ft);
10225 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10226 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10227 tcg_temp_free_i64(fp1);
b6d96bed 10228 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10229 tcg_temp_free_i64(fp0);
b6d96bed 10230 }
57fa1fb3 10231 break;
bf4120ad 10232 case OPC_RECIP2_PS:
e29c9628 10233 check_ps(ctx);
b6d96bed 10234 {
a7812ae4
PB
10235 TCGv_i64 fp0 = tcg_temp_new_i64();
10236 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10237
10238 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10239 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10240 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10241 tcg_temp_free_i64(fp1);
b6d96bed 10242 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10243 tcg_temp_free_i64(fp0);
b6d96bed 10244 }
57fa1fb3 10245 break;
bf4120ad 10246 case OPC_RECIP1_PS:
e29c9628 10247 check_ps(ctx);
b6d96bed 10248 {
a7812ae4 10249 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10250
10251 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10252 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10253 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10254 tcg_temp_free_i64(fp0);
b6d96bed 10255 }
57fa1fb3 10256 break;
bf4120ad 10257 case OPC_RSQRT1_PS:
e29c9628 10258 check_ps(ctx);
b6d96bed 10259 {
a7812ae4 10260 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10261
10262 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10263 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10264 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10265 tcg_temp_free_i64(fp0);
b6d96bed 10266 }
57fa1fb3 10267 break;
bf4120ad 10268 case OPC_RSQRT2_PS:
e29c9628 10269 check_ps(ctx);
b6d96bed 10270 {
a7812ae4
PB
10271 TCGv_i64 fp0 = tcg_temp_new_i64();
10272 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10273
10274 gen_load_fpr64(ctx, fp0, fs);
10275 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10276 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10277 tcg_temp_free_i64(fp1);
b6d96bed 10278 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10279 tcg_temp_free_i64(fp0);
b6d96bed 10280 }
57fa1fb3 10281 break;
bf4120ad 10282 case OPC_CVT_S_PU:
5e755519 10283 check_cp1_64bitmode(ctx);
b6d96bed 10284 {
a7812ae4 10285 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10286
7f6613ce 10287 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10288 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10289 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10290 tcg_temp_free_i32(fp0);
b6d96bed 10291 }
dd016883 10292 break;
bf4120ad 10293 case OPC_CVT_PW_PS:
e29c9628 10294 check_ps(ctx);
b6d96bed 10295 {
a7812ae4 10296 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10297
10298 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10299 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10300 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10301 tcg_temp_free_i64(fp0);
b6d96bed 10302 }
6ea83fed 10303 break;
bf4120ad 10304 case OPC_CVT_S_PL:
5e755519 10305 check_cp1_64bitmode(ctx);
b6d96bed 10306 {
a7812ae4 10307 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10308
7c979afd 10309 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10310 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10311 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10312 tcg_temp_free_i32(fp0);
b6d96bed 10313 }
6ea83fed 10314 break;
bf4120ad 10315 case OPC_PLL_PS:
e29c9628 10316 check_ps(ctx);
b6d96bed 10317 {
a7812ae4
PB
10318 TCGv_i32 fp0 = tcg_temp_new_i32();
10319 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10320
7c979afd
LA
10321 gen_load_fpr32(ctx, fp0, fs);
10322 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10323 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10324 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10325 tcg_temp_free_i32(fp0);
10326 tcg_temp_free_i32(fp1);
b6d96bed 10327 }
6ea83fed 10328 break;
bf4120ad 10329 case OPC_PLU_PS:
e29c9628 10330 check_ps(ctx);
b6d96bed 10331 {
a7812ae4
PB
10332 TCGv_i32 fp0 = tcg_temp_new_i32();
10333 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10334
7c979afd 10335 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10336 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10337 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10338 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10339 tcg_temp_free_i32(fp0);
10340 tcg_temp_free_i32(fp1);
b6d96bed 10341 }
5a5012ec 10342 break;
bf4120ad 10343 case OPC_PUL_PS:
e29c9628 10344 check_ps(ctx);
b6d96bed 10345 {
a7812ae4
PB
10346 TCGv_i32 fp0 = tcg_temp_new_i32();
10347 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10348
7f6613ce 10349 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10350 gen_load_fpr32(ctx, fp1, ft);
10351 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10352 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10353 tcg_temp_free_i32(fp0);
10354 tcg_temp_free_i32(fp1);
b6d96bed 10355 }
5a5012ec 10356 break;
bf4120ad 10357 case OPC_PUU_PS:
e29c9628 10358 check_ps(ctx);
b6d96bed 10359 {
a7812ae4
PB
10360 TCGv_i32 fp0 = tcg_temp_new_i32();
10361 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10362
7f6613ce
PJ
10363 gen_load_fpr32h(ctx, fp0, fs);
10364 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10365 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10366 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10367 tcg_temp_free_i32(fp0);
10368 tcg_temp_free_i32(fp1);
b6d96bed 10369 }
5a5012ec 10370 break;
bf4120ad
NF
10371 case OPC_CMP_F_PS:
10372 case OPC_CMP_UN_PS:
10373 case OPC_CMP_EQ_PS:
10374 case OPC_CMP_UEQ_PS:
10375 case OPC_CMP_OLT_PS:
10376 case OPC_CMP_ULT_PS:
10377 case OPC_CMP_OLE_PS:
10378 case OPC_CMP_ULE_PS:
10379 case OPC_CMP_SF_PS:
10380 case OPC_CMP_NGLE_PS:
10381 case OPC_CMP_SEQ_PS:
10382 case OPC_CMP_NGL_PS:
10383 case OPC_CMP_LT_PS:
10384 case OPC_CMP_NGE_PS:
10385 case OPC_CMP_LE_PS:
10386 case OPC_CMP_NGT_PS:
8153667c
NF
10387 if (ctx->opcode & (1 << 6)) {
10388 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10389 } else {
10390 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10391 }
6ea83fed 10392 break;
5a5012ec 10393 default:
9d68ac14 10394 MIPS_INVAL("farith");
9c708c7f 10395 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10396 return;
10397 }
6ea83fed 10398}
6af0bf9c 10399
5a5012ec 10400/* Coprocessor 3 (FPU) */
5e755519
TS
10401static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10402 int fd, int fs, int base, int index)
7a387fff 10403{
4e2474d6 10404 TCGv t0 = tcg_temp_new();
7a387fff 10405
93b12ccc 10406 if (base == 0) {
6c5c1e20 10407 gen_load_gpr(t0, index);
93b12ccc 10408 } else if (index == 0) {
6c5c1e20 10409 gen_load_gpr(t0, base);
93b12ccc 10410 } else {
05168674 10411 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10412 }
5a5012ec 10413 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10414 memory access. */
5a5012ec
TS
10415 switch (opc) {
10416 case OPC_LWXC1:
8c0ab41f 10417 check_cop1x(ctx);
b6d96bed 10418 {
a7812ae4 10419 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10420
5f68f5ae 10421 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10422 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10423 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10424 tcg_temp_free_i32(fp0);
b6d96bed 10425 }
5a5012ec
TS
10426 break;
10427 case OPC_LDXC1:
8c0ab41f
AJ
10428 check_cop1x(ctx);
10429 check_cp1_registers(ctx, fd);
b6d96bed 10430 {
a7812ae4 10431 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10432 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10433 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10434 tcg_temp_free_i64(fp0);
b6d96bed 10435 }
5a5012ec
TS
10436 break;
10437 case OPC_LUXC1:
8c0ab41f 10438 check_cp1_64bitmode(ctx);
6c5c1e20 10439 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10440 {
a7812ae4 10441 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10442
5f68f5ae 10443 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10444 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10445 tcg_temp_free_i64(fp0);
b6d96bed 10446 }
5a5012ec
TS
10447 break;
10448 case OPC_SWXC1:
8c0ab41f 10449 check_cop1x(ctx);
b6d96bed 10450 {
a7812ae4 10451 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10452 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10453 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10454 tcg_temp_free_i32(fp0);
b6d96bed 10455 }
5a5012ec
TS
10456 break;
10457 case OPC_SDXC1:
8c0ab41f
AJ
10458 check_cop1x(ctx);
10459 check_cp1_registers(ctx, fs);
b6d96bed 10460 {
a7812ae4 10461 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10462 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10463 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10464 tcg_temp_free_i64(fp0);
b6d96bed 10465 }
5a5012ec
TS
10466 break;
10467 case OPC_SUXC1:
8c0ab41f 10468 check_cp1_64bitmode(ctx);
6c5c1e20 10469 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10470 {
a7812ae4 10471 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10472 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10473 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10474 tcg_temp_free_i64(fp0);
b6d96bed 10475 }
5a5012ec 10476 break;
5a5012ec 10477 }
6c5c1e20 10478 tcg_temp_free(t0);
5a5012ec
TS
10479}
10480
5e755519
TS
10481static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10482 int fd, int fr, int fs, int ft)
5a5012ec 10483{
5a5012ec
TS
10484 switch (opc) {
10485 case OPC_ALNV_PS:
e29c9628 10486 check_ps(ctx);
a16336e4 10487 {
a7812ae4 10488 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10489 TCGv_i32 fp = tcg_temp_new_i32();
10490 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10491 TCGLabel *l1 = gen_new_label();
10492 TCGLabel *l2 = gen_new_label();
a16336e4 10493
6c5c1e20
TS
10494 gen_load_gpr(t0, fr);
10495 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10496
10497 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10498 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10499 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10500 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10501 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10502 tcg_gen_br(l2);
10503 gen_set_label(l1);
6c5c1e20
TS
10504 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10505 tcg_temp_free(t0);
a16336e4 10506#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10507 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10508 gen_load_fpr32h(ctx, fph, ft);
10509 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10510 gen_store_fpr32(ctx, fph, fd);
a16336e4 10511#else
7f6613ce 10512 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10513 gen_load_fpr32(ctx, fp, ft);
10514 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10515 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10516#endif
10517 gen_set_label(l2);
c905fdac
AJ
10518 tcg_temp_free_i32(fp);
10519 tcg_temp_free_i32(fph);
a16336e4 10520 }
5a5012ec
TS
10521 break;
10522 case OPC_MADD_S:
b8aa4598 10523 check_cop1x(ctx);
b6d96bed 10524 {
a7812ae4
PB
10525 TCGv_i32 fp0 = tcg_temp_new_i32();
10526 TCGv_i32 fp1 = tcg_temp_new_i32();
10527 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10528
7c979afd
LA
10529 gen_load_fpr32(ctx, fp0, fs);
10530 gen_load_fpr32(ctx, fp1, ft);
10531 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10532 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10533 tcg_temp_free_i32(fp0);
10534 tcg_temp_free_i32(fp1);
7c979afd 10535 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10536 tcg_temp_free_i32(fp2);
b6d96bed 10537 }
5a5012ec
TS
10538 break;
10539 case OPC_MADD_D:
b8aa4598
TS
10540 check_cop1x(ctx);
10541 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10542 {
a7812ae4
PB
10543 TCGv_i64 fp0 = tcg_temp_new_i64();
10544 TCGv_i64 fp1 = tcg_temp_new_i64();
10545 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10546
10547 gen_load_fpr64(ctx, fp0, fs);
10548 gen_load_fpr64(ctx, fp1, ft);
10549 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10550 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10551 tcg_temp_free_i64(fp0);
10552 tcg_temp_free_i64(fp1);
b6d96bed 10553 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10554 tcg_temp_free_i64(fp2);
b6d96bed 10555 }
5a5012ec
TS
10556 break;
10557 case OPC_MADD_PS:
e29c9628 10558 check_ps(ctx);
b6d96bed 10559 {
a7812ae4
PB
10560 TCGv_i64 fp0 = tcg_temp_new_i64();
10561 TCGv_i64 fp1 = tcg_temp_new_i64();
10562 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10563
10564 gen_load_fpr64(ctx, fp0, fs);
10565 gen_load_fpr64(ctx, fp1, ft);
10566 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10567 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10568 tcg_temp_free_i64(fp0);
10569 tcg_temp_free_i64(fp1);
b6d96bed 10570 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10571 tcg_temp_free_i64(fp2);
b6d96bed 10572 }
5a5012ec
TS
10573 break;
10574 case OPC_MSUB_S:
b8aa4598 10575 check_cop1x(ctx);
b6d96bed 10576 {
a7812ae4
PB
10577 TCGv_i32 fp0 = tcg_temp_new_i32();
10578 TCGv_i32 fp1 = tcg_temp_new_i32();
10579 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10580
7c979afd
LA
10581 gen_load_fpr32(ctx, fp0, fs);
10582 gen_load_fpr32(ctx, fp1, ft);
10583 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10584 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10585 tcg_temp_free_i32(fp0);
10586 tcg_temp_free_i32(fp1);
7c979afd 10587 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10588 tcg_temp_free_i32(fp2);
b6d96bed 10589 }
5a5012ec
TS
10590 break;
10591 case OPC_MSUB_D:
b8aa4598
TS
10592 check_cop1x(ctx);
10593 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10594 {
a7812ae4
PB
10595 TCGv_i64 fp0 = tcg_temp_new_i64();
10596 TCGv_i64 fp1 = tcg_temp_new_i64();
10597 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10598
10599 gen_load_fpr64(ctx, fp0, fs);
10600 gen_load_fpr64(ctx, fp1, ft);
10601 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10602 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10603 tcg_temp_free_i64(fp0);
10604 tcg_temp_free_i64(fp1);
b6d96bed 10605 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10606 tcg_temp_free_i64(fp2);
b6d96bed 10607 }
5a5012ec
TS
10608 break;
10609 case OPC_MSUB_PS:
e29c9628 10610 check_ps(ctx);
b6d96bed 10611 {
a7812ae4
PB
10612 TCGv_i64 fp0 = tcg_temp_new_i64();
10613 TCGv_i64 fp1 = tcg_temp_new_i64();
10614 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10615
10616 gen_load_fpr64(ctx, fp0, fs);
10617 gen_load_fpr64(ctx, fp1, ft);
10618 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10619 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10620 tcg_temp_free_i64(fp0);
10621 tcg_temp_free_i64(fp1);
b6d96bed 10622 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10623 tcg_temp_free_i64(fp2);
b6d96bed 10624 }
5a5012ec
TS
10625 break;
10626 case OPC_NMADD_S:
b8aa4598 10627 check_cop1x(ctx);
b6d96bed 10628 {
a7812ae4
PB
10629 TCGv_i32 fp0 = tcg_temp_new_i32();
10630 TCGv_i32 fp1 = tcg_temp_new_i32();
10631 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10632
7c979afd
LA
10633 gen_load_fpr32(ctx, fp0, fs);
10634 gen_load_fpr32(ctx, fp1, ft);
10635 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10636 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10637 tcg_temp_free_i32(fp0);
10638 tcg_temp_free_i32(fp1);
7c979afd 10639 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10640 tcg_temp_free_i32(fp2);
b6d96bed 10641 }
5a5012ec
TS
10642 break;
10643 case OPC_NMADD_D:
b8aa4598
TS
10644 check_cop1x(ctx);
10645 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10646 {
a7812ae4
PB
10647 TCGv_i64 fp0 = tcg_temp_new_i64();
10648 TCGv_i64 fp1 = tcg_temp_new_i64();
10649 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10650
10651 gen_load_fpr64(ctx, fp0, fs);
10652 gen_load_fpr64(ctx, fp1, ft);
10653 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10654 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10655 tcg_temp_free_i64(fp0);
10656 tcg_temp_free_i64(fp1);
b6d96bed 10657 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10658 tcg_temp_free_i64(fp2);
b6d96bed 10659 }
5a5012ec
TS
10660 break;
10661 case OPC_NMADD_PS:
e29c9628 10662 check_ps(ctx);
b6d96bed 10663 {
a7812ae4
PB
10664 TCGv_i64 fp0 = tcg_temp_new_i64();
10665 TCGv_i64 fp1 = tcg_temp_new_i64();
10666 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10667
10668 gen_load_fpr64(ctx, fp0, fs);
10669 gen_load_fpr64(ctx, fp1, ft);
10670 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10671 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10672 tcg_temp_free_i64(fp0);
10673 tcg_temp_free_i64(fp1);
b6d96bed 10674 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10675 tcg_temp_free_i64(fp2);
b6d96bed 10676 }
5a5012ec
TS
10677 break;
10678 case OPC_NMSUB_S:
b8aa4598 10679 check_cop1x(ctx);
b6d96bed 10680 {
a7812ae4
PB
10681 TCGv_i32 fp0 = tcg_temp_new_i32();
10682 TCGv_i32 fp1 = tcg_temp_new_i32();
10683 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10684
7c979afd
LA
10685 gen_load_fpr32(ctx, fp0, fs);
10686 gen_load_fpr32(ctx, fp1, ft);
10687 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10688 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10689 tcg_temp_free_i32(fp0);
10690 tcg_temp_free_i32(fp1);
7c979afd 10691 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10692 tcg_temp_free_i32(fp2);
b6d96bed 10693 }
5a5012ec
TS
10694 break;
10695 case OPC_NMSUB_D:
b8aa4598
TS
10696 check_cop1x(ctx);
10697 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10698 {
a7812ae4
PB
10699 TCGv_i64 fp0 = tcg_temp_new_i64();
10700 TCGv_i64 fp1 = tcg_temp_new_i64();
10701 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10702
10703 gen_load_fpr64(ctx, fp0, fs);
10704 gen_load_fpr64(ctx, fp1, ft);
10705 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10706 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10707 tcg_temp_free_i64(fp0);
10708 tcg_temp_free_i64(fp1);
b6d96bed 10709 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10710 tcg_temp_free_i64(fp2);
b6d96bed 10711 }
5a5012ec
TS
10712 break;
10713 case OPC_NMSUB_PS:
e29c9628 10714 check_ps(ctx);
b6d96bed 10715 {
a7812ae4
PB
10716 TCGv_i64 fp0 = tcg_temp_new_i64();
10717 TCGv_i64 fp1 = tcg_temp_new_i64();
10718 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10719
10720 gen_load_fpr64(ctx, fp0, fs);
10721 gen_load_fpr64(ctx, fp1, ft);
10722 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10723 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10724 tcg_temp_free_i64(fp0);
10725 tcg_temp_free_i64(fp1);
b6d96bed 10726 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10727 tcg_temp_free_i64(fp2);
b6d96bed 10728 }
5a5012ec 10729 break;
923617a3 10730 default:
9d68ac14 10731 MIPS_INVAL("flt3_arith");
9c708c7f 10732 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10733 return;
10734 }
7a387fff
TS
10735}
10736
b00c7218 10737static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10738{
10739 TCGv t0;
10740
b3167288
RH
10741#if !defined(CONFIG_USER_ONLY)
10742 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10743 Therefore only check the ISA in system mode. */
d75c135e 10744 check_insn(ctx, ISA_MIPS32R2);
b3167288 10745#endif
26ebe468
NF
10746 t0 = tcg_temp_new();
10747
10748 switch (rd) {
10749 case 0:
895c2d04 10750 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10751 gen_store_gpr(t0, rt);
10752 break;
10753 case 1:
895c2d04 10754 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10755 gen_store_gpr(t0, rt);
10756 break;
10757 case 2:
d673a68d
JH
10758 if (ctx->tb->cflags & CF_USE_ICOUNT) {
10759 gen_io_start();
10760 }
895c2d04 10761 gen_helper_rdhwr_cc(t0, cpu_env);
d673a68d
JH
10762 if (ctx->tb->cflags & CF_USE_ICOUNT) {
10763 gen_io_end();
10764 }
26ebe468 10765 gen_store_gpr(t0, rt);
d673a68d
JH
10766 /* Break the TB to be able to take timer interrupts immediately
10767 after reading count. BS_STOP isn't sufficient, we need to ensure
10768 we break completely out of translated code. */
10769 gen_save_pc(ctx->pc + 4);
10770 ctx->bstate = BS_EXCP;
26ebe468
NF
10771 break;
10772 case 3:
895c2d04 10773 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10774 gen_store_gpr(t0, rt);
10775 break;
b00c7218
YK
10776 case 4:
10777 check_insn(ctx, ISA_MIPS32R6);
10778 if (sel != 0) {
10779 /* Performance counter registers are not implemented other than
10780 * control register 0.
10781 */
10782 generate_exception(ctx, EXCP_RI);
10783 }
10784 gen_helper_rdhwr_performance(t0, cpu_env);
10785 gen_store_gpr(t0, rt);
10786 break;
10787 case 5:
10788 check_insn(ctx, ISA_MIPS32R6);
10789 gen_helper_rdhwr_xnp(t0, cpu_env);
10790 gen_store_gpr(t0, rt);
10791 break;
26ebe468
NF
10792 case 29:
10793#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10794 tcg_gen_ld_tl(t0, cpu_env,
10795 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10796 gen_store_gpr(t0, rt);
10797 break;
10798#else
d279279e
PJ
10799 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10800 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10801 tcg_gen_ld_tl(t0, cpu_env,
10802 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10803 gen_store_gpr(t0, rt);
10804 } else {
9c708c7f 10805 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10806 }
10807 break;
26ebe468
NF
10808#endif
10809 default: /* Invalid */
10810 MIPS_INVAL("rdhwr");
9c708c7f 10811 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10812 break;
10813 }
10814 tcg_temp_free(t0);
10815}
10816
a5f53390
LA
10817static inline void clear_branch_hflags(DisasContext *ctx)
10818{
10819 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10820 if (ctx->bstate == BS_NONE) {
10821 save_cpu_state(ctx, 0);
10822 } else {
10823 /* it is not safe to save ctx->hflags as hflags may be changed
10824 in execution time by the instruction in delay / forbidden slot. */
10825 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10826 }
10827}
10828
31837be3 10829static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10830{
10831 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10832 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10833 /* Branches completion */
a5f53390 10834 clear_branch_hflags(ctx);
c9602061 10835 ctx->bstate = BS_BRANCH;
c9602061 10836 /* FIXME: Need to clear can_do_io. */
364d4831 10837 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10838 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10839 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10840 break;
c9602061
NF
10841 case MIPS_HFLAG_B:
10842 /* unconditional branch */
364d4831
NF
10843 if (proc_hflags & MIPS_HFLAG_BX) {
10844 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10845 }
c9602061
NF
10846 gen_goto_tb(ctx, 0, ctx->btarget);
10847 break;
10848 case MIPS_HFLAG_BL:
10849 /* blikely taken case */
c9602061
NF
10850 gen_goto_tb(ctx, 0, ctx->btarget);
10851 break;
10852 case MIPS_HFLAG_BC:
10853 /* Conditional branch */
c9602061 10854 {
42a268c2 10855 TCGLabel *l1 = gen_new_label();
c9602061
NF
10856
10857 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10858 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10859 gen_set_label(l1);
10860 gen_goto_tb(ctx, 0, ctx->btarget);
10861 }
10862 break;
10863 case MIPS_HFLAG_BR:
10864 /* unconditional branch to register */
d75c135e 10865 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10866 TCGv t0 = tcg_temp_new();
10867 TCGv_i32 t1 = tcg_temp_new_i32();
10868
10869 tcg_gen_andi_tl(t0, btarget, 0x1);
10870 tcg_gen_trunc_tl_i32(t1, t0);
10871 tcg_temp_free(t0);
10872 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10873 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10874 tcg_gen_or_i32(hflags, hflags, t1);
10875 tcg_temp_free_i32(t1);
10876
10877 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10878 } else {
10879 tcg_gen_mov_tl(cpu_PC, btarget);
10880 }
c9602061
NF
10881 if (ctx->singlestep_enabled) {
10882 save_cpu_state(ctx, 0);
9c708c7f 10883 gen_helper_raise_exception_debug(cpu_env);
c9602061 10884 }
e350d8ca 10885 tcg_gen_lookup_and_goto_ptr(cpu_PC);
c9602061
NF
10886 break;
10887 default:
a5f53390
LA
10888 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10889 abort();
c9602061
NF
10890 }
10891 }
10892}
10893
6893f074
YK
10894/* Compact Branches */
10895static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10896 int rs, int rt, int32_t offset)
10897{
10898 int bcond_compute = 0;
10899 TCGv t0 = tcg_temp_new();
10900 TCGv t1 = tcg_temp_new();
65935f07 10901 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10902
10903 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10904#ifdef MIPS_DEBUG_DISAS
10905 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10906 "\n", ctx->pc);
10907#endif
9c708c7f 10908 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10909 goto out;
10910 }
10911
10912 /* Load needed operands and calculate btarget */
10913 switch (opc) {
10914 /* compact branch */
10915 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10916 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10917 gen_load_gpr(t0, rs);
10918 gen_load_gpr(t1, rt);
10919 bcond_compute = 1;
10920 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10921 if (rs <= rt && rs == 0) {
10922 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10923 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10924 }
10925 break;
10926 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10927 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10928 gen_load_gpr(t0, rs);
10929 gen_load_gpr(t1, rt);
10930 bcond_compute = 1;
10931 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10932 break;
10933 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10934 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10935 if (rs == 0 || rs == rt) {
10936 /* OPC_BLEZALC, OPC_BGEZALC */
10937 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10938 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10939 }
10940 gen_load_gpr(t0, rs);
10941 gen_load_gpr(t1, rt);
10942 bcond_compute = 1;
10943 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10944 break;
10945 case OPC_BC:
10946 case OPC_BALC:
10947 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10948 break;
10949 case OPC_BEQZC:
10950 case OPC_BNEZC:
10951 if (rs != 0) {
10952 /* OPC_BEQZC, OPC_BNEZC */
10953 gen_load_gpr(t0, rs);
10954 bcond_compute = 1;
10955 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10956 } else {
10957 /* OPC_JIC, OPC_JIALC */
10958 TCGv tbase = tcg_temp_new();
10959 TCGv toffset = tcg_temp_new();
10960
10961 gen_load_gpr(tbase, rt);
10962 tcg_gen_movi_tl(toffset, offset);
10963 gen_op_addr_add(ctx, btarget, tbase, toffset);
10964 tcg_temp_free(tbase);
10965 tcg_temp_free(toffset);
10966 }
10967 break;
10968 default:
10969 MIPS_INVAL("Compact branch/jump");
9c708c7f 10970 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10971 goto out;
10972 }
10973
10974 if (bcond_compute == 0) {
10975 /* Uncoditional compact branch */
10976 switch (opc) {
10977 case OPC_JIALC:
65935f07 10978 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10979 /* Fallthrough */
10980 case OPC_JIC:
10981 ctx->hflags |= MIPS_HFLAG_BR;
10982 break;
10983 case OPC_BALC:
65935f07 10984 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10985 /* Fallthrough */
10986 case OPC_BC:
10987 ctx->hflags |= MIPS_HFLAG_B;
10988 break;
10989 default:
10990 MIPS_INVAL("Compact branch/jump");
9c708c7f 10991 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10992 goto out;
10993 }
10994
10995 /* Generating branch here as compact branches don't have delay slot */
10996 gen_branch(ctx, 4);
10997 } else {
10998 /* Conditional compact branch */
10999 TCGLabel *fs = gen_new_label();
11000 save_cpu_state(ctx, 0);
11001
11002 switch (opc) {
11003 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11004 if (rs == 0 && rt != 0) {
11005 /* OPC_BLEZALC */
11006 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11007 } else if (rs != 0 && rt != 0 && rs == rt) {
11008 /* OPC_BGEZALC */
11009 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11010 } else {
11011 /* OPC_BGEUC */
11012 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11013 }
11014 break;
11015 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11016 if (rs == 0 && rt != 0) {
11017 /* OPC_BGTZALC */
11018 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11019 } else if (rs != 0 && rt != 0 && rs == rt) {
11020 /* OPC_BLTZALC */
11021 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11022 } else {
11023 /* OPC_BLTUC */
11024 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11025 }
11026 break;
11027 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11028 if (rs == 0 && rt != 0) {
11029 /* OPC_BLEZC */
11030 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11031 } else if (rs != 0 && rt != 0 && rs == rt) {
11032 /* OPC_BGEZC */
11033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11034 } else {
11035 /* OPC_BGEC */
11036 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11037 }
11038 break;
11039 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11040 if (rs == 0 && rt != 0) {
11041 /* OPC_BGTZC */
11042 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11043 } else if (rs != 0 && rt != 0 && rs == rt) {
11044 /* OPC_BLTZC */
11045 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11046 } else {
11047 /* OPC_BLTC */
11048 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11049 }
11050 break;
11051 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11052 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11053 if (rs >= rt) {
11054 /* OPC_BOVC, OPC_BNVC */
11055 TCGv t2 = tcg_temp_new();
11056 TCGv t3 = tcg_temp_new();
11057 TCGv t4 = tcg_temp_new();
11058 TCGv input_overflow = tcg_temp_new();
11059
11060 gen_load_gpr(t0, rs);
11061 gen_load_gpr(t1, rt);
11062 tcg_gen_ext32s_tl(t2, t0);
11063 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11064 tcg_gen_ext32s_tl(t3, t1);
11065 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11066 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11067
11068 tcg_gen_add_tl(t4, t2, t3);
11069 tcg_gen_ext32s_tl(t4, t4);
11070 tcg_gen_xor_tl(t2, t2, t3);
11071 tcg_gen_xor_tl(t3, t4, t3);
11072 tcg_gen_andc_tl(t2, t3, t2);
11073 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11074 tcg_gen_or_tl(t4, t4, input_overflow);
11075 if (opc == OPC_BOVC) {
11076 /* OPC_BOVC */
11077 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11078 } else {
11079 /* OPC_BNVC */
11080 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11081 }
11082 tcg_temp_free(input_overflow);
11083 tcg_temp_free(t4);
11084 tcg_temp_free(t3);
11085 tcg_temp_free(t2);
11086 } else if (rs < rt && rs == 0) {
11087 /* OPC_BEQZALC, OPC_BNEZALC */
11088 if (opc == OPC_BEQZALC) {
11089 /* OPC_BEQZALC */
11090 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11091 } else {
11092 /* OPC_BNEZALC */
11093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11094 }
11095 } else {
11096 /* OPC_BEQC, OPC_BNEC */
11097 if (opc == OPC_BEQC) {
11098 /* OPC_BEQC */
11099 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11100 } else {
11101 /* OPC_BNEC */
11102 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11103 }
11104 }
11105 break;
11106 case OPC_BEQZC:
11107 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11108 break;
11109 case OPC_BNEZC:
11110 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11111 break;
11112 default:
11113 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 11114 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11115 goto out;
11116 }
11117
11118 /* Generating branch here as compact branches don't have delay slot */
11119 gen_goto_tb(ctx, 1, ctx->btarget);
11120 gen_set_label(fs);
11121
11122 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
11123 }
11124
11125out:
11126 tcg_temp_free(t0);
11127 tcg_temp_free(t1);
11128}
11129
7a387fff 11130/* ISA extensions (ASEs) */
6af0bf9c 11131/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11132
11133/* MIPS16 major opcodes */
11134enum {
11135 M16_OPC_ADDIUSP = 0x00,
11136 M16_OPC_ADDIUPC = 0x01,
11137 M16_OPC_B = 0x02,
11138 M16_OPC_JAL = 0x03,
11139 M16_OPC_BEQZ = 0x04,
11140 M16_OPC_BNEQZ = 0x05,
11141 M16_OPC_SHIFT = 0x06,
11142 M16_OPC_LD = 0x07,
11143 M16_OPC_RRIA = 0x08,
11144 M16_OPC_ADDIU8 = 0x09,
11145 M16_OPC_SLTI = 0x0a,
11146 M16_OPC_SLTIU = 0x0b,
11147 M16_OPC_I8 = 0x0c,
11148 M16_OPC_LI = 0x0d,
11149 M16_OPC_CMPI = 0x0e,
11150 M16_OPC_SD = 0x0f,
11151 M16_OPC_LB = 0x10,
11152 M16_OPC_LH = 0x11,
11153 M16_OPC_LWSP = 0x12,
11154 M16_OPC_LW = 0x13,
11155 M16_OPC_LBU = 0x14,
11156 M16_OPC_LHU = 0x15,
11157 M16_OPC_LWPC = 0x16,
11158 M16_OPC_LWU = 0x17,
11159 M16_OPC_SB = 0x18,
11160 M16_OPC_SH = 0x19,
11161 M16_OPC_SWSP = 0x1a,
11162 M16_OPC_SW = 0x1b,
11163 M16_OPC_RRR = 0x1c,
11164 M16_OPC_RR = 0x1d,
11165 M16_OPC_EXTEND = 0x1e,
11166 M16_OPC_I64 = 0x1f
11167};
11168
11169/* I8 funct field */
11170enum {
11171 I8_BTEQZ = 0x0,
11172 I8_BTNEZ = 0x1,
11173 I8_SWRASP = 0x2,
11174 I8_ADJSP = 0x3,
11175 I8_SVRS = 0x4,
11176 I8_MOV32R = 0x5,
11177 I8_MOVR32 = 0x7
11178};
11179
11180/* RRR f field */
11181enum {
11182 RRR_DADDU = 0x0,
11183 RRR_ADDU = 0x1,
11184 RRR_DSUBU = 0x2,
11185 RRR_SUBU = 0x3
11186};
11187
11188/* RR funct field */
11189enum {
11190 RR_JR = 0x00,
11191 RR_SDBBP = 0x01,
11192 RR_SLT = 0x02,
11193 RR_SLTU = 0x03,
11194 RR_SLLV = 0x04,
11195 RR_BREAK = 0x05,
11196 RR_SRLV = 0x06,
11197 RR_SRAV = 0x07,
11198 RR_DSRL = 0x08,
11199 RR_CMP = 0x0a,
11200 RR_NEG = 0x0b,
11201 RR_AND = 0x0c,
11202 RR_OR = 0x0d,
11203 RR_XOR = 0x0e,
11204 RR_NOT = 0x0f,
11205 RR_MFHI = 0x10,
11206 RR_CNVT = 0x11,
11207 RR_MFLO = 0x12,
11208 RR_DSRA = 0x13,
11209 RR_DSLLV = 0x14,
11210 RR_DSRLV = 0x16,
11211 RR_DSRAV = 0x17,
11212 RR_MULT = 0x18,
11213 RR_MULTU = 0x19,
11214 RR_DIV = 0x1a,
11215 RR_DIVU = 0x1b,
11216 RR_DMULT = 0x1c,
11217 RR_DMULTU = 0x1d,
11218 RR_DDIV = 0x1e,
11219 RR_DDIVU = 0x1f
11220};
11221
11222/* I64 funct field */
11223enum {
11224 I64_LDSP = 0x0,
11225 I64_SDSP = 0x1,
11226 I64_SDRASP = 0x2,
11227 I64_DADJSP = 0x3,
11228 I64_LDPC = 0x4,
364d4831 11229 I64_DADDIU5 = 0x5,
6ea219d0
NF
11230 I64_DADDIUPC = 0x6,
11231 I64_DADDIUSP = 0x7
11232};
11233
11234/* RR ry field for CNVT */
11235enum {
11236 RR_RY_CNVT_ZEB = 0x0,
11237 RR_RY_CNVT_ZEH = 0x1,
11238 RR_RY_CNVT_ZEW = 0x2,
11239 RR_RY_CNVT_SEB = 0x4,
11240 RR_RY_CNVT_SEH = 0x5,
11241 RR_RY_CNVT_SEW = 0x6,
11242};
11243
364d4831
NF
11244static int xlat (int r)
11245{
11246 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11247
11248 return map[r];
11249}
11250
11251static void gen_mips16_save (DisasContext *ctx,
11252 int xsregs, int aregs,
11253 int do_ra, int do_s0, int do_s1,
11254 int framesize)
11255{
11256 TCGv t0 = tcg_temp_new();
11257 TCGv t1 = tcg_temp_new();
c48245f0 11258 TCGv t2 = tcg_temp_new();
364d4831
NF
11259 int args, astatic;
11260
11261 switch (aregs) {
11262 case 0:
11263 case 1:
11264 case 2:
11265 case 3:
11266 case 11:
11267 args = 0;
11268 break;
11269 case 4:
11270 case 5:
11271 case 6:
11272 case 7:
11273 args = 1;
11274 break;
11275 case 8:
11276 case 9:
11277 case 10:
11278 args = 2;
11279 break;
11280 case 12:
11281 case 13:
11282 args = 3;
11283 break;
11284 case 14:
11285 args = 4;
11286 break;
11287 default:
9c708c7f 11288 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11289 return;
11290 }
11291
11292 switch (args) {
11293 case 4:
11294 gen_base_offset_addr(ctx, t0, 29, 12);
11295 gen_load_gpr(t1, 7);
5f68f5ae 11296 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11297 /* Fall through */
11298 case 3:
11299 gen_base_offset_addr(ctx, t0, 29, 8);
11300 gen_load_gpr(t1, 6);
5f68f5ae 11301 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11302 /* Fall through */
11303 case 2:
11304 gen_base_offset_addr(ctx, t0, 29, 4);
11305 gen_load_gpr(t1, 5);
5f68f5ae 11306 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11307 /* Fall through */
11308 case 1:
11309 gen_base_offset_addr(ctx, t0, 29, 0);
11310 gen_load_gpr(t1, 4);
5f68f5ae 11311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11312 }
11313
11314 gen_load_gpr(t0, 29);
11315
5f68f5ae 11316#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11317 tcg_gen_movi_tl(t2, -4); \
11318 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11319 gen_load_gpr(t1, reg); \
11320 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11321 } while (0)
11322
11323 if (do_ra) {
11324 DECR_AND_STORE(31);
11325 }
11326
11327 switch (xsregs) {
11328 case 7:
11329 DECR_AND_STORE(30);
11330 /* Fall through */
11331 case 6:
11332 DECR_AND_STORE(23);
11333 /* Fall through */
11334 case 5:
11335 DECR_AND_STORE(22);
11336 /* Fall through */
11337 case 4:
11338 DECR_AND_STORE(21);
11339 /* Fall through */
11340 case 3:
11341 DECR_AND_STORE(20);
11342 /* Fall through */
11343 case 2:
11344 DECR_AND_STORE(19);
11345 /* Fall through */
11346 case 1:
11347 DECR_AND_STORE(18);
11348 }
11349
11350 if (do_s1) {
11351 DECR_AND_STORE(17);
11352 }
11353 if (do_s0) {
11354 DECR_AND_STORE(16);
11355 }
11356
11357 switch (aregs) {
11358 case 0:
11359 case 4:
11360 case 8:
11361 case 12:
11362 case 14:
11363 astatic = 0;
11364 break;
11365 case 1:
11366 case 5:
11367 case 9:
11368 case 13:
11369 astatic = 1;
11370 break;
11371 case 2:
11372 case 6:
11373 case 10:
11374 astatic = 2;
11375 break;
11376 case 3:
11377 case 7:
11378 astatic = 3;
11379 break;
11380 case 11:
11381 astatic = 4;
11382 break;
11383 default:
9c708c7f 11384 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11385 return;
11386 }
11387
11388 if (astatic > 0) {
11389 DECR_AND_STORE(7);
11390 if (astatic > 1) {
11391 DECR_AND_STORE(6);
11392 if (astatic > 2) {
11393 DECR_AND_STORE(5);
11394 if (astatic > 3) {
11395 DECR_AND_STORE(4);
11396 }
11397 }
11398 }
11399 }
11400#undef DECR_AND_STORE
11401
c48245f0
MR
11402 tcg_gen_movi_tl(t2, -framesize);
11403 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11404 tcg_temp_free(t0);
11405 tcg_temp_free(t1);
c48245f0 11406 tcg_temp_free(t2);
364d4831
NF
11407}
11408
11409static void gen_mips16_restore (DisasContext *ctx,
11410 int xsregs, int aregs,
11411 int do_ra, int do_s0, int do_s1,
11412 int framesize)
11413{
11414 int astatic;
11415 TCGv t0 = tcg_temp_new();
11416 TCGv t1 = tcg_temp_new();
c48245f0 11417 TCGv t2 = tcg_temp_new();
364d4831 11418
c48245f0
MR
11419 tcg_gen_movi_tl(t2, framesize);
11420 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11421
5f68f5ae 11422#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11423 tcg_gen_movi_tl(t2, -4); \
11424 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11425 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11426 gen_store_gpr(t1, reg); \
364d4831
NF
11427 } while (0)
11428
11429 if (do_ra) {
11430 DECR_AND_LOAD(31);
11431 }
11432
11433 switch (xsregs) {
11434 case 7:
11435 DECR_AND_LOAD(30);
11436 /* Fall through */
11437 case 6:
11438 DECR_AND_LOAD(23);
11439 /* Fall through */
11440 case 5:
11441 DECR_AND_LOAD(22);
11442 /* Fall through */
11443 case 4:
11444 DECR_AND_LOAD(21);
11445 /* Fall through */
11446 case 3:
11447 DECR_AND_LOAD(20);
11448 /* Fall through */
11449 case 2:
11450 DECR_AND_LOAD(19);
11451 /* Fall through */
11452 case 1:
11453 DECR_AND_LOAD(18);
11454 }
11455
11456 if (do_s1) {
11457 DECR_AND_LOAD(17);
11458 }
11459 if (do_s0) {
11460 DECR_AND_LOAD(16);
11461 }
11462
11463 switch (aregs) {
11464 case 0:
11465 case 4:
11466 case 8:
11467 case 12:
11468 case 14:
11469 astatic = 0;
11470 break;
11471 case 1:
11472 case 5:
11473 case 9:
11474 case 13:
11475 astatic = 1;
11476 break;
11477 case 2:
11478 case 6:
11479 case 10:
11480 astatic = 2;
11481 break;
11482 case 3:
11483 case 7:
11484 astatic = 3;
11485 break;
11486 case 11:
11487 astatic = 4;
11488 break;
11489 default:
9c708c7f 11490 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11491 return;
11492 }
11493
11494 if (astatic > 0) {
11495 DECR_AND_LOAD(7);
11496 if (astatic > 1) {
11497 DECR_AND_LOAD(6);
11498 if (astatic > 2) {
11499 DECR_AND_LOAD(5);
11500 if (astatic > 3) {
11501 DECR_AND_LOAD(4);
11502 }
11503 }
11504 }
11505 }
11506#undef DECR_AND_LOAD
11507
c48245f0
MR
11508 tcg_gen_movi_tl(t2, framesize);
11509 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11510 tcg_temp_free(t0);
11511 tcg_temp_free(t1);
c48245f0 11512 tcg_temp_free(t2);
364d4831
NF
11513}
11514
11515static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11516 int is_64_bit, int extended)
11517{
11518 TCGv t0;
11519
11520 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11521 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11522 return;
11523 }
11524
11525 t0 = tcg_temp_new();
11526
11527 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11528 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11529 if (!is_64_bit) {
11530 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11531 }
11532
11533 tcg_temp_free(t0);
11534}
11535
0d74a222
LA
11536static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11537 int16_t offset)
11538{
11539 TCGv_i32 t0 = tcg_const_i32(op);
11540 TCGv t1 = tcg_temp_new();
11541 gen_base_offset_addr(ctx, t1, base, offset);
11542 gen_helper_cache(cpu_env, t1, t0);
11543}
11544
364d4831 11545#if defined(TARGET_MIPS64)
d75c135e 11546static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11547 int ry, int funct, int16_t offset,
11548 int extended)
11549{
11550 switch (funct) {
11551 case I64_LDSP:
d9224450 11552 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11553 check_mips_64(ctx);
11554 offset = extended ? offset : offset << 3;
d75c135e 11555 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11556 break;
11557 case I64_SDSP:
d9224450 11558 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11559 check_mips_64(ctx);
11560 offset = extended ? offset : offset << 3;
5c13fdfd 11561 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11562 break;
11563 case I64_SDRASP:
d9224450 11564 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11565 check_mips_64(ctx);
11566 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11567 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11568 break;
11569 case I64_DADJSP:
d9224450 11570 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11571 check_mips_64(ctx);
11572 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11573 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11574 break;
11575 case I64_LDPC:
d9224450
MR
11576 check_insn(ctx, ISA_MIPS3);
11577 check_mips_64(ctx);
364d4831 11578 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11579 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11580 } else {
11581 offset = extended ? offset : offset << 3;
d75c135e 11582 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11583 }
11584 break;
11585 case I64_DADDIU5:
d9224450 11586 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11587 check_mips_64(ctx);
11588 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11589 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11590 break;
11591 case I64_DADDIUPC:
d9224450 11592 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11593 check_mips_64(ctx);
11594 offset = extended ? offset : offset << 2;
11595 gen_addiupc(ctx, ry, offset, 1, extended);
11596 break;
11597 case I64_DADDIUSP:
d9224450 11598 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11599 check_mips_64(ctx);
11600 offset = extended ? offset : offset << 2;
d75c135e 11601 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11602 break;
11603 }
11604}
11605#endif
11606
240ce26a 11607static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11608{
895c2d04 11609 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11610 int op, rx, ry, funct, sa;
11611 int16_t imm, offset;
11612
11613 ctx->opcode = (ctx->opcode << 16) | extend;
11614 op = (ctx->opcode >> 11) & 0x1f;
11615 sa = (ctx->opcode >> 22) & 0x1f;
11616 funct = (ctx->opcode >> 8) & 0x7;
11617 rx = xlat((ctx->opcode >> 8) & 0x7);
11618 ry = xlat((ctx->opcode >> 5) & 0x7);
11619 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11620 | ((ctx->opcode >> 21) & 0x3f) << 5
11621 | (ctx->opcode & 0x1f));
11622
11623 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11624 counterparts. */
11625 switch (op) {
11626 case M16_OPC_ADDIUSP:
d75c135e 11627 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11628 break;
11629 case M16_OPC_ADDIUPC:
11630 gen_addiupc(ctx, rx, imm, 0, 1);
11631 break;
11632 case M16_OPC_B:
b231c103 11633 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11634 /* No delay slot, so just process as a normal instruction */
11635 break;
11636 case M16_OPC_BEQZ:
b231c103 11637 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11638 /* No delay slot, so just process as a normal instruction */
11639 break;
11640 case M16_OPC_BNEQZ:
b231c103 11641 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11642 /* No delay slot, so just process as a normal instruction */
11643 break;
11644 case M16_OPC_SHIFT:
11645 switch (ctx->opcode & 0x3) {
11646 case 0x0:
d75c135e 11647 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11648 break;
11649 case 0x1:
11650#if defined(TARGET_MIPS64)
11651 check_mips_64(ctx);
d75c135e 11652 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11653#else
9c708c7f 11654 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11655#endif
11656 break;
11657 case 0x2:
d75c135e 11658 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11659 break;
11660 case 0x3:
d75c135e 11661 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11662 break;
11663 }
11664 break;
11665#if defined(TARGET_MIPS64)
11666 case M16_OPC_LD:
d9224450 11667 check_insn(ctx, ISA_MIPS3);
d75de749 11668 check_mips_64(ctx);
d75c135e 11669 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11670 break;
11671#endif
11672 case M16_OPC_RRIA:
11673 imm = ctx->opcode & 0xf;
11674 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11675 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11676 imm = (int16_t) (imm << 1) >> 1;
11677 if ((ctx->opcode >> 4) & 0x1) {
11678#if defined(TARGET_MIPS64)
11679 check_mips_64(ctx);
d75c135e 11680 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11681#else
9c708c7f 11682 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11683#endif
11684 } else {
d75c135e 11685 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11686 }
11687 break;
11688 case M16_OPC_ADDIU8:
d75c135e 11689 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11690 break;
11691 case M16_OPC_SLTI:
d75c135e 11692 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11693 break;
11694 case M16_OPC_SLTIU:
d75c135e 11695 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11696 break;
11697 case M16_OPC_I8:
11698 switch (funct) {
11699 case I8_BTEQZ:
b231c103 11700 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11701 break;
11702 case I8_BTNEZ:
b231c103 11703 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11704 break;
11705 case I8_SWRASP:
5c13fdfd 11706 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11707 break;
11708 case I8_ADJSP:
d75c135e 11709 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11710 break;
11711 case I8_SVRS:
d9224450 11712 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11713 {
11714 int xsregs = (ctx->opcode >> 24) & 0x7;
11715 int aregs = (ctx->opcode >> 16) & 0xf;
11716 int do_ra = (ctx->opcode >> 6) & 0x1;
11717 int do_s0 = (ctx->opcode >> 5) & 0x1;
11718 int do_s1 = (ctx->opcode >> 4) & 0x1;
11719 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11720 | (ctx->opcode & 0xf)) << 3;
11721
11722 if (ctx->opcode & (1 << 7)) {
11723 gen_mips16_save(ctx, xsregs, aregs,
11724 do_ra, do_s0, do_s1,
11725 framesize);
11726 } else {
11727 gen_mips16_restore(ctx, xsregs, aregs,
11728 do_ra, do_s0, do_s1,
11729 framesize);
11730 }
11731 }
11732 break;
11733 default:
9c708c7f 11734 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11735 break;
11736 }
11737 break;
11738 case M16_OPC_LI:
11739 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11740 break;
11741 case M16_OPC_CMPI:
11742 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11743 break;
11744#if defined(TARGET_MIPS64)
11745 case M16_OPC_SD:
d9224450
MR
11746 check_insn(ctx, ISA_MIPS3);
11747 check_mips_64(ctx);
5c13fdfd 11748 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11749 break;
11750#endif
11751 case M16_OPC_LB:
d75c135e 11752 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11753 break;
11754 case M16_OPC_LH:
d75c135e 11755 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11756 break;
11757 case M16_OPC_LWSP:
d75c135e 11758 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11759 break;
11760 case M16_OPC_LW:
d75c135e 11761 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11762 break;
11763 case M16_OPC_LBU:
d75c135e 11764 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11765 break;
11766 case M16_OPC_LHU:
d75c135e 11767 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11768 break;
11769 case M16_OPC_LWPC:
d75c135e 11770 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11771 break;
11772#if defined(TARGET_MIPS64)
11773 case M16_OPC_LWU:
d9224450
MR
11774 check_insn(ctx, ISA_MIPS3);
11775 check_mips_64(ctx);
d75c135e 11776 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11777 break;
11778#endif
11779 case M16_OPC_SB:
5c13fdfd 11780 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11781 break;
11782 case M16_OPC_SH:
5c13fdfd 11783 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11784 break;
11785 case M16_OPC_SWSP:
5c13fdfd 11786 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11787 break;
11788 case M16_OPC_SW:
5c13fdfd 11789 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11790 break;
11791#if defined(TARGET_MIPS64)
11792 case M16_OPC_I64:
d75c135e 11793 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11794 break;
11795#endif
11796 default:
9c708c7f 11797 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11798 break;
11799 }
11800
11801 return 4;
11802}
11803
3b3c1694
LA
11804static inline bool is_uhi(int sdbbp_code)
11805{
11806#ifdef CONFIG_USER_ONLY
11807 return false;
11808#else
11809 return semihosting_enabled() && sdbbp_code == 1;
11810#endif
11811}
11812
240ce26a 11813static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11814{
11815 int rx, ry;
11816 int sa;
11817 int op, cnvt_op, op1, offset;
11818 int funct;
11819 int n_bytes;
11820
11821 op = (ctx->opcode >> 11) & 0x1f;
11822 sa = (ctx->opcode >> 2) & 0x7;
11823 sa = sa == 0 ? 8 : sa;
11824 rx = xlat((ctx->opcode >> 8) & 0x7);
11825 cnvt_op = (ctx->opcode >> 5) & 0x7;
11826 ry = xlat((ctx->opcode >> 5) & 0x7);
11827 op1 = offset = ctx->opcode & 0x1f;
11828
11829 n_bytes = 2;
11830
11831 switch (op) {
11832 case M16_OPC_ADDIUSP:
11833 {
11834 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11835
d75c135e 11836 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11837 }
11838 break;
11839 case M16_OPC_ADDIUPC:
11840 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11841 break;
11842 case M16_OPC_B:
11843 offset = (ctx->opcode & 0x7ff) << 1;
11844 offset = (int16_t)(offset << 4) >> 4;
b231c103 11845 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11846 /* No delay slot, so just process as a normal instruction */
11847 break;
11848 case M16_OPC_JAL:
895c2d04 11849 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11850 offset = (((ctx->opcode & 0x1f) << 21)
11851 | ((ctx->opcode >> 5) & 0x1f) << 16
11852 | offset) << 2;
b231c103
YK
11853 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11854 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11855 n_bytes = 4;
364d4831
NF
11856 break;
11857 case M16_OPC_BEQZ:
b231c103
YK
11858 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11859 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11860 /* No delay slot, so just process as a normal instruction */
11861 break;
11862 case M16_OPC_BNEQZ:
b231c103
YK
11863 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11864 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11865 /* No delay slot, so just process as a normal instruction */
11866 break;
11867 case M16_OPC_SHIFT:
11868 switch (ctx->opcode & 0x3) {
11869 case 0x0:
d75c135e 11870 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11871 break;
11872 case 0x1:
11873#if defined(TARGET_MIPS64)
d9224450 11874 check_insn(ctx, ISA_MIPS3);
364d4831 11875 check_mips_64(ctx);
d75c135e 11876 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11877#else
9c708c7f 11878 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11879#endif
11880 break;
11881 case 0x2:
d75c135e 11882 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11883 break;
11884 case 0x3:
d75c135e 11885 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11886 break;
11887 }
11888 break;
11889#if defined(TARGET_MIPS64)
11890 case M16_OPC_LD:
d9224450 11891 check_insn(ctx, ISA_MIPS3);
364d4831 11892 check_mips_64(ctx);
d75c135e 11893 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11894 break;
11895#endif
11896 case M16_OPC_RRIA:
11897 {
11898 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11899
11900 if ((ctx->opcode >> 4) & 1) {
11901#if defined(TARGET_MIPS64)
d9224450 11902 check_insn(ctx, ISA_MIPS3);
364d4831 11903 check_mips_64(ctx);
d75c135e 11904 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11905#else
9c708c7f 11906 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11907#endif
11908 } else {
d75c135e 11909 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11910 }
11911 }
11912 break;
11913 case M16_OPC_ADDIU8:
11914 {
11915 int16_t imm = (int8_t) ctx->opcode;
11916
d75c135e 11917 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11918 }
11919 break;
11920 case M16_OPC_SLTI:
11921 {
11922 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11923 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11924 }
11925 break;
11926 case M16_OPC_SLTIU:
11927 {
11928 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11929 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11930 }
11931 break;
11932 case M16_OPC_I8:
11933 {
11934 int reg32;
11935
11936 funct = (ctx->opcode >> 8) & 0x7;
11937 switch (funct) {
11938 case I8_BTEQZ:
11939 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11940 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11941 break;
11942 case I8_BTNEZ:
11943 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11944 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11945 break;
11946 case I8_SWRASP:
5c13fdfd 11947 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11948 break;
11949 case I8_ADJSP:
d75c135e 11950 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11951 ((int8_t)ctx->opcode) << 3);
11952 break;
11953 case I8_SVRS:
d9224450 11954 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11955 {
11956 int do_ra = ctx->opcode & (1 << 6);
11957 int do_s0 = ctx->opcode & (1 << 5);
11958 int do_s1 = ctx->opcode & (1 << 4);
11959 int framesize = ctx->opcode & 0xf;
11960
11961 if (framesize == 0) {
11962 framesize = 128;
11963 } else {
11964 framesize = framesize << 3;
11965 }
11966
11967 if (ctx->opcode & (1 << 7)) {
11968 gen_mips16_save(ctx, 0, 0,
11969 do_ra, do_s0, do_s1, framesize);
11970 } else {
11971 gen_mips16_restore(ctx, 0, 0,
11972 do_ra, do_s0, do_s1, framesize);
11973 }
11974 }
11975 break;
11976 case I8_MOV32R:
11977 {
11978 int rz = xlat(ctx->opcode & 0x7);
11979
11980 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11981 ((ctx->opcode >> 5) & 0x7);
d75c135e 11982 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11983 }
11984 break;
11985 case I8_MOVR32:
11986 reg32 = ctx->opcode & 0x1f;
d75c135e 11987 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11988 break;
11989 default:
9c708c7f 11990 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11991 break;
11992 }
11993 }
11994 break;
11995 case M16_OPC_LI:
11996 {
11997 int16_t imm = (uint8_t) ctx->opcode;
11998
d75c135e 11999 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12000 }
12001 break;
12002 case M16_OPC_CMPI:
12003 {
12004 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12005 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12006 }
12007 break;
12008#if defined(TARGET_MIPS64)
12009 case M16_OPC_SD:
d9224450 12010 check_insn(ctx, ISA_MIPS3);
364d4831 12011 check_mips_64(ctx);
5c13fdfd 12012 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12013 break;
12014#endif
12015 case M16_OPC_LB:
d75c135e 12016 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12017 break;
12018 case M16_OPC_LH:
d75c135e 12019 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12020 break;
12021 case M16_OPC_LWSP:
d75c135e 12022 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12023 break;
12024 case M16_OPC_LW:
d75c135e 12025 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12026 break;
12027 case M16_OPC_LBU:
d75c135e 12028 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12029 break;
12030 case M16_OPC_LHU:
d75c135e 12031 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12032 break;
12033 case M16_OPC_LWPC:
d75c135e 12034 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12035 break;
12036#if defined (TARGET_MIPS64)
12037 case M16_OPC_LWU:
d9224450 12038 check_insn(ctx, ISA_MIPS3);
364d4831 12039 check_mips_64(ctx);
d75c135e 12040 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12041 break;
12042#endif
12043 case M16_OPC_SB:
5c13fdfd 12044 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12045 break;
12046 case M16_OPC_SH:
5c13fdfd 12047 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12048 break;
12049 case M16_OPC_SWSP:
5c13fdfd 12050 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12051 break;
12052 case M16_OPC_SW:
5c13fdfd 12053 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12054 break;
12055 case M16_OPC_RRR:
12056 {
12057 int rz = xlat((ctx->opcode >> 2) & 0x7);
12058 int mips32_op;
12059
12060 switch (ctx->opcode & 0x3) {
12061 case RRR_ADDU:
12062 mips32_op = OPC_ADDU;
12063 break;
12064 case RRR_SUBU:
12065 mips32_op = OPC_SUBU;
12066 break;
12067#if defined(TARGET_MIPS64)
12068 case RRR_DADDU:
12069 mips32_op = OPC_DADDU;
d9224450 12070 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12071 check_mips_64(ctx);
12072 break;
12073 case RRR_DSUBU:
12074 mips32_op = OPC_DSUBU;
d9224450 12075 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12076 check_mips_64(ctx);
12077 break;
12078#endif
12079 default:
9c708c7f 12080 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12081 goto done;
12082 }
12083
d75c135e 12084 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12085 done:
12086 ;
12087 }
12088 break;
12089 case M16_OPC_RR:
12090 switch (op1) {
12091 case RR_JR:
12092 {
12093 int nd = (ctx->opcode >> 7) & 0x1;
12094 int link = (ctx->opcode >> 6) & 0x1;
12095 int ra = (ctx->opcode >> 5) & 0x1;
12096
d9224450
MR
12097 if (nd) {
12098 check_insn(ctx, ISA_MIPS32);
12099 }
12100
364d4831 12101 if (link) {
b231c103 12102 op = OPC_JALR;
364d4831
NF
12103 } else {
12104 op = OPC_JR;
12105 }
12106
b231c103
YK
12107 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12108 (nd ? 0 : 2));
364d4831
NF
12109 }
12110 break;
12111 case RR_SDBBP:
3b3c1694
LA
12112 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12113 gen_helper_do_semihosting(cpu_env);
12114 } else {
12115 /* XXX: not clear which exception should be raised
12116 * when in debug mode...
12117 */
12118 check_insn(ctx, ISA_MIPS32);
9c708c7f 12119 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12120 }
364d4831
NF
12121 break;
12122 case RR_SLT:
d75c135e 12123 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12124 break;
12125 case RR_SLTU:
d75c135e 12126 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12127 break;
12128 case RR_BREAK:
9c708c7f 12129 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
12130 break;
12131 case RR_SLLV:
d75c135e 12132 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12133 break;
12134 case RR_SRLV:
d75c135e 12135 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12136 break;
12137 case RR_SRAV:
d75c135e 12138 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12139 break;
12140#if defined (TARGET_MIPS64)
12141 case RR_DSRL:
d9224450 12142 check_insn(ctx, ISA_MIPS3);
364d4831 12143 check_mips_64(ctx);
d75c135e 12144 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12145 break;
12146#endif
12147 case RR_CMP:
d75c135e 12148 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12149 break;
12150 case RR_NEG:
d75c135e 12151 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12152 break;
12153 case RR_AND:
d75c135e 12154 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12155 break;
12156 case RR_OR:
d75c135e 12157 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12158 break;
12159 case RR_XOR:
d75c135e 12160 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12161 break;
12162 case RR_NOT:
d75c135e 12163 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12164 break;
12165 case RR_MFHI:
26135ead 12166 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12167 break;
12168 case RR_CNVT:
d9224450 12169 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12170 switch (cnvt_op) {
12171 case RR_RY_CNVT_ZEB:
12172 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12173 break;
12174 case RR_RY_CNVT_ZEH:
12175 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12176 break;
12177 case RR_RY_CNVT_SEB:
12178 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12179 break;
12180 case RR_RY_CNVT_SEH:
12181 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12182 break;
12183#if defined (TARGET_MIPS64)
12184 case RR_RY_CNVT_ZEW:
d9224450 12185 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12186 check_mips_64(ctx);
12187 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12188 break;
12189 case RR_RY_CNVT_SEW:
d9224450 12190 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12191 check_mips_64(ctx);
12192 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12193 break;
12194#endif
12195 default:
9c708c7f 12196 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12197 break;
12198 }
12199 break;
12200 case RR_MFLO:
26135ead 12201 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12202 break;
12203#if defined (TARGET_MIPS64)
12204 case RR_DSRA:
d9224450 12205 check_insn(ctx, ISA_MIPS3);
364d4831 12206 check_mips_64(ctx);
d75c135e 12207 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12208 break;
12209 case RR_DSLLV:
d9224450 12210 check_insn(ctx, ISA_MIPS3);
364d4831 12211 check_mips_64(ctx);
d75c135e 12212 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12213 break;
12214 case RR_DSRLV:
d9224450 12215 check_insn(ctx, ISA_MIPS3);
364d4831 12216 check_mips_64(ctx);
d75c135e 12217 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12218 break;
12219 case RR_DSRAV:
d9224450 12220 check_insn(ctx, ISA_MIPS3);
364d4831 12221 check_mips_64(ctx);
d75c135e 12222 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12223 break;
12224#endif
12225 case RR_MULT:
26135ead 12226 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12227 break;
12228 case RR_MULTU:
26135ead 12229 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12230 break;
12231 case RR_DIV:
26135ead 12232 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12233 break;
12234 case RR_DIVU:
26135ead 12235 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12236 break;
12237#if defined (TARGET_MIPS64)
12238 case RR_DMULT:
d9224450 12239 check_insn(ctx, ISA_MIPS3);
364d4831 12240 check_mips_64(ctx);
26135ead 12241 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12242 break;
12243 case RR_DMULTU:
d9224450 12244 check_insn(ctx, ISA_MIPS3);
364d4831 12245 check_mips_64(ctx);
26135ead 12246 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12247 break;
12248 case RR_DDIV:
d9224450 12249 check_insn(ctx, ISA_MIPS3);
364d4831 12250 check_mips_64(ctx);
26135ead 12251 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12252 break;
12253 case RR_DDIVU:
d9224450 12254 check_insn(ctx, ISA_MIPS3);
364d4831 12255 check_mips_64(ctx);
26135ead 12256 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12257 break;
12258#endif
12259 default:
9c708c7f 12260 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12261 break;
12262 }
12263 break;
12264 case M16_OPC_EXTEND:
240ce26a 12265 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12266 n_bytes = 4;
12267 break;
12268#if defined(TARGET_MIPS64)
12269 case M16_OPC_I64:
12270 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12271 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12272 break;
12273#endif
12274 default:
9c708c7f 12275 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12276 break;
12277 }
12278
12279 return n_bytes;
12280}
12281
211da992 12282/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12283
211da992
CWR
12284/*
12285 * microMIPS32/microMIPS64 major opcodes
12286 *
12287 * 1. MIPS Architecture for Programmers Volume II-B:
12288 * The microMIPS32 Instruction Set (Revision 3.05)
12289 *
12290 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12291 *
12292 * 2. MIPS Architecture For Programmers Volume II-A:
12293 * The MIPS64 Instruction Set (Revision 3.51)
12294 */
6af0bf9c 12295
3c824109
NF
12296enum {
12297 POOL32A = 0x00,
12298 POOL16A = 0x01,
12299 LBU16 = 0x02,
12300 MOVE16 = 0x03,
12301 ADDI32 = 0x04,
3a1f4268
YK
12302 R6_LUI = 0x04,
12303 AUI = 0x04,
3c824109
NF
12304 LBU32 = 0x05,
12305 SB32 = 0x06,
12306 LB32 = 0x07,
12307
12308 POOL32B = 0x08,
12309 POOL16B = 0x09,
12310 LHU16 = 0x0a,
12311 ANDI16 = 0x0b,
12312 ADDIU32 = 0x0c,
12313 LHU32 = 0x0d,
12314 SH32 = 0x0e,
12315 LH32 = 0x0f,
12316
12317 POOL32I = 0x10,
12318 POOL16C = 0x11,
12319 LWSP16 = 0x12,
12320 POOL16D = 0x13,
12321 ORI32 = 0x14,
12322 POOL32F = 0x15,
211da992
CWR
12323 POOL32S = 0x16, /* MIPS64 */
12324 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12325
12326 POOL32C = 0x18,
12327 LWGP16 = 0x19,
12328 LW16 = 0x1a,
12329 POOL16E = 0x1b,
12330 XORI32 = 0x1c,
12331 JALS32 = 0x1d,
3a1f4268
YK
12332 BOVC = 0x1d,
12333 BEQC = 0x1d,
12334 BEQZALC = 0x1d,
3c824109 12335 ADDIUPC = 0x1e,
3a1f4268
YK
12336 PCREL = 0x1e,
12337 BNVC = 0x1f,
12338 BNEC = 0x1f,
12339 BNEZALC = 0x1f,
3c824109 12340
3a1f4268
YK
12341 R6_BEQZC = 0x20,
12342 JIC = 0x20,
3c824109
NF
12343 POOL16F = 0x21,
12344 SB16 = 0x22,
12345 BEQZ16 = 0x23,
3a1f4268 12346 BEQZC16 = 0x23,
3c824109
NF
12347 SLTI32 = 0x24,
12348 BEQ32 = 0x25,
3a1f4268 12349 BC = 0x25,
3c824109
NF
12350 SWC132 = 0x26,
12351 LWC132 = 0x27,
12352
3a1f4268 12353 /* 0x29 is reserved */
3c824109 12354 RES_29 = 0x29,
3a1f4268
YK
12355 R6_BNEZC = 0x28,
12356 JIALC = 0x28,
3c824109
NF
12357 SH16 = 0x2a,
12358 BNEZ16 = 0x2b,
3a1f4268 12359 BNEZC16 = 0x2b,
3c824109
NF
12360 SLTIU32 = 0x2c,
12361 BNE32 = 0x2d,
3a1f4268 12362 BALC = 0x2d,
3c824109
NF
12363 SDC132 = 0x2e,
12364 LDC132 = 0x2f,
12365
3a1f4268 12366 /* 0x31 is reserved */
3c824109 12367 RES_31 = 0x31,
3a1f4268
YK
12368 BLEZALC = 0x30,
12369 BGEZALC = 0x30,
12370 BGEUC = 0x30,
3c824109
NF
12371 SWSP16 = 0x32,
12372 B16 = 0x33,
3a1f4268 12373 BC16 = 0x33,
3c824109
NF
12374 ANDI32 = 0x34,
12375 J32 = 0x35,
3a1f4268
YK
12376 BGTZC = 0x35,
12377 BLTZC = 0x35,
12378 BLTC = 0x35,
211da992
CWR
12379 SD32 = 0x36, /* MIPS64 */
12380 LD32 = 0x37, /* MIPS64 */
3c824109 12381
3a1f4268 12382 /* 0x39 is reserved */
3c824109 12383 RES_39 = 0x39,
3a1f4268
YK
12384 BGTZALC = 0x38,
12385 BLTZALC = 0x38,
12386 BLTUC = 0x38,
3c824109
NF
12387 SW16 = 0x3a,
12388 LI16 = 0x3b,
12389 JALX32 = 0x3c,
12390 JAL32 = 0x3d,
3a1f4268
YK
12391 BLEZC = 0x3d,
12392 BGEZC = 0x3d,
12393 BGEC = 0x3d,
3c824109
NF
12394 SW32 = 0x3e,
12395 LW32 = 0x3f
12396};
12397
3a1f4268
YK
12398/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12399enum {
12400 ADDIUPC_00 = 0x00,
12401 ADDIUPC_07 = 0x07,
12402 AUIPC = 0x1e,
12403 ALUIPC = 0x1f,
12404 LWPC_08 = 0x08,
12405 LWPC_0F = 0x0F,
12406};
12407
3c824109
NF
12408/* POOL32A encoding of minor opcode field */
12409
12410enum {
12411 /* These opcodes are distinguished only by bits 9..6; those bits are
12412 * what are recorded below. */
12413 SLL32 = 0x0,
12414 SRL32 = 0x1,
12415 SRA = 0x2,
12416 ROTR = 0x3,
3a1f4268
YK
12417 SELEQZ = 0x5,
12418 SELNEZ = 0x6,
b00c7218 12419 R6_RDHWR = 0x7,
3c824109
NF
12420
12421 SLLV = 0x0,
12422 SRLV = 0x1,
12423 SRAV = 0x2,
12424 ROTRV = 0x3,
12425 ADD = 0x4,
12426 ADDU32 = 0x5,
12427 SUB = 0x6,
12428 SUBU32 = 0x7,
12429 MUL = 0x8,
12430 AND = 0x9,
12431 OR32 = 0xa,
12432 NOR = 0xb,
12433 XOR32 = 0xc,
12434 SLT = 0xd,
12435 SLTU = 0xe,
12436
12437 MOVN = 0x0,
3a1f4268 12438 R6_MUL = 0x0,
3c824109 12439 MOVZ = 0x1,
3a1f4268
YK
12440 MUH = 0x1,
12441 MULU = 0x2,
12442 MUHU = 0x3,
3c824109 12443 LWXS = 0x4,
3a1f4268
YK
12444 R6_DIV = 0x4,
12445 MOD = 0x5,
12446 R6_DIVU = 0x6,
12447 MODU = 0x7,
3c824109
NF
12448
12449 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12450 BREAK32 = 0x07,
3c824109 12451 INS = 0x0c,
3a1f4268
YK
12452 LSA = 0x0f,
12453 ALIGN = 0x1f,
3c824109 12454 EXT = 0x2c,
bb238210
YK
12455 POOL32AXF = 0x3c,
12456 SIGRIE = 0x3f
3c824109
NF
12457};
12458
12459/* POOL32AXF encoding of minor opcode field extension */
12460
d132c79f
CWR
12461/*
12462 * 1. MIPS Architecture for Programmers Volume II-B:
12463 * The microMIPS32 Instruction Set (Revision 3.05)
12464 *
12465 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12466 *
12467 * 2. MIPS Architecture for Programmers VolumeIV-e:
12468 * The MIPS DSP Application-Specific Extension
12469 * to the microMIPS32 Architecture (Revision 2.34)
12470 *
12471 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12472 */
12473
3c824109
NF
12474enum {
12475 /* bits 11..6 */
12476 TEQ = 0x00,
12477 TGE = 0x08,
12478 TGEU = 0x10,
12479 TLT = 0x20,
12480 TLTU = 0x28,
12481 TNE = 0x30,
12482
12483 MFC0 = 0x03,
12484 MTC0 = 0x0b,
12485
d132c79f
CWR
12486 /* begin of microMIPS32 DSP */
12487
3c824109
NF
12488 /* bits 13..12 for 0x01 */
12489 MFHI_ACC = 0x0,
12490 MFLO_ACC = 0x1,
12491 MTHI_ACC = 0x2,
12492 MTLO_ACC = 0x3,
12493
12494 /* bits 13..12 for 0x2a */
12495 MADD_ACC = 0x0,
12496 MADDU_ACC = 0x1,
12497 MSUB_ACC = 0x2,
12498 MSUBU_ACC = 0x3,
12499
12500 /* bits 13..12 for 0x32 */
12501 MULT_ACC = 0x0,
6801038b 12502 MULTU_ACC = 0x1,
3c824109 12503
d132c79f
CWR
12504 /* end of microMIPS32 DSP */
12505
3c824109 12506 /* bits 15..12 for 0x2c */
3a1f4268 12507 BITSWAP = 0x0,
3c824109
NF
12508 SEB = 0x2,
12509 SEH = 0x3,
12510 CLO = 0x4,
12511 CLZ = 0x5,
12512 RDHWR = 0x6,
12513 WSBH = 0x7,
12514 MULT = 0x8,
12515 MULTU = 0x9,
12516 DIV = 0xa,
12517 DIVU = 0xb,
12518 MADD = 0xc,
12519 MADDU = 0xd,
12520 MSUB = 0xe,
12521 MSUBU = 0xf,
12522
12523 /* bits 15..12 for 0x34 */
12524 MFC2 = 0x4,
12525 MTC2 = 0x5,
12526 MFHC2 = 0x8,
12527 MTHC2 = 0x9,
12528 CFC2 = 0xc,
12529 CTC2 = 0xd,
12530
12531 /* bits 15..12 for 0x3c */
12532 JALR = 0x0,
12533 JR = 0x0, /* alias */
3a1f4268
YK
12534 JALRC = 0x0,
12535 JRC = 0x0,
3c824109 12536 JALR_HB = 0x1,
3a1f4268 12537 JALRC_HB = 0x1,
3c824109
NF
12538 JALRS = 0x4,
12539 JALRS_HB = 0x5,
12540
12541 /* bits 15..12 for 0x05 */
12542 RDPGPR = 0xe,
12543 WRPGPR = 0xf,
12544
12545 /* bits 15..12 for 0x0d */
12546 TLBP = 0x0,
12547 TLBR = 0x1,
12548 TLBWI = 0x2,
12549 TLBWR = 0x3,
e60ec063
YK
12550 TLBINV = 0x4,
12551 TLBINVF = 0x5,
3c824109
NF
12552 WAIT = 0x9,
12553 IRET = 0xd,
12554 DERET = 0xe,
12555 ERET = 0xf,
12556
12557 /* bits 15..12 for 0x15 */
12558 DMT = 0x0,
12559 DVPE = 0x1,
12560 EMT = 0x2,
12561 EVPE = 0x3,
12562
12563 /* bits 15..12 for 0x1d */
12564 DI = 0x4,
12565 EI = 0x5,
12566
12567 /* bits 15..12 for 0x2d */
12568 SYNC = 0x6,
12569 SYSCALL = 0x8,
12570 SDBBP = 0xd,
12571
12572 /* bits 15..12 for 0x35 */
12573 MFHI32 = 0x0,
12574 MFLO32 = 0x1,
12575 MTHI32 = 0x2,
12576 MTLO32 = 0x3,
12577};
12578
12579/* POOL32B encoding of minor opcode field (bits 15..12) */
12580
12581enum {
12582 LWC2 = 0x0,
12583 LWP = 0x1,
12584 LDP = 0x4,
12585 LWM32 = 0x5,
12586 CACHE = 0x6,
12587 LDM = 0x7,
12588 SWC2 = 0x8,
12589 SWP = 0x9,
12590 SDP = 0xc,
12591 SWM32 = 0xd,
12592 SDM = 0xf
12593};
12594
12595/* POOL32C encoding of minor opcode field (bits 15..12) */
12596
12597enum {
12598 LWL = 0x0,
12599 SWL = 0x8,
12600 LWR = 0x1,
12601 SWR = 0x9,
12602 PREF = 0x2,
8fffc646 12603 ST_EVA = 0xa,
3c824109
NF
12604 LL = 0x3,
12605 SC = 0xb,
12606 LDL = 0x4,
12607 SDL = 0xc,
12608 LDR = 0x5,
12609 SDR = 0xd,
8fffc646 12610 LD_EVA = 0x6,
3c824109
NF
12611 LWU = 0xe,
12612 LLD = 0x7,
12613 SCD = 0xf
12614};
12615
8fffc646
JH
12616/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12617
12618enum {
12619 LBUE = 0x0,
12620 LHUE = 0x1,
12621 LWLE = 0x2,
12622 LWRE = 0x3,
12623 LBE = 0x4,
12624 LHE = 0x5,
12625 LLE = 0x6,
12626 LWE = 0x7,
12627};
12628
12629/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12630
12631enum {
12632 SWLE = 0x0,
12633 SWRE = 0x1,
12634 PREFE = 0x2,
12635 CACHEE = 0x3,
12636 SBE = 0x4,
12637 SHE = 0x5,
12638 SCE = 0x6,
12639 SWE = 0x7,
12640};
12641
3c824109
NF
12642/* POOL32F encoding of minor opcode field (bits 5..0) */
12643
12644enum {
12645 /* These are the bit 7..6 values */
12646 ADD_FMT = 0x0,
3c824109
NF
12647
12648 SUB_FMT = 0x1,
3c824109
NF
12649
12650 MUL_FMT = 0x2,
12651
12652 DIV_FMT = 0x3,
12653
12654 /* These are the bit 8..6 values */
3a1f4268 12655 MOVN_FMT = 0x0,
3c824109
NF
12656 RSQRT2_FMT = 0x0,
12657 MOVF_FMT = 0x0,
3a1f4268
YK
12658 RINT_FMT = 0x0,
12659 SELNEZ_FMT = 0x0,
3c824109 12660
3a1f4268 12661 MOVZ_FMT = 0x1,
3c824109
NF
12662 LWXC1 = 0x1,
12663 MOVT_FMT = 0x1,
3a1f4268
YK
12664 CLASS_FMT = 0x1,
12665 SELEQZ_FMT = 0x1,
3c824109
NF
12666
12667 PLL_PS = 0x2,
12668 SWXC1 = 0x2,
3a1f4268 12669 SEL_FMT = 0x2,
3c824109
NF
12670
12671 PLU_PS = 0x3,
12672 LDXC1 = 0x3,
12673
3a1f4268 12674 MOVN_FMT_04 = 0x4,
3c824109
NF
12675 PUL_PS = 0x4,
12676 SDXC1 = 0x4,
12677 RECIP2_FMT = 0x4,
12678
3a1f4268 12679 MOVZ_FMT_05 = 0x05,
3c824109
NF
12680 PUU_PS = 0x5,
12681 LUXC1 = 0x5,
12682
12683 CVT_PS_S = 0x6,
12684 SUXC1 = 0x6,
12685 ADDR_PS = 0x6,
12686 PREFX = 0x6,
3a1f4268 12687 MADDF_FMT = 0x6,
3c824109
NF
12688
12689 MULR_PS = 0x7,
3a1f4268 12690 MSUBF_FMT = 0x7,
3c824109
NF
12691
12692 MADD_S = 0x01,
12693 MADD_D = 0x09,
12694 MADD_PS = 0x11,
12695 ALNV_PS = 0x19,
12696 MSUB_S = 0x21,
12697 MSUB_D = 0x29,
12698 MSUB_PS = 0x31,
12699
12700 NMADD_S = 0x02,
12701 NMADD_D = 0x0a,
12702 NMADD_PS = 0x12,
12703 NMSUB_S = 0x22,
12704 NMSUB_D = 0x2a,
12705 NMSUB_PS = 0x32,
12706
3a1f4268
YK
12707 MIN_FMT = 0x3,
12708 MAX_FMT = 0xb,
12709 MINA_FMT = 0x23,
12710 MAXA_FMT = 0x2b,
3c824109
NF
12711 POOL32FXF = 0x3b,
12712
12713 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12714 C_COND_FMT = 0x3c,
12715
12716 CMP_CONDN_S = 0x5,
12717 CMP_CONDN_D = 0x15
3c824109
NF
12718};
12719
12720/* POOL32Fxf encoding of minor opcode extension field */
12721
12722enum {
12723 CVT_L = 0x04,
12724 RSQRT_FMT = 0x08,
12725 FLOOR_L = 0x0c,
12726 CVT_PW_PS = 0x1c,
12727 CVT_W = 0x24,
12728 SQRT_FMT = 0x28,
12729 FLOOR_W = 0x2c,
12730 CVT_PS_PW = 0x3c,
12731 CFC1 = 0x40,
12732 RECIP_FMT = 0x48,
12733 CEIL_L = 0x4c,
12734 CTC1 = 0x60,
12735 CEIL_W = 0x6c,
12736 MFC1 = 0x80,
12737 CVT_S_PL = 0x84,
12738 TRUNC_L = 0x8c,
12739 MTC1 = 0xa0,
12740 CVT_S_PU = 0xa4,
12741 TRUNC_W = 0xac,
12742 MFHC1 = 0xc0,
12743 ROUND_L = 0xcc,
12744 MTHC1 = 0xe0,
12745 ROUND_W = 0xec,
12746
12747 MOV_FMT = 0x01,
12748 MOVF = 0x05,
12749 ABS_FMT = 0x0d,
12750 RSQRT1_FMT = 0x1d,
12751 MOVT = 0x25,
12752 NEG_FMT = 0x2d,
12753 CVT_D = 0x4d,
12754 RECIP1_FMT = 0x5d,
12755 CVT_S = 0x6d
12756};
12757
12758/* POOL32I encoding of minor opcode field (bits 25..21) */
12759
12760enum {
12761 BLTZ = 0x00,
12762 BLTZAL = 0x01,
12763 BGEZ = 0x02,
12764 BGEZAL = 0x03,
12765 BLEZ = 0x04,
12766 BNEZC = 0x05,
12767 BGTZ = 0x06,
12768 BEQZC = 0x07,
12769 TLTI = 0x08,
3a1f4268 12770 BC1EQZC = 0x08,
3c824109 12771 TGEI = 0x09,
3a1f4268 12772 BC1NEZC = 0x09,
3c824109 12773 TLTIU = 0x0a,
3a1f4268 12774 BC2EQZC = 0x0a,
3c824109 12775 TGEIU = 0x0b,
3a1f4268 12776 BC2NEZC = 0x0a,
3c824109 12777 TNEI = 0x0c,
3a1f4268 12778 R6_SYNCI = 0x0c,
3c824109
NF
12779 LUI = 0x0d,
12780 TEQI = 0x0e,
12781 SYNCI = 0x10,
12782 BLTZALS = 0x11,
12783 BGEZALS = 0x13,
12784 BC2F = 0x14,
12785 BC2T = 0x15,
12786 BPOSGE64 = 0x1a,
12787 BPOSGE32 = 0x1b,
12788 /* These overlap and are distinguished by bit16 of the instruction */
12789 BC1F = 0x1c,
12790 BC1T = 0x1d,
12791 BC1ANY2F = 0x1c,
12792 BC1ANY2T = 0x1d,
12793 BC1ANY4F = 0x1e,
12794 BC1ANY4T = 0x1f
12795};
12796
12797/* POOL16A encoding of minor opcode field */
12798
12799enum {
12800 ADDU16 = 0x0,
12801 SUBU16 = 0x1
12802};
12803
12804/* POOL16B encoding of minor opcode field */
12805
12806enum {
12807 SLL16 = 0x0,
12808 SRL16 = 0x1
12809};
12810
12811/* POOL16C encoding of minor opcode field */
12812
12813enum {
12814 NOT16 = 0x00,
12815 XOR16 = 0x04,
12816 AND16 = 0x08,
12817 OR16 = 0x0c,
12818 LWM16 = 0x10,
12819 SWM16 = 0x14,
12820 JR16 = 0x18,
12821 JRC16 = 0x1a,
12822 JALR16 = 0x1c,
12823 JALR16S = 0x1e,
12824 MFHI16 = 0x20,
12825 MFLO16 = 0x24,
12826 BREAK16 = 0x28,
12827 SDBBP16 = 0x2c,
12828 JRADDIUSP = 0x30
12829};
12830
3a1f4268
YK
12831/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12832
12833enum {
12834 R6_NOT16 = 0x00,
12835 R6_AND16 = 0x01,
12836 R6_LWM16 = 0x02,
12837 R6_JRC16 = 0x03,
12838 MOVEP = 0x04,
12839 MOVEP_07 = 0x07,
12840 R6_XOR16 = 0x08,
12841 R6_OR16 = 0x09,
12842 R6_SWM16 = 0x0a,
12843 JALRC16 = 0x0b,
12844 MOVEP_0C = 0x0c,
12845 MOVEP_0F = 0x0f,
12846 JRCADDIUSP = 0x13,
12847 R6_BREAK16 = 0x1b,
12848 R6_SDBBP16 = 0x3b
12849};
12850
3c824109
NF
12851/* POOL16D encoding of minor opcode field */
12852
12853enum {
12854 ADDIUS5 = 0x0,
12855 ADDIUSP = 0x1
12856};
12857
12858/* POOL16E encoding of minor opcode field */
12859
12860enum {
12861 ADDIUR2 = 0x0,
12862 ADDIUR1SP = 0x1
12863};
12864
12865static int mmreg (int r)
12866{
12867 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12868
12869 return map[r];
12870}
12871
12872/* Used for 16-bit store instructions. */
12873static int mmreg2 (int r)
12874{
12875 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12876
12877 return map[r];
12878}
12879
12880#define uMIPS_RD(op) ((op >> 7) & 0x7)
12881#define uMIPS_RS(op) ((op >> 4) & 0x7)
12882#define uMIPS_RS2(op) uMIPS_RS(op)
12883#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12884#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12885#define uMIPS_RS5(op) (op & 0x1f)
12886
12887/* Signed immediate */
12888#define SIMM(op, start, width) \
12889 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12890 << (32-width)) \
12891 >> (32-width))
12892/* Zero-extended immediate */
12893#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12894
d75c135e 12895static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12896{
12897 int rd = mmreg(uMIPS_RD(ctx->opcode));
12898
d75c135e 12899 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12900}
12901
d75c135e 12902static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12903{
12904 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12905 int rd = mmreg(uMIPS_RD(ctx->opcode));
12906 int rs = mmreg(uMIPS_RS(ctx->opcode));
12907
d75c135e 12908 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12909}
12910
d75c135e 12911static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12912{
12913 int encoded = ZIMM(ctx->opcode, 1, 9);
12914 int decoded;
12915
12916 if (encoded <= 1) {
12917 decoded = 256 + encoded;
12918 } else if (encoded <= 255) {
12919 decoded = encoded;
12920 } else if (encoded <= 509) {
12921 decoded = encoded - 512;
12922 } else {
12923 decoded = encoded - 768;
12924 }
12925
d75c135e 12926 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12927}
12928
d75c135e 12929static void gen_addius5(DisasContext *ctx)
3c824109
NF
12930{
12931 int imm = SIMM(ctx->opcode, 1, 4);
12932 int rd = (ctx->opcode >> 5) & 0x1f;
12933
d75c135e 12934 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12935}
12936
d75c135e 12937static void gen_andi16(DisasContext *ctx)
3c824109
NF
12938{
12939 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12940 31, 32, 63, 64, 255, 32768, 65535 };
12941 int rd = mmreg(uMIPS_RD(ctx->opcode));
12942 int rs = mmreg(uMIPS_RS(ctx->opcode));
12943 int encoded = ZIMM(ctx->opcode, 0, 4);
12944
d75c135e 12945 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12946}
12947
12948static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12949 int base, int16_t offset)
12950{
12951 TCGv t0, t1;
12952 TCGv_i32 t2;
12953
12954 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12955 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12956 return;
12957 }
12958
12959 t0 = tcg_temp_new();
12960
12961 gen_base_offset_addr(ctx, t0, base, offset);
12962
12963 t1 = tcg_const_tl(reglist);
12964 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12965
3c824109
NF
12966 save_cpu_state(ctx, 1);
12967 switch (opc) {
12968 case LWM32:
895c2d04 12969 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12970 break;
12971 case SWM32:
895c2d04 12972 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12973 break;
12974#ifdef TARGET_MIPS64
12975 case LDM:
895c2d04 12976 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12977 break;
12978 case SDM:
895c2d04 12979 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12980 break;
6af0bf9c 12981#endif
3c824109 12982 }
3c824109 12983 tcg_temp_free(t0);
33087598 12984 tcg_temp_free(t1);
3c824109
NF
12985 tcg_temp_free_i32(t2);
12986}
6af0bf9c 12987
3c824109 12988
240ce26a 12989static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12990{
3c824109
NF
12991 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12992 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12993
3c824109
NF
12994 switch (((ctx->opcode) >> 4) & 0x3f) {
12995 case NOT16 + 0:
12996 case NOT16 + 1:
12997 case NOT16 + 2:
12998 case NOT16 + 3:
d75c135e 12999 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13000 break;
13001 case XOR16 + 0:
13002 case XOR16 + 1:
13003 case XOR16 + 2:
13004 case XOR16 + 3:
d75c135e 13005 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13006 break;
13007 case AND16 + 0:
13008 case AND16 + 1:
13009 case AND16 + 2:
13010 case AND16 + 3:
d75c135e 13011 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13012 break;
13013 case OR16 + 0:
13014 case OR16 + 1:
13015 case OR16 + 2:
13016 case OR16 + 3:
d75c135e 13017 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13018 break;
13019 case LWM16 + 0:
13020 case LWM16 + 1:
13021 case LWM16 + 2:
13022 case LWM16 + 3:
13023 {
13024 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13025 int offset = ZIMM(ctx->opcode, 0, 4);
13026
13027 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13028 29, offset << 2);
13029 }
13030 break;
13031 case SWM16 + 0:
13032 case SWM16 + 1:
13033 case SWM16 + 2:
13034 case SWM16 + 3:
13035 {
13036 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13037 int offset = ZIMM(ctx->opcode, 0, 4);
13038
13039 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13040 29, offset << 2);
13041 }
13042 break;
13043 case JR16 + 0:
13044 case JR16 + 1:
13045 {
13046 int reg = ctx->opcode & 0x1f;
13047
b231c103 13048 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13049 }
3c824109
NF
13050 break;
13051 case JRC16 + 0:
13052 case JRC16 + 1:
13053 {
13054 int reg = ctx->opcode & 0x1f;
b231c103 13055 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13056 /* Let normal delay slot handling in our caller take us
13057 to the branch target. */
13058 }
13059 break;
13060 case JALR16 + 0:
13061 case JALR16 + 1:
b231c103
YK
13062 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13063 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13064 break;
3c824109
NF
13065 case JALR16S + 0:
13066 case JALR16S + 1:
b231c103
YK
13067 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13068 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13069 break;
13070 case MFHI16 + 0:
13071 case MFHI16 + 1:
26135ead 13072 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13073 break;
13074 case MFLO16 + 0:
13075 case MFLO16 + 1:
26135ead 13076 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13077 break;
13078 case BREAK16:
9c708c7f 13079 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13080 break;
13081 case SDBBP16:
3b3c1694
LA
13082 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13083 gen_helper_do_semihosting(cpu_env);
13084 } else {
13085 /* XXX: not clear which exception should be raised
13086 * when in debug mode...
13087 */
13088 check_insn(ctx, ISA_MIPS32);
9c708c7f 13089 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13090 }
3c824109
NF
13091 break;
13092 case JRADDIUSP + 0:
13093 case JRADDIUSP + 1:
13094 {
13095 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13096 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13097 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13098 /* Let normal delay slot handling in our caller take us
13099 to the branch target. */
13100 }
13101 break;
13102 default:
9c708c7f 13103 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13104 break;
13105 }
13106}
13107
ed7ce6c0
YK
13108static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13109 int enc_rs)
13110{
13111 int rd, rs, re, rt;
13112 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13113 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13114 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13115 rd = rd_enc[enc_dest];
13116 re = re_enc[enc_dest];
13117 rs = rs_rt_enc[enc_rs];
13118 rt = rs_rt_enc[enc_rt];
13119 if (rs) {
13120 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13121 } else {
13122 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13123 }
13124 if (rt) {
13125 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13126 } else {
13127 tcg_gen_movi_tl(cpu_gpr[re], 0);
13128 }
13129}
13130
13131static void gen_pool16c_r6_insn(DisasContext *ctx)
13132{
13133 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13134 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13135
13136 switch (ctx->opcode & 0xf) {
13137 case R6_NOT16:
13138 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13139 break;
13140 case R6_AND16:
13141 gen_logic(ctx, OPC_AND, rt, rt, rs);
13142 break;
13143 case R6_LWM16:
13144 {
13145 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13146 int offset = extract32(ctx->opcode, 4, 4);
13147 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13148 }
13149 break;
13150 case R6_JRC16: /* JRCADDIUSP */
13151 if ((ctx->opcode >> 4) & 1) {
13152 /* JRCADDIUSP */
13153 int imm = extract32(ctx->opcode, 5, 5);
13154 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13155 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13156 } else {
13157 /* JRC16 */
13158 int rs = extract32(ctx->opcode, 5, 5);
13159 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13160 }
13161 break;
13162 case MOVEP ... MOVEP_07:
13163 case MOVEP_0C ... MOVEP_0F:
13164 {
13165 int enc_dest = uMIPS_RD(ctx->opcode);
13166 int enc_rt = uMIPS_RS2(ctx->opcode);
13167 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13168 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13169 }
13170 break;
13171 case R6_XOR16:
13172 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13173 break;
13174 case R6_OR16:
13175 gen_logic(ctx, OPC_OR, rt, rt, rs);
13176 break;
13177 case R6_SWM16:
13178 {
13179 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13180 int offset = extract32(ctx->opcode, 4, 4);
13181 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13182 }
13183 break;
13184 case JALRC16: /* BREAK16, SDBBP16 */
13185 switch (ctx->opcode & 0x3f) {
13186 case JALRC16:
13187 case JALRC16 + 0x20:
13188 /* JALRC16 */
13189 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13190 31, 0, 0);
13191 break;
13192 case R6_BREAK16:
13193 /* BREAK16 */
13194 generate_exception(ctx, EXCP_BREAK);
13195 break;
13196 case R6_SDBBP16:
13197 /* SDBBP16 */
060ebfef
LA
13198 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13199 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13200 } else {
060ebfef
LA
13201 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13202 generate_exception(ctx, EXCP_RI);
13203 } else {
13204 generate_exception(ctx, EXCP_DBp);
13205 }
ed7ce6c0
YK
13206 }
13207 break;
13208 }
13209 break;
13210 default:
13211 generate_exception(ctx, EXCP_RI);
13212 break;
13213 }
13214}
13215
3c824109
NF
13216static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13217{
13218 TCGv t0 = tcg_temp_new();
13219 TCGv t1 = tcg_temp_new();
13220
13221 gen_load_gpr(t0, base);
13222
13223 if (index != 0) {
13224 gen_load_gpr(t1, index);
13225 tcg_gen_shli_tl(t1, t1, 2);
13226 gen_op_addr_add(ctx, t0, t1, t0);
13227 }
13228
5f68f5ae 13229 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13230 gen_store_gpr(t1, rd);
13231
13232 tcg_temp_free(t0);
13233 tcg_temp_free(t1);
13234}
13235
13236static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13237 int base, int16_t offset)
13238{
3c824109
NF
13239 TCGv t0, t1;
13240
36c6711b 13241 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13242 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13243 return;
13244 }
13245
3c824109
NF
13246 t0 = tcg_temp_new();
13247 t1 = tcg_temp_new();
8e9ade68 13248
3c824109
NF
13249 gen_base_offset_addr(ctx, t0, base, offset);
13250
13251 switch (opc) {
13252 case LWP:
36c6711b 13253 if (rd == base) {
9c708c7f 13254 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13255 return;
13256 }
5f68f5ae 13257 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13258 gen_store_gpr(t1, rd);
13259 tcg_gen_movi_tl(t1, 4);
13260 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13261 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13262 gen_store_gpr(t1, rd+1);
3c824109
NF
13263 break;
13264 case SWP:
3c824109 13265 gen_load_gpr(t1, rd);
5f68f5ae 13266 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13267 tcg_gen_movi_tl(t1, 4);
13268 gen_op_addr_add(ctx, t0, t0, t1);
13269 gen_load_gpr(t1, rd+1);
5f68f5ae 13270 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13271 break;
13272#ifdef TARGET_MIPS64
13273 case LDP:
36c6711b 13274 if (rd == base) {
9c708c7f 13275 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13276 return;
13277 }
5f68f5ae 13278 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13279 gen_store_gpr(t1, rd);
13280 tcg_gen_movi_tl(t1, 8);
13281 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13282 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13283 gen_store_gpr(t1, rd+1);
3c824109
NF
13284 break;
13285 case SDP:
3c824109 13286 gen_load_gpr(t1, rd);
5f68f5ae 13287 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13288 tcg_gen_movi_tl(t1, 8);
13289 gen_op_addr_add(ctx, t0, t0, t1);
13290 gen_load_gpr(t1, rd+1);
5f68f5ae 13291 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13292 break;
13293#endif
6af0bf9c 13294 }
3c824109
NF
13295 tcg_temp_free(t0);
13296 tcg_temp_free(t1);
13297}
618b0fe9 13298
d208ac0c
LA
13299static void gen_sync(int stype)
13300{
13301 TCGBar tcg_mo = TCG_BAR_SC;
13302
13303 switch (stype) {
13304 case 0x4: /* SYNC_WMB */
13305 tcg_mo |= TCG_MO_ST_ST;
13306 break;
13307 case 0x10: /* SYNC_MB */
13308 tcg_mo |= TCG_MO_ALL;
13309 break;
13310 case 0x11: /* SYNC_ACQUIRE */
13311 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13312 break;
13313 case 0x12: /* SYNC_RELEASE */
13314 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13315 break;
13316 case 0x13: /* SYNC_RMB */
13317 tcg_mo |= TCG_MO_LD_LD;
13318 break;
13319 default:
13320 tcg_mo |= TCG_MO_ALL;
13321 break;
13322 }
13323
13324 tcg_gen_mb(tcg_mo);
13325}
13326
240ce26a 13327static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13328{
13329 int extension = (ctx->opcode >> 6) & 0x3f;
13330 int minor = (ctx->opcode >> 12) & 0xf;
13331 uint32_t mips32_op;
13332
13333 switch (extension) {
13334 case TEQ:
13335 mips32_op = OPC_TEQ;
13336 goto do_trap;
13337 case TGE:
13338 mips32_op = OPC_TGE;
13339 goto do_trap;
13340 case TGEU:
13341 mips32_op = OPC_TGEU;
13342 goto do_trap;
13343 case TLT:
13344 mips32_op = OPC_TLT;
13345 goto do_trap;
13346 case TLTU:
13347 mips32_op = OPC_TLTU;
13348 goto do_trap;
13349 case TNE:
13350 mips32_op = OPC_TNE;
13351 do_trap:
13352 gen_trap(ctx, mips32_op, rs, rt, -1);
13353 break;
13354#ifndef CONFIG_USER_ONLY
13355 case MFC0:
13356 case MFC0 + 32:
2e15497c 13357 check_cp0_enabled(ctx);
3c824109
NF
13358 if (rt == 0) {
13359 /* Treat as NOP. */
13360 break;
13361 }
d75c135e 13362 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13363 break;
13364 case MTC0:
13365 case MTC0 + 32:
2e15497c 13366 check_cp0_enabled(ctx);
3c824109
NF
13367 {
13368 TCGv t0 = tcg_temp_new();
618b0fe9 13369
3c824109 13370 gen_load_gpr(t0, rt);
d75c135e 13371 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13372 tcg_temp_free(t0);
13373 }
13374 break;
13375#endif
a1fc6246
LA
13376 case 0x2a:
13377 switch (minor & 3) {
13378 case MADD_ACC:
13379 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13380 break;
13381 case MADDU_ACC:
13382 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13383 break;
13384 case MSUB_ACC:
13385 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13386 break;
13387 case MSUBU_ACC:
13388 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13389 break;
13390 default:
13391 goto pool32axf_invalid;
13392 }
13393 break;
13394 case 0x32:
13395 switch (minor & 3) {
13396 case MULT_ACC:
13397 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13398 break;
13399 case MULTU_ACC:
13400 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13401 break;
13402 default:
13403 goto pool32axf_invalid;
13404 }
13405 break;
3c824109
NF
13406 case 0x2c:
13407 switch (minor) {
e0332095
YK
13408 case BITSWAP:
13409 check_insn(ctx, ISA_MIPS32R6);
13410 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13411 break;
3c824109
NF
13412 case SEB:
13413 gen_bshfl(ctx, OPC_SEB, rs, rt);
13414 break;
13415 case SEH:
13416 gen_bshfl(ctx, OPC_SEH, rs, rt);
13417 break;
13418 case CLO:
13419 mips32_op = OPC_CLO;
13420 goto do_cl;
13421 case CLZ:
13422 mips32_op = OPC_CLZ;
13423 do_cl:
d75c135e 13424 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13425 gen_cl(ctx, mips32_op, rt, rs);
13426 break;
13427 case RDHWR:
b00c7218
YK
13428 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13429 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13430 break;
13431 case WSBH:
13432 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13433 break;
13434 case MULT:
9e8f441a 13435 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13436 mips32_op = OPC_MULT;
26135ead 13437 goto do_mul;
3c824109 13438 case MULTU:
9e8f441a 13439 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13440 mips32_op = OPC_MULTU;
26135ead 13441 goto do_mul;
3c824109 13442 case DIV:
9e8f441a 13443 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13444 mips32_op = OPC_DIV;
26135ead 13445 goto do_div;
3c824109 13446 case DIVU:
9e8f441a 13447 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13448 mips32_op = OPC_DIVU;
26135ead
RS
13449 goto do_div;
13450 do_div:
13451 check_insn(ctx, ISA_MIPS32);
13452 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13453 break;
3c824109 13454 case MADD:
9e8f441a 13455 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13456 mips32_op = OPC_MADD;
26135ead 13457 goto do_mul;
3c824109 13458 case MADDU:
9e8f441a 13459 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13460 mips32_op = OPC_MADDU;
26135ead 13461 goto do_mul;
3c824109 13462 case MSUB:
9e8f441a 13463 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13464 mips32_op = OPC_MSUB;
26135ead 13465 goto do_mul;
3c824109 13466 case MSUBU:
9e8f441a 13467 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13468 mips32_op = OPC_MSUBU;
26135ead 13469 do_mul:
d75c135e 13470 check_insn(ctx, ISA_MIPS32);
a1fc6246 13471 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13472 break;
13473 default:
13474 goto pool32axf_invalid;
13475 }
13476 break;
13477 case 0x34:
13478 switch (minor) {
13479 case MFC2:
13480 case MTC2:
13481 case MFHC2:
13482 case MTHC2:
13483 case CFC2:
13484 case CTC2:
13485 generate_exception_err(ctx, EXCP_CpU, 2);
13486 break;
13487 default:
13488 goto pool32axf_invalid;
13489 }
13490 break;
13491 case 0x3c:
13492 switch (minor) {
65935f07
YK
13493 case JALR: /* JALRC */
13494 case JALR_HB: /* JALRC_HB */
13495 if (ctx->insn_flags & ISA_MIPS32R6) {
13496 /* JALRC, JALRC_HB */
13497 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13498 } else {
13499 /* JALR, JALR_HB */
13500 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13501 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13502 }
3c824109
NF
13503 break;
13504 case JALRS:
13505 case JALRS_HB:
9e8f441a 13506 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13507 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13508 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13509 break;
13510 default:
13511 goto pool32axf_invalid;
13512 }
13513 break;
13514 case 0x05:
13515 switch (minor) {
13516 case RDPGPR:
2e15497c 13517 check_cp0_enabled(ctx);
d75c135e 13518 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13519 gen_load_srsgpr(rs, rt);
3c824109
NF
13520 break;
13521 case WRPGPR:
2e15497c 13522 check_cp0_enabled(ctx);
d75c135e 13523 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13524 gen_store_srsgpr(rs, rt);
3c824109
NF
13525 break;
13526 default:
13527 goto pool32axf_invalid;
13528 }
13529 break;
13530#ifndef CONFIG_USER_ONLY
13531 case 0x0d:
13532 switch (minor) {
13533 case TLBP:
13534 mips32_op = OPC_TLBP;
13535 goto do_cp0;
13536 case TLBR:
13537 mips32_op = OPC_TLBR;
13538 goto do_cp0;
13539 case TLBWI:
13540 mips32_op = OPC_TLBWI;
13541 goto do_cp0;
13542 case TLBWR:
13543 mips32_op = OPC_TLBWR;
13544 goto do_cp0;
e60ec063
YK
13545 case TLBINV:
13546 mips32_op = OPC_TLBINV;
13547 goto do_cp0;
13548 case TLBINVF:
13549 mips32_op = OPC_TLBINVF;
13550 goto do_cp0;
3c824109
NF
13551 case WAIT:
13552 mips32_op = OPC_WAIT;
13553 goto do_cp0;
13554 case DERET:
13555 mips32_op = OPC_DERET;
13556 goto do_cp0;
13557 case ERET:
13558 mips32_op = OPC_ERET;
13559 do_cp0:
13560 gen_cp0(env, ctx, mips32_op, rt, rs);
13561 break;
13562 default:
13563 goto pool32axf_invalid;
13564 }
13565 break;
13566 case 0x1d:
13567 switch (minor) {
13568 case DI:
2e15497c 13569 check_cp0_enabled(ctx);
3c824109
NF
13570 {
13571 TCGv t0 = tcg_temp_new();
13572
13573 save_cpu_state(ctx, 1);
895c2d04 13574 gen_helper_di(t0, cpu_env);
3c824109
NF
13575 gen_store_gpr(t0, rs);
13576 /* Stop translation as we may have switched the execution mode */
13577 ctx->bstate = BS_STOP;
13578 tcg_temp_free(t0);
13579 }
13580 break;
13581 case EI:
2e15497c 13582 check_cp0_enabled(ctx);
3c824109
NF
13583 {
13584 TCGv t0 = tcg_temp_new();
13585
13586 save_cpu_state(ctx, 1);
895c2d04 13587 gen_helper_ei(t0, cpu_env);
3c824109 13588 gen_store_gpr(t0, rs);
b74cddcb
JH
13589 /* BS_STOP isn't sufficient, we need to ensure we break out
13590 of translated code to check for pending interrupts. */
13591 gen_save_pc(ctx->pc + 4);
13592 ctx->bstate = BS_EXCP;
3c824109
NF
13593 tcg_temp_free(t0);
13594 }
13595 break;
13596 default:
13597 goto pool32axf_invalid;
13598 }
13599 break;
13600#endif
13601 case 0x2d:
13602 switch (minor) {
13603 case SYNC:
d208ac0c 13604 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13605 break;
13606 case SYSCALL:
9c708c7f 13607 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13608 break;
13609 case SDBBP:
3b3c1694
LA
13610 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13611 gen_helper_do_semihosting(cpu_env);
13612 } else {
13613 check_insn(ctx, ISA_MIPS32);
e0332095 13614 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13615 generate_exception_end(ctx, EXCP_RI);
e0332095 13616 } else {
9c708c7f 13617 generate_exception_end(ctx, EXCP_DBp);
e0332095 13618 }
3b3c1694 13619 }
3c824109
NF
13620 break;
13621 default:
13622 goto pool32axf_invalid;
13623 }
13624 break;
a1fc6246 13625 case 0x01:
26135ead 13626 switch (minor & 3) {
a1fc6246 13627 case MFHI_ACC:
26135ead 13628 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13629 break;
a1fc6246 13630 case MFLO_ACC:
26135ead 13631 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13632 break;
a1fc6246 13633 case MTHI_ACC:
26135ead 13634 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13635 break;
a1fc6246 13636 case MTLO_ACC:
26135ead 13637 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13638 break;
13639 default:
13640 goto pool32axf_invalid;
13641 }
13642 break;
a1fc6246 13643 case 0x35:
9e8f441a 13644 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13645 switch (minor) {
13646 case MFHI32:
13647 gen_HILO(ctx, OPC_MFHI, 0, rs);
13648 break;
13649 case MFLO32:
13650 gen_HILO(ctx, OPC_MFLO, 0, rs);
13651 break;
13652 case MTHI32:
13653 gen_HILO(ctx, OPC_MTHI, 0, rs);
13654 break;
13655 case MTLO32:
13656 gen_HILO(ctx, OPC_MTLO, 0, rs);
13657 break;
13658 default:
13659 goto pool32axf_invalid;
13660 }
13661 break;
3c824109
NF
13662 default:
13663 pool32axf_invalid:
13664 MIPS_INVAL("pool32axf");
9c708c7f 13665 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13666 break;
13667 }
13668}
13669
13670/* Values for microMIPS fmt field. Variable-width, depending on which
13671 formats the instruction supports. */
13672
13673enum {
13674 FMT_SD_S = 0,
13675 FMT_SD_D = 1,
13676
13677 FMT_SDPS_S = 0,
13678 FMT_SDPS_D = 1,
13679 FMT_SDPS_PS = 2,
13680
13681 FMT_SWL_S = 0,
13682 FMT_SWL_W = 1,
13683 FMT_SWL_L = 2,
13684
13685 FMT_DWL_D = 0,
13686 FMT_DWL_W = 1,
13687 FMT_DWL_L = 2
13688};
13689
d75c135e 13690static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13691{
13692 int extension = (ctx->opcode >> 6) & 0x3ff;
13693 uint32_t mips32_op;
13694
13695#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13696#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13697#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13698
13699 switch (extension) {
13700 case FLOAT_1BIT_FMT(CFC1, 0):
13701 mips32_op = OPC_CFC1;
13702 goto do_cp1;
13703 case FLOAT_1BIT_FMT(CTC1, 0):
13704 mips32_op = OPC_CTC1;
13705 goto do_cp1;
13706 case FLOAT_1BIT_FMT(MFC1, 0):
13707 mips32_op = OPC_MFC1;
13708 goto do_cp1;
13709 case FLOAT_1BIT_FMT(MTC1, 0):
13710 mips32_op = OPC_MTC1;
13711 goto do_cp1;
13712 case FLOAT_1BIT_FMT(MFHC1, 0):
13713 mips32_op = OPC_MFHC1;
13714 goto do_cp1;
13715 case FLOAT_1BIT_FMT(MTHC1, 0):
13716 mips32_op = OPC_MTHC1;
13717 do_cp1:
13718 gen_cp1(ctx, mips32_op, rt, rs);
13719 break;
13720
13721 /* Reciprocal square root */
13722 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13723 mips32_op = OPC_RSQRT_S;
13724 goto do_unaryfp;
13725 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13726 mips32_op = OPC_RSQRT_D;
13727 goto do_unaryfp;
13728
13729 /* Square root */
13730 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13731 mips32_op = OPC_SQRT_S;
13732 goto do_unaryfp;
13733 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13734 mips32_op = OPC_SQRT_D;
13735 goto do_unaryfp;
13736
13737 /* Reciprocal */
13738 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13739 mips32_op = OPC_RECIP_S;
13740 goto do_unaryfp;
13741 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13742 mips32_op = OPC_RECIP_D;
13743 goto do_unaryfp;
13744
13745 /* Floor */
13746 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13747 mips32_op = OPC_FLOOR_L_S;
13748 goto do_unaryfp;
13749 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13750 mips32_op = OPC_FLOOR_L_D;
13751 goto do_unaryfp;
13752 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13753 mips32_op = OPC_FLOOR_W_S;
13754 goto do_unaryfp;
13755 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13756 mips32_op = OPC_FLOOR_W_D;
13757 goto do_unaryfp;
13758
13759 /* Ceiling */
13760 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13761 mips32_op = OPC_CEIL_L_S;
13762 goto do_unaryfp;
13763 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13764 mips32_op = OPC_CEIL_L_D;
13765 goto do_unaryfp;
13766 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13767 mips32_op = OPC_CEIL_W_S;
13768 goto do_unaryfp;
13769 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13770 mips32_op = OPC_CEIL_W_D;
13771 goto do_unaryfp;
13772
13773 /* Truncation */
13774 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13775 mips32_op = OPC_TRUNC_L_S;
13776 goto do_unaryfp;
13777 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13778 mips32_op = OPC_TRUNC_L_D;
13779 goto do_unaryfp;
13780 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13781 mips32_op = OPC_TRUNC_W_S;
13782 goto do_unaryfp;
13783 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13784 mips32_op = OPC_TRUNC_W_D;
13785 goto do_unaryfp;
13786
13787 /* Round */
13788 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13789 mips32_op = OPC_ROUND_L_S;
13790 goto do_unaryfp;
13791 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13792 mips32_op = OPC_ROUND_L_D;
13793 goto do_unaryfp;
13794 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13795 mips32_op = OPC_ROUND_W_S;
13796 goto do_unaryfp;
13797 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13798 mips32_op = OPC_ROUND_W_D;
13799 goto do_unaryfp;
13800
13801 /* Integer to floating-point conversion */
13802 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13803 mips32_op = OPC_CVT_L_S;
13804 goto do_unaryfp;
13805 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13806 mips32_op = OPC_CVT_L_D;
13807 goto do_unaryfp;
13808 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13809 mips32_op = OPC_CVT_W_S;
13810 goto do_unaryfp;
13811 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13812 mips32_op = OPC_CVT_W_D;
13813 goto do_unaryfp;
13814
13815 /* Paired-foo conversions */
13816 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13817 mips32_op = OPC_CVT_S_PL;
13818 goto do_unaryfp;
13819 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13820 mips32_op = OPC_CVT_S_PU;
13821 goto do_unaryfp;
13822 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13823 mips32_op = OPC_CVT_PW_PS;
13824 goto do_unaryfp;
13825 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13826 mips32_op = OPC_CVT_PS_PW;
13827 goto do_unaryfp;
13828
13829 /* Floating-point moves */
13830 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13831 mips32_op = OPC_MOV_S;
13832 goto do_unaryfp;
13833 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13834 mips32_op = OPC_MOV_D;
13835 goto do_unaryfp;
13836 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13837 mips32_op = OPC_MOV_PS;
13838 goto do_unaryfp;
13839
13840 /* Absolute value */
13841 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13842 mips32_op = OPC_ABS_S;
13843 goto do_unaryfp;
13844 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13845 mips32_op = OPC_ABS_D;
13846 goto do_unaryfp;
13847 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13848 mips32_op = OPC_ABS_PS;
13849 goto do_unaryfp;
13850
13851 /* Negation */
13852 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13853 mips32_op = OPC_NEG_S;
13854 goto do_unaryfp;
13855 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13856 mips32_op = OPC_NEG_D;
13857 goto do_unaryfp;
13858 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13859 mips32_op = OPC_NEG_PS;
13860 goto do_unaryfp;
13861
13862 /* Reciprocal square root step */
13863 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13864 mips32_op = OPC_RSQRT1_S;
13865 goto do_unaryfp;
13866 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13867 mips32_op = OPC_RSQRT1_D;
13868 goto do_unaryfp;
13869 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13870 mips32_op = OPC_RSQRT1_PS;
13871 goto do_unaryfp;
13872
13873 /* Reciprocal step */
13874 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13875 mips32_op = OPC_RECIP1_S;
13876 goto do_unaryfp;
13877 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13878 mips32_op = OPC_RECIP1_S;
13879 goto do_unaryfp;
13880 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13881 mips32_op = OPC_RECIP1_PS;
13882 goto do_unaryfp;
13883
13884 /* Conversions from double */
13885 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13886 mips32_op = OPC_CVT_D_S;
13887 goto do_unaryfp;
13888 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13889 mips32_op = OPC_CVT_D_W;
13890 goto do_unaryfp;
13891 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13892 mips32_op = OPC_CVT_D_L;
13893 goto do_unaryfp;
13894
13895 /* Conversions from single */
13896 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13897 mips32_op = OPC_CVT_S_D;
13898 goto do_unaryfp;
13899 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13900 mips32_op = OPC_CVT_S_W;
13901 goto do_unaryfp;
13902 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13903 mips32_op = OPC_CVT_S_L;
13904 do_unaryfp:
13905 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13906 break;
13907
13908 /* Conditional moves on floating-point codes */
13909 case COND_FLOAT_MOV(MOVT, 0):
13910 case COND_FLOAT_MOV(MOVT, 1):
13911 case COND_FLOAT_MOV(MOVT, 2):
13912 case COND_FLOAT_MOV(MOVT, 3):
13913 case COND_FLOAT_MOV(MOVT, 4):
13914 case COND_FLOAT_MOV(MOVT, 5):
13915 case COND_FLOAT_MOV(MOVT, 6):
13916 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13917 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13918 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13919 break;
13920 case COND_FLOAT_MOV(MOVF, 0):
13921 case COND_FLOAT_MOV(MOVF, 1):
13922 case COND_FLOAT_MOV(MOVF, 2):
13923 case COND_FLOAT_MOV(MOVF, 3):
13924 case COND_FLOAT_MOV(MOVF, 4):
13925 case COND_FLOAT_MOV(MOVF, 5):
13926 case COND_FLOAT_MOV(MOVF, 6):
13927 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13928 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13929 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13930 break;
13931 default:
13932 MIPS_INVAL("pool32fxf");
9c708c7f 13933 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13934 break;
13935 }
13936}
13937
f60eeb0c 13938static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13939{
13940 int32_t offset;
13941 uint16_t insn;
13942 int rt, rs, rd, rr;
13943 int16_t imm;
8fffc646 13944 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
13945 uint32_t cond, fmt, cc;
13946
895c2d04 13947 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13948 ctx->opcode = (ctx->opcode << 16) | insn;
13949
13950 rt = (ctx->opcode >> 21) & 0x1f;
13951 rs = (ctx->opcode >> 16) & 0x1f;
13952 rd = (ctx->opcode >> 11) & 0x1f;
13953 rr = (ctx->opcode >> 6) & 0x1f;
13954 imm = (int16_t) ctx->opcode;
13955
13956 op = (ctx->opcode >> 26) & 0x3f;
13957 switch (op) {
13958 case POOL32A:
13959 minor = ctx->opcode & 0x3f;
13960 switch (minor) {
13961 case 0x00:
13962 minor = (ctx->opcode >> 6) & 0xf;
13963 switch (minor) {
13964 case SLL32:
13965 mips32_op = OPC_SLL;
13966 goto do_shifti;
13967 case SRA:
13968 mips32_op = OPC_SRA;
13969 goto do_shifti;
13970 case SRL32:
13971 mips32_op = OPC_SRL;
13972 goto do_shifti;
13973 case ROTR:
13974 mips32_op = OPC_ROTR;
13975 do_shifti:
d75c135e 13976 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13977 break;
e0332095
YK
13978 case SELEQZ:
13979 check_insn(ctx, ISA_MIPS32R6);
13980 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13981 break;
13982 case SELNEZ:
13983 check_insn(ctx, ISA_MIPS32R6);
13984 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13985 break;
b00c7218
YK
13986 case R6_RDHWR:
13987 check_insn(ctx, ISA_MIPS32R6);
13988 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13989 break;
3c824109
NF
13990 default:
13991 goto pool32a_invalid;
13992 }
13993 break;
13994 case 0x10:
13995 minor = (ctx->opcode >> 6) & 0xf;
13996 switch (minor) {
13997 /* Arithmetic */
13998 case ADD:
13999 mips32_op = OPC_ADD;
14000 goto do_arith;
14001 case ADDU32:
14002 mips32_op = OPC_ADDU;
14003 goto do_arith;
14004 case SUB:
14005 mips32_op = OPC_SUB;
14006 goto do_arith;
14007 case SUBU32:
14008 mips32_op = OPC_SUBU;
14009 goto do_arith;
14010 case MUL:
9e8f441a 14011 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14012 mips32_op = OPC_MUL;
14013 do_arith:
d75c135e 14014 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14015 break;
14016 /* Shifts */
14017 case SLLV:
14018 mips32_op = OPC_SLLV;
14019 goto do_shift;
14020 case SRLV:
14021 mips32_op = OPC_SRLV;
14022 goto do_shift;
14023 case SRAV:
14024 mips32_op = OPC_SRAV;
14025 goto do_shift;
14026 case ROTRV:
14027 mips32_op = OPC_ROTRV;
14028 do_shift:
d75c135e 14029 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14030 break;
14031 /* Logical operations */
14032 case AND:
14033 mips32_op = OPC_AND;
14034 goto do_logic;
14035 case OR32:
14036 mips32_op = OPC_OR;
14037 goto do_logic;
14038 case NOR:
14039 mips32_op = OPC_NOR;
14040 goto do_logic;
14041 case XOR32:
14042 mips32_op = OPC_XOR;
14043 do_logic:
d75c135e 14044 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14045 break;
14046 /* Set less than */
14047 case SLT:
14048 mips32_op = OPC_SLT;
14049 goto do_slt;
14050 case SLTU:
14051 mips32_op = OPC_SLTU;
14052 do_slt:
d75c135e 14053 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14054 break;
14055 default:
14056 goto pool32a_invalid;
14057 }
14058 break;
14059 case 0x18:
14060 minor = (ctx->opcode >> 6) & 0xf;
14061 switch (minor) {
14062 /* Conditional moves */
e0332095
YK
14063 case MOVN: /* MUL */
14064 if (ctx->insn_flags & ISA_MIPS32R6) {
14065 /* MUL */
14066 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14067 } else {
14068 /* MOVN */
14069 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14070 }
14071 break;
14072 case MOVZ: /* MUH */
14073 if (ctx->insn_flags & ISA_MIPS32R6) {
14074 /* MUH */
14075 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14076 } else {
14077 /* MOVZ */
14078 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14079 }
14080 break;
14081 case MULU:
14082 check_insn(ctx, ISA_MIPS32R6);
14083 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14084 break;
14085 case MUHU:
14086 check_insn(ctx, ISA_MIPS32R6);
14087 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14088 break;
14089 case LWXS: /* DIV */
14090 if (ctx->insn_flags & ISA_MIPS32R6) {
14091 /* DIV */
14092 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14093 } else {
14094 /* LWXS */
14095 gen_ldxs(ctx, rs, rt, rd);
14096 }
14097 break;
14098 case MOD:
14099 check_insn(ctx, ISA_MIPS32R6);
14100 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14101 break;
14102 case R6_DIVU:
14103 check_insn(ctx, ISA_MIPS32R6);
14104 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14105 break;
e0332095
YK
14106 case MODU:
14107 check_insn(ctx, ISA_MIPS32R6);
14108 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14109 break;
14110 default:
14111 goto pool32a_invalid;
14112 }
14113 break;
14114 case INS:
14115 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14116 return;
e0332095
YK
14117 case LSA:
14118 check_insn(ctx, ISA_MIPS32R6);
14119 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14120 extract32(ctx->opcode, 9, 2));
14121 break;
14122 case ALIGN:
14123 check_insn(ctx, ISA_MIPS32R6);
14124 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14125 extract32(ctx->opcode, 9, 2));
14126 break;
3c824109
NF
14127 case EXT:
14128 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14129 return;
14130 case POOL32AXF:
240ce26a 14131 gen_pool32axf(env, ctx, rt, rs);
3c824109 14132 break;
dbd8af98 14133 case BREAK32:
9c708c7f 14134 generate_exception_end(ctx, EXCP_BREAK);
3c824109 14135 break;
bb238210
YK
14136 case SIGRIE:
14137 check_insn(ctx, ISA_MIPS32R6);
14138 generate_exception_end(ctx, EXCP_RI);
14139 break;
3c824109
NF
14140 default:
14141 pool32a_invalid:
14142 MIPS_INVAL("pool32a");
9c708c7f 14143 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14144 break;
14145 }
14146 break;
14147 case POOL32B:
14148 minor = (ctx->opcode >> 12) & 0xf;
14149 switch (minor) {
14150 case CACHE:
2e15497c 14151 check_cp0_enabled(ctx);
0d74a222
LA
14152 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14153 gen_cache_operation(ctx, rt, rs, imm);
14154 }
3c824109
NF
14155 break;
14156 case LWC2:
14157 case SWC2:
14158 /* COP2: Not implemented. */
14159 generate_exception_err(ctx, EXCP_CpU, 2);
14160 break;
3c824109
NF
14161#ifdef TARGET_MIPS64
14162 case LDP:
14163 case SDP:
d9224450
MR
14164 check_insn(ctx, ISA_MIPS3);
14165 check_mips_64(ctx);
14166 /* Fallthrough */
3c824109 14167#endif
d9224450
MR
14168 case LWP:
14169 case SWP:
3c824109
NF
14170 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14171 break;
3c824109
NF
14172#ifdef TARGET_MIPS64
14173 case LDM:
14174 case SDM:
d9224450
MR
14175 check_insn(ctx, ISA_MIPS3);
14176 check_mips_64(ctx);
14177 /* Fallthrough */
3c824109 14178#endif
d9224450
MR
14179 case LWM32:
14180 case SWM32:
3c824109
NF
14181 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14182 break;
14183 default:
14184 MIPS_INVAL("pool32b");
9c708c7f 14185 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14186 break;
14187 }
14188 break;
14189 case POOL32F:
5ab5c041 14190 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14191 minor = ctx->opcode & 0x3f;
14192 check_cp1_enabled(ctx);
14193 switch (minor) {
14194 case ALNV_PS:
9e8f441a 14195 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14196 mips32_op = OPC_ALNV_PS;
14197 goto do_madd;
14198 case MADD_S:
9e8f441a 14199 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14200 mips32_op = OPC_MADD_S;
14201 goto do_madd;
14202 case MADD_D:
9e8f441a 14203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14204 mips32_op = OPC_MADD_D;
14205 goto do_madd;
14206 case MADD_PS:
9e8f441a 14207 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14208 mips32_op = OPC_MADD_PS;
14209 goto do_madd;
14210 case MSUB_S:
9e8f441a 14211 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14212 mips32_op = OPC_MSUB_S;
14213 goto do_madd;
14214 case MSUB_D:
9e8f441a 14215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14216 mips32_op = OPC_MSUB_D;
14217 goto do_madd;
14218 case MSUB_PS:
9e8f441a 14219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14220 mips32_op = OPC_MSUB_PS;
14221 goto do_madd;
14222 case NMADD_S:
9e8f441a 14223 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14224 mips32_op = OPC_NMADD_S;
14225 goto do_madd;
14226 case NMADD_D:
9e8f441a 14227 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14228 mips32_op = OPC_NMADD_D;
14229 goto do_madd;
14230 case NMADD_PS:
9e8f441a 14231 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14232 mips32_op = OPC_NMADD_PS;
14233 goto do_madd;
14234 case NMSUB_S:
9e8f441a 14235 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14236 mips32_op = OPC_NMSUB_S;
14237 goto do_madd;
14238 case NMSUB_D:
9e8f441a 14239 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14240 mips32_op = OPC_NMSUB_D;
14241 goto do_madd;
14242 case NMSUB_PS:
9e8f441a 14243 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14244 mips32_op = OPC_NMSUB_PS;
14245 do_madd:
14246 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14247 break;
14248 case CABS_COND_FMT:
9e8f441a 14249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14250 cond = (ctx->opcode >> 6) & 0xf;
14251 cc = (ctx->opcode >> 13) & 0x7;
14252 fmt = (ctx->opcode >> 10) & 0x3;
14253 switch (fmt) {
14254 case 0x0:
14255 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14256 break;
14257 case 0x1:
14258 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14259 break;
14260 case 0x2:
14261 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14262 break;
14263 default:
14264 goto pool32f_invalid;
14265 }
14266 break;
14267 case C_COND_FMT:
9e8f441a 14268 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14269 cond = (ctx->opcode >> 6) & 0xf;
14270 cc = (ctx->opcode >> 13) & 0x7;
14271 fmt = (ctx->opcode >> 10) & 0x3;
14272 switch (fmt) {
14273 case 0x0:
14274 gen_cmp_s(ctx, cond, rt, rs, cc);
14275 break;
14276 case 0x1:
14277 gen_cmp_d(ctx, cond, rt, rs, cc);
14278 break;
14279 case 0x2:
14280 gen_cmp_ps(ctx, cond, rt, rs, cc);
14281 break;
14282 default:
14283 goto pool32f_invalid;
14284 }
14285 break;
2a24a7ba
YK
14286 case CMP_CONDN_S:
14287 check_insn(ctx, ISA_MIPS32R6);
14288 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14289 break;
14290 case CMP_CONDN_D:
14291 check_insn(ctx, ISA_MIPS32R6);
14292 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14293 break;
3c824109 14294 case POOL32FXF:
d75c135e 14295 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14296 break;
14297 case 0x00:
14298 /* PLL foo */
14299 switch ((ctx->opcode >> 6) & 0x7) {
14300 case PLL_PS:
14301 mips32_op = OPC_PLL_PS;
14302 goto do_ps;
14303 case PLU_PS:
14304 mips32_op = OPC_PLU_PS;
14305 goto do_ps;
14306 case PUL_PS:
14307 mips32_op = OPC_PUL_PS;
14308 goto do_ps;
14309 case PUU_PS:
14310 mips32_op = OPC_PUU_PS;
14311 goto do_ps;
14312 case CVT_PS_S:
9e8f441a 14313 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14314 mips32_op = OPC_CVT_PS_S;
14315 do_ps:
14316 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14317 break;
14318 default:
14319 goto pool32f_invalid;
14320 }
14321 break;
2a24a7ba
YK
14322 case MIN_FMT:
14323 check_insn(ctx, ISA_MIPS32R6);
14324 switch ((ctx->opcode >> 9) & 0x3) {
14325 case FMT_SDPS_S:
14326 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14327 break;
14328 case FMT_SDPS_D:
14329 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14330 break;
14331 default:
14332 goto pool32f_invalid;
14333 }
14334 break;
3c824109
NF
14335 case 0x08:
14336 /* [LS][WDU]XC1 */
14337 switch ((ctx->opcode >> 6) & 0x7) {
14338 case LWXC1:
9e8f441a 14339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14340 mips32_op = OPC_LWXC1;
14341 goto do_ldst_cp1;
14342 case SWXC1:
9e8f441a 14343 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14344 mips32_op = OPC_SWXC1;
14345 goto do_ldst_cp1;
14346 case LDXC1:
9e8f441a 14347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14348 mips32_op = OPC_LDXC1;
14349 goto do_ldst_cp1;
14350 case SDXC1:
9e8f441a 14351 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14352 mips32_op = OPC_SDXC1;
14353 goto do_ldst_cp1;
14354 case LUXC1:
9e8f441a 14355 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14356 mips32_op = OPC_LUXC1;
14357 goto do_ldst_cp1;
14358 case SUXC1:
9e8f441a 14359 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14360 mips32_op = OPC_SUXC1;
14361 do_ldst_cp1:
14362 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14363 break;
14364 default:
14365 goto pool32f_invalid;
14366 }
14367 break;
2a24a7ba
YK
14368 case MAX_FMT:
14369 check_insn(ctx, ISA_MIPS32R6);
14370 switch ((ctx->opcode >> 9) & 0x3) {
14371 case FMT_SDPS_S:
14372 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14373 break;
14374 case FMT_SDPS_D:
14375 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14376 break;
14377 default:
14378 goto pool32f_invalid;
14379 }
14380 break;
3c824109
NF
14381 case 0x18:
14382 /* 3D insns */
9e8f441a 14383 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14384 fmt = (ctx->opcode >> 9) & 0x3;
14385 switch ((ctx->opcode >> 6) & 0x7) {
14386 case RSQRT2_FMT:
14387 switch (fmt) {
14388 case FMT_SDPS_S:
14389 mips32_op = OPC_RSQRT2_S;
14390 goto do_3d;
14391 case FMT_SDPS_D:
14392 mips32_op = OPC_RSQRT2_D;
14393 goto do_3d;
14394 case FMT_SDPS_PS:
14395 mips32_op = OPC_RSQRT2_PS;
14396 goto do_3d;
14397 default:
14398 goto pool32f_invalid;
14399 }
14400 break;
14401 case RECIP2_FMT:
14402 switch (fmt) {
14403 case FMT_SDPS_S:
14404 mips32_op = OPC_RECIP2_S;
14405 goto do_3d;
14406 case FMT_SDPS_D:
14407 mips32_op = OPC_RECIP2_D;
14408 goto do_3d;
14409 case FMT_SDPS_PS:
14410 mips32_op = OPC_RECIP2_PS;
14411 goto do_3d;
14412 default:
14413 goto pool32f_invalid;
14414 }
14415 break;
14416 case ADDR_PS:
14417 mips32_op = OPC_ADDR_PS;
14418 goto do_3d;
14419 case MULR_PS:
14420 mips32_op = OPC_MULR_PS;
14421 do_3d:
14422 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14423 break;
14424 default:
14425 goto pool32f_invalid;
14426 }
14427 break;
14428 case 0x20:
2a24a7ba 14429 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14430 cc = (ctx->opcode >> 13) & 0x7;
14431 fmt = (ctx->opcode >> 9) & 0x3;
14432 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14433 case MOVF_FMT: /* RINT_FMT */
14434 if (ctx->insn_flags & ISA_MIPS32R6) {
14435 /* RINT_FMT */
14436 switch (fmt) {
14437 case FMT_SDPS_S:
14438 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14439 break;
14440 case FMT_SDPS_D:
14441 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14442 break;
14443 default:
14444 goto pool32f_invalid;
14445 }
14446 } else {
14447 /* MOVF_FMT */
14448 switch (fmt) {
14449 case FMT_SDPS_S:
14450 gen_movcf_s(ctx, rs, rt, cc, 0);
14451 break;
14452 case FMT_SDPS_D:
14453 gen_movcf_d(ctx, rs, rt, cc, 0);
14454 break;
14455 case FMT_SDPS_PS:
14456 check_ps(ctx);
14457 gen_movcf_ps(ctx, rs, rt, cc, 0);
14458 break;
14459 default:
14460 goto pool32f_invalid;
14461 }
3c824109
NF
14462 }
14463 break;
2a24a7ba
YK
14464 case MOVT_FMT: /* CLASS_FMT */
14465 if (ctx->insn_flags & ISA_MIPS32R6) {
14466 /* CLASS_FMT */
14467 switch (fmt) {
14468 case FMT_SDPS_S:
14469 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14470 break;
14471 case FMT_SDPS_D:
14472 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14473 break;
14474 default:
14475 goto pool32f_invalid;
14476 }
14477 } else {
14478 /* MOVT_FMT */
14479 switch (fmt) {
14480 case FMT_SDPS_S:
14481 gen_movcf_s(ctx, rs, rt, cc, 1);
14482 break;
14483 case FMT_SDPS_D:
14484 gen_movcf_d(ctx, rs, rt, cc, 1);
14485 break;
14486 case FMT_SDPS_PS:
14487 check_ps(ctx);
14488 gen_movcf_ps(ctx, rs, rt, cc, 1);
14489 break;
14490 default:
14491 goto pool32f_invalid;
14492 }
3c824109
NF
14493 }
14494 break;
14495 case PREFX:
9e8f441a 14496 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14497 break;
14498 default:
14499 goto pool32f_invalid;
14500 }
14501 break;
14502#define FINSN_3ARG_SDPS(prfx) \
14503 switch ((ctx->opcode >> 8) & 0x3) { \
14504 case FMT_SDPS_S: \
14505 mips32_op = OPC_##prfx##_S; \
14506 goto do_fpop; \
14507 case FMT_SDPS_D: \
14508 mips32_op = OPC_##prfx##_D; \
14509 goto do_fpop; \
14510 case FMT_SDPS_PS: \
e29c9628 14511 check_ps(ctx); \
3c824109
NF
14512 mips32_op = OPC_##prfx##_PS; \
14513 goto do_fpop; \
14514 default: \
14515 goto pool32f_invalid; \
14516 }
2a24a7ba
YK
14517 case MINA_FMT:
14518 check_insn(ctx, ISA_MIPS32R6);
14519 switch ((ctx->opcode >> 9) & 0x3) {
14520 case FMT_SDPS_S:
14521 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14522 break;
14523 case FMT_SDPS_D:
14524 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14525 break;
14526 default:
14527 goto pool32f_invalid;
14528 }
14529 break;
14530 case MAXA_FMT:
14531 check_insn(ctx, ISA_MIPS32R6);
14532 switch ((ctx->opcode >> 9) & 0x3) {
14533 case FMT_SDPS_S:
14534 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14535 break;
14536 case FMT_SDPS_D:
14537 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14538 break;
14539 default:
14540 goto pool32f_invalid;
14541 }
14542 break;
3c824109
NF
14543 case 0x30:
14544 /* regular FP ops */
14545 switch ((ctx->opcode >> 6) & 0x3) {
14546 case ADD_FMT:
14547 FINSN_3ARG_SDPS(ADD);
14548 break;
14549 case SUB_FMT:
14550 FINSN_3ARG_SDPS(SUB);
14551 break;
14552 case MUL_FMT:
14553 FINSN_3ARG_SDPS(MUL);
14554 break;
14555 case DIV_FMT:
14556 fmt = (ctx->opcode >> 8) & 0x3;
14557 if (fmt == 1) {
14558 mips32_op = OPC_DIV_D;
14559 } else if (fmt == 0) {
14560 mips32_op = OPC_DIV_S;
14561 } else {
14562 goto pool32f_invalid;
14563 }
14564 goto do_fpop;
14565 default:
14566 goto pool32f_invalid;
14567 }
14568 break;
14569 case 0x38:
14570 /* cmovs */
2a24a7ba
YK
14571 switch ((ctx->opcode >> 6) & 0x7) {
14572 case MOVN_FMT: /* SELNEZ_FMT */
14573 if (ctx->insn_flags & ISA_MIPS32R6) {
14574 /* SELNEZ_FMT */
14575 switch ((ctx->opcode >> 9) & 0x3) {
14576 case FMT_SDPS_S:
14577 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14578 break;
14579 case FMT_SDPS_D:
14580 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14581 break;
14582 default:
14583 goto pool32f_invalid;
14584 }
14585 } else {
14586 /* MOVN_FMT */
14587 FINSN_3ARG_SDPS(MOVN);
14588 }
14589 break;
14590 case MOVN_FMT_04:
14591 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14592 FINSN_3ARG_SDPS(MOVN);
14593 break;
2a24a7ba
YK
14594 case MOVZ_FMT: /* SELEQZ_FMT */
14595 if (ctx->insn_flags & ISA_MIPS32R6) {
14596 /* SELEQZ_FMT */
14597 switch ((ctx->opcode >> 9) & 0x3) {
14598 case FMT_SDPS_S:
14599 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14600 break;
14601 case FMT_SDPS_D:
14602 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14603 break;
14604 default:
14605 goto pool32f_invalid;
14606 }
14607 } else {
14608 /* MOVZ_FMT */
14609 FINSN_3ARG_SDPS(MOVZ);
14610 }
14611 break;
14612 case MOVZ_FMT_05:
14613 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14614 FINSN_3ARG_SDPS(MOVZ);
14615 break;
2a24a7ba
YK
14616 case SEL_FMT:
14617 check_insn(ctx, ISA_MIPS32R6);
14618 switch ((ctx->opcode >> 9) & 0x3) {
14619 case FMT_SDPS_S:
14620 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14621 break;
14622 case FMT_SDPS_D:
14623 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14624 break;
14625 default:
14626 goto pool32f_invalid;
14627 }
14628 break;
14629 case MADDF_FMT:
14630 check_insn(ctx, ISA_MIPS32R6);
14631 switch ((ctx->opcode >> 9) & 0x3) {
14632 case FMT_SDPS_S:
14633 mips32_op = OPC_MADDF_S;
14634 goto do_fpop;
14635 case FMT_SDPS_D:
14636 mips32_op = OPC_MADDF_D;
14637 goto do_fpop;
14638 default:
14639 goto pool32f_invalid;
14640 }
14641 break;
14642 case MSUBF_FMT:
14643 check_insn(ctx, ISA_MIPS32R6);
14644 switch ((ctx->opcode >> 9) & 0x3) {
14645 case FMT_SDPS_S:
14646 mips32_op = OPC_MSUBF_S;
14647 goto do_fpop;
14648 case FMT_SDPS_D:
14649 mips32_op = OPC_MSUBF_D;
14650 goto do_fpop;
14651 default:
14652 goto pool32f_invalid;
14653 }
14654 break;
3c824109
NF
14655 default:
14656 goto pool32f_invalid;
14657 }
14658 break;
14659 do_fpop:
14660 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14661 break;
14662 default:
14663 pool32f_invalid:
14664 MIPS_INVAL("pool32f");
9c708c7f 14665 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14666 break;
14667 }
14668 } else {
14669 generate_exception_err(ctx, EXCP_CpU, 1);
14670 }
14671 break;
14672 case POOL32I:
14673 minor = (ctx->opcode >> 21) & 0x1f;
14674 switch (minor) {
14675 case BLTZ:
9e8f441a 14676 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14677 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14678 break;
3c824109 14679 case BLTZAL:
9e8f441a 14680 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14681 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14682 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14683 break;
3c824109 14684 case BLTZALS:
9e8f441a 14685 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14686 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14687 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14688 break;
3c824109 14689 case BGEZ:
9e8f441a 14690 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14691 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14692 break;
3c824109 14693 case BGEZAL:
9e8f441a 14694 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14695 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14696 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14697 break;
3c824109 14698 case BGEZALS:
9e8f441a 14699 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14700 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14701 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14702 break;
3c824109 14703 case BLEZ:
9e8f441a 14704 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14705 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14706 break;
3c824109 14707 case BGTZ:
9e8f441a 14708 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14709 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14710 break;
14711
14712 /* Traps */
65935f07
YK
14713 case TLTI: /* BC1EQZC */
14714 if (ctx->insn_flags & ISA_MIPS32R6) {
14715 /* BC1EQZC */
14716 check_cp1_enabled(ctx);
14717 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14718 } else {
14719 /* TLTI */
14720 mips32_op = OPC_TLTI;
14721 goto do_trapi;
14722 }
14723 break;
14724 case TGEI: /* BC1NEZC */
14725 if (ctx->insn_flags & ISA_MIPS32R6) {
14726 /* BC1NEZC */
14727 check_cp1_enabled(ctx);
14728 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14729 } else {
14730 /* TGEI */
14731 mips32_op = OPC_TGEI;
14732 goto do_trapi;
14733 }
14734 break;
3c824109 14735 case TLTIU:
9e8f441a 14736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14737 mips32_op = OPC_TLTIU;
14738 goto do_trapi;
14739 case TGEIU:
9e8f441a 14740 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14741 mips32_op = OPC_TGEIU;
14742 goto do_trapi;
3b4a5489
YK
14743 case TNEI: /* SYNCI */
14744 if (ctx->insn_flags & ISA_MIPS32R6) {
14745 /* SYNCI */
14746 /* Break the TB to be able to sync copied instructions
14747 immediately */
14748 ctx->bstate = BS_STOP;
14749 } else {
14750 /* TNEI */
14751 mips32_op = OPC_TNEI;
14752 goto do_trapi;
14753 }
14754 break;
3c824109 14755 case TEQI:
9e8f441a 14756 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14757 mips32_op = OPC_TEQI;
14758 do_trapi:
14759 gen_trap(ctx, mips32_op, rs, -1, imm);
14760 break;
14761
14762 case BNEZC:
14763 case BEQZC:
9e8f441a 14764 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14765 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14766 4, rs, 0, imm << 1, 0);
3c824109
NF
14767 /* Compact branches don't have a delay slot, so just let
14768 the normal delay slot handling take us to the branch
14769 target. */
14770 break;
14771 case LUI:
9e8f441a 14772 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14773 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14774 break;
14775 case SYNCI:
9e8f441a 14776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14777 /* Break the TB to be able to sync copied instructions
14778 immediately */
14779 ctx->bstate = BS_STOP;
3c824109
NF
14780 break;
14781 case BC2F:
14782 case BC2T:
9e8f441a 14783 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14784 /* COP2: Not implemented. */
14785 generate_exception_err(ctx, EXCP_CpU, 2);
14786 break;
14787 case BC1F:
9e8f441a 14788 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14789 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14790 goto do_cp1branch;
14791 case BC1T:
9e8f441a 14792 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14793 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14794 goto do_cp1branch;
14795 case BC1ANY4F:
9e8f441a 14796 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14797 mips32_op = OPC_BC1FANY4;
14798 goto do_cp1mips3d;
14799 case BC1ANY4T:
9e8f441a 14800 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14801 mips32_op = OPC_BC1TANY4;
14802 do_cp1mips3d:
14803 check_cop1x(ctx);
d75c135e 14804 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14805 /* Fall through */
14806 do_cp1branch:
272f458d
MR
14807 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14808 check_cp1_enabled(ctx);
14809 gen_compute_branch1(ctx, mips32_op,
14810 (ctx->opcode >> 18) & 0x7, imm << 1);
14811 } else {
14812 generate_exception_err(ctx, EXCP_CpU, 1);
14813 }
3c824109
NF
14814 break;
14815 case BPOSGE64:
14816 case BPOSGE32:
14817 /* MIPS DSP: not implemented */
14818 /* Fall through */
14819 default:
14820 MIPS_INVAL("pool32i");
9c708c7f 14821 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14822 break;
14823 }
14824 break;
14825 case POOL32C:
14826 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14827 offset = sextract32(ctx->opcode, 0,
14828 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14829 switch (minor) {
14830 case LWL:
9e8f441a 14831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14832 mips32_op = OPC_LWL;
5c13fdfd 14833 goto do_ld_lr;
3c824109 14834 case SWL:
9e8f441a 14835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14836 mips32_op = OPC_SWL;
5c13fdfd 14837 goto do_st_lr;
3c824109 14838 case LWR:
9e8f441a 14839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14840 mips32_op = OPC_LWR;
5c13fdfd 14841 goto do_ld_lr;
3c824109 14842 case SWR:
9e8f441a 14843 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14844 mips32_op = OPC_SWR;
5c13fdfd 14845 goto do_st_lr;
3c824109
NF
14846#if defined(TARGET_MIPS64)
14847 case LDL:
d9224450
MR
14848 check_insn(ctx, ISA_MIPS3);
14849 check_mips_64(ctx);
9e8f441a 14850 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14851 mips32_op = OPC_LDL;
5c13fdfd 14852 goto do_ld_lr;
3c824109 14853 case SDL:
d9224450
MR
14854 check_insn(ctx, ISA_MIPS3);
14855 check_mips_64(ctx);
9e8f441a 14856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14857 mips32_op = OPC_SDL;
5c13fdfd 14858 goto do_st_lr;
3c824109 14859 case LDR:
d9224450
MR
14860 check_insn(ctx, ISA_MIPS3);
14861 check_mips_64(ctx);
9e8f441a 14862 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14863 mips32_op = OPC_LDR;
5c13fdfd 14864 goto do_ld_lr;
3c824109 14865 case SDR:
d9224450
MR
14866 check_insn(ctx, ISA_MIPS3);
14867 check_mips_64(ctx);
9e8f441a 14868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14869 mips32_op = OPC_SDR;
5c13fdfd 14870 goto do_st_lr;
3c824109 14871 case LWU:
d9224450
MR
14872 check_insn(ctx, ISA_MIPS3);
14873 check_mips_64(ctx);
3c824109 14874 mips32_op = OPC_LWU;
5c13fdfd 14875 goto do_ld_lr;
3c824109 14876 case LLD:
d9224450
MR
14877 check_insn(ctx, ISA_MIPS3);
14878 check_mips_64(ctx);
3c824109 14879 mips32_op = OPC_LLD;
5c13fdfd 14880 goto do_ld_lr;
3c824109
NF
14881#endif
14882 case LL:
14883 mips32_op = OPC_LL;
5c13fdfd
AJ
14884 goto do_ld_lr;
14885 do_ld_lr:
3b4a5489 14886 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14887 break;
14888 do_st_lr:
8fffc646 14889 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
14890 break;
14891 case SC:
3b4a5489 14892 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14893 break;
14894#if defined(TARGET_MIPS64)
14895 case SCD:
d9224450
MR
14896 check_insn(ctx, ISA_MIPS3);
14897 check_mips_64(ctx);
3b4a5489 14898 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14899 break;
14900#endif
8fffc646
JH
14901 case LD_EVA:
14902 if (!ctx->eva) {
14903 MIPS_INVAL("pool32c ld-eva");
14904 generate_exception_end(ctx, EXCP_RI);
14905 break;
14906 }
14907 check_cp0_enabled(ctx);
14908
14909 minor2 = (ctx->opcode >> 9) & 0x7;
14910 offset = sextract32(ctx->opcode, 0, 9);
14911 switch (minor2) {
14912 case LBUE:
14913 mips32_op = OPC_LBUE;
14914 goto do_ld_lr;
14915 case LHUE:
14916 mips32_op = OPC_LHUE;
14917 goto do_ld_lr;
14918 case LWLE:
14919 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14920 mips32_op = OPC_LWLE;
14921 goto do_ld_lr;
14922 case LWRE:
14923 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14924 mips32_op = OPC_LWRE;
14925 goto do_ld_lr;
14926 case LBE:
14927 mips32_op = OPC_LBE;
14928 goto do_ld_lr;
14929 case LHE:
14930 mips32_op = OPC_LHE;
14931 goto do_ld_lr;
14932 case LLE:
14933 mips32_op = OPC_LLE;
14934 goto do_ld_lr;
14935 case LWE:
14936 mips32_op = OPC_LWE;
14937 goto do_ld_lr;
14938 };
14939 break;
14940 case ST_EVA:
14941 if (!ctx->eva) {
14942 MIPS_INVAL("pool32c st-eva");
14943 generate_exception_end(ctx, EXCP_RI);
14944 break;
14945 }
14946 check_cp0_enabled(ctx);
14947
14948 minor2 = (ctx->opcode >> 9) & 0x7;
14949 offset = sextract32(ctx->opcode, 0, 9);
14950 switch (minor2) {
14951 case SWLE:
14952 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14953 mips32_op = OPC_SWLE;
14954 goto do_st_lr;
14955 case SWRE:
14956 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14957 mips32_op = OPC_SWRE;
14958 goto do_st_lr;
14959 case PREFE:
14960 /* Treat as no-op */
14961 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14962 /* hint codes 24-31 are reserved and signal RI */
14963 generate_exception(ctx, EXCP_RI);
14964 }
14965 break;
14966 case CACHEE:
14967 /* Treat as no-op */
14968 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14969 gen_cache_operation(ctx, rt, rs, offset);
14970 }
14971 break;
14972 case SBE:
14973 mips32_op = OPC_SBE;
14974 goto do_st_lr;
14975 case SHE:
14976 mips32_op = OPC_SHE;
14977 goto do_st_lr;
14978 case SCE:
14979 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
14980 break;
14981 case SWE:
14982 mips32_op = OPC_SWE;
14983 goto do_st_lr;
14984 };
14985 break;
3c824109
NF
14986 case PREF:
14987 /* Treat as no-op */
3b4a5489
YK
14988 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14989 /* hint codes 24-31 are reserved and signal RI */
14990 generate_exception(ctx, EXCP_RI);
14991 }
3c824109
NF
14992 break;
14993 default:
14994 MIPS_INVAL("pool32c");
9c708c7f 14995 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14996 break;
14997 }
14998 break;
ab39ee45
YK
14999 case ADDI32: /* AUI, LUI */
15000 if (ctx->insn_flags & ISA_MIPS32R6) {
15001 /* AUI, LUI */
15002 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15003 } else {
15004 /* ADDI32 */
15005 mips32_op = OPC_ADDI;
15006 goto do_addi;
15007 }
15008 break;
3c824109
NF
15009 case ADDIU32:
15010 mips32_op = OPC_ADDIU;
15011 do_addi:
d75c135e 15012 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15013 break;
15014
15015 /* Logical operations */
15016 case ORI32:
15017 mips32_op = OPC_ORI;
15018 goto do_logici;
15019 case XORI32:
15020 mips32_op = OPC_XORI;
15021 goto do_logici;
15022 case ANDI32:
15023 mips32_op = OPC_ANDI;
15024 do_logici:
d75c135e 15025 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15026 break;
15027
15028 /* Set less than immediate */
15029 case SLTI32:
15030 mips32_op = OPC_SLTI;
15031 goto do_slti;
15032 case SLTIU32:
15033 mips32_op = OPC_SLTIU;
15034 do_slti:
d75c135e 15035 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15036 break;
15037 case JALX32:
9e8f441a 15038 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15039 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
15040 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15041 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 15042 break;
65935f07
YK
15043 case JALS32: /* BOVC, BEQC, BEQZALC */
15044 if (ctx->insn_flags & ISA_MIPS32R6) {
15045 if (rs >= rt) {
15046 /* BOVC */
15047 mips32_op = OPC_BOVC;
15048 } else if (rs < rt && rs == 0) {
15049 /* BEQZALC */
15050 mips32_op = OPC_BEQZALC;
15051 } else {
15052 /* BEQC */
15053 mips32_op = OPC_BEQC;
15054 }
15055 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15056 } else {
15057 /* JALS32 */
15058 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15059 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15060 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15061 }
3c824109 15062 break;
65935f07
YK
15063 case BEQ32: /* BC */
15064 if (ctx->insn_flags & ISA_MIPS32R6) {
15065 /* BC */
15066 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15067 sextract32(ctx->opcode << 1, 0, 27));
15068 } else {
15069 /* BEQ32 */
15070 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15071 }
3c824109 15072 break;
65935f07
YK
15073 case BNE32: /* BALC */
15074 if (ctx->insn_flags & ISA_MIPS32R6) {
15075 /* BALC */
15076 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15077 sextract32(ctx->opcode << 1, 0, 27));
15078 } else {
15079 /* BNE32 */
15080 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15081 }
3c824109 15082 break;
65935f07
YK
15083 case J32: /* BGTZC, BLTZC, BLTC */
15084 if (ctx->insn_flags & ISA_MIPS32R6) {
15085 if (rs == 0 && rt != 0) {
15086 /* BGTZC */
15087 mips32_op = OPC_BGTZC;
15088 } else if (rs != 0 && rt != 0 && rs == rt) {
15089 /* BLTZC */
15090 mips32_op = OPC_BLTZC;
15091 } else {
15092 /* BLTC */
15093 mips32_op = OPC_BLTC;
15094 }
15095 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15096 } else {
15097 /* J32 */
15098 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15099 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15100 }
3c824109 15101 break;
65935f07
YK
15102 case JAL32: /* BLEZC, BGEZC, BGEC */
15103 if (ctx->insn_flags & ISA_MIPS32R6) {
15104 if (rs == 0 && rt != 0) {
15105 /* BLEZC */
15106 mips32_op = OPC_BLEZC;
15107 } else if (rs != 0 && rt != 0 && rs == rt) {
15108 /* BGEZC */
15109 mips32_op = OPC_BGEZC;
15110 } else {
15111 /* BGEC */
15112 mips32_op = OPC_BGEC;
15113 }
15114 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15115 } else {
15116 /* JAL32 */
15117 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15118 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15119 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15120 }
3c824109
NF
15121 break;
15122 /* Floating point (COP1) */
15123 case LWC132:
15124 mips32_op = OPC_LWC1;
15125 goto do_cop1;
15126 case LDC132:
15127 mips32_op = OPC_LDC1;
15128 goto do_cop1;
15129 case SWC132:
15130 mips32_op = OPC_SWC1;
15131 goto do_cop1;
15132 case SDC132:
15133 mips32_op = OPC_SDC1;
15134 do_cop1:
5ab5c041 15135 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 15136 break;
ab39ee45
YK
15137 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15138 if (ctx->insn_flags & ISA_MIPS32R6) {
15139 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15140 switch ((ctx->opcode >> 16) & 0x1f) {
15141 case ADDIUPC_00 ... ADDIUPC_07:
15142 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
15143 break;
15144 case AUIPC:
15145 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
15146 break;
15147 case ALUIPC:
15148 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
15149 break;
15150 case LWPC_08 ... LWPC_0F:
15151 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
15152 break;
15153 default:
15154 generate_exception(ctx, EXCP_RI);
15155 break;
15156 }
15157 } else {
15158 /* ADDIUPC */
3c824109
NF
15159 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
15160 int offset = SIMM(ctx->opcode, 0, 23) << 2;
15161
15162 gen_addiupc(ctx, reg, offset, 0, 0);
15163 }
15164 break;
65935f07
YK
15165 case BNVC: /* BNEC, BNEZALC */
15166 check_insn(ctx, ISA_MIPS32R6);
15167 if (rs >= rt) {
15168 /* BNVC */
15169 mips32_op = OPC_BNVC;
15170 } else if (rs < rt && rs == 0) {
15171 /* BNEZALC */
15172 mips32_op = OPC_BNEZALC;
15173 } else {
15174 /* BNEC */
15175 mips32_op = OPC_BNEC;
15176 }
15177 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15178 break;
15179 case R6_BNEZC: /* JIALC */
15180 check_insn(ctx, ISA_MIPS32R6);
15181 if (rt != 0) {
15182 /* BNEZC */
15183 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15184 sextract32(ctx->opcode << 1, 0, 22));
15185 } else {
15186 /* JIALC */
15187 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15188 }
15189 break;
15190 case R6_BEQZC: /* JIC */
15191 check_insn(ctx, ISA_MIPS32R6);
15192 if (rt != 0) {
15193 /* BEQZC */
15194 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15195 sextract32(ctx->opcode << 1, 0, 22));
15196 } else {
15197 /* JIC */
15198 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15199 }
15200 break;
15201 case BLEZALC: /* BGEZALC, BGEUC */
15202 check_insn(ctx, ISA_MIPS32R6);
15203 if (rs == 0 && rt != 0) {
15204 /* BLEZALC */
15205 mips32_op = OPC_BLEZALC;
15206 } else if (rs != 0 && rt != 0 && rs == rt) {
15207 /* BGEZALC */
15208 mips32_op = OPC_BGEZALC;
15209 } else {
15210 /* BGEUC */
15211 mips32_op = OPC_BGEUC;
15212 }
15213 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15214 break;
15215 case BGTZALC: /* BLTZALC, BLTUC */
15216 check_insn(ctx, ISA_MIPS32R6);
15217 if (rs == 0 && rt != 0) {
15218 /* BGTZALC */
15219 mips32_op = OPC_BGTZALC;
15220 } else if (rs != 0 && rt != 0 && rs == rt) {
15221 /* BLTZALC */
15222 mips32_op = OPC_BLTZALC;
15223 } else {
15224 /* BLTUC */
15225 mips32_op = OPC_BLTUC;
15226 }
15227 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15228 break;
3c824109
NF
15229 /* Loads and stores */
15230 case LB32:
15231 mips32_op = OPC_LB;
5c13fdfd 15232 goto do_ld;
3c824109
NF
15233 case LBU32:
15234 mips32_op = OPC_LBU;
5c13fdfd 15235 goto do_ld;
3c824109
NF
15236 case LH32:
15237 mips32_op = OPC_LH;
5c13fdfd 15238 goto do_ld;
3c824109
NF
15239 case LHU32:
15240 mips32_op = OPC_LHU;
5c13fdfd 15241 goto do_ld;
3c824109
NF
15242 case LW32:
15243 mips32_op = OPC_LW;
5c13fdfd 15244 goto do_ld;
3c824109
NF
15245#ifdef TARGET_MIPS64
15246 case LD32:
d9224450
MR
15247 check_insn(ctx, ISA_MIPS3);
15248 check_mips_64(ctx);
3c824109 15249 mips32_op = OPC_LD;
5c13fdfd 15250 goto do_ld;
3c824109 15251 case SD32:
d9224450
MR
15252 check_insn(ctx, ISA_MIPS3);
15253 check_mips_64(ctx);
3c824109 15254 mips32_op = OPC_SD;
5c13fdfd 15255 goto do_st;
3c824109
NF
15256#endif
15257 case SB32:
15258 mips32_op = OPC_SB;
5c13fdfd 15259 goto do_st;
3c824109
NF
15260 case SH32:
15261 mips32_op = OPC_SH;
5c13fdfd 15262 goto do_st;
3c824109
NF
15263 case SW32:
15264 mips32_op = OPC_SW;
5c13fdfd
AJ
15265 goto do_st;
15266 do_ld:
d75c135e 15267 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15268 break;
15269 do_st:
15270 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15271 break;
15272 default:
9c708c7f 15273 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15274 break;
15275 }
15276}
15277
240ce26a 15278static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15279{
15280 uint32_t op;
15281
15282 /* make sure instructions are on a halfword boundary */
15283 if (ctx->pc & 0x1) {
15284 env->CP0_BadVAddr = ctx->pc;
9c708c7f 15285 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15286 return 2;
15287 }
15288
15289 op = (ctx->opcode >> 10) & 0x3f;
15290 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15291 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15292 switch (op & 0x7) { /* MSB-3..MSB-5 */
15293 case 0:
15294 /* POOL32A, POOL32B, POOL32I, POOL32C */
15295 case 4:
15296 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15297 case 5:
15298 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15299 case 6:
15300 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15301 case 7:
15302 /* LB32, LH32, LWC132, LDC132, LW32 */
15303 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15304 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15305 return 2;
15306 }
15307 break;
b231c103
YK
15308 case 1:
15309 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15310 case 2:
15311 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15312 case 3:
15313 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15314 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15315 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15316 return 2;
15317 }
15318 break;
3c824109
NF
15319 }
15320 }
b231c103 15321
3c824109
NF
15322 switch (op) {
15323 case POOL16A:
15324 {
15325 int rd = mmreg(uMIPS_RD(ctx->opcode));
15326 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15327 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15328 uint32_t opc = 0;
15329
15330 switch (ctx->opcode & 0x1) {
15331 case ADDU16:
15332 opc = OPC_ADDU;
15333 break;
15334 case SUBU16:
15335 opc = OPC_SUBU;
15336 break;
15337 }
ed7ce6c0
YK
15338 if (ctx->insn_flags & ISA_MIPS32R6) {
15339 /* In the Release 6 the register number location in
15340 * the instruction encoding has changed.
15341 */
15342 gen_arith(ctx, opc, rs1, rd, rs2);
15343 } else {
15344 gen_arith(ctx, opc, rd, rs1, rs2);
15345 }
3c824109
NF
15346 }
15347 break;
15348 case POOL16B:
15349 {
15350 int rd = mmreg(uMIPS_RD(ctx->opcode));
15351 int rs = mmreg(uMIPS_RS(ctx->opcode));
15352 int amount = (ctx->opcode >> 1) & 0x7;
15353 uint32_t opc = 0;
15354 amount = amount == 0 ? 8 : amount;
15355
15356 switch (ctx->opcode & 0x1) {
15357 case SLL16:
15358 opc = OPC_SLL;
15359 break;
15360 case SRL16:
15361 opc = OPC_SRL;
15362 break;
15363 }
15364
d75c135e 15365 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15366 }
15367 break;
15368 case POOL16C:
ed7ce6c0
YK
15369 if (ctx->insn_flags & ISA_MIPS32R6) {
15370 gen_pool16c_r6_insn(ctx);
15371 } else {
15372 gen_pool16c_insn(ctx);
15373 }
3c824109
NF
15374 break;
15375 case LWGP16:
15376 {
15377 int rd = mmreg(uMIPS_RD(ctx->opcode));
15378 int rb = 28; /* GP */
15379 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15380
d75c135e 15381 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15382 }
15383 break;
15384 case POOL16F:
9e8f441a 15385 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15386 if (ctx->opcode & 1) {
9c708c7f 15387 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15388 } else {
15389 /* MOVEP */
15390 int enc_dest = uMIPS_RD(ctx->opcode);
15391 int enc_rt = uMIPS_RS2(ctx->opcode);
15392 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15393 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15394 }
15395 break;
15396 case LBU16:
15397 {
15398 int rd = mmreg(uMIPS_RD(ctx->opcode));
15399 int rb = mmreg(uMIPS_RS(ctx->opcode));
15400 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15401 offset = (offset == 0xf ? -1 : offset);
15402
d75c135e 15403 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15404 }
15405 break;
15406 case LHU16:
15407 {
15408 int rd = mmreg(uMIPS_RD(ctx->opcode));
15409 int rb = mmreg(uMIPS_RS(ctx->opcode));
15410 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15411
d75c135e 15412 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15413 }
15414 break;
15415 case LWSP16:
15416 {
15417 int rd = (ctx->opcode >> 5) & 0x1f;
15418 int rb = 29; /* SP */
15419 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15420
d75c135e 15421 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15422 }
15423 break;
15424 case LW16:
15425 {
15426 int rd = mmreg(uMIPS_RD(ctx->opcode));
15427 int rb = mmreg(uMIPS_RS(ctx->opcode));
15428 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15429
d75c135e 15430 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15431 }
15432 break;
15433 case SB16:
15434 {
15435 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15436 int rb = mmreg(uMIPS_RS(ctx->opcode));
15437 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15438
5c13fdfd 15439 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15440 }
15441 break;
15442 case SH16:
15443 {
15444 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15445 int rb = mmreg(uMIPS_RS(ctx->opcode));
15446 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15447
5c13fdfd 15448 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15449 }
15450 break;
15451 case SWSP16:
15452 {
15453 int rd = (ctx->opcode >> 5) & 0x1f;
15454 int rb = 29; /* SP */
15455 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15456
5c13fdfd 15457 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15458 }
15459 break;
15460 case SW16:
15461 {
15462 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15463 int rb = mmreg(uMIPS_RS(ctx->opcode));
15464 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15465
5c13fdfd 15466 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15467 }
15468 break;
15469 case MOVE16:
15470 {
15471 int rd = uMIPS_RD5(ctx->opcode);
15472 int rs = uMIPS_RS5(ctx->opcode);
15473
7215d7e7 15474 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15475 }
15476 break;
15477 case ANDI16:
d75c135e 15478 gen_andi16(ctx);
3c824109
NF
15479 break;
15480 case POOL16D:
15481 switch (ctx->opcode & 0x1) {
15482 case ADDIUS5:
d75c135e 15483 gen_addius5(ctx);
3c824109
NF
15484 break;
15485 case ADDIUSP:
d75c135e 15486 gen_addiusp(ctx);
3c824109
NF
15487 break;
15488 }
15489 break;
15490 case POOL16E:
15491 switch (ctx->opcode & 0x1) {
15492 case ADDIUR2:
d75c135e 15493 gen_addiur2(ctx);
3c824109
NF
15494 break;
15495 case ADDIUR1SP:
d75c135e 15496 gen_addiur1sp(ctx);
3c824109
NF
15497 break;
15498 }
15499 break;
65935f07 15500 case B16: /* BC16 */
3c824109 15501 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15502 sextract32(ctx->opcode, 0, 10) << 1,
15503 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15504 break;
65935f07
YK
15505 case BNEZ16: /* BNEZC16 */
15506 case BEQZ16: /* BEQZC16 */
3c824109
NF
15507 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15508 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15509 0, sextract32(ctx->opcode, 0, 7) << 1,
15510 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15511
3c824109
NF
15512 break;
15513 case LI16:
15514 {
15515 int reg = mmreg(uMIPS_RD(ctx->opcode));
15516 int imm = ZIMM(ctx->opcode, 0, 7);
15517
15518 imm = (imm == 0x7f ? -1 : imm);
15519 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15520 }
15521 break;
3c824109 15522 case RES_29:
3c824109 15523 case RES_31:
3c824109 15524 case RES_39:
9c708c7f 15525 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15526 break;
15527 default:
f60eeb0c 15528 decode_micromips32_opc(env, ctx);
3c824109
NF
15529 return 4;
15530 }
15531
15532 return 2;
15533}
15534
15535/* SmartMIPS extension to MIPS32 */
15536
15537#if defined(TARGET_MIPS64)
15538
15539/* MDMX extension to MIPS64 */
15540
15541#endif
15542
9b1a1d68 15543/* MIPSDSP functions. */
d75c135e 15544static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15545 int rd, int base, int offset)
15546{
9b1a1d68
JL
15547 TCGv t0;
15548
9b1a1d68
JL
15549 check_dsp(ctx);
15550 t0 = tcg_temp_new();
15551
15552 if (base == 0) {
15553 gen_load_gpr(t0, offset);
15554 } else if (offset == 0) {
15555 gen_load_gpr(t0, base);
15556 } else {
15557 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15558 }
15559
9b1a1d68
JL
15560 switch (opc) {
15561 case OPC_LBUX:
5f68f5ae 15562 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15563 gen_store_gpr(t0, rd);
9b1a1d68
JL
15564 break;
15565 case OPC_LHX:
5f68f5ae 15566 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15567 gen_store_gpr(t0, rd);
9b1a1d68
JL
15568 break;
15569 case OPC_LWX:
5f68f5ae 15570 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15571 gen_store_gpr(t0, rd);
9b1a1d68
JL
15572 break;
15573#if defined(TARGET_MIPS64)
15574 case OPC_LDX:
5f68f5ae 15575 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15576 gen_store_gpr(t0, rd);
9b1a1d68
JL
15577 break;
15578#endif
15579 }
9b1a1d68
JL
15580 tcg_temp_free(t0);
15581}
15582
461c08df
JL
15583static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15584 int ret, int v1, int v2)
15585{
461c08df
JL
15586 TCGv v1_t;
15587 TCGv v2_t;
15588
15589 if (ret == 0) {
15590 /* Treat as NOP. */
461c08df
JL
15591 return;
15592 }
15593
15594 v1_t = tcg_temp_new();
15595 v2_t = tcg_temp_new();
15596
15597 gen_load_gpr(v1_t, v1);
15598 gen_load_gpr(v2_t, v2);
15599
15600 switch (op1) {
15601 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15602 case OPC_MULT_G_2E:
15603 check_dspr2(ctx);
15604 switch (op2) {
15605 case OPC_ADDUH_QB:
15606 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15607 break;
15608 case OPC_ADDUH_R_QB:
15609 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15610 break;
15611 case OPC_ADDQH_PH:
15612 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15613 break;
15614 case OPC_ADDQH_R_PH:
15615 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15616 break;
15617 case OPC_ADDQH_W:
15618 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15619 break;
15620 case OPC_ADDQH_R_W:
15621 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15622 break;
15623 case OPC_SUBUH_QB:
15624 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15625 break;
15626 case OPC_SUBUH_R_QB:
15627 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15628 break;
15629 case OPC_SUBQH_PH:
15630 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15631 break;
15632 case OPC_SUBQH_R_PH:
15633 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15634 break;
15635 case OPC_SUBQH_W:
15636 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15637 break;
15638 case OPC_SUBQH_R_W:
15639 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15640 break;
15641 }
15642 break;
15643 case OPC_ABSQ_S_PH_DSP:
15644 switch (op2) {
15645 case OPC_ABSQ_S_QB:
15646 check_dspr2(ctx);
15647 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15648 break;
15649 case OPC_ABSQ_S_PH:
15650 check_dsp(ctx);
15651 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15652 break;
15653 case OPC_ABSQ_S_W:
15654 check_dsp(ctx);
15655 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15656 break;
15657 case OPC_PRECEQ_W_PHL:
15658 check_dsp(ctx);
15659 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15660 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15661 break;
15662 case OPC_PRECEQ_W_PHR:
15663 check_dsp(ctx);
15664 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15665 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15666 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15667 break;
15668 case OPC_PRECEQU_PH_QBL:
15669 check_dsp(ctx);
15670 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15671 break;
15672 case OPC_PRECEQU_PH_QBR:
15673 check_dsp(ctx);
15674 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15675 break;
15676 case OPC_PRECEQU_PH_QBLA:
15677 check_dsp(ctx);
15678 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15679 break;
15680 case OPC_PRECEQU_PH_QBRA:
15681 check_dsp(ctx);
15682 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15683 break;
15684 case OPC_PRECEU_PH_QBL:
15685 check_dsp(ctx);
15686 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15687 break;
15688 case OPC_PRECEU_PH_QBR:
15689 check_dsp(ctx);
15690 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15691 break;
15692 case OPC_PRECEU_PH_QBLA:
15693 check_dsp(ctx);
15694 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15695 break;
15696 case OPC_PRECEU_PH_QBRA:
15697 check_dsp(ctx);
15698 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15699 break;
15700 }
15701 break;
15702 case OPC_ADDU_QB_DSP:
15703 switch (op2) {
15704 case OPC_ADDQ_PH:
15705 check_dsp(ctx);
15706 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15707 break;
15708 case OPC_ADDQ_S_PH:
15709 check_dsp(ctx);
15710 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15711 break;
15712 case OPC_ADDQ_S_W:
15713 check_dsp(ctx);
15714 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15715 break;
15716 case OPC_ADDU_QB:
15717 check_dsp(ctx);
15718 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15719 break;
15720 case OPC_ADDU_S_QB:
15721 check_dsp(ctx);
15722 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15723 break;
15724 case OPC_ADDU_PH:
15725 check_dspr2(ctx);
15726 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15727 break;
15728 case OPC_ADDU_S_PH:
15729 check_dspr2(ctx);
15730 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15731 break;
15732 case OPC_SUBQ_PH:
15733 check_dsp(ctx);
15734 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15735 break;
15736 case OPC_SUBQ_S_PH:
15737 check_dsp(ctx);
15738 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15739 break;
15740 case OPC_SUBQ_S_W:
15741 check_dsp(ctx);
15742 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15743 break;
15744 case OPC_SUBU_QB:
15745 check_dsp(ctx);
15746 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15747 break;
15748 case OPC_SUBU_S_QB:
15749 check_dsp(ctx);
15750 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15751 break;
15752 case OPC_SUBU_PH:
15753 check_dspr2(ctx);
15754 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15755 break;
15756 case OPC_SUBU_S_PH:
15757 check_dspr2(ctx);
15758 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15759 break;
15760 case OPC_ADDSC:
15761 check_dsp(ctx);
15762 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15763 break;
15764 case OPC_ADDWC:
15765 check_dsp(ctx);
15766 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15767 break;
15768 case OPC_MODSUB:
15769 check_dsp(ctx);
15770 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15771 break;
15772 case OPC_RADDU_W_QB:
15773 check_dsp(ctx);
15774 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15775 break;
15776 }
15777 break;
15778 case OPC_CMPU_EQ_QB_DSP:
15779 switch (op2) {
15780 case OPC_PRECR_QB_PH:
15781 check_dspr2(ctx);
15782 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15783 break;
15784 case OPC_PRECRQ_QB_PH:
15785 check_dsp(ctx);
15786 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15787 break;
15788 case OPC_PRECR_SRA_PH_W:
15789 check_dspr2(ctx);
15790 {
15791 TCGv_i32 sa_t = tcg_const_i32(v2);
15792 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15793 cpu_gpr[ret]);
15794 tcg_temp_free_i32(sa_t);
15795 break;
15796 }
15797 case OPC_PRECR_SRA_R_PH_W:
15798 check_dspr2(ctx);
15799 {
15800 TCGv_i32 sa_t = tcg_const_i32(v2);
15801 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15802 cpu_gpr[ret]);
15803 tcg_temp_free_i32(sa_t);
15804 break;
15805 }
15806 case OPC_PRECRQ_PH_W:
15807 check_dsp(ctx);
15808 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15809 break;
15810 case OPC_PRECRQ_RS_PH_W:
15811 check_dsp(ctx);
15812 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15813 break;
15814 case OPC_PRECRQU_S_QB_PH:
15815 check_dsp(ctx);
15816 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15817 break;
15818 }
15819 break;
15820#ifdef TARGET_MIPS64
15821 case OPC_ABSQ_S_QH_DSP:
15822 switch (op2) {
15823 case OPC_PRECEQ_L_PWL:
15824 check_dsp(ctx);
15825 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15826 break;
15827 case OPC_PRECEQ_L_PWR:
15828 check_dsp(ctx);
15829 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15830 break;
15831 case OPC_PRECEQ_PW_QHL:
15832 check_dsp(ctx);
15833 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15834 break;
15835 case OPC_PRECEQ_PW_QHR:
15836 check_dsp(ctx);
15837 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15838 break;
15839 case OPC_PRECEQ_PW_QHLA:
15840 check_dsp(ctx);
15841 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15842 break;
15843 case OPC_PRECEQ_PW_QHRA:
15844 check_dsp(ctx);
15845 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15846 break;
15847 case OPC_PRECEQU_QH_OBL:
15848 check_dsp(ctx);
15849 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15850 break;
15851 case OPC_PRECEQU_QH_OBR:
15852 check_dsp(ctx);
15853 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15854 break;
15855 case OPC_PRECEQU_QH_OBLA:
15856 check_dsp(ctx);
15857 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15858 break;
15859 case OPC_PRECEQU_QH_OBRA:
15860 check_dsp(ctx);
15861 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15862 break;
15863 case OPC_PRECEU_QH_OBL:
15864 check_dsp(ctx);
15865 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15866 break;
15867 case OPC_PRECEU_QH_OBR:
15868 check_dsp(ctx);
15869 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15870 break;
15871 case OPC_PRECEU_QH_OBLA:
15872 check_dsp(ctx);
15873 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15874 break;
15875 case OPC_PRECEU_QH_OBRA:
15876 check_dsp(ctx);
15877 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15878 break;
15879 case OPC_ABSQ_S_OB:
15880 check_dspr2(ctx);
15881 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15882 break;
15883 case OPC_ABSQ_S_PW:
15884 check_dsp(ctx);
15885 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15886 break;
15887 case OPC_ABSQ_S_QH:
15888 check_dsp(ctx);
15889 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15890 break;
15891 }
15892 break;
15893 case OPC_ADDU_OB_DSP:
15894 switch (op2) {
15895 case OPC_RADDU_L_OB:
15896 check_dsp(ctx);
15897 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15898 break;
15899 case OPC_SUBQ_PW:
15900 check_dsp(ctx);
15901 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15902 break;
15903 case OPC_SUBQ_S_PW:
15904 check_dsp(ctx);
15905 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15906 break;
15907 case OPC_SUBQ_QH:
15908 check_dsp(ctx);
15909 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15910 break;
15911 case OPC_SUBQ_S_QH:
15912 check_dsp(ctx);
15913 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15914 break;
15915 case OPC_SUBU_OB:
15916 check_dsp(ctx);
15917 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15918 break;
15919 case OPC_SUBU_S_OB:
15920 check_dsp(ctx);
15921 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15922 break;
15923 case OPC_SUBU_QH:
15924 check_dspr2(ctx);
15925 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15926 break;
15927 case OPC_SUBU_S_QH:
15928 check_dspr2(ctx);
15929 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15930 break;
15931 case OPC_SUBUH_OB:
15932 check_dspr2(ctx);
15933 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15934 break;
15935 case OPC_SUBUH_R_OB:
15936 check_dspr2(ctx);
15937 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15938 break;
15939 case OPC_ADDQ_PW:
15940 check_dsp(ctx);
15941 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15942 break;
15943 case OPC_ADDQ_S_PW:
15944 check_dsp(ctx);
15945 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15946 break;
15947 case OPC_ADDQ_QH:
15948 check_dsp(ctx);
15949 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15950 break;
15951 case OPC_ADDQ_S_QH:
15952 check_dsp(ctx);
15953 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15954 break;
15955 case OPC_ADDU_OB:
15956 check_dsp(ctx);
15957 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15958 break;
15959 case OPC_ADDU_S_OB:
15960 check_dsp(ctx);
15961 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15962 break;
15963 case OPC_ADDU_QH:
15964 check_dspr2(ctx);
15965 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15966 break;
15967 case OPC_ADDU_S_QH:
15968 check_dspr2(ctx);
15969 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15970 break;
15971 case OPC_ADDUH_OB:
15972 check_dspr2(ctx);
15973 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15974 break;
15975 case OPC_ADDUH_R_OB:
15976 check_dspr2(ctx);
15977 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15978 break;
15979 }
15980 break;
15981 case OPC_CMPU_EQ_OB_DSP:
15982 switch (op2) {
15983 case OPC_PRECR_OB_QH:
15984 check_dspr2(ctx);
15985 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15986 break;
15987 case OPC_PRECR_SRA_QH_PW:
15988 check_dspr2(ctx);
15989 {
15990 TCGv_i32 ret_t = tcg_const_i32(ret);
15991 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15992 tcg_temp_free_i32(ret_t);
15993 break;
15994 }
15995 case OPC_PRECR_SRA_R_QH_PW:
15996 check_dspr2(ctx);
15997 {
15998 TCGv_i32 sa_v = tcg_const_i32(ret);
15999 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
16000 tcg_temp_free_i32(sa_v);
16001 break;
16002 }
16003 case OPC_PRECRQ_OB_QH:
16004 check_dsp(ctx);
16005 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16006 break;
16007 case OPC_PRECRQ_PW_L:
16008 check_dsp(ctx);
16009 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
16010 break;
16011 case OPC_PRECRQ_QH_PW:
16012 check_dsp(ctx);
16013 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
16014 break;
16015 case OPC_PRECRQ_RS_QH_PW:
16016 check_dsp(ctx);
16017 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16018 break;
16019 case OPC_PRECRQU_S_OB_QH:
16020 check_dsp(ctx);
16021 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16022 break;
16023 }
16024 break;
16025#endif
16026 }
16027
16028 tcg_temp_free(v1_t);
16029 tcg_temp_free(v2_t);
461c08df 16030}
9b1a1d68 16031
77c5fa8b
JL
16032static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16033 int ret, int v1, int v2)
16034{
16035 uint32_t op2;
77c5fa8b
JL
16036 TCGv t0;
16037 TCGv v1_t;
16038 TCGv v2_t;
16039
16040 if (ret == 0) {
16041 /* Treat as NOP. */
77c5fa8b
JL
16042 return;
16043 }
16044
16045 t0 = tcg_temp_new();
16046 v1_t = tcg_temp_new();
16047 v2_t = tcg_temp_new();
16048
16049 tcg_gen_movi_tl(t0, v1);
16050 gen_load_gpr(v1_t, v1);
16051 gen_load_gpr(v2_t, v2);
16052
16053 switch (opc) {
16054 case OPC_SHLL_QB_DSP:
16055 {
16056 op2 = MASK_SHLL_QB(ctx->opcode);
16057 switch (op2) {
16058 case OPC_SHLL_QB:
16059 check_dsp(ctx);
16060 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16061 break;
16062 case OPC_SHLLV_QB:
16063 check_dsp(ctx);
16064 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16065 break;
16066 case OPC_SHLL_PH:
16067 check_dsp(ctx);
16068 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16069 break;
16070 case OPC_SHLLV_PH:
16071 check_dsp(ctx);
16072 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16073 break;
16074 case OPC_SHLL_S_PH:
16075 check_dsp(ctx);
16076 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16077 break;
16078 case OPC_SHLLV_S_PH:
16079 check_dsp(ctx);
16080 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16081 break;
16082 case OPC_SHLL_S_W:
16083 check_dsp(ctx);
16084 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16085 break;
16086 case OPC_SHLLV_S_W:
16087 check_dsp(ctx);
16088 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16089 break;
16090 case OPC_SHRL_QB:
16091 check_dsp(ctx);
16092 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16093 break;
16094 case OPC_SHRLV_QB:
16095 check_dsp(ctx);
16096 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16097 break;
16098 case OPC_SHRL_PH:
16099 check_dspr2(ctx);
16100 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16101 break;
16102 case OPC_SHRLV_PH:
16103 check_dspr2(ctx);
16104 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16105 break;
16106 case OPC_SHRA_QB:
16107 check_dspr2(ctx);
16108 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16109 break;
16110 case OPC_SHRA_R_QB:
16111 check_dspr2(ctx);
16112 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16113 break;
16114 case OPC_SHRAV_QB:
16115 check_dspr2(ctx);
16116 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16117 break;
16118 case OPC_SHRAV_R_QB:
16119 check_dspr2(ctx);
16120 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16121 break;
16122 case OPC_SHRA_PH:
16123 check_dsp(ctx);
16124 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16125 break;
16126 case OPC_SHRA_R_PH:
16127 check_dsp(ctx);
16128 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16129 break;
16130 case OPC_SHRAV_PH:
16131 check_dsp(ctx);
16132 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16133 break;
16134 case OPC_SHRAV_R_PH:
16135 check_dsp(ctx);
16136 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16137 break;
16138 case OPC_SHRA_R_W:
16139 check_dsp(ctx);
16140 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16141 break;
16142 case OPC_SHRAV_R_W:
16143 check_dsp(ctx);
16144 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16145 break;
16146 default: /* Invalid */
16147 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 16148 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16149 break;
16150 }
16151 break;
16152 }
16153#ifdef TARGET_MIPS64
16154 case OPC_SHLL_OB_DSP:
16155 op2 = MASK_SHLL_OB(ctx->opcode);
16156 switch (op2) {
16157 case OPC_SHLL_PW:
16158 check_dsp(ctx);
16159 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16160 break;
16161 case OPC_SHLLV_PW:
16162 check_dsp(ctx);
16163 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16164 break;
16165 case OPC_SHLL_S_PW:
16166 check_dsp(ctx);
16167 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16168 break;
16169 case OPC_SHLLV_S_PW:
16170 check_dsp(ctx);
16171 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16172 break;
16173 case OPC_SHLL_OB:
16174 check_dsp(ctx);
16175 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16176 break;
16177 case OPC_SHLLV_OB:
16178 check_dsp(ctx);
16179 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16180 break;
16181 case OPC_SHLL_QH:
16182 check_dsp(ctx);
16183 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16184 break;
16185 case OPC_SHLLV_QH:
16186 check_dsp(ctx);
16187 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16188 break;
16189 case OPC_SHLL_S_QH:
16190 check_dsp(ctx);
16191 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16192 break;
16193 case OPC_SHLLV_S_QH:
16194 check_dsp(ctx);
16195 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16196 break;
16197 case OPC_SHRA_OB:
16198 check_dspr2(ctx);
16199 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16200 break;
16201 case OPC_SHRAV_OB:
16202 check_dspr2(ctx);
16203 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16204 break;
16205 case OPC_SHRA_R_OB:
16206 check_dspr2(ctx);
16207 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16208 break;
16209 case OPC_SHRAV_R_OB:
16210 check_dspr2(ctx);
16211 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16212 break;
16213 case OPC_SHRA_PW:
16214 check_dsp(ctx);
16215 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16216 break;
16217 case OPC_SHRAV_PW:
16218 check_dsp(ctx);
16219 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16220 break;
16221 case OPC_SHRA_R_PW:
16222 check_dsp(ctx);
16223 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16224 break;
16225 case OPC_SHRAV_R_PW:
16226 check_dsp(ctx);
16227 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16228 break;
16229 case OPC_SHRA_QH:
16230 check_dsp(ctx);
16231 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16232 break;
16233 case OPC_SHRAV_QH:
16234 check_dsp(ctx);
16235 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16236 break;
16237 case OPC_SHRA_R_QH:
16238 check_dsp(ctx);
16239 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16240 break;
16241 case OPC_SHRAV_R_QH:
16242 check_dsp(ctx);
16243 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16244 break;
16245 case OPC_SHRL_OB:
16246 check_dsp(ctx);
16247 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16248 break;
16249 case OPC_SHRLV_OB:
16250 check_dsp(ctx);
16251 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16252 break;
16253 case OPC_SHRL_QH:
16254 check_dspr2(ctx);
16255 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16256 break;
16257 case OPC_SHRLV_QH:
16258 check_dspr2(ctx);
16259 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16260 break;
16261 default: /* Invalid */
16262 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 16263 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16264 break;
16265 }
16266 break;
16267#endif
16268 }
16269
16270 tcg_temp_free(t0);
16271 tcg_temp_free(v1_t);
16272 tcg_temp_free(v2_t);
77c5fa8b
JL
16273}
16274
a22260ae
JL
16275static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16276 int ret, int v1, int v2, int check_ret)
16277{
a22260ae
JL
16278 TCGv_i32 t0;
16279 TCGv v1_t;
16280 TCGv v2_t;
16281
16282 if ((ret == 0) && (check_ret == 1)) {
16283 /* Treat as NOP. */
a22260ae
JL
16284 return;
16285 }
16286
16287 t0 = tcg_temp_new_i32();
16288 v1_t = tcg_temp_new();
16289 v2_t = tcg_temp_new();
16290
16291 tcg_gen_movi_i32(t0, ret);
16292 gen_load_gpr(v1_t, v1);
16293 gen_load_gpr(v2_t, v2);
16294
16295 switch (op1) {
16296 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16297 * the same mask and op1. */
16298 case OPC_MULT_G_2E:
639eadb9 16299 check_dspr2(ctx);
a22260ae
JL
16300 switch (op2) {
16301 case OPC_MUL_PH:
16302 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16303 break;
16304 case OPC_MUL_S_PH:
16305 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16306 break;
16307 case OPC_MULQ_S_W:
16308 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16309 break;
16310 case OPC_MULQ_RS_W:
16311 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16312 break;
16313 }
16314 break;
16315 case OPC_DPA_W_PH_DSP:
16316 switch (op2) {
16317 case OPC_DPAU_H_QBL:
16318 check_dsp(ctx);
16319 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16320 break;
16321 case OPC_DPAU_H_QBR:
16322 check_dsp(ctx);
16323 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16324 break;
16325 case OPC_DPSU_H_QBL:
16326 check_dsp(ctx);
16327 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16328 break;
16329 case OPC_DPSU_H_QBR:
16330 check_dsp(ctx);
16331 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16332 break;
16333 case OPC_DPA_W_PH:
16334 check_dspr2(ctx);
16335 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16336 break;
16337 case OPC_DPAX_W_PH:
16338 check_dspr2(ctx);
16339 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16340 break;
16341 case OPC_DPAQ_S_W_PH:
16342 check_dsp(ctx);
16343 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16344 break;
16345 case OPC_DPAQX_S_W_PH:
16346 check_dspr2(ctx);
16347 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16348 break;
16349 case OPC_DPAQX_SA_W_PH:
16350 check_dspr2(ctx);
16351 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16352 break;
16353 case OPC_DPS_W_PH:
16354 check_dspr2(ctx);
16355 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16356 break;
16357 case OPC_DPSX_W_PH:
16358 check_dspr2(ctx);
16359 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16360 break;
16361 case OPC_DPSQ_S_W_PH:
16362 check_dsp(ctx);
16363 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16364 break;
16365 case OPC_DPSQX_S_W_PH:
16366 check_dspr2(ctx);
16367 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16368 break;
16369 case OPC_DPSQX_SA_W_PH:
16370 check_dspr2(ctx);
16371 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16372 break;
16373 case OPC_MULSAQ_S_W_PH:
16374 check_dsp(ctx);
16375 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16376 break;
16377 case OPC_DPAQ_SA_L_W:
16378 check_dsp(ctx);
16379 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16380 break;
16381 case OPC_DPSQ_SA_L_W:
16382 check_dsp(ctx);
16383 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16384 break;
16385 case OPC_MAQ_S_W_PHL:
16386 check_dsp(ctx);
16387 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16388 break;
16389 case OPC_MAQ_S_W_PHR:
16390 check_dsp(ctx);
16391 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16392 break;
16393 case OPC_MAQ_SA_W_PHL:
16394 check_dsp(ctx);
16395 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16396 break;
16397 case OPC_MAQ_SA_W_PHR:
16398 check_dsp(ctx);
16399 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16400 break;
16401 case OPC_MULSA_W_PH:
16402 check_dspr2(ctx);
16403 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16404 break;
16405 }
16406 break;
16407#ifdef TARGET_MIPS64
16408 case OPC_DPAQ_W_QH_DSP:
16409 {
16410 int ac = ret & 0x03;
16411 tcg_gen_movi_i32(t0, ac);
16412
16413 switch (op2) {
16414 case OPC_DMADD:
16415 check_dsp(ctx);
16416 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16417 break;
16418 case OPC_DMADDU:
16419 check_dsp(ctx);
16420 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16421 break;
16422 case OPC_DMSUB:
16423 check_dsp(ctx);
16424 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16425 break;
16426 case OPC_DMSUBU:
16427 check_dsp(ctx);
16428 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16429 break;
16430 case OPC_DPA_W_QH:
16431 check_dspr2(ctx);
16432 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16433 break;
16434 case OPC_DPAQ_S_W_QH:
16435 check_dsp(ctx);
16436 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16437 break;
16438 case OPC_DPAQ_SA_L_PW:
16439 check_dsp(ctx);
16440 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16441 break;
16442 case OPC_DPAU_H_OBL:
16443 check_dsp(ctx);
16444 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16445 break;
16446 case OPC_DPAU_H_OBR:
16447 check_dsp(ctx);
16448 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16449 break;
16450 case OPC_DPS_W_QH:
16451 check_dspr2(ctx);
16452 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16453 break;
16454 case OPC_DPSQ_S_W_QH:
16455 check_dsp(ctx);
16456 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16457 break;
16458 case OPC_DPSQ_SA_L_PW:
16459 check_dsp(ctx);
16460 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16461 break;
16462 case OPC_DPSU_H_OBL:
16463 check_dsp(ctx);
16464 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16465 break;
16466 case OPC_DPSU_H_OBR:
16467 check_dsp(ctx);
16468 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16469 break;
16470 case OPC_MAQ_S_L_PWL:
16471 check_dsp(ctx);
16472 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16473 break;
16474 case OPC_MAQ_S_L_PWR:
16475 check_dsp(ctx);
16476 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16477 break;
16478 case OPC_MAQ_S_W_QHLL:
16479 check_dsp(ctx);
16480 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16481 break;
16482 case OPC_MAQ_SA_W_QHLL:
16483 check_dsp(ctx);
16484 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16485 break;
16486 case OPC_MAQ_S_W_QHLR:
16487 check_dsp(ctx);
16488 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16489 break;
16490 case OPC_MAQ_SA_W_QHLR:
16491 check_dsp(ctx);
16492 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16493 break;
16494 case OPC_MAQ_S_W_QHRL:
16495 check_dsp(ctx);
16496 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16497 break;
16498 case OPC_MAQ_SA_W_QHRL:
16499 check_dsp(ctx);
16500 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16501 break;
16502 case OPC_MAQ_S_W_QHRR:
16503 check_dsp(ctx);
16504 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16505 break;
16506 case OPC_MAQ_SA_W_QHRR:
16507 check_dsp(ctx);
16508 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16509 break;
16510 case OPC_MULSAQ_S_L_PW:
16511 check_dsp(ctx);
16512 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16513 break;
16514 case OPC_MULSAQ_S_W_QH:
16515 check_dsp(ctx);
16516 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16517 break;
16518 }
16519 }
16520 break;
16521#endif
16522 case OPC_ADDU_QB_DSP:
16523 switch (op2) {
16524 case OPC_MULEU_S_PH_QBL:
16525 check_dsp(ctx);
16526 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16527 break;
16528 case OPC_MULEU_S_PH_QBR:
16529 check_dsp(ctx);
16530 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16531 break;
16532 case OPC_MULQ_RS_PH:
16533 check_dsp(ctx);
16534 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16535 break;
16536 case OPC_MULEQ_S_W_PHL:
16537 check_dsp(ctx);
16538 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16539 break;
16540 case OPC_MULEQ_S_W_PHR:
16541 check_dsp(ctx);
16542 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16543 break;
16544 case OPC_MULQ_S_PH:
16545 check_dspr2(ctx);
16546 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16547 break;
16548 }
16549 break;
16550#ifdef TARGET_MIPS64
16551 case OPC_ADDU_OB_DSP:
16552 switch (op2) {
16553 case OPC_MULEQ_S_PW_QHL:
16554 check_dsp(ctx);
16555 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16556 break;
16557 case OPC_MULEQ_S_PW_QHR:
16558 check_dsp(ctx);
16559 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16560 break;
16561 case OPC_MULEU_S_QH_OBL:
16562 check_dsp(ctx);
16563 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16564 break;
16565 case OPC_MULEU_S_QH_OBR:
16566 check_dsp(ctx);
16567 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16568 break;
16569 case OPC_MULQ_RS_QH:
16570 check_dsp(ctx);
16571 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16572 break;
16573 }
16574 break;
16575#endif
16576 }
16577
16578 tcg_temp_free_i32(t0);
16579 tcg_temp_free(v1_t);
16580 tcg_temp_free(v2_t);
a22260ae
JL
16581}
16582
d75c135e 16583static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16584 int ret, int val)
16585{
1cb6686c
JL
16586 int16_t imm;
16587 TCGv t0;
16588 TCGv val_t;
16589
16590 if (ret == 0) {
16591 /* Treat as NOP. */
1cb6686c
JL
16592 return;
16593 }
16594
16595 t0 = tcg_temp_new();
16596 val_t = tcg_temp_new();
16597 gen_load_gpr(val_t, val);
16598
16599 switch (op1) {
16600 case OPC_ABSQ_S_PH_DSP:
16601 switch (op2) {
16602 case OPC_BITREV:
16603 check_dsp(ctx);
16604 gen_helper_bitrev(cpu_gpr[ret], val_t);
16605 break;
16606 case OPC_REPL_QB:
16607 check_dsp(ctx);
16608 {
16609 target_long result;
16610 imm = (ctx->opcode >> 16) & 0xFF;
16611 result = (uint32_t)imm << 24 |
16612 (uint32_t)imm << 16 |
16613 (uint32_t)imm << 8 |
16614 (uint32_t)imm;
16615 result = (int32_t)result;
16616 tcg_gen_movi_tl(cpu_gpr[ret], result);
16617 }
16618 break;
16619 case OPC_REPLV_QB:
16620 check_dsp(ctx);
16621 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16622 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16623 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16624 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16625 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16626 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16627 break;
16628 case OPC_REPL_PH:
16629 check_dsp(ctx);
16630 {
16631 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16632 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16633 tcg_gen_movi_tl(cpu_gpr[ret], \
16634 (target_long)((int32_t)imm << 16 | \
c4aaba92 16635 (uint16_t)imm));
1cb6686c
JL
16636 }
16637 break;
16638 case OPC_REPLV_PH:
16639 check_dsp(ctx);
16640 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16641 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16642 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16643 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16644 break;
16645 }
16646 break;
16647#ifdef TARGET_MIPS64
16648 case OPC_ABSQ_S_QH_DSP:
16649 switch (op2) {
16650 case OPC_REPL_OB:
16651 check_dsp(ctx);
16652 {
16653 target_long temp;
16654
16655 imm = (ctx->opcode >> 16) & 0xFF;
16656 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16657 temp = (temp << 16) | temp;
16658 temp = (temp << 32) | temp;
16659 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16660 break;
16661 }
16662 case OPC_REPL_PW:
16663 check_dsp(ctx);
16664 {
16665 target_long temp;
16666
16667 imm = (ctx->opcode >> 16) & 0x03FF;
16668 imm = (int16_t)(imm << 6) >> 6;
16669 temp = ((target_long)imm << 32) \
16670 | ((target_long)imm & 0xFFFFFFFF);
16671 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16672 break;
16673 }
16674 case OPC_REPL_QH:
16675 check_dsp(ctx);
16676 {
16677 target_long temp;
16678
16679 imm = (ctx->opcode >> 16) & 0x03FF;
16680 imm = (int16_t)(imm << 6) >> 6;
16681
16682 temp = ((uint64_t)(uint16_t)imm << 48) |
16683 ((uint64_t)(uint16_t)imm << 32) |
16684 ((uint64_t)(uint16_t)imm << 16) |
16685 (uint64_t)(uint16_t)imm;
16686 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16687 break;
16688 }
16689 case OPC_REPLV_OB:
16690 check_dsp(ctx);
16691 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16692 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16693 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16694 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16695 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16696 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16697 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16698 break;
16699 case OPC_REPLV_PW:
16700 check_dsp(ctx);
16701 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16702 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16703 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16704 break;
16705 case OPC_REPLV_QH:
16706 check_dsp(ctx);
16707 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16708 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16709 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16710 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16711 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16712 break;
16713 }
16714 break;
16715#endif
16716 }
16717 tcg_temp_free(t0);
16718 tcg_temp_free(val_t);
1cb6686c
JL
16719}
16720
26690560
JL
16721static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16722 uint32_t op1, uint32_t op2,
16723 int ret, int v1, int v2, int check_ret)
16724{
26690560
JL
16725 TCGv t1;
16726 TCGv v1_t;
16727 TCGv v2_t;
16728
16729 if ((ret == 0) && (check_ret == 1)) {
16730 /* Treat as NOP. */
26690560
JL
16731 return;
16732 }
16733
26690560
JL
16734 t1 = tcg_temp_new();
16735 v1_t = tcg_temp_new();
16736 v2_t = tcg_temp_new();
16737
16738 gen_load_gpr(v1_t, v1);
16739 gen_load_gpr(v2_t, v2);
16740
16741 switch (op1) {
26690560
JL
16742 case OPC_CMPU_EQ_QB_DSP:
16743 switch (op2) {
16744 case OPC_CMPU_EQ_QB:
16745 check_dsp(ctx);
16746 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16747 break;
16748 case OPC_CMPU_LT_QB:
16749 check_dsp(ctx);
16750 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16751 break;
16752 case OPC_CMPU_LE_QB:
16753 check_dsp(ctx);
16754 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16755 break;
16756 case OPC_CMPGU_EQ_QB:
16757 check_dsp(ctx);
16758 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16759 break;
16760 case OPC_CMPGU_LT_QB:
16761 check_dsp(ctx);
16762 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16763 break;
16764 case OPC_CMPGU_LE_QB:
16765 check_dsp(ctx);
16766 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16767 break;
16768 case OPC_CMPGDU_EQ_QB:
16769 check_dspr2(ctx);
16770 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16771 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16772 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16773 tcg_gen_shli_tl(t1, t1, 24);
16774 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16775 break;
16776 case OPC_CMPGDU_LT_QB:
16777 check_dspr2(ctx);
16778 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16779 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16780 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16781 tcg_gen_shli_tl(t1, t1, 24);
16782 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16783 break;
16784 case OPC_CMPGDU_LE_QB:
16785 check_dspr2(ctx);
16786 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16787 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16788 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16789 tcg_gen_shli_tl(t1, t1, 24);
16790 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16791 break;
16792 case OPC_CMP_EQ_PH:
16793 check_dsp(ctx);
16794 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16795 break;
16796 case OPC_CMP_LT_PH:
16797 check_dsp(ctx);
16798 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16799 break;
16800 case OPC_CMP_LE_PH:
16801 check_dsp(ctx);
16802 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16803 break;
16804 case OPC_PICK_QB:
16805 check_dsp(ctx);
16806 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16807 break;
16808 case OPC_PICK_PH:
16809 check_dsp(ctx);
16810 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16811 break;
16812 case OPC_PACKRL_PH:
16813 check_dsp(ctx);
16814 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16815 break;
16816 }
16817 break;
16818#ifdef TARGET_MIPS64
16819 case OPC_CMPU_EQ_OB_DSP:
16820 switch (op2) {
16821 case OPC_CMP_EQ_PW:
16822 check_dsp(ctx);
16823 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16824 break;
16825 case OPC_CMP_LT_PW:
16826 check_dsp(ctx);
16827 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16828 break;
16829 case OPC_CMP_LE_PW:
16830 check_dsp(ctx);
16831 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16832 break;
16833 case OPC_CMP_EQ_QH:
16834 check_dsp(ctx);
16835 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16836 break;
16837 case OPC_CMP_LT_QH:
16838 check_dsp(ctx);
16839 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16840 break;
16841 case OPC_CMP_LE_QH:
16842 check_dsp(ctx);
16843 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16844 break;
16845 case OPC_CMPGDU_EQ_OB:
16846 check_dspr2(ctx);
16847 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16848 break;
16849 case OPC_CMPGDU_LT_OB:
16850 check_dspr2(ctx);
16851 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16852 break;
16853 case OPC_CMPGDU_LE_OB:
16854 check_dspr2(ctx);
16855 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16856 break;
16857 case OPC_CMPGU_EQ_OB:
16858 check_dsp(ctx);
16859 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16860 break;
16861 case OPC_CMPGU_LT_OB:
16862 check_dsp(ctx);
16863 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16864 break;
16865 case OPC_CMPGU_LE_OB:
16866 check_dsp(ctx);
16867 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16868 break;
16869 case OPC_CMPU_EQ_OB:
16870 check_dsp(ctx);
16871 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16872 break;
16873 case OPC_CMPU_LT_OB:
16874 check_dsp(ctx);
16875 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16876 break;
16877 case OPC_CMPU_LE_OB:
16878 check_dsp(ctx);
16879 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16880 break;
16881 case OPC_PACKRL_PW:
16882 check_dsp(ctx);
16883 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16884 break;
16885 case OPC_PICK_OB:
16886 check_dsp(ctx);
16887 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16888 break;
16889 case OPC_PICK_PW:
16890 check_dsp(ctx);
16891 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16892 break;
16893 case OPC_PICK_QH:
16894 check_dsp(ctx);
16895 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16896 break;
16897 }
16898 break;
df6126a7
AJ
16899#endif
16900 }
16901
16902 tcg_temp_free(t1);
16903 tcg_temp_free(v1_t);
16904 tcg_temp_free(v2_t);
df6126a7
AJ
16905}
16906
16907static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16908 uint32_t op1, int rt, int rs, int sa)
16909{
df6126a7
AJ
16910 TCGv t0;
16911
16912 check_dspr2(ctx);
16913
16914 if (rt == 0) {
16915 /* Treat as NOP. */
df6126a7
AJ
16916 return;
16917 }
16918
16919 t0 = tcg_temp_new();
16920 gen_load_gpr(t0, rs);
16921
16922 switch (op1) {
16923 case OPC_APPEND_DSP:
16924 switch (MASK_APPEND(ctx->opcode)) {
16925 case OPC_APPEND:
16926 if (sa != 0) {
16927 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16928 }
16929 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16930 break;
16931 case OPC_PREPEND:
16932 if (sa != 0) {
16933 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16934 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16935 tcg_gen_shli_tl(t0, t0, 32 - sa);
16936 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16937 }
16938 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16939 break;
16940 case OPC_BALIGN:
16941 sa &= 3;
16942 if (sa != 0 && sa != 2) {
16943 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16944 tcg_gen_ext32u_tl(t0, t0);
16945 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16946 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16947 }
16948 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16949 break;
16950 default: /* Invalid */
16951 MIPS_INVAL("MASK APPEND");
9c708c7f 16952 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16953 break;
16954 }
16955 break;
16956#ifdef TARGET_MIPS64
26690560 16957 case OPC_DAPPEND_DSP:
df6126a7 16958 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16959 case OPC_DAPPEND:
df6126a7
AJ
16960 if (sa != 0) {
16961 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16962 }
26690560
JL
16963 break;
16964 case OPC_PREPENDD:
df6126a7
AJ
16965 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16966 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16967 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16968 break;
16969 case OPC_PREPENDW:
df6126a7
AJ
16970 if (sa != 0) {
16971 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16972 tcg_gen_shli_tl(t0, t0, 64 - sa);
16973 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16974 }
26690560
JL
16975 break;
16976 case OPC_DBALIGN:
df6126a7
AJ
16977 sa &= 7;
16978 if (sa != 0 && sa != 2 && sa != 4) {
16979 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16980 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16981 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16982 }
26690560
JL
16983 break;
16984 default: /* Invalid */
16985 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16986 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16987 break;
16988 }
16989 break;
16990#endif
16991 }
df6126a7 16992 tcg_temp_free(t0);
26690560
JL
16993}
16994
b53371ed
JL
16995static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16996 int ret, int v1, int v2, int check_ret)
16997
16998{
b53371ed
JL
16999 TCGv t0;
17000 TCGv t1;
17001 TCGv v1_t;
17002 TCGv v2_t;
17003 int16_t imm;
17004
17005 if ((ret == 0) && (check_ret == 1)) {
17006 /* Treat as NOP. */
b53371ed
JL
17007 return;
17008 }
17009
17010 t0 = tcg_temp_new();
17011 t1 = tcg_temp_new();
17012 v1_t = tcg_temp_new();
17013 v2_t = tcg_temp_new();
17014
17015 gen_load_gpr(v1_t, v1);
17016 gen_load_gpr(v2_t, v2);
17017
17018 switch (op1) {
17019 case OPC_EXTR_W_DSP:
17020 check_dsp(ctx);
17021 switch (op2) {
17022 case OPC_EXTR_W:
17023 tcg_gen_movi_tl(t0, v2);
17024 tcg_gen_movi_tl(t1, v1);
17025 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17026 break;
17027 case OPC_EXTR_R_W:
17028 tcg_gen_movi_tl(t0, v2);
17029 tcg_gen_movi_tl(t1, v1);
17030 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17031 break;
17032 case OPC_EXTR_RS_W:
17033 tcg_gen_movi_tl(t0, v2);
17034 tcg_gen_movi_tl(t1, v1);
17035 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17036 break;
17037 case OPC_EXTR_S_H:
17038 tcg_gen_movi_tl(t0, v2);
17039 tcg_gen_movi_tl(t1, v1);
17040 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17041 break;
17042 case OPC_EXTRV_S_H:
17043 tcg_gen_movi_tl(t0, v2);
17044 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17045 break;
17046 case OPC_EXTRV_W:
17047 tcg_gen_movi_tl(t0, v2);
17048 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17049 break;
17050 case OPC_EXTRV_R_W:
17051 tcg_gen_movi_tl(t0, v2);
17052 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17053 break;
17054 case OPC_EXTRV_RS_W:
17055 tcg_gen_movi_tl(t0, v2);
17056 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17057 break;
17058 case OPC_EXTP:
17059 tcg_gen_movi_tl(t0, v2);
17060 tcg_gen_movi_tl(t1, v1);
17061 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17062 break;
17063 case OPC_EXTPV:
17064 tcg_gen_movi_tl(t0, v2);
17065 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17066 break;
17067 case OPC_EXTPDP:
17068 tcg_gen_movi_tl(t0, v2);
17069 tcg_gen_movi_tl(t1, v1);
17070 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17071 break;
17072 case OPC_EXTPDPV:
17073 tcg_gen_movi_tl(t0, v2);
17074 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17075 break;
17076 case OPC_SHILO:
17077 imm = (ctx->opcode >> 20) & 0x3F;
17078 tcg_gen_movi_tl(t0, ret);
17079 tcg_gen_movi_tl(t1, imm);
17080 gen_helper_shilo(t0, t1, cpu_env);
17081 break;
17082 case OPC_SHILOV:
17083 tcg_gen_movi_tl(t0, ret);
17084 gen_helper_shilo(t0, v1_t, cpu_env);
17085 break;
17086 case OPC_MTHLIP:
17087 tcg_gen_movi_tl(t0, ret);
17088 gen_helper_mthlip(t0, v1_t, cpu_env);
17089 break;
17090 case OPC_WRDSP:
17091 imm = (ctx->opcode >> 11) & 0x3FF;
17092 tcg_gen_movi_tl(t0, imm);
17093 gen_helper_wrdsp(v1_t, t0, cpu_env);
17094 break;
17095 case OPC_RDDSP:
17096 imm = (ctx->opcode >> 16) & 0x03FF;
17097 tcg_gen_movi_tl(t0, imm);
17098 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17099 break;
17100 }
17101 break;
17102#ifdef TARGET_MIPS64
17103 case OPC_DEXTR_W_DSP:
17104 check_dsp(ctx);
17105 switch (op2) {
17106 case OPC_DMTHLIP:
17107 tcg_gen_movi_tl(t0, ret);
17108 gen_helper_dmthlip(v1_t, t0, cpu_env);
17109 break;
17110 case OPC_DSHILO:
17111 {
17112 int shift = (ctx->opcode >> 19) & 0x7F;
17113 int ac = (ctx->opcode >> 11) & 0x03;
17114 tcg_gen_movi_tl(t0, shift);
17115 tcg_gen_movi_tl(t1, ac);
17116 gen_helper_dshilo(t0, t1, cpu_env);
17117 break;
17118 }
17119 case OPC_DSHILOV:
17120 {
17121 int ac = (ctx->opcode >> 11) & 0x03;
17122 tcg_gen_movi_tl(t0, ac);
17123 gen_helper_dshilo(v1_t, t0, cpu_env);
17124 break;
17125 }
17126 case OPC_DEXTP:
17127 tcg_gen_movi_tl(t0, v2);
17128 tcg_gen_movi_tl(t1, v1);
17129
17130 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17131 break;
17132 case OPC_DEXTPV:
17133 tcg_gen_movi_tl(t0, v2);
17134 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17135 break;
17136 case OPC_DEXTPDP:
17137 tcg_gen_movi_tl(t0, v2);
17138 tcg_gen_movi_tl(t1, v1);
17139 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17140 break;
17141 case OPC_DEXTPDPV:
17142 tcg_gen_movi_tl(t0, v2);
17143 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17144 break;
17145 case OPC_DEXTR_L:
17146 tcg_gen_movi_tl(t0, v2);
17147 tcg_gen_movi_tl(t1, v1);
17148 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17149 break;
17150 case OPC_DEXTR_R_L:
17151 tcg_gen_movi_tl(t0, v2);
17152 tcg_gen_movi_tl(t1, v1);
17153 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17154 break;
17155 case OPC_DEXTR_RS_L:
17156 tcg_gen_movi_tl(t0, v2);
17157 tcg_gen_movi_tl(t1, v1);
17158 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17159 break;
17160 case OPC_DEXTR_W:
17161 tcg_gen_movi_tl(t0, v2);
17162 tcg_gen_movi_tl(t1, v1);
17163 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17164 break;
17165 case OPC_DEXTR_R_W:
17166 tcg_gen_movi_tl(t0, v2);
17167 tcg_gen_movi_tl(t1, v1);
17168 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17169 break;
17170 case OPC_DEXTR_RS_W:
17171 tcg_gen_movi_tl(t0, v2);
17172 tcg_gen_movi_tl(t1, v1);
17173 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17174 break;
17175 case OPC_DEXTR_S_H:
17176 tcg_gen_movi_tl(t0, v2);
17177 tcg_gen_movi_tl(t1, v1);
17178 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17179 break;
17180 case OPC_DEXTRV_S_H:
17181 tcg_gen_movi_tl(t0, v2);
17182 tcg_gen_movi_tl(t1, v1);
17183 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17184 break;
17185 case OPC_DEXTRV_L:
17186 tcg_gen_movi_tl(t0, v2);
17187 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17188 break;
17189 case OPC_DEXTRV_R_L:
17190 tcg_gen_movi_tl(t0, v2);
17191 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17192 break;
17193 case OPC_DEXTRV_RS_L:
17194 tcg_gen_movi_tl(t0, v2);
17195 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17196 break;
17197 case OPC_DEXTRV_W:
17198 tcg_gen_movi_tl(t0, v2);
17199 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17200 break;
17201 case OPC_DEXTRV_R_W:
17202 tcg_gen_movi_tl(t0, v2);
17203 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17204 break;
17205 case OPC_DEXTRV_RS_W:
17206 tcg_gen_movi_tl(t0, v2);
17207 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17208 break;
17209 }
17210 break;
17211#endif
17212 }
17213
17214 tcg_temp_free(t0);
17215 tcg_temp_free(t1);
17216 tcg_temp_free(v1_t);
17217 tcg_temp_free(v2_t);
b53371ed
JL
17218}
17219
9b1a1d68
JL
17220/* End MIPSDSP functions. */
17221
10dc65db
LA
17222static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17223{
4267d3e6 17224 int rs, rt, rd, sa;
b42ee5e1 17225 uint32_t op1, op2;
10dc65db
LA
17226
17227 rs = (ctx->opcode >> 21) & 0x1f;
17228 rt = (ctx->opcode >> 16) & 0x1f;
17229 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 17230 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17231
17232 op1 = MASK_SPECIAL(ctx->opcode);
17233 switch (op1) {
d4ea6acd 17234 case OPC_LSA:
1f1b4c00 17235 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17236 break;
b42ee5e1
LA
17237 case OPC_MULT ... OPC_DIVU:
17238 op2 = MASK_R6_MULDIV(ctx->opcode);
17239 switch (op2) {
17240 case R6_OPC_MUL:
17241 case R6_OPC_MUH:
17242 case R6_OPC_MULU:
17243 case R6_OPC_MUHU:
17244 case R6_OPC_DIV:
17245 case R6_OPC_MOD:
17246 case R6_OPC_DIVU:
17247 case R6_OPC_MODU:
17248 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17249 break;
17250 default:
17251 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17252 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17253 break;
17254 }
17255 break;
10dc65db
LA
17256 case OPC_SELEQZ:
17257 case OPC_SELNEZ:
17258 gen_cond_move(ctx, op1, rd, rs, rt);
17259 break;
4267d3e6
LA
17260 case R6_OPC_CLO:
17261 case R6_OPC_CLZ:
17262 if (rt == 0 && sa == 1) {
17263 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17264 We need additionally to check other fields */
17265 gen_cl(ctx, op1, rd, rs);
17266 } else {
9c708c7f 17267 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17268 }
17269 break;
17270 case R6_OPC_SDBBP:
3b3c1694
LA
17271 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17272 gen_helper_do_semihosting(cpu_env);
faf1f68b 17273 } else {
3b3c1694 17274 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 17275 generate_exception_end(ctx, EXCP_RI);
3b3c1694 17276 } else {
9c708c7f 17277 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17278 }
faf1f68b 17279 }
4267d3e6 17280 break;
b42ee5e1 17281#if defined(TARGET_MIPS64)
d4ea6acd
LA
17282 case OPC_DLSA:
17283 check_mips_64(ctx);
1f1b4c00 17284 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17285 break;
4267d3e6
LA
17286 case R6_OPC_DCLO:
17287 case R6_OPC_DCLZ:
17288 if (rt == 0 && sa == 1) {
17289 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17290 We need additionally to check other fields */
17291 check_mips_64(ctx);
17292 gen_cl(ctx, op1, rd, rs);
17293 } else {
9c708c7f 17294 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17295 }
17296 break;
b42ee5e1
LA
17297 case OPC_DMULT ... OPC_DDIVU:
17298 op2 = MASK_R6_MULDIV(ctx->opcode);
17299 switch (op2) {
17300 case R6_OPC_DMUL:
17301 case R6_OPC_DMUH:
17302 case R6_OPC_DMULU:
17303 case R6_OPC_DMUHU:
17304 case R6_OPC_DDIV:
17305 case R6_OPC_DMOD:
17306 case R6_OPC_DDIVU:
17307 case R6_OPC_DMODU:
17308 check_mips_64(ctx);
17309 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17310 break;
17311 default:
17312 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17313 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17314 break;
17315 }
17316 break;
17317#endif
10dc65db
LA
17318 default: /* Invalid */
17319 MIPS_INVAL("special_r6");
9c708c7f 17320 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17321 break;
17322 }
17323}
17324
17325static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17326{
b42ee5e1 17327 int rs, rt, rd, sa;
10dc65db
LA
17328 uint32_t op1;
17329
17330 rs = (ctx->opcode >> 21) & 0x1f;
17331 rt = (ctx->opcode >> 16) & 0x1f;
17332 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17333 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17334
17335 op1 = MASK_SPECIAL(ctx->opcode);
17336 switch (op1) {
17337 case OPC_MOVN: /* Conditional move */
17338 case OPC_MOVZ:
17339 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17340 INSN_LOONGSON2E | INSN_LOONGSON2F);
17341 gen_cond_move(ctx, op1, rd, rs, rt);
17342 break;
17343 case OPC_MFHI: /* Move from HI/LO */
17344 case OPC_MFLO:
17345 gen_HILO(ctx, op1, rs & 3, rd);
17346 break;
17347 case OPC_MTHI:
17348 case OPC_MTLO: /* Move to HI/LO */
17349 gen_HILO(ctx, op1, rd & 3, rs);
17350 break;
17351 case OPC_MOVCI:
17352 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17353 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17354 check_cp1_enabled(ctx);
17355 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17356 (ctx->opcode >> 16) & 1);
17357 } else {
17358 generate_exception_err(ctx, EXCP_CpU, 1);
17359 }
17360 break;
b42ee5e1
LA
17361 case OPC_MULT:
17362 case OPC_MULTU:
17363 if (sa) {
17364 check_insn(ctx, INSN_VR54XX);
17365 op1 = MASK_MUL_VR54XX(ctx->opcode);
17366 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17367 } else {
17368 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17369 }
17370 break;
17371 case OPC_DIV:
17372 case OPC_DIVU:
17373 gen_muldiv(ctx, op1, 0, rs, rt);
17374 break;
17375#if defined(TARGET_MIPS64)
17376 case OPC_DMULT ... OPC_DDIVU:
17377 check_insn(ctx, ISA_MIPS3);
17378 check_mips_64(ctx);
17379 gen_muldiv(ctx, op1, 0, rs, rt);
17380 break;
17381#endif
0aefa333 17382 case OPC_JR:
b231c103 17383 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17384 break;
4267d3e6
LA
17385 case OPC_SPIM:
17386#ifdef MIPS_STRICT_STANDARD
17387 MIPS_INVAL("SPIM");
9c708c7f 17388 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17389#else
17390 /* Implemented as RI exception for now. */
17391 MIPS_INVAL("spim (unofficial)");
9c708c7f 17392 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17393#endif
17394 break;
10dc65db
LA
17395 default: /* Invalid */
17396 MIPS_INVAL("special_legacy");
9c708c7f 17397 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17398 break;
17399 }
17400}
17401
099e5b4d 17402static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17403{
3c824109 17404 int rs, rt, rd, sa;
099e5b4d 17405 uint32_t op1;
3c824109 17406
3c824109
NF
17407 rs = (ctx->opcode >> 21) & 0x1f;
17408 rt = (ctx->opcode >> 16) & 0x1f;
17409 rd = (ctx->opcode >> 11) & 0x1f;
17410 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17411
17412 op1 = MASK_SPECIAL(ctx->opcode);
17413 switch (op1) {
17414 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17415 if (sa == 5 && rd == 0 &&
17416 rs == 0 && rt == 0) { /* PAUSE */
17417 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17418 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17419 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17420 break;
17421 }
17422 }
17423 /* Fallthrough */
099e5b4d
LA
17424 case OPC_SRA:
17425 gen_shift_imm(ctx, op1, rd, rt, sa);
17426 break;
17427 case OPC_SRL:
17428 switch ((ctx->opcode >> 21) & 0x1f) {
17429 case 1:
17430 /* rotr is decoded as srl on non-R2 CPUs */
17431 if (ctx->insn_flags & ISA_MIPS32R2) {
17432 op1 = OPC_ROTR;
ea63e2c3 17433 }
099e5b4d
LA
17434 /* Fallthrough */
17435 case 0:
17436 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17437 break;
099e5b4d 17438 default:
9c708c7f 17439 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17440 break;
099e5b4d
LA
17441 }
17442 break;
099e5b4d
LA
17443 case OPC_ADD ... OPC_SUBU:
17444 gen_arith(ctx, op1, rd, rs, rt);
17445 break;
17446 case OPC_SLLV: /* Shifts */
17447 case OPC_SRAV:
17448 gen_shift(ctx, op1, rd, rs, rt);
17449 break;
17450 case OPC_SRLV:
17451 switch ((ctx->opcode >> 6) & 0x1f) {
17452 case 1:
17453 /* rotrv is decoded as srlv on non-R2 CPUs */
17454 if (ctx->insn_flags & ISA_MIPS32R2) {
17455 op1 = OPC_ROTRV;
26135ead 17456 }
099e5b4d
LA
17457 /* Fallthrough */
17458 case 0:
17459 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17460 break;
099e5b4d 17461 default:
9c708c7f 17462 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17463 break;
099e5b4d
LA
17464 }
17465 break;
17466 case OPC_SLT: /* Set on less than */
17467 case OPC_SLTU:
17468 gen_slt(ctx, op1, rd, rs, rt);
17469 break;
17470 case OPC_AND: /* Logic*/
17471 case OPC_OR:
17472 case OPC_NOR:
17473 case OPC_XOR:
17474 gen_logic(ctx, op1, rd, rs, rt);
17475 break;
0aefa333 17476 case OPC_JALR:
b231c103 17477 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
17478 break;
17479 case OPC_TGE ... OPC_TEQ: /* Traps */
17480 case OPC_TNE:
d9224450 17481 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17482 gen_trap(ctx, op1, rs, rt, -1);
17483 break;
d4ea6acd 17484 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17485 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17486 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17487 decode_opc_special_r6(env, ctx);
17488 } else {
17489 /* Pmon entry point, also R4010 selsl */
b48cfdff 17490#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17491 MIPS_INVAL("PMON / selsl");
9c708c7f 17492 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17493#else
d4ea6acd 17494 gen_helper_0e0i(pmon, sa);
b48cfdff 17495#endif
d4ea6acd 17496 }
099e5b4d
LA
17497 break;
17498 case OPC_SYSCALL:
9c708c7f 17499 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17500 break;
17501 case OPC_BREAK:
9c708c7f 17502 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17503 break;
099e5b4d 17504 case OPC_SYNC:
d9224450 17505 check_insn(ctx, ISA_MIPS2);
d208ac0c 17506 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 17507 break;
4ad40f36 17508
d26bc211 17509#if defined(TARGET_MIPS64)
099e5b4d
LA
17510 /* MIPS64 specific opcodes */
17511 case OPC_DSLL:
17512 case OPC_DSRA:
17513 case OPC_DSLL32:
17514 case OPC_DSRA32:
17515 check_insn(ctx, ISA_MIPS3);
17516 check_mips_64(ctx);
17517 gen_shift_imm(ctx, op1, rd, rt, sa);
17518 break;
17519 case OPC_DSRL:
17520 switch ((ctx->opcode >> 21) & 0x1f) {
17521 case 1:
17522 /* drotr is decoded as dsrl on non-R2 CPUs */
17523 if (ctx->insn_flags & ISA_MIPS32R2) {
17524 op1 = OPC_DROTR;
ea63e2c3 17525 }
099e5b4d
LA
17526 /* Fallthrough */
17527 case 0:
d75c135e 17528 check_insn(ctx, ISA_MIPS3);
e189e748 17529 check_mips_64(ctx);
099e5b4d 17530 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17531 break;
099e5b4d 17532 default:
9c708c7f 17533 generate_exception_end(ctx, EXCP_RI);
460f00c4 17534 break;
099e5b4d
LA
17535 }
17536 break;
17537 case OPC_DSRL32:
17538 switch ((ctx->opcode >> 21) & 0x1f) {
17539 case 1:
17540 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17541 if (ctx->insn_flags & ISA_MIPS32R2) {
17542 op1 = OPC_DROTR32;
ea63e2c3 17543 }
099e5b4d
LA
17544 /* Fallthrough */
17545 case 0:
d75c135e 17546 check_insn(ctx, ISA_MIPS3);
e189e748 17547 check_mips_64(ctx);
099e5b4d 17548 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17549 break;
099e5b4d 17550 default:
9c708c7f 17551 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17552 break;
17553 }
17554 break;
099e5b4d
LA
17555 case OPC_DADD ... OPC_DSUBU:
17556 check_insn(ctx, ISA_MIPS3);
17557 check_mips_64(ctx);
17558 gen_arith(ctx, op1, rd, rs, rt);
17559 break;
17560 case OPC_DSLLV:
17561 case OPC_DSRAV:
17562 check_insn(ctx, ISA_MIPS3);
17563 check_mips_64(ctx);
17564 gen_shift(ctx, op1, rd, rs, rt);
17565 break;
17566 case OPC_DSRLV:
17567 switch ((ctx->opcode >> 6) & 0x1f) {
17568 case 1:
17569 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17570 if (ctx->insn_flags & ISA_MIPS32R2) {
17571 op1 = OPC_DROTRV;
6af0bf9c 17572 }
099e5b4d
LA
17573 /* Fallthrough */
17574 case 0:
17575 check_insn(ctx, ISA_MIPS3);
e189e748 17576 check_mips_64(ctx);
099e5b4d 17577 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17578 break;
099e5b4d 17579 default:
9c708c7f 17580 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17581 break;
17582 }
17583 break;
f7685877
YK
17584 case OPC_DLSA:
17585 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17586 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17587 decode_opc_special_r6(env, ctx);
17588 }
17589 break;
099e5b4d 17590#endif
10dc65db
LA
17591 default:
17592 if (ctx->insn_flags & ISA_MIPS32R6) {
17593 decode_opc_special_r6(env, ctx);
17594 } else {
17595 decode_opc_special_legacy(env, ctx);
17596 }
17597 }
17598}
17599
10dc65db 17600static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17601{
17602 int rs, rt, rd;
17603 uint32_t op1;
6c5c1e20 17604
4267d3e6
LA
17605 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17606
099e5b4d
LA
17607 rs = (ctx->opcode >> 21) & 0x1f;
17608 rt = (ctx->opcode >> 16) & 0x1f;
17609 rd = (ctx->opcode >> 11) & 0x1f;
17610
17611 op1 = MASK_SPECIAL2(ctx->opcode);
17612 switch (op1) {
17613 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17614 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17615 check_insn(ctx, ISA_MIPS32);
17616 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17617 break;
17618 case OPC_MUL:
099e5b4d
LA
17619 gen_arith(ctx, op1, rd, rs, rt);
17620 break;
fac5a073
LA
17621 case OPC_DIV_G_2F:
17622 case OPC_DIVU_G_2F:
17623 case OPC_MULT_G_2F:
17624 case OPC_MULTU_G_2F:
17625 case OPC_MOD_G_2F:
17626 case OPC_MODU_G_2F:
17627 check_insn(ctx, INSN_LOONGSON2F);
17628 gen_loongson_integer(ctx, op1, rd, rs, rt);
17629 break;
099e5b4d
LA
17630 case OPC_CLO:
17631 case OPC_CLZ:
17632 check_insn(ctx, ISA_MIPS32);
17633 gen_cl(ctx, op1, rd, rs);
17634 break;
17635 case OPC_SDBBP:
3b3c1694
LA
17636 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17637 gen_helper_do_semihosting(cpu_env);
17638 } else {
17639 /* XXX: not clear which exception should be raised
17640 * when in debug mode...
17641 */
17642 check_insn(ctx, ISA_MIPS32);
9c708c7f 17643 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17644 }
099e5b4d 17645 break;
9b1a1d68 17646#if defined(TARGET_MIPS64)
099e5b4d
LA
17647 case OPC_DCLO:
17648 case OPC_DCLZ:
17649 check_insn(ctx, ISA_MIPS64);
17650 check_mips_64(ctx);
17651 gen_cl(ctx, op1, rd, rs);
17652 break;
4267d3e6
LA
17653 case OPC_DMULT_G_2F:
17654 case OPC_DMULTU_G_2F:
17655 case OPC_DDIV_G_2F:
17656 case OPC_DDIVU_G_2F:
17657 case OPC_DMOD_G_2F:
17658 case OPC_DMODU_G_2F:
17659 check_insn(ctx, INSN_LOONGSON2F);
17660 gen_loongson_integer(ctx, op1, rd, rs, rt);
17661 break;
10dc65db 17662#endif
4267d3e6
LA
17663 default: /* Invalid */
17664 MIPS_INVAL("special2_legacy");
9c708c7f 17665 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17666 break;
10dc65db
LA
17667 }
17668}
17669
17670static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17671{
15eacb9b
YK
17672 int rs, rt, rd, sa;
17673 uint32_t op1, op2;
10dc65db
LA
17674 int16_t imm;
17675
17676 rs = (ctx->opcode >> 21) & 0x1f;
17677 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17678 rd = (ctx->opcode >> 11) & 0x1f;
17679 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17680 imm = (int16_t)ctx->opcode >> 7;
17681
17682 op1 = MASK_SPECIAL3(ctx->opcode);
17683 switch (op1) {
bf7910c6
LA
17684 case R6_OPC_PREF:
17685 if (rt >= 24) {
17686 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17687 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17688 }
17689 /* Treat as NOP. */
17690 break;
17691 case R6_OPC_CACHE:
40d48212 17692 check_cp0_enabled(ctx);
0d74a222
LA
17693 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17694 gen_cache_operation(ctx, rt, rs, imm);
17695 }
bf7910c6 17696 break;
10dc65db
LA
17697 case R6_OPC_SC:
17698 gen_st_cond(ctx, op1, rt, rs, imm);
17699 break;
17700 case R6_OPC_LL:
17701 gen_ld(ctx, op1, rt, rs, imm);
17702 break;
15eacb9b
YK
17703 case OPC_BSHFL:
17704 {
17705 if (rd == 0) {
17706 /* Treat as NOP. */
17707 break;
17708 }
15eacb9b
YK
17709 op2 = MASK_BSHFL(ctx->opcode);
17710 switch (op2) {
17711 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17712 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17713 break;
17714 case OPC_BITSWAP:
1f1b4c00 17715 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17716 break;
17717 }
15eacb9b
YK
17718 }
17719 break;
bf7910c6
LA
17720#if defined(TARGET_MIPS64)
17721 case R6_OPC_SCD:
17722 gen_st_cond(ctx, op1, rt, rs, imm);
17723 break;
17724 case R6_OPC_LLD:
17725 gen_ld(ctx, op1, rt, rs, imm);
17726 break;
15eacb9b
YK
17727 case OPC_DBSHFL:
17728 check_mips_64(ctx);
17729 {
17730 if (rd == 0) {
17731 /* Treat as NOP. */
17732 break;
17733 }
15eacb9b
YK
17734 op2 = MASK_DBSHFL(ctx->opcode);
17735 switch (op2) {
17736 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17737 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17738 break;
17739 case OPC_DBITSWAP:
1f1b4c00 17740 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17741 break;
17742 }
1f1b4c00 17743
15eacb9b
YK
17744 }
17745 break;
bf7910c6 17746#endif
10dc65db
LA
17747 default: /* Invalid */
17748 MIPS_INVAL("special3_r6");
9c708c7f 17749 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17750 break;
17751 }
17752}
17753
17754static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17755{
fac5a073 17756 int rs, rt, rd;
099e5b4d 17757 uint32_t op1, op2;
099e5b4d
LA
17758
17759 rs = (ctx->opcode >> 21) & 0x1f;
17760 rt = (ctx->opcode >> 16) & 0x1f;
17761 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17762
17763 op1 = MASK_SPECIAL3(ctx->opcode);
17764 switch (op1) {
099e5b4d
LA
17765 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17766 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17767 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17768 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17769 * the same mask and op1. */
17770 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17771 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17772 switch (op2) {
099e5b4d
LA
17773 case OPC_ADDUH_QB:
17774 case OPC_ADDUH_R_QB:
17775 case OPC_ADDQH_PH:
17776 case OPC_ADDQH_R_PH:
17777 case OPC_ADDQH_W:
17778 case OPC_ADDQH_R_W:
17779 case OPC_SUBUH_QB:
17780 case OPC_SUBUH_R_QB:
17781 case OPC_SUBQH_PH:
17782 case OPC_SUBQH_R_PH:
17783 case OPC_SUBQH_W:
17784 case OPC_SUBQH_R_W:
461c08df
JL
17785 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17786 break;
099e5b4d
LA
17787 case OPC_MUL_PH:
17788 case OPC_MUL_S_PH:
17789 case OPC_MULQ_S_W:
17790 case OPC_MULQ_RS_W:
17791 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17792 break;
461c08df 17793 default:
099e5b4d 17794 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17795 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17796 break;
17797 }
099e5b4d
LA
17798 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17799 gen_loongson_integer(ctx, op1, rd, rs, rt);
17800 } else {
9c708c7f 17801 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17802 }
17803 break;
17804 case OPC_LX_DSP:
17805 op2 = MASK_LX(ctx->opcode);
17806 switch (op2) {
17807#if defined(TARGET_MIPS64)
17808 case OPC_LDX:
17809#endif
17810 case OPC_LBUX:
17811 case OPC_LHX:
17812 case OPC_LWX:
17813 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17814 break;
17815 default: /* Invalid */
17816 MIPS_INVAL("MASK LX");
9c708c7f 17817 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17818 break;
17819 }
17820 break;
17821 case OPC_ABSQ_S_PH_DSP:
17822 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17823 switch (op2) {
17824 case OPC_ABSQ_S_QB:
17825 case OPC_ABSQ_S_PH:
17826 case OPC_ABSQ_S_W:
17827 case OPC_PRECEQ_W_PHL:
17828 case OPC_PRECEQ_W_PHR:
17829 case OPC_PRECEQU_PH_QBL:
17830 case OPC_PRECEQU_PH_QBR:
17831 case OPC_PRECEQU_PH_QBLA:
17832 case OPC_PRECEQU_PH_QBRA:
17833 case OPC_PRECEU_PH_QBL:
17834 case OPC_PRECEU_PH_QBR:
17835 case OPC_PRECEU_PH_QBLA:
17836 case OPC_PRECEU_PH_QBRA:
17837 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17838 break;
17839 case OPC_BITREV:
17840 case OPC_REPL_QB:
17841 case OPC_REPLV_QB:
17842 case OPC_REPL_PH:
17843 case OPC_REPLV_PH:
17844 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17845 break;
17846 default:
17847 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17848 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17849 break;
17850 }
17851 break;
17852 case OPC_ADDU_QB_DSP:
17853 op2 = MASK_ADDU_QB(ctx->opcode);
17854 switch (op2) {
17855 case OPC_ADDQ_PH:
17856 case OPC_ADDQ_S_PH:
17857 case OPC_ADDQ_S_W:
17858 case OPC_ADDU_QB:
17859 case OPC_ADDU_S_QB:
17860 case OPC_ADDU_PH:
17861 case OPC_ADDU_S_PH:
17862 case OPC_SUBQ_PH:
17863 case OPC_SUBQ_S_PH:
17864 case OPC_SUBQ_S_W:
17865 case OPC_SUBU_QB:
17866 case OPC_SUBU_S_QB:
17867 case OPC_SUBU_PH:
17868 case OPC_SUBU_S_PH:
17869 case OPC_ADDSC:
17870 case OPC_ADDWC:
17871 case OPC_MODSUB:
17872 case OPC_RADDU_W_QB:
17873 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17874 break;
17875 case OPC_MULEU_S_PH_QBL:
17876 case OPC_MULEU_S_PH_QBR:
17877 case OPC_MULQ_RS_PH:
17878 case OPC_MULEQ_S_W_PHL:
17879 case OPC_MULEQ_S_W_PHR:
17880 case OPC_MULQ_S_PH:
17881 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17882 break;
17883 default: /* Invalid */
17884 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17885 generate_exception_end(ctx, EXCP_RI);
461c08df 17886 break;
461c08df 17887
099e5b4d
LA
17888 }
17889 break;
17890 case OPC_CMPU_EQ_QB_DSP:
17891 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17892 switch (op2) {
17893 case OPC_PRECR_SRA_PH_W:
17894 case OPC_PRECR_SRA_R_PH_W:
17895 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17896 break;
099e5b4d
LA
17897 case OPC_PRECR_QB_PH:
17898 case OPC_PRECRQ_QB_PH:
17899 case OPC_PRECRQ_PH_W:
17900 case OPC_PRECRQ_RS_PH_W:
17901 case OPC_PRECRQU_S_QB_PH:
17902 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17903 break;
099e5b4d
LA
17904 case OPC_CMPU_EQ_QB:
17905 case OPC_CMPU_LT_QB:
17906 case OPC_CMPU_LE_QB:
17907 case OPC_CMP_EQ_PH:
17908 case OPC_CMP_LT_PH:
17909 case OPC_CMP_LE_PH:
17910 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17911 break;
099e5b4d
LA
17912 case OPC_CMPGU_EQ_QB:
17913 case OPC_CMPGU_LT_QB:
17914 case OPC_CMPGU_LE_QB:
17915 case OPC_CMPGDU_EQ_QB:
17916 case OPC_CMPGDU_LT_QB:
17917 case OPC_CMPGDU_LE_QB:
17918 case OPC_PICK_QB:
17919 case OPC_PICK_PH:
17920 case OPC_PACKRL_PH:
17921 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17922 break;
17923 default: /* Invalid */
17924 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17925 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17926 break;
17927 }
17928 break;
17929 case OPC_SHLL_QB_DSP:
17930 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17931 break;
17932 case OPC_DPA_W_PH_DSP:
17933 op2 = MASK_DPA_W_PH(ctx->opcode);
17934 switch (op2) {
17935 case OPC_DPAU_H_QBL:
17936 case OPC_DPAU_H_QBR:
17937 case OPC_DPSU_H_QBL:
17938 case OPC_DPSU_H_QBR:
17939 case OPC_DPA_W_PH:
17940 case OPC_DPAX_W_PH:
17941 case OPC_DPAQ_S_W_PH:
17942 case OPC_DPAQX_S_W_PH:
17943 case OPC_DPAQX_SA_W_PH:
17944 case OPC_DPS_W_PH:
17945 case OPC_DPSX_W_PH:
17946 case OPC_DPSQ_S_W_PH:
17947 case OPC_DPSQX_S_W_PH:
17948 case OPC_DPSQX_SA_W_PH:
17949 case OPC_MULSAQ_S_W_PH:
17950 case OPC_DPAQ_SA_L_W:
17951 case OPC_DPSQ_SA_L_W:
17952 case OPC_MAQ_S_W_PHL:
17953 case OPC_MAQ_S_W_PHR:
17954 case OPC_MAQ_SA_W_PHL:
17955 case OPC_MAQ_SA_W_PHR:
17956 case OPC_MULSA_W_PH:
17957 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17958 break;
17959 default: /* Invalid */
17960 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17961 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17962 break;
17963 }
17964 break;
17965 case OPC_INSV_DSP:
17966 op2 = MASK_INSV(ctx->opcode);
17967 switch (op2) {
17968 case OPC_INSV:
17969 check_dsp(ctx);
17970 {
17971 TCGv t0, t1;
17972
17973 if (rt == 0) {
099e5b4d
LA
17974 break;
17975 }
17976
17977 t0 = tcg_temp_new();
17978 t1 = tcg_temp_new();
17979
17980 gen_load_gpr(t0, rt);
17981 gen_load_gpr(t1, rs);
17982
17983 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17984
17985 tcg_temp_free(t0);
17986 tcg_temp_free(t1);
a22260ae
JL
17987 break;
17988 }
099e5b4d
LA
17989 default: /* Invalid */
17990 MIPS_INVAL("MASK INSV");
9c708c7f 17991 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17992 break;
17993 }
17994 break;
17995 case OPC_APPEND_DSP:
17996 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17997 break;
17998 case OPC_EXTR_W_DSP:
17999 op2 = MASK_EXTR_W(ctx->opcode);
18000 switch (op2) {
18001 case OPC_EXTR_W:
18002 case OPC_EXTR_R_W:
18003 case OPC_EXTR_RS_W:
18004 case OPC_EXTR_S_H:
18005 case OPC_EXTRV_S_H:
18006 case OPC_EXTRV_W:
18007 case OPC_EXTRV_R_W:
18008 case OPC_EXTRV_RS_W:
18009 case OPC_EXTP:
18010 case OPC_EXTPV:
18011 case OPC_EXTPDP:
18012 case OPC_EXTPDPV:
18013 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18014 break;
18015 case OPC_RDDSP:
18016 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
18017 break;
18018 case OPC_SHILO:
18019 case OPC_SHILOV:
18020 case OPC_MTHLIP:
18021 case OPC_WRDSP:
18022 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18023 break;
18024 default: /* Invalid */
18025 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18026 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18027 break;
18028 }
18029 break;
099e5b4d 18030#if defined(TARGET_MIPS64)
fac5a073
LA
18031 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
18032 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
18033 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
18034 check_insn(ctx, INSN_LOONGSON2E);
18035 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 18036 break;
099e5b4d
LA
18037 case OPC_ABSQ_S_QH_DSP:
18038 op2 = MASK_ABSQ_S_QH(ctx->opcode);
18039 switch (op2) {
18040 case OPC_PRECEQ_L_PWL:
18041 case OPC_PRECEQ_L_PWR:
18042 case OPC_PRECEQ_PW_QHL:
18043 case OPC_PRECEQ_PW_QHR:
18044 case OPC_PRECEQ_PW_QHLA:
18045 case OPC_PRECEQ_PW_QHRA:
18046 case OPC_PRECEQU_QH_OBL:
18047 case OPC_PRECEQU_QH_OBR:
18048 case OPC_PRECEQU_QH_OBLA:
18049 case OPC_PRECEQU_QH_OBRA:
18050 case OPC_PRECEU_QH_OBL:
18051 case OPC_PRECEU_QH_OBR:
18052 case OPC_PRECEU_QH_OBLA:
18053 case OPC_PRECEU_QH_OBRA:
18054 case OPC_ABSQ_S_OB:
18055 case OPC_ABSQ_S_PW:
18056 case OPC_ABSQ_S_QH:
18057 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18058 break;
18059 case OPC_REPL_OB:
18060 case OPC_REPL_PW:
18061 case OPC_REPL_QH:
18062 case OPC_REPLV_OB:
18063 case OPC_REPLV_PW:
18064 case OPC_REPLV_QH:
18065 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18066 break;
18067 default: /* Invalid */
18068 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 18069 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18070 break;
18071 }
18072 break;
18073 case OPC_ADDU_OB_DSP:
18074 op2 = MASK_ADDU_OB(ctx->opcode);
18075 switch (op2) {
18076 case OPC_RADDU_L_OB:
18077 case OPC_SUBQ_PW:
18078 case OPC_SUBQ_S_PW:
18079 case OPC_SUBQ_QH:
18080 case OPC_SUBQ_S_QH:
18081 case OPC_SUBU_OB:
18082 case OPC_SUBU_S_OB:
18083 case OPC_SUBU_QH:
18084 case OPC_SUBU_S_QH:
18085 case OPC_SUBUH_OB:
18086 case OPC_SUBUH_R_OB:
18087 case OPC_ADDQ_PW:
18088 case OPC_ADDQ_S_PW:
18089 case OPC_ADDQ_QH:
18090 case OPC_ADDQ_S_QH:
18091 case OPC_ADDU_OB:
18092 case OPC_ADDU_S_OB:
18093 case OPC_ADDU_QH:
18094 case OPC_ADDU_S_QH:
18095 case OPC_ADDUH_OB:
18096 case OPC_ADDUH_R_OB:
18097 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 18098 break;
099e5b4d
LA
18099 case OPC_MULEQ_S_PW_QHL:
18100 case OPC_MULEQ_S_PW_QHR:
18101 case OPC_MULEU_S_QH_OBL:
18102 case OPC_MULEU_S_QH_OBR:
18103 case OPC_MULQ_RS_QH:
18104 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 18105 break;
099e5b4d
LA
18106 default: /* Invalid */
18107 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 18108 generate_exception_end(ctx, EXCP_RI);
26690560 18109 break;
099e5b4d
LA
18110 }
18111 break;
18112 case OPC_CMPU_EQ_OB_DSP:
18113 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18114 switch (op2) {
18115 case OPC_PRECR_SRA_QH_PW:
18116 case OPC_PRECR_SRA_R_QH_PW:
18117 /* Return value is rt. */
18118 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 18119 break;
099e5b4d
LA
18120 case OPC_PRECR_OB_QH:
18121 case OPC_PRECRQ_OB_QH:
18122 case OPC_PRECRQ_PW_L:
18123 case OPC_PRECRQ_QH_PW:
18124 case OPC_PRECRQ_RS_QH_PW:
18125 case OPC_PRECRQU_S_OB_QH:
18126 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 18127 break;
099e5b4d
LA
18128 case OPC_CMPU_EQ_OB:
18129 case OPC_CMPU_LT_OB:
18130 case OPC_CMPU_LE_OB:
18131 case OPC_CMP_EQ_QH:
18132 case OPC_CMP_LT_QH:
18133 case OPC_CMP_LE_QH:
18134 case OPC_CMP_EQ_PW:
18135 case OPC_CMP_LT_PW:
18136 case OPC_CMP_LE_PW:
18137 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 18138 break;
099e5b4d
LA
18139 case OPC_CMPGDU_EQ_OB:
18140 case OPC_CMPGDU_LT_OB:
18141 case OPC_CMPGDU_LE_OB:
18142 case OPC_CMPGU_EQ_OB:
18143 case OPC_CMPGU_LT_OB:
18144 case OPC_CMPGU_LE_OB:
18145 case OPC_PACKRL_PW:
18146 case OPC_PICK_OB:
18147 case OPC_PICK_PW:
18148 case OPC_PICK_QH:
18149 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 18150 break;
099e5b4d
LA
18151 default: /* Invalid */
18152 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 18153 generate_exception_end(ctx, EXCP_RI);
161f85e6 18154 break;
099e5b4d
LA
18155 }
18156 break;
18157 case OPC_DAPPEND_DSP:
18158 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18159 break;
18160 case OPC_DEXTR_W_DSP:
18161 op2 = MASK_DEXTR_W(ctx->opcode);
18162 switch (op2) {
18163 case OPC_DEXTP:
18164 case OPC_DEXTPDP:
18165 case OPC_DEXTPDPV:
18166 case OPC_DEXTPV:
18167 case OPC_DEXTR_L:
18168 case OPC_DEXTR_R_L:
18169 case OPC_DEXTR_RS_L:
18170 case OPC_DEXTR_W:
18171 case OPC_DEXTR_R_W:
18172 case OPC_DEXTR_RS_W:
18173 case OPC_DEXTR_S_H:
18174 case OPC_DEXTRV_L:
18175 case OPC_DEXTRV_R_L:
18176 case OPC_DEXTRV_RS_L:
18177 case OPC_DEXTRV_S_H:
18178 case OPC_DEXTRV_W:
18179 case OPC_DEXTRV_R_W:
18180 case OPC_DEXTRV_RS_W:
18181 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 18182 break;
099e5b4d
LA
18183 case OPC_DMTHLIP:
18184 case OPC_DSHILO:
18185 case OPC_DSHILOV:
18186 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 18187 break;
099e5b4d
LA
18188 default: /* Invalid */
18189 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18190 generate_exception_end(ctx, EXCP_RI);
461c08df 18191 break;
099e5b4d
LA
18192 }
18193 break;
18194 case OPC_DPAQ_W_QH_DSP:
18195 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18196 switch (op2) {
18197 case OPC_DPAU_H_OBL:
18198 case OPC_DPAU_H_OBR:
18199 case OPC_DPSU_H_OBL:
18200 case OPC_DPSU_H_OBR:
18201 case OPC_DPA_W_QH:
18202 case OPC_DPAQ_S_W_QH:
18203 case OPC_DPS_W_QH:
18204 case OPC_DPSQ_S_W_QH:
18205 case OPC_MULSAQ_S_W_QH:
18206 case OPC_DPAQ_SA_L_PW:
18207 case OPC_DPSQ_SA_L_PW:
18208 case OPC_MULSAQ_S_L_PW:
18209 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18210 break;
18211 case OPC_MAQ_S_W_QHLL:
18212 case OPC_MAQ_S_W_QHLR:
18213 case OPC_MAQ_S_W_QHRL:
18214 case OPC_MAQ_S_W_QHRR:
18215 case OPC_MAQ_SA_W_QHLL:
18216 case OPC_MAQ_SA_W_QHLR:
18217 case OPC_MAQ_SA_W_QHRL:
18218 case OPC_MAQ_SA_W_QHRR:
18219 case OPC_MAQ_S_L_PWL:
18220 case OPC_MAQ_S_L_PWR:
18221 case OPC_DMADD:
18222 case OPC_DMADDU:
18223 case OPC_DMSUB:
18224 case OPC_DMSUBU:
18225 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 18226 break;
099e5b4d
LA
18227 default: /* Invalid */
18228 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 18229 generate_exception_end(ctx, EXCP_RI);
b53371ed 18230 break;
099e5b4d
LA
18231 }
18232 break;
18233 case OPC_DINSV_DSP:
18234 op2 = MASK_INSV(ctx->opcode);
18235 switch (op2) {
18236 case OPC_DINSV:
18237 {
18238 TCGv t0, t1;
18239
18240 if (rt == 0) {
a22260ae
JL
18241 break;
18242 }
099e5b4d 18243 check_dsp(ctx);
1cb6686c 18244
099e5b4d
LA
18245 t0 = tcg_temp_new();
18246 t1 = tcg_temp_new();
1cb6686c 18247
099e5b4d
LA
18248 gen_load_gpr(t0, rt);
18249 gen_load_gpr(t1, rs);
1cb6686c 18250
099e5b4d 18251 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 18252
099e5b4d
LA
18253 tcg_temp_free(t0);
18254 tcg_temp_free(t1);
77c5fa8b 18255 break;
099e5b4d 18256 }
7a387fff 18257 default: /* Invalid */
099e5b4d 18258 MIPS_INVAL("MASK DINSV");
9c708c7f 18259 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
18260 break;
18261 }
18262 break;
099e5b4d
LA
18263 case OPC_SHLL_OB_DSP:
18264 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18265 break;
18266#endif
fac5a073
LA
18267 default: /* Invalid */
18268 MIPS_INVAL("special3_legacy");
9c708c7f 18269 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
18270 break;
18271 }
18272}
18273
18274static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18275{
18276 int rs, rt, rd, sa;
18277 uint32_t op1, op2;
76964147 18278 int16_t imm;
fac5a073
LA
18279
18280 rs = (ctx->opcode >> 21) & 0x1f;
18281 rt = (ctx->opcode >> 16) & 0x1f;
18282 rd = (ctx->opcode >> 11) & 0x1f;
18283 sa = (ctx->opcode >> 6) & 0x1f;
76964147 18284 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
18285
18286 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
18287
18288 /*
18289 * EVA loads and stores overlap Loongson 2E instructions decoded by
18290 * decode_opc_special3_legacy(), so be careful to allow their decoding when
18291 * EVA is absent.
18292 */
18293 if (ctx->eva) {
18294 switch (op1) {
18295 case OPC_LWLE ... OPC_LWRE:
18296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18297 /* fall through */
18298 case OPC_LBUE ... OPC_LHUE:
18299 case OPC_LBE ... OPC_LWE:
18300 check_cp0_enabled(ctx);
18301 gen_ld(ctx, op1, rt, rs, imm);
18302 return;
18303 case OPC_SWLE ... OPC_SWRE:
18304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18305 /* fall through */
18306 case OPC_SBE ... OPC_SHE:
18307 case OPC_SWE:
18308 check_cp0_enabled(ctx);
18309 gen_st(ctx, op1, rt, rs, imm);
18310 return;
18311 case OPC_SCE:
18312 check_cp0_enabled(ctx);
18313 gen_st_cond(ctx, op1, rt, rs, imm);
18314 return;
18315 case OPC_CACHEE:
18316 check_cp0_enabled(ctx);
18317 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18318 gen_cache_operation(ctx, rt, rs, imm);
18319 }
18320 /* Treat as NOP. */
18321 return;
18322 case OPC_PREFE:
18323 check_cp0_enabled(ctx);
18324 /* Treat as NOP. */
18325 return;
18326 }
18327 }
18328
fac5a073
LA
18329 switch (op1) {
18330 case OPC_EXT:
18331 case OPC_INS:
18332 check_insn(ctx, ISA_MIPS32R2);
18333 gen_bitops(ctx, op1, rt, rs, sa, rd);
18334 break;
18335 case OPC_BSHFL:
fac5a073 18336 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
18337 switch (op2) {
18338 case OPC_ALIGN ... OPC_ALIGN_END:
18339 case OPC_BITSWAP:
18340 check_insn(ctx, ISA_MIPS32R6);
18341 decode_opc_special3_r6(env, ctx);
18342 break;
18343 default:
18344 check_insn(ctx, ISA_MIPS32R2);
18345 gen_bshfl(ctx, op2, rt, rd);
18346 break;
18347 }
fac5a073
LA
18348 break;
18349#if defined(TARGET_MIPS64)
18350 case OPC_DEXTM ... OPC_DEXT:
18351 case OPC_DINSM ... OPC_DINS:
18352 check_insn(ctx, ISA_MIPS64R2);
18353 check_mips_64(ctx);
18354 gen_bitops(ctx, op1, rt, rs, sa, rd);
18355 break;
18356 case OPC_DBSHFL:
fac5a073 18357 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
18358 switch (op2) {
18359 case OPC_DALIGN ... OPC_DALIGN_END:
18360 case OPC_DBITSWAP:
18361 check_insn(ctx, ISA_MIPS32R6);
18362 decode_opc_special3_r6(env, ctx);
18363 break;
18364 default:
18365 check_insn(ctx, ISA_MIPS64R2);
18366 check_mips_64(ctx);
18367 op2 = MASK_DBSHFL(ctx->opcode);
18368 gen_bshfl(ctx, op2, rt, rd);
18369 break;
18370 }
fac5a073
LA
18371 break;
18372#endif
18373 case OPC_RDHWR:
b00c7218 18374 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18375 break;
18376 case OPC_FORK:
18377 check_insn(ctx, ASE_MT);
18378 {
18379 TCGv t0 = tcg_temp_new();
18380 TCGv t1 = tcg_temp_new();
18381
18382 gen_load_gpr(t0, rt);
18383 gen_load_gpr(t1, rs);
18384 gen_helper_fork(t0, t1);
18385 tcg_temp_free(t0);
18386 tcg_temp_free(t1);
18387 }
18388 break;
18389 case OPC_YIELD:
18390 check_insn(ctx, ASE_MT);
18391 {
18392 TCGv t0 = tcg_temp_new();
18393
fac5a073
LA
18394 gen_load_gpr(t0, rs);
18395 gen_helper_yield(t0, cpu_env, t0);
18396 gen_store_gpr(t0, rd);
18397 tcg_temp_free(t0);
18398 }
18399 break;
10dc65db
LA
18400 default:
18401 if (ctx->insn_flags & ISA_MIPS32R6) {
18402 decode_opc_special3_r6(env, ctx);
18403 } else {
18404 decode_opc_special3_legacy(env, ctx);
18405 }
099e5b4d
LA
18406 }
18407}
18408
863f264d
YK
18409/* MIPS SIMD Architecture (MSA) */
18410static inline int check_msa_access(DisasContext *ctx)
18411{
18412 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18413 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18414 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18415 return 0;
18416 }
18417
18418 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18419 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18420 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18421 return 0;
18422 } else {
9c708c7f 18423 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18424 return 0;
18425 }
18426 }
18427 return 1;
18428}
18429
5692c6e1
YK
18430static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18431{
18432 /* generates tcg ops to check if any element is 0 */
18433 /* Note this function only works with MSA_WRLEN = 128 */
18434 uint64_t eval_zero_or_big = 0;
18435 uint64_t eval_big = 0;
18436 TCGv_i64 t0 = tcg_temp_new_i64();
18437 TCGv_i64 t1 = tcg_temp_new_i64();
18438 switch (df) {
18439 case DF_BYTE:
18440 eval_zero_or_big = 0x0101010101010101ULL;
18441 eval_big = 0x8080808080808080ULL;
18442 break;
18443 case DF_HALF:
18444 eval_zero_or_big = 0x0001000100010001ULL;
18445 eval_big = 0x8000800080008000ULL;
18446 break;
18447 case DF_WORD:
18448 eval_zero_or_big = 0x0000000100000001ULL;
18449 eval_big = 0x8000000080000000ULL;
18450 break;
18451 case DF_DOUBLE:
18452 eval_zero_or_big = 0x0000000000000001ULL;
18453 eval_big = 0x8000000000000000ULL;
18454 break;
18455 }
18456 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18457 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18458 tcg_gen_andi_i64(t0, t0, eval_big);
18459 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18460 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18461 tcg_gen_andi_i64(t1, t1, eval_big);
18462 tcg_gen_or_i64(t0, t0, t1);
18463 /* if all bits are zero then all elements are not zero */
18464 /* if some bit is non-zero then some element is zero */
18465 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18466 tcg_gen_trunc_i64_tl(tresult, t0);
18467 tcg_temp_free_i64(t0);
18468 tcg_temp_free_i64(t1);
18469}
18470
18471static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18472{
18473 uint8_t df = (ctx->opcode >> 21) & 0x3;
18474 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18475 int64_t s16 = (int16_t)ctx->opcode;
18476
18477 check_msa_access(ctx);
18478
075a1fe7 18479 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18480 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18481 return;
18482 }
18483 switch (op1) {
18484 case OPC_BZ_V:
18485 case OPC_BNZ_V:
18486 {
18487 TCGv_i64 t0 = tcg_temp_new_i64();
18488 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18489 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18490 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18491 tcg_gen_trunc_i64_tl(bcond, t0);
18492 tcg_temp_free_i64(t0);
18493 }
18494 break;
18495 case OPC_BZ_B:
18496 case OPC_BZ_H:
18497 case OPC_BZ_W:
18498 case OPC_BZ_D:
18499 gen_check_zero_element(bcond, df, wt);
18500 break;
18501 case OPC_BNZ_B:
18502 case OPC_BNZ_H:
18503 case OPC_BNZ_W:
18504 case OPC_BNZ_D:
18505 gen_check_zero_element(bcond, df, wt);
18506 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18507 break;
18508 }
18509
18510 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18511
18512 ctx->hflags |= MIPS_HFLAG_BC;
18513 ctx->hflags |= MIPS_HFLAG_BDS32;
18514}
18515
4c789546
YK
18516static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18517{
18518#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18519 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18520 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18521 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18522
18523 TCGv_i32 twd = tcg_const_i32(wd);
18524 TCGv_i32 tws = tcg_const_i32(ws);
18525 TCGv_i32 ti8 = tcg_const_i32(i8);
18526
18527 switch (MASK_MSA_I8(ctx->opcode)) {
18528 case OPC_ANDI_B:
18529 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18530 break;
18531 case OPC_ORI_B:
18532 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18533 break;
18534 case OPC_NORI_B:
18535 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18536 break;
18537 case OPC_XORI_B:
18538 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18539 break;
18540 case OPC_BMNZI_B:
18541 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18542 break;
18543 case OPC_BMZI_B:
18544 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18545 break;
18546 case OPC_BSELI_B:
18547 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18548 break;
18549 case OPC_SHF_B:
18550 case OPC_SHF_H:
18551 case OPC_SHF_W:
18552 {
18553 uint8_t df = (ctx->opcode >> 24) & 0x3;
18554 if (df == DF_DOUBLE) {
9c708c7f 18555 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18556 } else {
18557 TCGv_i32 tdf = tcg_const_i32(df);
18558 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18559 tcg_temp_free_i32(tdf);
18560 }
18561 }
18562 break;
18563 default:
18564 MIPS_INVAL("MSA instruction");
9c708c7f 18565 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18566 break;
18567 }
18568
18569 tcg_temp_free_i32(twd);
18570 tcg_temp_free_i32(tws);
18571 tcg_temp_free_i32(ti8);
18572}
18573
80e71591
YK
18574static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18575{
18576#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18577 uint8_t df = (ctx->opcode >> 21) & 0x3;
18578 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18579 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18580 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18581 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18582
18583 TCGv_i32 tdf = tcg_const_i32(df);
18584 TCGv_i32 twd = tcg_const_i32(wd);
18585 TCGv_i32 tws = tcg_const_i32(ws);
18586 TCGv_i32 timm = tcg_temp_new_i32();
18587 tcg_gen_movi_i32(timm, u5);
18588
18589 switch (MASK_MSA_I5(ctx->opcode)) {
18590 case OPC_ADDVI_df:
18591 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18592 break;
18593 case OPC_SUBVI_df:
18594 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18595 break;
18596 case OPC_MAXI_S_df:
18597 tcg_gen_movi_i32(timm, s5);
18598 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18599 break;
18600 case OPC_MAXI_U_df:
18601 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18602 break;
18603 case OPC_MINI_S_df:
18604 tcg_gen_movi_i32(timm, s5);
18605 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18606 break;
18607 case OPC_MINI_U_df:
18608 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18609 break;
18610 case OPC_CEQI_df:
18611 tcg_gen_movi_i32(timm, s5);
18612 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18613 break;
18614 case OPC_CLTI_S_df:
18615 tcg_gen_movi_i32(timm, s5);
18616 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18617 break;
18618 case OPC_CLTI_U_df:
18619 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18620 break;
18621 case OPC_CLEI_S_df:
18622 tcg_gen_movi_i32(timm, s5);
18623 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18624 break;
18625 case OPC_CLEI_U_df:
18626 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18627 break;
18628 case OPC_LDI_df:
18629 {
18630 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18631 tcg_gen_movi_i32(timm, s10);
18632 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18633 }
18634 break;
18635 default:
18636 MIPS_INVAL("MSA instruction");
9c708c7f 18637 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18638 break;
18639 }
18640
18641 tcg_temp_free_i32(tdf);
18642 tcg_temp_free_i32(twd);
18643 tcg_temp_free_i32(tws);
18644 tcg_temp_free_i32(timm);
18645}
18646
d4cf28de
YK
18647static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18648{
18649#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18650 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18651 uint32_t df = 0, m = 0;
18652 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18653 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18654
18655 TCGv_i32 tdf;
18656 TCGv_i32 tm;
18657 TCGv_i32 twd;
18658 TCGv_i32 tws;
18659
18660 if ((dfm & 0x40) == 0x00) {
18661 m = dfm & 0x3f;
18662 df = DF_DOUBLE;
18663 } else if ((dfm & 0x60) == 0x40) {
18664 m = dfm & 0x1f;
18665 df = DF_WORD;
18666 } else if ((dfm & 0x70) == 0x60) {
18667 m = dfm & 0x0f;
18668 df = DF_HALF;
18669 } else if ((dfm & 0x78) == 0x70) {
18670 m = dfm & 0x7;
18671 df = DF_BYTE;
18672 } else {
9c708c7f 18673 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18674 return;
18675 }
18676
18677 tdf = tcg_const_i32(df);
18678 tm = tcg_const_i32(m);
18679 twd = tcg_const_i32(wd);
18680 tws = tcg_const_i32(ws);
18681
18682 switch (MASK_MSA_BIT(ctx->opcode)) {
18683 case OPC_SLLI_df:
18684 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18685 break;
18686 case OPC_SRAI_df:
18687 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18688 break;
18689 case OPC_SRLI_df:
18690 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18691 break;
18692 case OPC_BCLRI_df:
18693 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18694 break;
18695 case OPC_BSETI_df:
18696 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18697 break;
18698 case OPC_BNEGI_df:
18699 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18700 break;
18701 case OPC_BINSLI_df:
18702 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18703 break;
18704 case OPC_BINSRI_df:
18705 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18706 break;
18707 case OPC_SAT_S_df:
18708 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18709 break;
18710 case OPC_SAT_U_df:
18711 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18712 break;
18713 case OPC_SRARI_df:
18714 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18715 break;
18716 case OPC_SRLRI_df:
18717 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18718 break;
18719 default:
18720 MIPS_INVAL("MSA instruction");
9c708c7f 18721 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18722 break;
18723 }
18724
18725 tcg_temp_free_i32(tdf);
18726 tcg_temp_free_i32(tm);
18727 tcg_temp_free_i32(twd);
18728 tcg_temp_free_i32(tws);
18729}
18730
28f99f08
YK
18731static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18732{
18733#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18734 uint8_t df = (ctx->opcode >> 21) & 0x3;
18735 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18736 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18737 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18738
18739 TCGv_i32 tdf = tcg_const_i32(df);
18740 TCGv_i32 twd = tcg_const_i32(wd);
18741 TCGv_i32 tws = tcg_const_i32(ws);
18742 TCGv_i32 twt = tcg_const_i32(wt);
18743
18744 switch (MASK_MSA_3R(ctx->opcode)) {
18745 case OPC_SLL_df:
18746 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18747 break;
18748 case OPC_ADDV_df:
18749 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18750 break;
18751 case OPC_CEQ_df:
18752 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18753 break;
18754 case OPC_ADD_A_df:
18755 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18756 break;
18757 case OPC_SUBS_S_df:
18758 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18759 break;
18760 case OPC_MULV_df:
18761 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18762 break;
18763 case OPC_SLD_df:
18764 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18765 break;
18766 case OPC_VSHF_df:
18767 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18768 break;
18769 case OPC_SRA_df:
18770 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18771 break;
18772 case OPC_SUBV_df:
18773 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18774 break;
18775 case OPC_ADDS_A_df:
18776 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18777 break;
18778 case OPC_SUBS_U_df:
18779 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18780 break;
18781 case OPC_MADDV_df:
18782 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18783 break;
18784 case OPC_SPLAT_df:
18785 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18786 break;
18787 case OPC_SRAR_df:
18788 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18789 break;
18790 case OPC_SRL_df:
18791 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18792 break;
18793 case OPC_MAX_S_df:
18794 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18795 break;
18796 case OPC_CLT_S_df:
18797 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18798 break;
18799 case OPC_ADDS_S_df:
18800 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18801 break;
18802 case OPC_SUBSUS_U_df:
18803 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18804 break;
18805 case OPC_MSUBV_df:
18806 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18807 break;
18808 case OPC_PCKEV_df:
18809 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18810 break;
18811 case OPC_SRLR_df:
18812 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18813 break;
18814 case OPC_BCLR_df:
18815 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18816 break;
18817 case OPC_MAX_U_df:
18818 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18819 break;
18820 case OPC_CLT_U_df:
18821 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18822 break;
18823 case OPC_ADDS_U_df:
18824 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18825 break;
18826 case OPC_SUBSUU_S_df:
18827 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18828 break;
18829 case OPC_PCKOD_df:
18830 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18831 break;
18832 case OPC_BSET_df:
18833 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18834 break;
18835 case OPC_MIN_S_df:
18836 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18837 break;
18838 case OPC_CLE_S_df:
18839 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18840 break;
18841 case OPC_AVE_S_df:
18842 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18843 break;
18844 case OPC_ASUB_S_df:
18845 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18846 break;
18847 case OPC_DIV_S_df:
18848 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18849 break;
18850 case OPC_ILVL_df:
18851 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18852 break;
18853 case OPC_BNEG_df:
18854 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18855 break;
18856 case OPC_MIN_U_df:
18857 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18858 break;
18859 case OPC_CLE_U_df:
18860 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18861 break;
18862 case OPC_AVE_U_df:
18863 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18864 break;
18865 case OPC_ASUB_U_df:
18866 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18867 break;
18868 case OPC_DIV_U_df:
18869 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18870 break;
18871 case OPC_ILVR_df:
18872 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18873 break;
18874 case OPC_BINSL_df:
18875 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18876 break;
18877 case OPC_MAX_A_df:
18878 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18879 break;
18880 case OPC_AVER_S_df:
18881 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18882 break;
18883 case OPC_MOD_S_df:
18884 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18885 break;
18886 case OPC_ILVEV_df:
18887 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18888 break;
18889 case OPC_BINSR_df:
18890 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18891 break;
18892 case OPC_MIN_A_df:
18893 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18894 break;
18895 case OPC_AVER_U_df:
18896 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18897 break;
18898 case OPC_MOD_U_df:
18899 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18900 break;
18901 case OPC_ILVOD_df:
18902 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18903 break;
18904
18905 case OPC_DOTP_S_df:
18906 case OPC_DOTP_U_df:
18907 case OPC_DPADD_S_df:
18908 case OPC_DPADD_U_df:
18909 case OPC_DPSUB_S_df:
18910 case OPC_HADD_S_df:
18911 case OPC_DPSUB_U_df:
18912 case OPC_HADD_U_df:
18913 case OPC_HSUB_S_df:
18914 case OPC_HSUB_U_df:
18915 if (df == DF_BYTE) {
9c708c7f
PD
18916 generate_exception_end(ctx, EXCP_RI);
18917 break;
28f99f08
YK
18918 }
18919 switch (MASK_MSA_3R(ctx->opcode)) {
18920 case OPC_DOTP_S_df:
18921 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18922 break;
18923 case OPC_DOTP_U_df:
18924 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18925 break;
18926 case OPC_DPADD_S_df:
18927 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18928 break;
18929 case OPC_DPADD_U_df:
18930 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18931 break;
18932 case OPC_DPSUB_S_df:
18933 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18934 break;
18935 case OPC_HADD_S_df:
18936 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18937 break;
18938 case OPC_DPSUB_U_df:
18939 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18940 break;
18941 case OPC_HADD_U_df:
18942 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18943 break;
18944 case OPC_HSUB_S_df:
18945 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18946 break;
18947 case OPC_HSUB_U_df:
18948 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18949 break;
18950 }
18951 break;
18952 default:
18953 MIPS_INVAL("MSA instruction");
9c708c7f 18954 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18955 break;
18956 }
18957 tcg_temp_free_i32(twd);
18958 tcg_temp_free_i32(tws);
18959 tcg_temp_free_i32(twt);
18960 tcg_temp_free_i32(tdf);
18961}
18962
1e608ec1
YK
18963static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18964{
18965#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18966 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18967 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18968 TCGv telm = tcg_temp_new();
18969 TCGv_i32 tsr = tcg_const_i32(source);
18970 TCGv_i32 tdt = tcg_const_i32(dest);
18971
18972 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18973 case OPC_CTCMSA:
18974 gen_load_gpr(telm, source);
18975 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18976 break;
18977 case OPC_CFCMSA:
18978 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18979 gen_store_gpr(telm, dest);
18980 break;
18981 case OPC_MOVE_V:
18982 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18983 break;
18984 default:
18985 MIPS_INVAL("MSA instruction");
9c708c7f 18986 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18987 break;
18988 }
18989
18990 tcg_temp_free(telm);
18991 tcg_temp_free_i32(tdt);
18992 tcg_temp_free_i32(tsr);
18993}
18994
18995static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18996 uint32_t n)
18997{
18998#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18999 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19000 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19001
19002 TCGv_i32 tws = tcg_const_i32(ws);
19003 TCGv_i32 twd = tcg_const_i32(wd);
19004 TCGv_i32 tn = tcg_const_i32(n);
19005 TCGv_i32 tdf = tcg_const_i32(df);
19006
19007 switch (MASK_MSA_ELM(ctx->opcode)) {
19008 case OPC_SLDI_df:
19009 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
19010 break;
19011 case OPC_SPLATI_df:
19012 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
19013 break;
19014 case OPC_INSVE_df:
19015 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
19016 break;
19017 case OPC_COPY_S_df:
19018 case OPC_COPY_U_df:
19019 case OPC_INSERT_df:
19020#if !defined(TARGET_MIPS64)
19021 /* Double format valid only for MIPS64 */
19022 if (df == DF_DOUBLE) {
9c708c7f 19023 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19024 break;
19025 }
19026#endif
19027 switch (MASK_MSA_ELM(ctx->opcode)) {
19028 case OPC_COPY_S_df:
cab48881
MD
19029 if (likely(wd != 0)) {
19030 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19031 }
1e608ec1
YK
19032 break;
19033 case OPC_COPY_U_df:
cab48881
MD
19034 if (likely(wd != 0)) {
19035 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19036 }
1e608ec1
YK
19037 break;
19038 case OPC_INSERT_df:
19039 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19040 break;
19041 }
19042 break;
19043 default:
19044 MIPS_INVAL("MSA instruction");
9c708c7f 19045 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19046 }
19047 tcg_temp_free_i32(twd);
19048 tcg_temp_free_i32(tws);
19049 tcg_temp_free_i32(tn);
19050 tcg_temp_free_i32(tdf);
19051}
19052
19053static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19054{
19055 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19056 uint32_t df = 0, n = 0;
19057
19058 if ((dfn & 0x30) == 0x00) {
19059 n = dfn & 0x0f;
19060 df = DF_BYTE;
19061 } else if ((dfn & 0x38) == 0x20) {
19062 n = dfn & 0x07;
19063 df = DF_HALF;
19064 } else if ((dfn & 0x3c) == 0x30) {
19065 n = dfn & 0x03;
19066 df = DF_WORD;
19067 } else if ((dfn & 0x3e) == 0x38) {
19068 n = dfn & 0x01;
19069 df = DF_DOUBLE;
19070 } else if (dfn == 0x3E) {
19071 /* CTCMSA, CFCMSA, MOVE.V */
19072 gen_msa_elm_3e(env, ctx);
19073 return;
19074 } else {
9c708c7f 19075 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19076 return;
19077 }
19078
19079 gen_msa_elm_df(env, ctx, df, n);
19080}
19081
7d05b9c8
YK
19082static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19083{
19084#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19085 uint8_t df = (ctx->opcode >> 21) & 0x1;
19086 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19087 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19088 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19089
19090 TCGv_i32 twd = tcg_const_i32(wd);
19091 TCGv_i32 tws = tcg_const_i32(ws);
19092 TCGv_i32 twt = tcg_const_i32(wt);
19093 TCGv_i32 tdf = tcg_temp_new_i32();
19094
19095 /* adjust df value for floating-point instruction */
19096 tcg_gen_movi_i32(tdf, df + 2);
19097
19098 switch (MASK_MSA_3RF(ctx->opcode)) {
19099 case OPC_FCAF_df:
19100 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19101 break;
19102 case OPC_FADD_df:
19103 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19104 break;
19105 case OPC_FCUN_df:
19106 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19107 break;
19108 case OPC_FSUB_df:
19109 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19110 break;
19111 case OPC_FCOR_df:
19112 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19113 break;
19114 case OPC_FCEQ_df:
19115 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19116 break;
19117 case OPC_FMUL_df:
19118 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19119 break;
19120 case OPC_FCUNE_df:
19121 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19122 break;
19123 case OPC_FCUEQ_df:
19124 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19125 break;
19126 case OPC_FDIV_df:
19127 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19128 break;
19129 case OPC_FCNE_df:
19130 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19131 break;
19132 case OPC_FCLT_df:
19133 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19134 break;
19135 case OPC_FMADD_df:
19136 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19137 break;
19138 case OPC_MUL_Q_df:
19139 tcg_gen_movi_i32(tdf, df + 1);
19140 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19141 break;
19142 case OPC_FCULT_df:
19143 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19144 break;
19145 case OPC_FMSUB_df:
19146 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19147 break;
19148 case OPC_MADD_Q_df:
19149 tcg_gen_movi_i32(tdf, df + 1);
19150 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19151 break;
19152 case OPC_FCLE_df:
19153 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19154 break;
19155 case OPC_MSUB_Q_df:
19156 tcg_gen_movi_i32(tdf, df + 1);
19157 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19158 break;
19159 case OPC_FCULE_df:
19160 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19161 break;
19162 case OPC_FEXP2_df:
19163 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19164 break;
19165 case OPC_FSAF_df:
19166 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19167 break;
19168 case OPC_FEXDO_df:
19169 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19170 break;
19171 case OPC_FSUN_df:
19172 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19173 break;
19174 case OPC_FSOR_df:
19175 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19176 break;
19177 case OPC_FSEQ_df:
19178 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19179 break;
19180 case OPC_FTQ_df:
19181 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19182 break;
19183 case OPC_FSUNE_df:
19184 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19185 break;
19186 case OPC_FSUEQ_df:
19187 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19188 break;
19189 case OPC_FSNE_df:
19190 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19191 break;
19192 case OPC_FSLT_df:
19193 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19194 break;
19195 case OPC_FMIN_df:
19196 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19197 break;
19198 case OPC_MULR_Q_df:
19199 tcg_gen_movi_i32(tdf, df + 1);
19200 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19201 break;
19202 case OPC_FSULT_df:
19203 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19204 break;
19205 case OPC_FMIN_A_df:
19206 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19207 break;
19208 case OPC_MADDR_Q_df:
19209 tcg_gen_movi_i32(tdf, df + 1);
19210 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19211 break;
19212 case OPC_FSLE_df:
19213 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19214 break;
19215 case OPC_FMAX_df:
19216 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19217 break;
19218 case OPC_MSUBR_Q_df:
19219 tcg_gen_movi_i32(tdf, df + 1);
19220 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19221 break;
19222 case OPC_FSULE_df:
19223 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19224 break;
19225 case OPC_FMAX_A_df:
19226 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19227 break;
19228 default:
19229 MIPS_INVAL("MSA instruction");
9c708c7f 19230 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
19231 break;
19232 }
19233
19234 tcg_temp_free_i32(twd);
19235 tcg_temp_free_i32(tws);
19236 tcg_temp_free_i32(twt);
19237 tcg_temp_free_i32(tdf);
19238}
19239
cbe50b9a
YK
19240static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19241{
19242#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19243 (op & (0x7 << 18)))
19244 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19245 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19246 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19247 uint8_t df = (ctx->opcode >> 16) & 0x3;
19248 TCGv_i32 twd = tcg_const_i32(wd);
19249 TCGv_i32 tws = tcg_const_i32(ws);
19250 TCGv_i32 twt = tcg_const_i32(wt);
19251 TCGv_i32 tdf = tcg_const_i32(df);
19252
19253 switch (MASK_MSA_2R(ctx->opcode)) {
19254 case OPC_FILL_df:
19255#if !defined(TARGET_MIPS64)
19256 /* Double format valid only for MIPS64 */
19257 if (df == DF_DOUBLE) {
9c708c7f 19258 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19259 break;
19260 }
19261#endif
19262 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19263 break;
19264 case OPC_PCNT_df:
19265 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19266 break;
19267 case OPC_NLOC_df:
19268 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19269 break;
19270 case OPC_NLZC_df:
19271 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19272 break;
19273 default:
19274 MIPS_INVAL("MSA instruction");
9c708c7f 19275 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19276 break;
19277 }
19278
19279 tcg_temp_free_i32(twd);
19280 tcg_temp_free_i32(tws);
19281 tcg_temp_free_i32(twt);
19282 tcg_temp_free_i32(tdf);
19283}
19284
3bdeb688
YK
19285static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19286{
19287#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19288 (op & (0xf << 17)))
19289 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19290 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19291 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19292 uint8_t df = (ctx->opcode >> 16) & 0x1;
19293 TCGv_i32 twd = tcg_const_i32(wd);
19294 TCGv_i32 tws = tcg_const_i32(ws);
19295 TCGv_i32 twt = tcg_const_i32(wt);
19296 /* adjust df value for floating-point instruction */
19297 TCGv_i32 tdf = tcg_const_i32(df + 2);
19298
19299 switch (MASK_MSA_2RF(ctx->opcode)) {
19300 case OPC_FCLASS_df:
19301 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19302 break;
19303 case OPC_FTRUNC_S_df:
19304 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19305 break;
19306 case OPC_FTRUNC_U_df:
19307 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19308 break;
19309 case OPC_FSQRT_df:
19310 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19311 break;
19312 case OPC_FRSQRT_df:
19313 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19314 break;
19315 case OPC_FRCP_df:
19316 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19317 break;
19318 case OPC_FRINT_df:
19319 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19320 break;
19321 case OPC_FLOG2_df:
19322 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19323 break;
19324 case OPC_FEXUPL_df:
19325 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19326 break;
19327 case OPC_FEXUPR_df:
19328 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19329 break;
19330 case OPC_FFQL_df:
19331 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19332 break;
19333 case OPC_FFQR_df:
19334 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19335 break;
19336 case OPC_FTINT_S_df:
19337 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19338 break;
19339 case OPC_FTINT_U_df:
19340 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19341 break;
19342 case OPC_FFINT_S_df:
19343 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19344 break;
19345 case OPC_FFINT_U_df:
19346 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19347 break;
19348 }
19349
19350 tcg_temp_free_i32(twd);
19351 tcg_temp_free_i32(tws);
19352 tcg_temp_free_i32(twt);
19353 tcg_temp_free_i32(tdf);
19354}
19355
cbe50b9a
YK
19356static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19357{
19358#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19359 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19360 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19361 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19362 TCGv_i32 twd = tcg_const_i32(wd);
19363 TCGv_i32 tws = tcg_const_i32(ws);
19364 TCGv_i32 twt = tcg_const_i32(wt);
19365
19366 switch (MASK_MSA_VEC(ctx->opcode)) {
19367 case OPC_AND_V:
19368 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19369 break;
19370 case OPC_OR_V:
19371 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19372 break;
19373 case OPC_NOR_V:
19374 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19375 break;
19376 case OPC_XOR_V:
19377 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19378 break;
19379 case OPC_BMNZ_V:
19380 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19381 break;
19382 case OPC_BMZ_V:
19383 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19384 break;
19385 case OPC_BSEL_V:
19386 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19387 break;
19388 default:
19389 MIPS_INVAL("MSA instruction");
9c708c7f 19390 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19391 break;
19392 }
19393
19394 tcg_temp_free_i32(twd);
19395 tcg_temp_free_i32(tws);
19396 tcg_temp_free_i32(twt);
19397}
19398
19399static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19400{
19401 switch (MASK_MSA_VEC(ctx->opcode)) {
19402 case OPC_AND_V:
19403 case OPC_OR_V:
19404 case OPC_NOR_V:
19405 case OPC_XOR_V:
19406 case OPC_BMNZ_V:
19407 case OPC_BMZ_V:
19408 case OPC_BSEL_V:
19409 gen_msa_vec_v(env, ctx);
19410 break;
19411 case OPC_MSA_2R:
19412 gen_msa_2r(env, ctx);
19413 break;
3bdeb688
YK
19414 case OPC_MSA_2RF:
19415 gen_msa_2rf(env, ctx);
19416 break;
cbe50b9a
YK
19417 default:
19418 MIPS_INVAL("MSA instruction");
9c708c7f 19419 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19420 break;
19421 }
19422}
19423
4c789546
YK
19424static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19425{
19426 uint32_t opcode = ctx->opcode;
19427 check_insn(ctx, ASE_MSA);
19428 check_msa_access(ctx);
19429
19430 switch (MASK_MSA_MINOR(opcode)) {
19431 case OPC_MSA_I8_00:
19432 case OPC_MSA_I8_01:
19433 case OPC_MSA_I8_02:
19434 gen_msa_i8(env, ctx);
19435 break;
80e71591
YK
19436 case OPC_MSA_I5_06:
19437 case OPC_MSA_I5_07:
19438 gen_msa_i5(env, ctx);
19439 break;
d4cf28de
YK
19440 case OPC_MSA_BIT_09:
19441 case OPC_MSA_BIT_0A:
19442 gen_msa_bit(env, ctx);
19443 break;
28f99f08
YK
19444 case OPC_MSA_3R_0D:
19445 case OPC_MSA_3R_0E:
19446 case OPC_MSA_3R_0F:
19447 case OPC_MSA_3R_10:
19448 case OPC_MSA_3R_11:
19449 case OPC_MSA_3R_12:
19450 case OPC_MSA_3R_13:
19451 case OPC_MSA_3R_14:
19452 case OPC_MSA_3R_15:
19453 gen_msa_3r(env, ctx);
19454 break;
1e608ec1
YK
19455 case OPC_MSA_ELM:
19456 gen_msa_elm(env, ctx);
19457 break;
7d05b9c8
YK
19458 case OPC_MSA_3RF_1A:
19459 case OPC_MSA_3RF_1B:
19460 case OPC_MSA_3RF_1C:
19461 gen_msa_3rf(env, ctx);
19462 break;
cbe50b9a
YK
19463 case OPC_MSA_VEC:
19464 gen_msa_vec(env, ctx);
19465 break;
f7685877
YK
19466 case OPC_LD_B:
19467 case OPC_LD_H:
19468 case OPC_LD_W:
19469 case OPC_LD_D:
19470 case OPC_ST_B:
19471 case OPC_ST_H:
19472 case OPC_ST_W:
19473 case OPC_ST_D:
19474 {
19475 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19476 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19477 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19478 uint8_t df = (ctx->opcode >> 0) & 0x3;
19479
f7685877 19480 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19481 TCGv taddr = tcg_temp_new();
19482 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19483
19484 switch (MASK_MSA_MINOR(opcode)) {
19485 case OPC_LD_B:
adc370a4
YK
19486 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19487 break;
f7685877 19488 case OPC_LD_H:
adc370a4
YK
19489 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19490 break;
f7685877 19491 case OPC_LD_W:
adc370a4
YK
19492 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19493 break;
f7685877 19494 case OPC_LD_D:
adc370a4 19495 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19496 break;
19497 case OPC_ST_B:
adc370a4
YK
19498 gen_helper_msa_st_b(cpu_env, twd, taddr);
19499 break;
f7685877 19500 case OPC_ST_H:
adc370a4
YK
19501 gen_helper_msa_st_h(cpu_env, twd, taddr);
19502 break;
f7685877 19503 case OPC_ST_W:
adc370a4
YK
19504 gen_helper_msa_st_w(cpu_env, twd, taddr);
19505 break;
f7685877 19506 case OPC_ST_D:
adc370a4 19507 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19508 break;
19509 }
19510
19511 tcg_temp_free_i32(twd);
adc370a4 19512 tcg_temp_free(taddr);
f7685877
YK
19513 }
19514 break;
4c789546
YK
19515 default:
19516 MIPS_INVAL("MSA instruction");
9c708c7f 19517 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19518 break;
19519 }
19520
19521}
19522
d2bfa6e6 19523static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19524{
19525 int32_t offset;
19526 int rs, rt, rd, sa;
19527 uint32_t op, op1;
19528 int16_t imm;
19529
19530 /* make sure instructions are on a word boundary */
19531 if (ctx->pc & 0x3) {
19532 env->CP0_BadVAddr = ctx->pc;
aea14095 19533 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19534 return;
19535 }
19536
19537 /* Handle blikely not taken case */
19538 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19539 TCGLabel *l1 = gen_new_label();
099e5b4d 19540
099e5b4d
LA
19541 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19542 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19543 gen_goto_tb(ctx, 1, ctx->pc + 4);
19544 gen_set_label(l1);
19545 }
19546
099e5b4d
LA
19547 op = MASK_OP_MAJOR(ctx->opcode);
19548 rs = (ctx->opcode >> 21) & 0x1f;
19549 rt = (ctx->opcode >> 16) & 0x1f;
19550 rd = (ctx->opcode >> 11) & 0x1f;
19551 sa = (ctx->opcode >> 6) & 0x1f;
19552 imm = (int16_t)ctx->opcode;
19553 switch (op) {
19554 case OPC_SPECIAL:
19555 decode_opc_special(env, ctx);
19556 break;
19557 case OPC_SPECIAL2:
4267d3e6 19558 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19559 break;
19560 case OPC_SPECIAL3:
19561 decode_opc_special3(env, ctx);
19562 break;
7a387fff
TS
19563 case OPC_REGIMM:
19564 op1 = MASK_REGIMM(ctx->opcode);
19565 switch (op1) {
fecd2646
LA
19566 case OPC_BLTZL: /* REGIMM branches */
19567 case OPC_BGEZL:
19568 case OPC_BLTZALL:
19569 case OPC_BGEZALL:
d9224450 19570 check_insn(ctx, ISA_MIPS2);
fecd2646 19571 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19572 /* Fallthrough */
fecd2646
LA
19573 case OPC_BLTZ:
19574 case OPC_BGEZ:
b231c103 19575 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19576 break;
fecd2646
LA
19577 case OPC_BLTZAL:
19578 case OPC_BGEZAL:
0aefa333
YK
19579 if (ctx->insn_flags & ISA_MIPS32R6) {
19580 if (rs == 0) {
19581 /* OPC_NAL, OPC_BAL */
b231c103 19582 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19583 } else {
9c708c7f 19584 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19585 }
19586 } else {
b231c103 19587 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19588 }
c9602061 19589 break;
7a387fff
TS
19590 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19591 case OPC_TNEI:
d9224450 19592 check_insn(ctx, ISA_MIPS2);
fecd2646 19593 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19594 gen_trap(ctx, op1, rs, -1, imm);
19595 break;
bb238210
YK
19596 case OPC_SIGRIE:
19597 check_insn(ctx, ISA_MIPS32R6);
19598 generate_exception_end(ctx, EXCP_RI);
19599 break;
7a387fff 19600 case OPC_SYNCI:
d75c135e 19601 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19602 /* Break the TB to be able to sync copied instructions
19603 immediately */
19604 ctx->bstate = BS_STOP;
6af0bf9c 19605 break;
e45a93e2
JL
19606 case OPC_BPOSGE32: /* MIPS DSP branch */
19607#if defined(TARGET_MIPS64)
19608 case OPC_BPOSGE64:
19609#endif
19610 check_dsp(ctx);
b231c103 19611 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19612 break;
d4ea6acd
LA
19613#if defined(TARGET_MIPS64)
19614 case OPC_DAHI:
19615 check_insn(ctx, ISA_MIPS32R6);
19616 check_mips_64(ctx);
19617 if (rs != 0) {
19618 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19619 }
d4ea6acd
LA
19620 break;
19621 case OPC_DATI:
19622 check_insn(ctx, ISA_MIPS32R6);
19623 check_mips_64(ctx);
19624 if (rs != 0) {
19625 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19626 }
d4ea6acd
LA
19627 break;
19628#endif
6af0bf9c 19629 default: /* Invalid */
923617a3 19630 MIPS_INVAL("regimm");
9c708c7f 19631 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19632 break;
19633 }
19634 break;
7a387fff 19635 case OPC_CP0:
387a8fe5 19636 check_cp0_enabled(ctx);
7a387fff 19637 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19638 switch (op1) {
7a387fff
TS
19639 case OPC_MFC0:
19640 case OPC_MTC0:
ead9360e
TS
19641 case OPC_MFTR:
19642 case OPC_MTTR:
5204ea79
LA
19643 case OPC_MFHC0:
19644 case OPC_MTHC0:
d26bc211 19645#if defined(TARGET_MIPS64)
7a387fff
TS
19646 case OPC_DMFC0:
19647 case OPC_DMTC0:
19648#endif
f1aa6320 19649#ifndef CONFIG_USER_ONLY
932e71cd 19650 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19651#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19652 break;
19653 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19654#ifndef CONFIG_USER_ONLY
932e71cd 19655 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19656#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19657 break;
19658 case OPC_MFMC0:
8706c382 19659#ifndef CONFIG_USER_ONLY
932e71cd 19660 {
099e5b4d 19661 uint32_t op2;
35fbce2c 19662 TCGv t0 = tcg_temp_new();
6c5c1e20 19663
0eaef5aa 19664 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19665 switch (op2) {
19666 case OPC_DMT:
d75c135e 19667 check_insn(ctx, ASE_MT);
9ed5726c 19668 gen_helper_dmt(t0);
35fbce2c 19669 gen_store_gpr(t0, rt);
6c5c1e20
TS
19670 break;
19671 case OPC_EMT:
d75c135e 19672 check_insn(ctx, ASE_MT);
9ed5726c 19673 gen_helper_emt(t0);
35fbce2c 19674 gen_store_gpr(t0, rt);
da80682b 19675 break;
6c5c1e20 19676 case OPC_DVPE:
d75c135e 19677 check_insn(ctx, ASE_MT);
895c2d04 19678 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19679 gen_store_gpr(t0, rt);
6c5c1e20
TS
19680 break;
19681 case OPC_EVPE:
d75c135e 19682 check_insn(ctx, ASE_MT);
895c2d04 19683 gen_helper_evpe(t0, cpu_env);
35fbce2c 19684 gen_store_gpr(t0, rt);
6c5c1e20 19685 break;
01bc435b
YK
19686 case OPC_DVP:
19687 check_insn(ctx, ISA_MIPS32R6);
19688 if (ctx->vp) {
19689 gen_helper_dvp(t0, cpu_env);
19690 gen_store_gpr(t0, rt);
19691 }
19692 break;
19693 case OPC_EVP:
19694 check_insn(ctx, ISA_MIPS32R6);
19695 if (ctx->vp) {
19696 gen_helper_evp(t0, cpu_env);
19697 gen_store_gpr(t0, rt);
19698 }
19699 break;
6c5c1e20 19700 case OPC_DI:
d75c135e 19701 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19702 save_cpu_state(ctx, 1);
895c2d04 19703 gen_helper_di(t0, cpu_env);
35fbce2c 19704 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19705 /* Stop translation as we may have switched
19706 the execution mode. */
6c5c1e20
TS
19707 ctx->bstate = BS_STOP;
19708 break;
19709 case OPC_EI:
d75c135e 19710 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19711 save_cpu_state(ctx, 1);
895c2d04 19712 gen_helper_ei(t0, cpu_env);
35fbce2c 19713 gen_store_gpr(t0, rt);
b74cddcb
JH
19714 /* BS_STOP isn't sufficient, we need to ensure we break out
19715 of translated code to check for pending interrupts. */
19716 gen_save_pc(ctx->pc + 4);
19717 ctx->bstate = BS_EXCP;
6c5c1e20
TS
19718 break;
19719 default: /* Invalid */
19720 MIPS_INVAL("mfmc0");
9c708c7f 19721 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19722 break;
19723 }
6c5c1e20 19724 tcg_temp_free(t0);
7a387fff 19725 }
0eaef5aa 19726#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19727 break;
7a387fff 19728 case OPC_RDPGPR:
d75c135e 19729 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19730 gen_load_srsgpr(rt, rd);
ead9360e 19731 break;
7a387fff 19732 case OPC_WRPGPR:
d75c135e 19733 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19734 gen_store_srsgpr(rt, rd);
38121543 19735 break;
6af0bf9c 19736 default:
923617a3 19737 MIPS_INVAL("cp0");
9c708c7f 19738 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19739 break;
19740 }
19741 break;
31837be3
YK
19742 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19743 if (ctx->insn_flags & ISA_MIPS32R6) {
19744 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19745 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19746 } else {
19747 /* OPC_ADDI */
19748 /* Arithmetic with immediate opcode */
19749 gen_arith_imm(ctx, op, rt, rs, imm);
19750 }
19751 break;
324d9e32 19752 case OPC_ADDIU:
d75c135e 19753 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19754 break;
324d9e32
AJ
19755 case OPC_SLTI: /* Set on less than with immediate opcode */
19756 case OPC_SLTIU:
d75c135e 19757 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19758 break;
19759 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19760 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19761 case OPC_ORI:
19762 case OPC_XORI:
d75c135e 19763 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19764 break;
7a387fff
TS
19765 case OPC_J ... OPC_JAL: /* Jump */
19766 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19767 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19768 break;
31837be3
YK
19769 /* Branch */
19770 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19771 if (ctx->insn_flags & ISA_MIPS32R6) {
19772 if (rt == 0) {
9c708c7f 19773 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19774 break;
19775 }
19776 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19777 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19778 } else {
19779 /* OPC_BLEZL */
b231c103 19780 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19781 }
19782 break;
19783 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19784 if (ctx->insn_flags & ISA_MIPS32R6) {
19785 if (rt == 0) {
9c708c7f 19786 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19787 break;
19788 }
19789 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19790 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19791 } else {
19792 /* OPC_BGTZL */
b231c103 19793 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19794 }
19795 break;
19796 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19797 if (rt == 0) {
19798 /* OPC_BLEZ */
b231c103 19799 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19800 } else {
19801 check_insn(ctx, ISA_MIPS32R6);
19802 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19803 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19804 }
19805 break;
19806 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19807 if (rt == 0) {
19808 /* OPC_BGTZ */
b231c103 19809 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19810 } else {
19811 check_insn(ctx, ISA_MIPS32R6);
19812 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19813 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19814 }
19815 break;
19816 case OPC_BEQL:
19817 case OPC_BNEL:
d9224450 19818 check_insn(ctx, ISA_MIPS2);
fecd2646 19819 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19820 /* Fallthrough */
31837be3
YK
19821 case OPC_BEQ:
19822 case OPC_BNE:
b231c103 19823 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19824 break;
d9224450
MR
19825 case OPC_LL: /* Load and stores */
19826 check_insn(ctx, ISA_MIPS2);
19827 /* Fallthrough */
19828 case OPC_LWL:
fecd2646
LA
19829 case OPC_LWR:
19830 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19831 /* Fallthrough */
fecd2646
LA
19832 case OPC_LB ... OPC_LH:
19833 case OPC_LW ... OPC_LHU:
d75c135e 19834 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19835 break;
fecd2646 19836 case OPC_SWL:
7a387fff 19837 case OPC_SWR:
fecd2646 19838 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19839 /* fall through */
fecd2646
LA
19840 case OPC_SB ... OPC_SH:
19841 case OPC_SW:
5c13fdfd 19842 gen_st(ctx, op, rt, rs, imm);
7a387fff 19843 break;
d66c7132 19844 case OPC_SC:
d9224450 19845 check_insn(ctx, ISA_MIPS2);
4368b29a 19846 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19847 gen_st_cond(ctx, op, rt, rs, imm);
19848 break;
7a387fff 19849 case OPC_CACHE:
bf7910c6 19850 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19851 check_cp0_enabled(ctx);
d75c135e 19852 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
19853 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19854 gen_cache_operation(ctx, rt, rs, imm);
19855 }
ead9360e 19856 /* Treat as NOP. */
34ae7b51 19857 break;
7a387fff 19858 case OPC_PREF:
bf7910c6 19859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19860 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19861 /* Treat as NOP. */
6af0bf9c 19862 break;
4ad40f36 19863
923617a3 19864 /* Floating point (COP1). */
7a387fff
TS
19865 case OPC_LWC1:
19866 case OPC_LDC1:
19867 case OPC_SWC1:
19868 case OPC_SDC1:
5ab5c041 19869 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19870 break;
19871
7a387fff 19872 case OPC_CP1:
5692c6e1
YK
19873 op1 = MASK_CP1(ctx->opcode);
19874
19875 switch (op1) {
19876 case OPC_MFHC1:
19877 case OPC_MTHC1:
5e755519 19878 check_cp1_enabled(ctx);
5692c6e1
YK
19879 check_insn(ctx, ISA_MIPS32R2);
19880 case OPC_MFC1:
19881 case OPC_CFC1:
19882 case OPC_MTC1:
19883 case OPC_CTC1:
19884 check_cp1_enabled(ctx);
19885 gen_cp1(ctx, op1, rt, rd);
19886 break;
d26bc211 19887#if defined(TARGET_MIPS64)
5692c6e1
YK
19888 case OPC_DMFC1:
19889 case OPC_DMTC1:
19890 check_cp1_enabled(ctx);
19891 check_insn(ctx, ISA_MIPS3);
d9224450 19892 check_mips_64(ctx);
5692c6e1
YK
19893 gen_cp1(ctx, op1, rt, rd);
19894 break;
e189e748 19895#endif
5692c6e1
YK
19896 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19897 check_cp1_enabled(ctx);
19898 if (ctx->insn_flags & ISA_MIPS32R6) {
19899 /* OPC_BC1EQZ */
31837be3 19900 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19901 rt, imm << 2, 4);
5692c6e1
YK
19902 } else {
19903 /* OPC_BC1ANY2 */
b8aa4598 19904 check_cop1x(ctx);
d75c135e 19905 check_insn(ctx, ASE_MIPS3D);
d75c135e 19906 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19907 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19908 }
19909 break;
19910 case OPC_BC1NEZ:
19911 check_cp1_enabled(ctx);
19912 check_insn(ctx, ISA_MIPS32R6);
19913 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19914 rt, imm << 2, 4);
5692c6e1
YK
19915 break;
19916 case OPC_BC1ANY4:
19917 check_cp1_enabled(ctx);
19918 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19919 check_cop1x(ctx);
19920 check_insn(ctx, ASE_MIPS3D);
19921 /* fall through */
19922 case OPC_BC1:
19923 check_cp1_enabled(ctx);
19924 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19925 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19926 (rt >> 2) & 0x7, imm << 2);
19927 break;
19928 case OPC_PS_FMT:
e29c9628 19929 check_ps(ctx);
b6f3b233 19930 /* fall through */
5692c6e1
YK
19931 case OPC_S_FMT:
19932 case OPC_D_FMT:
19933 check_cp1_enabled(ctx);
19934 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19935 (imm >> 8) & 0x7);
19936 break;
19937 case OPC_W_FMT:
19938 case OPC_L_FMT:
19939 {
19940 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19941 check_cp1_enabled(ctx);
19942 if (ctx->insn_flags & ISA_MIPS32R6) {
19943 switch (r6_op) {
19944 case R6_OPC_CMP_AF_S:
19945 case R6_OPC_CMP_UN_S:
19946 case R6_OPC_CMP_EQ_S:
19947 case R6_OPC_CMP_UEQ_S:
19948 case R6_OPC_CMP_LT_S:
19949 case R6_OPC_CMP_ULT_S:
19950 case R6_OPC_CMP_LE_S:
19951 case R6_OPC_CMP_ULE_S:
19952 case R6_OPC_CMP_SAF_S:
19953 case R6_OPC_CMP_SUN_S:
19954 case R6_OPC_CMP_SEQ_S:
19955 case R6_OPC_CMP_SEUQ_S:
19956 case R6_OPC_CMP_SLT_S:
19957 case R6_OPC_CMP_SULT_S:
19958 case R6_OPC_CMP_SLE_S:
19959 case R6_OPC_CMP_SULE_S:
19960 case R6_OPC_CMP_OR_S:
19961 case R6_OPC_CMP_UNE_S:
19962 case R6_OPC_CMP_NE_S:
19963 case R6_OPC_CMP_SOR_S:
19964 case R6_OPC_CMP_SUNE_S:
19965 case R6_OPC_CMP_SNE_S:
19966 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19967 break;
19968 case R6_OPC_CMP_AF_D:
19969 case R6_OPC_CMP_UN_D:
19970 case R6_OPC_CMP_EQ_D:
19971 case R6_OPC_CMP_UEQ_D:
19972 case R6_OPC_CMP_LT_D:
19973 case R6_OPC_CMP_ULT_D:
19974 case R6_OPC_CMP_LE_D:
19975 case R6_OPC_CMP_ULE_D:
19976 case R6_OPC_CMP_SAF_D:
19977 case R6_OPC_CMP_SUN_D:
19978 case R6_OPC_CMP_SEQ_D:
19979 case R6_OPC_CMP_SEUQ_D:
19980 case R6_OPC_CMP_SLT_D:
19981 case R6_OPC_CMP_SULT_D:
19982 case R6_OPC_CMP_SLE_D:
19983 case R6_OPC_CMP_SULE_D:
19984 case R6_OPC_CMP_OR_D:
19985 case R6_OPC_CMP_UNE_D:
19986 case R6_OPC_CMP_NE_D:
19987 case R6_OPC_CMP_SOR_D:
19988 case R6_OPC_CMP_SUNE_D:
19989 case R6_OPC_CMP_SNE_D:
19990 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19991 break;
19992 default:
d2bfa6e6
MR
19993 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19994 rt, rd, sa, (imm >> 8) & 0x7);
19995
5692c6e1 19996 break;
3f493883 19997 }
5692c6e1
YK
19998 } else {
19999 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20000 (imm >> 8) & 0x7);
36d23958 20001 }
5692c6e1
YK
20002 break;
20003 }
20004 case OPC_BZ_V:
20005 case OPC_BNZ_V:
20006 case OPC_BZ_B:
20007 case OPC_BZ_H:
20008 case OPC_BZ_W:
20009 case OPC_BZ_D:
20010 case OPC_BNZ_B:
20011 case OPC_BNZ_H:
20012 case OPC_BNZ_W:
20013 case OPC_BNZ_D:
20014 check_insn(ctx, ASE_MSA);
20015 gen_msa_branch(env, ctx, op1);
20016 break;
20017 default:
20018 MIPS_INVAL("cp1");
9c708c7f 20019 generate_exception_end(ctx, EXCP_RI);
5692c6e1 20020 break;
6ea83fed 20021 }
4ad40f36
FB
20022 break;
20023
31837be3
YK
20024 /* Compact branches [R6] and COP2 [non-R6] */
20025 case OPC_BC: /* OPC_LWC2 */
20026 case OPC_BALC: /* OPC_SWC2 */
20027 if (ctx->insn_flags & ISA_MIPS32R6) {
20028 /* OPC_BC, OPC_BALC */
20029 gen_compute_compact_branch(ctx, op, 0, 0,
20030 sextract32(ctx->opcode << 2, 0, 28));
20031 } else {
20032 /* OPC_LWC2, OPC_SWC2 */
20033 /* COP2: Not implemented. */
20034 generate_exception_err(ctx, EXCP_CpU, 2);
20035 }
20036 break;
20037 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20038 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20039 if (ctx->insn_flags & ISA_MIPS32R6) {
20040 if (rs != 0) {
20041 /* OPC_BEQZC, OPC_BNEZC */
20042 gen_compute_compact_branch(ctx, op, rs, 0,
20043 sextract32(ctx->opcode << 2, 0, 23));
20044 } else {
20045 /* OPC_JIC, OPC_JIALC */
20046 gen_compute_compact_branch(ctx, op, 0, rt, imm);
20047 }
20048 } else {
20049 /* OPC_LWC2, OPC_SWC2 */
20050 /* COP2: Not implemented. */
20051 generate_exception_err(ctx, EXCP_CpU, 2);
20052 }
4ad40f36 20053 break;
bd277fa1 20054 case OPC_CP2:
d75c135e 20055 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
20056 /* Note that these instructions use different fields. */
20057 gen_loongson_multimedia(ctx, sa, rd, rt);
20058 break;
4ad40f36 20059
7a387fff 20060 case OPC_CP3:
fecd2646 20061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 20062 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 20063 check_cp1_enabled(ctx);
36d23958
TS
20064 op1 = MASK_CP3(ctx->opcode);
20065 switch (op1) {
d9224450
MR
20066 case OPC_LUXC1:
20067 case OPC_SUXC1:
20068 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20069 /* Fallthrough */
5a5012ec
TS
20070 case OPC_LWXC1:
20071 case OPC_LDXC1:
5a5012ec
TS
20072 case OPC_SWXC1:
20073 case OPC_SDXC1:
d9224450 20074 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 20075 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 20076 break;
e0c84da7 20077 case OPC_PREFX:
d9224450 20078 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 20079 /* Treat as NOP. */
e0c84da7 20080 break;
5a5012ec 20081 case OPC_ALNV_PS:
d9224450
MR
20082 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20083 /* Fallthrough */
5a5012ec
TS
20084 case OPC_MADD_S:
20085 case OPC_MADD_D:
20086 case OPC_MADD_PS:
20087 case OPC_MSUB_S:
20088 case OPC_MSUB_D:
20089 case OPC_MSUB_PS:
20090 case OPC_NMADD_S:
20091 case OPC_NMADD_D:
20092 case OPC_NMADD_PS:
20093 case OPC_NMSUB_S:
20094 case OPC_NMSUB_D:
20095 case OPC_NMSUB_PS:
d9224450 20096 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
20097 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20098 break;
36d23958 20099 default:
923617a3 20100 MIPS_INVAL("cp3");
9c708c7f 20101 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
20102 break;
20103 }
20104 } else {
e397ee33 20105 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 20106 }
4ad40f36
FB
20107 break;
20108
d26bc211 20109#if defined(TARGET_MIPS64)
7a387fff 20110 /* MIPS64 opcodes */
7a387fff 20111 case OPC_LDL ... OPC_LDR:
bf7910c6 20112 case OPC_LLD:
fecd2646 20113 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20114 /* fall through */
fecd2646 20115 case OPC_LWU:
7a387fff 20116 case OPC_LD:
d75c135e 20117 check_insn(ctx, ISA_MIPS3);
5c13fdfd 20118 check_mips_64(ctx);
d75c135e 20119 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
20120 break;
20121 case OPC_SDL ... OPC_SDR:
fecd2646 20122 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20123 /* fall through */
7a387fff 20124 case OPC_SD:
d75c135e 20125 check_insn(ctx, ISA_MIPS3);
e189e748 20126 check_mips_64(ctx);
5c13fdfd 20127 gen_st(ctx, op, rt, rs, imm);
7a387fff 20128 break;
d66c7132 20129 case OPC_SCD:
bf7910c6 20130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20131 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
20132 check_mips_64(ctx);
20133 gen_st_cond(ctx, op, rt, rs, imm);
20134 break;
31837be3
YK
20135 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20136 if (ctx->insn_flags & ISA_MIPS32R6) {
20137 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20138 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20139 } else {
20140 /* OPC_DADDI */
20141 check_insn(ctx, ISA_MIPS3);
20142 check_mips_64(ctx);
20143 gen_arith_imm(ctx, op, rt, rs, imm);
20144 }
20145 break;
324d9e32 20146 case OPC_DADDIU:
d75c135e 20147 check_insn(ctx, ISA_MIPS3);
e189e748 20148 check_mips_64(ctx);
d75c135e 20149 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 20150 break;
31837be3
YK
20151#else
20152 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20153 if (ctx->insn_flags & ISA_MIPS32R6) {
20154 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20155 } else {
20156 MIPS_INVAL("major opcode");
9c708c7f 20157 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
20158 }
20159 break;
6af0bf9c 20160#endif
d4ea6acd
LA
20161 case OPC_DAUI: /* OPC_JALX */
20162 if (ctx->insn_flags & ISA_MIPS32R6) {
20163#if defined(TARGET_MIPS64)
20164 /* OPC_DAUI */
20165 check_mips_64(ctx);
db77d852
LA
20166 if (rs == 0) {
20167 generate_exception(ctx, EXCP_RI);
20168 } else if (rt != 0) {
d4ea6acd
LA
20169 TCGv t0 = tcg_temp_new();
20170 gen_load_gpr(t0, rs);
20171 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20172 tcg_temp_free(t0);
20173 }
d4ea6acd 20174#else
9c708c7f 20175 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
20176 MIPS_INVAL("major opcode");
20177#endif
20178 } else {
20179 /* OPC_JALX */
20180 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20181 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 20182 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 20183 }
364d4831 20184 break;
4c789546 20185 case OPC_MSA: /* OPC_MDMX */
7a387fff 20186 /* MDMX: Not implemented. */
4c789546 20187 gen_msa(env, ctx);
d4ea6acd
LA
20188 break;
20189 case OPC_PCREL:
20190 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 20191 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 20192 break;
6af0bf9c 20193 default: /* Invalid */
923617a3 20194 MIPS_INVAL("major opcode");
9c708c7f 20195 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
20196 break;
20197 }
6af0bf9c
FB
20198}
20199
9c489ea6 20200void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
6af0bf9c 20201{
9c489ea6 20202 CPUMIPSState *env = cs->env_ptr;
278d0702 20203 DisasContext ctx;
6af0bf9c 20204 target_ulong pc_start;
fe237291 20205 target_ulong next_page_start;
2e70f6ef
PB
20206 int num_insns;
20207 int max_insns;
c9602061 20208 int insn_bytes;
339cd2a8 20209 int is_slot;
6af0bf9c
FB
20210
20211 pc_start = tb->pc;
fe237291 20212 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 20213 ctx.pc = pc_start;
4ad40f36 20214 ctx.saved_pc = -1;
ed2803da 20215 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 20216 ctx.insn_flags = env->insn_flags;
5ab5c041 20217 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
20218 ctx.tb = tb;
20219 ctx.bstate = BS_NONE;
c20d594e 20220 ctx.btarget = 0;
e98c0d17 20221 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 20222 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 20223 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
20224 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20225 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
20226 ctx.PAMask = env->PAMask;
20227 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
76964147 20228 ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
cec56a73 20229 ctx.sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
5204ea79 20230 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
c870e3f5 20231 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 20232 /* Restore delay slot state from the tb context. */
c068688b 20233 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 20234 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
20235 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
20236 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
01bc435b 20237 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
f6d4dd81 20238 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
87552089 20239 ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
6be77480 20240 ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
fd4a04eb 20241 restore_cpu_state(env, &ctx);
932e71cd 20242#ifdef CONFIG_USER_ONLY
0eaef5aa 20243 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 20244#else
b0fc6003 20245 ctx.mem_idx = hflags_mmu_index(ctx.hflags);
932e71cd 20246#endif
be3a8c53
YK
20247 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
20248 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
20249 num_insns = 0;
20250 max_insns = tb->cflags & CF_COUNT_MASK;
190ce7fb 20251 if (max_insns == 0) {
2e70f6ef 20252 max_insns = CF_COUNT_MASK;
190ce7fb
RH
20253 }
20254 if (max_insns > TCG_MAX_INSNS) {
20255 max_insns = TCG_MAX_INSNS;
20256 }
20257
d12d51d5 20258 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 20259 gen_tb_start(tb);
faf7aaa9 20260 while (ctx.bstate == BS_NONE) {
c20d594e 20261 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
959082fc 20262 num_insns++;
667b8e29 20263
b933066a
RH
20264 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
20265 save_cpu_state(&ctx, 1);
20266 ctx.bstate = BS_BRANCH;
20267 gen_helper_raise_exception_debug(cpu_env);
522a0d4e
RH
20268 /* The address covered by the breakpoint must be included in
20269 [tb->pc, tb->pc + tb->size) in order to for it to be
20270 properly cleared -- thus we increment the PC here so that
20271 the logic setting tb->size below does the right thing. */
b933066a
RH
20272 ctx.pc += 4;
20273 goto done_generating;
20274 }
20275
959082fc 20276 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 20277 gen_io_start();
667b8e29 20278 }
c9602061 20279
339cd2a8 20280 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 20281 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 20282 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 20283 insn_bytes = 4;
240ce26a 20284 decode_opc(env, &ctx);
d75c135e 20285 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 20286 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 20287 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 20288 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 20289 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 20290 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 20291 } else {
9c708c7f 20292 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
20293 break;
20294 }
31837be3 20295
b231c103 20296 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
20297 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20298 MIPS_HFLAG_FBNSLOT))) {
20299 /* force to generate branch as there is neither delay nor
20300 forbidden slot */
20301 is_slot = 1;
b231c103 20302 }
65935f07
YK
20303 if ((ctx.hflags & MIPS_HFLAG_M16) &&
20304 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
20305 /* Force to generate branch as microMIPS R6 doesn't restrict
20306 branches in the forbidden slot. */
20307 is_slot = 1;
20308 }
b231c103 20309 }
339cd2a8 20310 if (is_slot) {
31837be3 20311 gen_branch(&ctx, insn_bytes);
c9602061
NF
20312 }
20313 ctx.pc += insn_bytes;
20314
7b270ef2
NF
20315 /* Execute a branch and its delay slot as a single instruction.
20316 This is what GDB expects and is consistent with what the
20317 hardware does (e.g. if a delay slot instruction faults, the
20318 reported PC is the PC of the branch). */
ed2803da 20319 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 20320 break;
ed2803da 20321 }
4ad40f36 20322
fe237291 20323 if (ctx.pc >= next_page_start) {
6af0bf9c 20324 break;
fe237291 20325 }
4ad40f36 20326
fe700adb 20327 if (tcg_op_buf_full()) {
faf7aaa9 20328 break;
efd7f486 20329 }
faf7aaa9 20330
2e70f6ef
PB
20331 if (num_insns >= max_insns)
20332 break;
1b530a6d
AJ
20333
20334 if (singlestep)
20335 break;
6af0bf9c 20336 }
ed2803da 20337 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 20338 gen_io_end();
ed2803da
AF
20339 }
20340 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 20341 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
9c708c7f 20342 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 20343 } else {
6958549d 20344 switch (ctx.bstate) {
16c00cb2 20345 case BS_STOP:
df1561e2
TS
20346 gen_goto_tb(&ctx, 0, ctx.pc);
20347 break;
16c00cb2 20348 case BS_NONE:
278d0702 20349 save_cpu_state(&ctx, 0);
16c00cb2
TS
20350 gen_goto_tb(&ctx, 0, ctx.pc);
20351 break;
5a5012ec 20352 case BS_EXCP:
57fec1fe 20353 tcg_gen_exit_tb(0);
16c00cb2 20354 break;
5a5012ec
TS
20355 case BS_BRANCH:
20356 default:
20357 break;
6958549d 20358 }
6af0bf9c 20359 }
4ad40f36 20360done_generating:
806f352d 20361 gen_tb_end(tb, num_insns);
0a7df5da 20362
4e5e1215
RH
20363 tb->size = ctx.pc - pc_start;
20364 tb->icount = num_insns;
20365
6af0bf9c 20366#ifdef DEBUG_DISAS
d12d51d5 20367 LOG_DISAS("\n");
4910e6e4
RH
20368 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20369 && qemu_log_in_addr_range(pc_start)) {
1ee73216 20370 qemu_log_lock();
93fcfe39 20371 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 20372 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 20373 qemu_log("\n");
1ee73216 20374 qemu_log_unlock();
6af0bf9c
FB
20375 }
20376#endif
6af0bf9c
FB
20377}
20378
7db13fae 20379static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20380 int flags)
6ea83fed
FB
20381{
20382 int i;
5e755519 20383 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20384
2a5612e6
SW
20385#define printfpr(fp) \
20386 do { \
20387 if (is_fpu64) \
20388 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20389 " fd:%13g fs:%13g psu: %13g\n", \
20390 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20391 (double)(fp)->fd, \
20392 (double)(fp)->fs[FP_ENDIAN_IDX], \
20393 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20394 else { \
20395 fpr_t tmp; \
20396 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20397 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20398 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20399 " fd:%13g fs:%13g psu:%13g\n", \
20400 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20401 (double)tmp.fd, \
20402 (double)tmp.fs[FP_ENDIAN_IDX], \
20403 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20404 } \
6ea83fed
FB
20405 } while(0)
20406
5a5012ec 20407
9a78eead
SW
20408 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20409 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20410 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20411 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20412 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20413 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20414 }
20415
20416#undef printfpr
20417}
20418
878096ee
AF
20419void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20420 int flags)
6af0bf9c 20421{
878096ee
AF
20422 MIPSCPU *cpu = MIPS_CPU(cs);
20423 CPUMIPSState *env = &cpu->env;
6af0bf9c 20424 int i;
3b46e624 20425
a7200c9f
SW
20426 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20427 " LO=0x" TARGET_FMT_lx " ds %04x "
20428 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20429 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20430 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20431 for (i = 0; i < 32; i++) {
20432 if ((i & 3) == 0)
20433 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20434 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20435 if ((i & 3) == 3)
20436 cpu_fprintf(f, "\n");
20437 }
568b600d 20438
3594c774 20439 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20440 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20441 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20442 PRIx64 "\n",
5499b6ff 20443 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20444 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20445 env->CP0_Config2, env->CP0_Config3);
20446 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20447 env->CP0_Config4, env->CP0_Config5);
5e755519 20448 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 20449 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
20450}
20451
78ce64f4 20452void mips_tcg_init(void)
39454628 20453{
f01be154 20454 int i;
39454628
TS
20455 static int inited;
20456
20457 /* Initialize various static tables. */
20458 if (inited)
6958549d 20459 return;
39454628 20460
a7812ae4 20461 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
7c255043 20462 tcg_ctx.tcg_env = cpu_env;
e1ccc054 20463
f2c94b92 20464 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 20465 for (i = 1; i < 32; i++)
e1ccc054 20466 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20467 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20468 regnames[i]);
d73ee8a2 20469
863f264d
YK
20470 for (i = 0; i < 32; i++) {
20471 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20472 msa_wr_d[i * 2] =
e1ccc054 20473 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20474 /* The scalar floating-point unit (FPU) registers are mapped on
20475 * the MSA vector registers. */
20476 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20477 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20478 msa_wr_d[i * 2 + 1] =
e1ccc054 20479 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20480 }
20481
e1ccc054 20482 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20483 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20484 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20485 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20486 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20487 regnames_HI[i]);
e1ccc054 20488 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20489 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20490 regnames_LO[i]);
4b2eb8d2 20491 }
e1ccc054 20492 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20493 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20494 "DSPControl");
e1ccc054 20495 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20496 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20497 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20498 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20499 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20500 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20501
e1ccc054 20502 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20503 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20504 "fcr0");
e1ccc054 20505 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20506 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20507 "fcr31");
39454628
TS
20508
20509 inited = 1;
20510}
20511
aaed909a
FB
20512#include "translate_init.c"
20513
30bf942d 20514MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 20515{
0f71a709 20516 MIPSCPU *cpu;
6af0bf9c 20517 CPUMIPSState *env;
c227f099 20518 const mips_def_t *def;
6af0bf9c 20519
aaed909a
FB
20520 def = cpu_mips_find_by_name(cpu_model);
20521 if (!def)
20522 return NULL;
0f71a709
AF
20523 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20524 env = &cpu->env;
aaed909a 20525 env->cpu_model = def;
89777fd1 20526 env->exception_base = (int32_t)0xBFC00000;
aaed909a 20527
51cc2e78
BS
20528#ifndef CONFIG_USER_ONLY
20529 mmu_init(env, def);
20530#endif
20531 fpu_init(env, def);
20532 mvp_init(env, def);
c1caf1d9
AF
20533
20534 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20535
30bf942d 20536 return cpu;
6ae81775
TS
20537}
20538
bff384a4
LA
20539bool cpu_supports_cps_smp(const char *cpu_model)
20540{
20541 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20542 if (!def) {
20543 return false;
20544 }
20545
20546 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20547}
20548
bed9e5ce
PB
20549bool cpu_supports_isa(const char *cpu_model, unsigned int isa)
20550{
20551 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20552 if (!def) {
20553 return false;
20554 }
20555
20556 return (def->insn_flags & isa) != 0;
20557}
20558
89777fd1
LA
20559void cpu_set_exception_base(int vp_index, target_ulong address)
20560{
20561 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20562 vp->env.exception_base = address;
20563}
20564
1bba0dc9 20565void cpu_state_reset(CPUMIPSState *env)
6ae81775 20566{
55e5c285
AF
20567 MIPSCPU *cpu = mips_env_get_cpu(env);
20568 CPUState *cs = CPU(cpu);
6ae81775 20569
51cc2e78
BS
20570 /* Reset registers to their default values */
20571 env->CP0_PRid = env->cpu_model->CP0_PRid;
20572 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20573#ifdef TARGET_WORDS_BIGENDIAN
20574 env->CP0_Config0 |= (1 << CP0C0_BE);
20575#endif
20576 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20577 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20578 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20579 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20580 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20581 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20582 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20583 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20584 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20585 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20586 << env->cpu_model->CP0_LLAddr_shift;
20587 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20588 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20589 env->CCRes = env->cpu_model->CCRes;
20590 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20591 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20592 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20593 env->current_tc = 0;
20594 env->SEGBITS = env->cpu_model->SEGBITS;
20595 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20596#if defined(TARGET_MIPS64)
20597 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20598 env->SEGMask |= 3ULL << 62;
20599 }
20600#endif
20601 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20602 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20603 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20604 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20605 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20606 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20607 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20608 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20609 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20610 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20611 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20612 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20613 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 20614 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 20615 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20616 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20617 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20618 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20619 env->insn_flags = env->cpu_model->insn_flags;
20620
0eaef5aa 20621#if defined(CONFIG_USER_ONLY)
03e6e501 20622 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20623# ifdef TARGET_MIPS64
20624 /* Enable 64-bit register mode. */
20625 env->CP0_Status |= (1 << CP0St_PX);
20626# endif
20627# ifdef TARGET_ABI_MIPSN64
20628 /* Enable 64-bit address mode. */
20629 env->CP0_Status |= (1 << CP0St_UX);
20630# endif
94159135
MI
20631 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20632 hardware registers. */
20633 env->CP0_HWREna |= 0x0000000F;
91a75935 20634 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20635 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20636 }
6f0af304
PJ
20637 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20638 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20639 }
4d66261f
PJ
20640# if defined(TARGET_MIPS64)
20641 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20642 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20643 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20644 env->CP0_Status |= (1 << CP0St_FR);
20645 }
4d66261f 20646# endif
932e71cd
AJ
20647#else
20648 if (env->hflags & MIPS_HFLAG_BMASK) {
20649 /* If the exception was raised from a delay slot,
20650 come back to the jump. */
c3577479
MR
20651 env->CP0_ErrorEPC = (env->active_tc.PC
20652 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20653 } else {
932e71cd
AJ
20654 env->CP0_ErrorEPC = env->active_tc.PC;
20655 }
89777fd1 20656 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20657 env->CP0_Random = env->tlb->nb_tlb - 1;
20658 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20659 env->CP0_Wired = 0;
01bc435b 20660 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 20661 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 20662 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
20663 env->CP0_EBase |= 0x40000000;
20664 } else {
74dbf824 20665 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 20666 }
c870e3f5
YK
20667 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20668 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20669 }
a0c80608
PB
20670 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20671 0x3ff : 0xff;
932e71cd
AJ
20672 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20673 /* vectored interrupts not implemented, timer on int 7,
20674 no performance counters. */
20675 env->CP0_IntCtl = 0xe0000000;
20676 {
20677 int i;
20678
20679 for (i = 0; i < 7; i++) {
20680 env->CP0_WatchLo[i] = 0;
20681 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20682 }
932e71cd
AJ
20683 env->CP0_WatchLo[7] = 0;
20684 env->CP0_WatchHi[7] = 0;
fd88b6ab 20685 }
932e71cd
AJ
20686 /* Count register increments in debug mode, EJTAG version 1 */
20687 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20688
4b69c7e2
JH
20689 cpu_mips_store_count(env, 1);
20690
9e56e756
EI
20691 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20692 int i;
20693
20694 /* Only TC0 on VPE 0 starts as active. */
20695 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20696 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20697 env->tcs[i].CP0_TCHalt = 1;
20698 }
20699 env->active_tc.CP0_TCHalt = 1;
259186a7 20700 cs->halted = 1;
9e56e756 20701
55e5c285 20702 if (cs->cpu_index == 0) {
9e56e756
EI
20703 /* VPE0 starts up enabled. */
20704 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20705 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20706
20707 /* TC0 starts up unhalted. */
259186a7 20708 cs->halted = 0;
9e56e756
EI
20709 env->active_tc.CP0_TCHalt = 0;
20710 env->tcs[0].CP0_TCHalt = 0;
20711 /* With thread 0 active. */
20712 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20713 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20714 }
20715 }
cec56a73
JH
20716
20717 /*
20718 * Configure default legacy segmentation control. We use this regardless of
20719 * whether segmentation control is presented to the guest.
20720 */
20721 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20722 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
20723 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20724 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20725 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20726 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20727 (2 << CP0SC_C);
20728 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20729 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20730 (3 << CP0SC_C)) << 16;
20731 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20732 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20733 (1 << CP0SC_EU) | (2 << CP0SC_C);
20734 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20735 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20736 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20737 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20738 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 20739#endif
ddc584bd
LA
20740 if ((env->insn_flags & ISA_MIPS32R6) &&
20741 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20742 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20743 env->CP0_Status |= (1 << CP0St_FR);
20744 }
20745
863f264d
YK
20746 /* MSA */
20747 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20748 msa_reset(env);
20749 }
20750
03e6e501 20751 compute_hflags(env);
599bc5e8 20752 restore_fp_status(env);
e117f526 20753 restore_pamask(env);
27103424 20754 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20755
20756 if (semihosting_get_argc()) {
20757 /* UHI interface can be used to obtain argc and argv */
20758 env->active_tc.gpr[4] = -1;
20759 }
6af0bf9c 20760}
d2856f1a 20761
bad729e2
RH
20762void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20763 target_ulong *data)
d2856f1a 20764{
bad729e2 20765 env->active_tc.PC = data[0];
d2856f1a 20766 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20767 env->hflags |= data[1];
4636401d
AJ
20768 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20769 case MIPS_HFLAG_BR:
20770 break;
20771 case MIPS_HFLAG_BC:
20772 case MIPS_HFLAG_BL:
20773 case MIPS_HFLAG_B:
bad729e2 20774 env->btarget = data[2];
4636401d
AJ
20775 break;
20776 }
d2856f1a 20777}