]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: check CP0 enabled for CACHE instruction also in R6
[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"
57fec1fe 27#include "tcg-op.h"
f08b6170 28#include "exec/cpu_ldst.h"
6af0bf9c 29
2ef6175a
RH
30#include "exec/helper-proto.h"
31#include "exec/helper-gen.h"
0a2672b7 32#include "sysemu/kvm.h"
3b3c1694 33#include "exec/semihost.h"
a7812ae4 34
a7e30d84 35#include "trace-tcg.h"
508127e2 36#include "exec/log.h"
a7e30d84 37
fb7729e2 38#define MIPS_DEBUG_DISAS 0
6af0bf9c 39
7a387fff
TS
40/* MIPS major opcodes */
41#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
42
43enum {
44 /* indirect opcode tables */
7a387fff
TS
45 OPC_SPECIAL = (0x00 << 26),
46 OPC_REGIMM = (0x01 << 26),
47 OPC_CP0 = (0x10 << 26),
48 OPC_CP1 = (0x11 << 26),
49 OPC_CP2 = (0x12 << 26),
50 OPC_CP3 = (0x13 << 26),
51 OPC_SPECIAL2 = (0x1C << 26),
52 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 53 /* arithmetic with immediate */
7a387fff
TS
54 OPC_ADDI = (0x08 << 26),
55 OPC_ADDIU = (0x09 << 26),
56 OPC_SLTI = (0x0A << 26),
57 OPC_SLTIU = (0x0B << 26),
324d9e32 58 /* logic with immediate */
7a387fff
TS
59 OPC_ANDI = (0x0C << 26),
60 OPC_ORI = (0x0D << 26),
61 OPC_XORI = (0x0E << 26),
62 OPC_LUI = (0x0F << 26),
324d9e32 63 /* arithmetic with immediate */
7a387fff
TS
64 OPC_DADDI = (0x18 << 26),
65 OPC_DADDIU = (0x19 << 26),
e37e863f 66 /* Jump and branches */
7a387fff
TS
67 OPC_J = (0x02 << 26),
68 OPC_JAL = (0x03 << 26),
69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
b231c103 77 OPC_JALX = (0x1D << 26),
d4ea6acd 78 OPC_DAUI = (0x1D << 26),
e37e863f 79 /* Load and stores */
7a387fff
TS
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
364d4831 86 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
364d4831 101 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
102 OPC_SC = (0x38 << 26),
103 OPC_SCD = (0x3C << 26),
104 OPC_SD = (0x3F << 26),
e37e863f 105 /* Floating point load/store */
7a387fff
TS
106 OPC_LWC1 = (0x31 << 26),
107 OPC_LWC2 = (0x32 << 26),
108 OPC_LDC1 = (0x35 << 26),
109 OPC_LDC2 = (0x36 << 26),
110 OPC_SWC1 = (0x39 << 26),
111 OPC_SWC2 = (0x3A << 26),
112 OPC_SDC1 = (0x3D << 26),
113 OPC_SDC2 = (0x3E << 26),
31837be3
YK
114 /* Compact Branches */
115 OPC_BLEZALC = (0x06 << 26),
116 OPC_BGEZALC = (0x06 << 26),
117 OPC_BGEUC = (0x06 << 26),
118 OPC_BGTZALC = (0x07 << 26),
119 OPC_BLTZALC = (0x07 << 26),
120 OPC_BLTUC = (0x07 << 26),
121 OPC_BOVC = (0x08 << 26),
122 OPC_BEQZALC = (0x08 << 26),
123 OPC_BEQC = (0x08 << 26),
124 OPC_BLEZC = (0x16 << 26),
125 OPC_BGEZC = (0x16 << 26),
126 OPC_BGEC = (0x16 << 26),
127 OPC_BGTZC = (0x17 << 26),
128 OPC_BLTZC = (0x17 << 26),
129 OPC_BLTC = (0x17 << 26),
130 OPC_BNVC = (0x18 << 26),
131 OPC_BNEZALC = (0x18 << 26),
132 OPC_BNEC = (0x18 << 26),
133 OPC_BC = (0x32 << 26),
134 OPC_BEQZC = (0x36 << 26),
135 OPC_JIC = (0x36 << 26),
136 OPC_BALC = (0x3A << 26),
137 OPC_BNEZC = (0x3E << 26),
138 OPC_JIALC = (0x3E << 26),
7a387fff
TS
139 /* MDMX ASE specific */
140 OPC_MDMX = (0x1E << 26),
239dfebe
YK
141 /* MSA ASE, same as MDMX */
142 OPC_MSA = OPC_MDMX,
e37e863f 143 /* Cache and prefetch */
7a387fff
TS
144 OPC_CACHE = (0x2F << 26),
145 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
146 /* PC-relative address computation / loads */
147 OPC_PCREL = (0x3B << 26),
148};
149
150/* PC-relative address computation / loads */
151#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
152#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153enum {
154 /* Instructions determined by bits 19 and 20 */
155 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
156 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
157 OPC_LWUPC = OPC_PCREL | (2 << 19),
158
159 /* Instructions determined by bits 16 ... 20 */
160 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
161 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
162
163 /* Other */
164 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
165};
166
167/* MIPS special opcodes */
7a387fff
TS
168#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
169
e37e863f
FB
170enum {
171 /* Shifts */
7a387fff 172 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
173 /* NOP is SLL r0, r0, 0 */
174 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
175 /* EHB is SLL r0, r0, 3 */
176 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 177 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
178 OPC_SRA = 0x03 | OPC_SPECIAL,
179 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 180 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 181 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
182 OPC_SRAV = 0x07 | OPC_SPECIAL,
183 OPC_DSLLV = 0x14 | OPC_SPECIAL,
184 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 185 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
186 OPC_DSRAV = 0x17 | OPC_SPECIAL,
187 OPC_DSLL = 0x38 | OPC_SPECIAL,
188 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 189 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
190 OPC_DSRA = 0x3B | OPC_SPECIAL,
191 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
192 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 193 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 194 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 195 /* Multiplication / division */
7a387fff
TS
196 OPC_MULT = 0x18 | OPC_SPECIAL,
197 OPC_MULTU = 0x19 | OPC_SPECIAL,
198 OPC_DIV = 0x1A | OPC_SPECIAL,
199 OPC_DIVU = 0x1B | OPC_SPECIAL,
200 OPC_DMULT = 0x1C | OPC_SPECIAL,
201 OPC_DMULTU = 0x1D | OPC_SPECIAL,
202 OPC_DDIV = 0x1E | OPC_SPECIAL,
203 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 204
e37e863f 205 /* 2 registers arithmetic / logic */
7a387fff
TS
206 OPC_ADD = 0x20 | OPC_SPECIAL,
207 OPC_ADDU = 0x21 | OPC_SPECIAL,
208 OPC_SUB = 0x22 | OPC_SPECIAL,
209 OPC_SUBU = 0x23 | OPC_SPECIAL,
210 OPC_AND = 0x24 | OPC_SPECIAL,
211 OPC_OR = 0x25 | OPC_SPECIAL,
212 OPC_XOR = 0x26 | OPC_SPECIAL,
213 OPC_NOR = 0x27 | OPC_SPECIAL,
214 OPC_SLT = 0x2A | OPC_SPECIAL,
215 OPC_SLTU = 0x2B | OPC_SPECIAL,
216 OPC_DADD = 0x2C | OPC_SPECIAL,
217 OPC_DADDU = 0x2D | OPC_SPECIAL,
218 OPC_DSUB = 0x2E | OPC_SPECIAL,
219 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 220 /* Jumps */
7a387fff
TS
221 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
222 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 223 /* Traps */
7a387fff
TS
224 OPC_TGE = 0x30 | OPC_SPECIAL,
225 OPC_TGEU = 0x31 | OPC_SPECIAL,
226 OPC_TLT = 0x32 | OPC_SPECIAL,
227 OPC_TLTU = 0x33 | OPC_SPECIAL,
228 OPC_TEQ = 0x34 | OPC_SPECIAL,
229 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 230 /* HI / LO registers load & stores */
7a387fff
TS
231 OPC_MFHI = 0x10 | OPC_SPECIAL,
232 OPC_MTHI = 0x11 | OPC_SPECIAL,
233 OPC_MFLO = 0x12 | OPC_SPECIAL,
234 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 235 /* Conditional moves */
7a387fff
TS
236 OPC_MOVZ = 0x0A | OPC_SPECIAL,
237 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 238
b691d9d2
LA
239 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
240 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
241
7a387fff 242 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
243
244 /* Special */
a0d700e4 245 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
246 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
247 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 248 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
249 OPC_SYNC = 0x0F | OPC_SPECIAL,
250
7a387fff
TS
251 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
252 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
253 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
254 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
255};
256
b42ee5e1
LA
257/* R6 Multiply and Divide instructions have the same Opcode
258 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
259#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260
261enum {
262 R6_OPC_MUL = OPC_MULT | (2 << 6),
263 R6_OPC_MUH = OPC_MULT | (3 << 6),
264 R6_OPC_MULU = OPC_MULTU | (2 << 6),
265 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
266 R6_OPC_DIV = OPC_DIV | (2 << 6),
267 R6_OPC_MOD = OPC_DIV | (3 << 6),
268 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
269 R6_OPC_MODU = OPC_DIVU | (3 << 6),
270
271 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
272 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
273 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
274 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
275 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
276 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
277 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
278 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
279
280 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
281 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
282 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
283 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
284 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
285
286 OPC_LSA = 0x05 | OPC_SPECIAL,
287 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
288};
289
e9c71dd1
TS
290/* Multiplication variants of the vr54xx. */
291#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
292
293enum {
294 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
295 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
296 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
297 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
298 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
299 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
301 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
303 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
304 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
305 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
306 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
307 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
308};
309
7a387fff
TS
310/* REGIMM (rt field) opcodes */
311#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
312
313enum {
314 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
315 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
316 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
317 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
318 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
319 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
320 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
321 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
322 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
323 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
324 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
325 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
326 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
327 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 328 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 329 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
330
331 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
332 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
333};
334
7a387fff
TS
335/* Special2 opcodes */
336#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
337
e37e863f 338enum {
7a387fff
TS
339 /* Multiply & xxx operations */
340 OPC_MADD = 0x00 | OPC_SPECIAL2,
341 OPC_MADDU = 0x01 | OPC_SPECIAL2,
342 OPC_MUL = 0x02 | OPC_SPECIAL2,
343 OPC_MSUB = 0x04 | OPC_SPECIAL2,
344 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
345 /* Loongson 2F */
346 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
347 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
348 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
349 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
350 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
351 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
352 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
353 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
354 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
355 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
356 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
357 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 358 /* Misc */
7a387fff
TS
359 OPC_CLZ = 0x20 | OPC_SPECIAL2,
360 OPC_CLO = 0x21 | OPC_SPECIAL2,
361 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
362 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 363 /* Special */
7a387fff
TS
364 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
365};
366
367/* Special3 opcodes */
368#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
369
370enum {
371 OPC_EXT = 0x00 | OPC_SPECIAL3,
372 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
373 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
374 OPC_DEXT = 0x03 | OPC_SPECIAL3,
375 OPC_INS = 0x04 | OPC_SPECIAL3,
376 OPC_DINSM = 0x05 | OPC_SPECIAL3,
377 OPC_DINSU = 0x06 | OPC_SPECIAL3,
378 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
379 OPC_FORK = 0x08 | OPC_SPECIAL3,
380 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
381 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
382 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
383 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
384
385 /* Loongson 2E */
386 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
387 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
388 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
389 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
390 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
391 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
392 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
393 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
394 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
395 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
396 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
397 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
398
399 /* MIPS DSP Load */
400 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
401 /* MIPS DSP Arithmetic */
402 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 403 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 404 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 405 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
406 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
407 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
408 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 409 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
410 /* MIPS DSP GPR-Based Shift Sub-class */
411 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 412 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
413 /* MIPS DSP Multiply Sub-class insns */
414 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
415 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
416 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 417 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
418 /* DSP Bit/Manipulation Sub-class */
419 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 420 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 421 /* MIPS DSP Append Sub-class */
26690560 422 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 423 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
424 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
425 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 426 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
427
428 /* R6 */
bf7910c6
LA
429 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
430 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
431 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
432 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
433 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
434 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
435};
436
7a387fff
TS
437/* BSHFL opcodes */
438#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
439
e37e863f 440enum {
15eacb9b
YK
441 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
442 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
443 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
444 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
445 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
446 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
447};
448
7a387fff
TS
449/* DBSHFL opcodes */
450#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
451
e37e863f 452enum {
15eacb9b
YK
453 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
454 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
455 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
456 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
457 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
458};
459
e45a93e2
JL
460/* MIPS DSP REGIMM opcodes */
461enum {
462 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 463 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
464};
465
9b1a1d68
JL
466#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467/* MIPS DSP Load */
468enum {
469 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
470 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
471 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 472 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
473};
474
461c08df
JL
475#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
476enum {
477 /* MIPS DSP Arithmetic Sub-class */
478 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
492 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
493 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
494 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
495 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
496 /* MIPS DSP Multiply Sub-class insns */
497 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
503};
504
505#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
506#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507enum {
508 /* MIPS DSP Arithmetic Sub-class */
509 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
521 /* MIPS DSP Multiply Sub-class insns */
522 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
526};
527
528#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529enum {
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
544 /* DSP Bit/Manipulation Sub-class */
545 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
550};
551
552#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553enum {
554 /* MIPS DSP Arithmetic Sub-class */
555 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
562 /* DSP Compare-Pick Sub-class */
563 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 578};
a22260ae 579
77c5fa8b
JL
580#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
581enum {
582 /* MIPS DSP GPR-Based Shift Sub-class */
583 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
605};
461c08df 606
a22260ae
JL
607#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608enum {
609 /* MIPS DSP Multiply Sub-class insns */
610 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
626 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
632};
633
1cb6686c
JL
634#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635enum {
636 /* DSP Bit/Manipulation Sub-class */
637 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
638};
639
26690560
JL
640#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641enum {
df6126a7 642 /* MIPS DSP Append Sub-class */
26690560
JL
643 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
644 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
645 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
646};
647
b53371ed
JL
648#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
649enum {
650 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
651 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
663 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
664 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
665 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
666 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
667 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
668};
669
461c08df
JL
670#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
672 /* MIPS DSP Arithmetic Sub-class */
673 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
690 /* DSP Bit/Manipulation Sub-class */
691 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 697};
461c08df 698
461c08df
JL
699#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700enum {
a22260ae
JL
701 /* MIPS DSP Multiply Sub-class insns */
702 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
707 /* MIPS DSP Arithmetic Sub-class */
708 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
729};
461c08df 730
461c08df
JL
731#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
732enum {
26690560
JL
733 /* DSP Compare-Pick Sub-class */
734 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
753 /* MIPS DSP Arithmetic Sub-class */
754 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
762};
461c08df 763
26690560
JL
764#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765enum {
df6126a7 766 /* DSP Append Sub-class */
26690560
JL
767 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
768 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
769 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
770 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
771};
26690560 772
b53371ed
JL
773#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
774enum {
775 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
776 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
777 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
797};
798
1cb6686c
JL
799#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
800enum {
801 /* DSP Bit/Manipulation Sub-class */
802 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
803};
1cb6686c 804
a22260ae
JL
805#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
806enum {
807 /* MIPS DSP Multiply Sub-class insns */
808 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
834};
a22260ae 835
77c5fa8b
JL
836#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837enum {
838 /* MIPS DSP GPR-Based Shift Sub-class */
839 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
865};
77c5fa8b 866
7a387fff
TS
867/* Coprocessor 0 (rs field) */
868#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
869
6ea83fed 870enum {
7a387fff
TS
871 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
872 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 873 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
874 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
875 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 876 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 877 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
878 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
879 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 880 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
881 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
882 OPC_C0 = (0x10 << 21) | OPC_CP0,
883 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
884 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 885};
7a387fff
TS
886
887/* MFMC0 opcodes */
b48cfdff 888#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
889
890enum {
ead9360e
TS
891 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
894 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
895 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
896 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
897 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
898 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
899};
900
901/* Coprocessor 0 (with rs == C0) */
902#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
903
904enum {
905 OPC_TLBR = 0x01 | OPC_C0,
906 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
907 OPC_TLBINV = 0x03 | OPC_C0,
908 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
909 OPC_TLBWR = 0x06 | OPC_C0,
910 OPC_TLBP = 0x08 | OPC_C0,
911 OPC_RFE = 0x10 | OPC_C0,
912 OPC_ERET = 0x18 | OPC_C0,
913 OPC_DERET = 0x1F | OPC_C0,
914 OPC_WAIT = 0x20 | OPC_C0,
915};
916
917/* Coprocessor 1 (rs field) */
918#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
919
bf4120ad
NF
920/* Values for the fmt field in FP instructions */
921enum {
922 /* 0 - 15 are reserved */
e459440a
AJ
923 FMT_S = 16, /* single fp */
924 FMT_D = 17, /* double fp */
925 FMT_E = 18, /* extended fp */
926 FMT_Q = 19, /* quad fp */
927 FMT_W = 20, /* 32-bit fixed */
928 FMT_L = 21, /* 64-bit fixed */
929 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
930 /* 23 - 31 are reserved */
931};
932
7a387fff
TS
933enum {
934 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
935 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
936 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 937 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
938 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
939 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
940 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 941 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 942 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
943 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
944 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
945 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
946 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
947 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
948 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
949 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
950 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
951 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
952 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
953 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
954 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
955 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
956 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
957 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
958 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
959 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
960 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
961 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
962 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
963 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
964};
965
5a5012ec
TS
966#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
967#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
968
7a387fff
TS
969enum {
970 OPC_BC1F = (0x00 << 16) | OPC_BC1,
971 OPC_BC1T = (0x01 << 16) | OPC_BC1,
972 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
973 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
974};
975
5a5012ec
TS
976enum {
977 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
978 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
979};
980
981enum {
982 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
983 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
984};
7a387fff
TS
985
986#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
987
988enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1000};
1001
bd277fa1
RH
1002#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
e0c84da7
TS
1099#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1100
1101enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1117 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1118 OPC_NMADD_PS= 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1122};
1123
239dfebe
YK
1124/* MSA Opcodes */
1125#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1126enum {
1127 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1128 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1129 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1130 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1131 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1132 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1133 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1134 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1135 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1136 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1137 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1138 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1139 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1140 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1141 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1142 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1143 OPC_MSA_ELM = 0x19 | OPC_MSA,
1144 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1145 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1146 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1147 OPC_MSA_VEC = 0x1E | OPC_MSA,
1148
1149 /* MI10 instruction */
1150 OPC_LD_B = (0x20) | OPC_MSA,
1151 OPC_LD_H = (0x21) | OPC_MSA,
1152 OPC_LD_W = (0x22) | OPC_MSA,
1153 OPC_LD_D = (0x23) | OPC_MSA,
1154 OPC_ST_B = (0x24) | OPC_MSA,
1155 OPC_ST_H = (0x25) | OPC_MSA,
1156 OPC_ST_W = (0x26) | OPC_MSA,
1157 OPC_ST_D = (0x27) | OPC_MSA,
1158};
1159
1160enum {
1161 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1162 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1163 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1164 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1165 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1166 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1167 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1168 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1169 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1170 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1171 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1172 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1173 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1174
1175 /* I8 instruction */
1176 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1177 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1179 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1180 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1181 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1182 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1183 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1184 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1185 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1186
1187 /* VEC/2R/2RF instruction */
1188 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1189 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1190 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1191 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1192 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1193 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1194 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1195
1196 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1197 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1198
1199 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1200 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1201 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1202 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1203 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1204
1205 /* 2RF instruction df(bit 16) = _w, _d */
1206 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1207 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1208 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1209 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1210 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1211 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1212 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1213 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1214 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1215 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1216 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1217 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1218 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1219 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1220 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1221 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1222
1223 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1224 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1225 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1226 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1227 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1228 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1229 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1230 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1231 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1232 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1233 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1234 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1235 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1236 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1237 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1238 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1239 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1240 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1241 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1242 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1243 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1244 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1245 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1246 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1247 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1248 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1249 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1250 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1251 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1252 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1253 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1254 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1255 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1256 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1257 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1258 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1259 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1260 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1261 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1262 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1263 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1264 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1265 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1266 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1267 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1268 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1269 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1270 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1271 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1272 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1273 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1274 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1276 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1281 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1282 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1283 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1284 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1285 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1286 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1287
1288 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1289 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1291 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298
1299 /* 3RF instruction _df(bit 21) = _w, _d */
1300 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1307 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1310 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1312 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1313 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1316 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1317 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1318 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1320 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1322 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1323 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1326 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1327 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1329 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1332 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1335 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1336 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1337 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1338 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1339 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1340 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1341
1342 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1343 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1344 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1345 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1346 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1347 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1348 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1349 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1350 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1351 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1352 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1353 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1354 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1355};
1356
39454628 1357/* global register indices */
1bcea73e 1358static TCGv_env cpu_env;
a7812ae4 1359static TCGv cpu_gpr[32], cpu_PC;
340fff72 1360static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1361static TCGv cpu_dspctrl, btarget, bcond;
1362static TCGv_i32 hflags;
a7812ae4 1363static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1364static TCGv_i64 fpu_f64[32];
863f264d 1365static TCGv_i64 msa_wr_d[64];
aa0bf00b 1366
022c62cb 1367#include "exec/gen-icount.h"
2e70f6ef 1368
895c2d04 1369#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1370 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1371 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1372 tcg_temp_free_i32(helper_tmp); \
1373 } while(0)
be24bb4f 1374
895c2d04 1375#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1376 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1377 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1378 tcg_temp_free_i32(helper_tmp); \
1379 } while(0)
be24bb4f 1380
895c2d04
BS
1381#define gen_helper_1e0i(name, ret, arg1) do { \
1382 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1383 gen_helper_##name(ret, cpu_env, helper_tmp); \
1384 tcg_temp_free_i32(helper_tmp); \
1385 } while(0)
1386
1387#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1388 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1389 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1390 tcg_temp_free_i32(helper_tmp); \
1391 } while(0)
1392
1393#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1394 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1395 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1396 tcg_temp_free_i32(helper_tmp); \
1397 } while(0)
1398
1399#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1400 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1401 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1402 tcg_temp_free_i32(helper_tmp); \
1403 } while(0)
be24bb4f 1404
895c2d04 1405#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1406 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1407 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1408 tcg_temp_free_i32(helper_tmp); \
1409 } while(0)
c239529e 1410
8e9ade68
TS
1411typedef struct DisasContext {
1412 struct TranslationBlock *tb;
1413 target_ulong pc, saved_pc;
1414 uint32_t opcode;
7b270ef2 1415 int singlestep_enabled;
d75c135e 1416 int insn_flags;
5ab5c041 1417 int32_t CP0_Config1;
8e9ade68
TS
1418 /* Routine used to access memory */
1419 int mem_idx;
be3a8c53 1420 TCGMemOp default_tcg_memop_mask;
8e9ade68
TS
1421 uint32_t hflags, saved_hflags;
1422 int bstate;
1423 target_ulong btarget;
d279279e 1424 bool ulri;
e98c0d17 1425 int kscrexist;
7207c7f9 1426 bool rxi;
9456c2fb 1427 int ie;
aea14095
LA
1428 bool bi;
1429 bool bp;
5204ea79
LA
1430 uint64_t PAMask;
1431 bool mvh;
1432 int CP0_LLAddr_shift;
e29c9628 1433 bool ps;
01bc435b 1434 bool vp;
c870e3f5 1435 bool cmgcr;
8e9ade68
TS
1436} DisasContext;
1437
1438enum {
1439 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1440 * exception condition */
8e9ade68
TS
1441 BS_STOP = 1, /* We want to stop translation for any reason */
1442 BS_BRANCH = 2, /* We reached a branch condition */
1443 BS_EXCP = 3, /* We reached an exception condition */
1444};
1445
d73ee8a2
RH
1446static const char * const regnames[] = {
1447 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1448 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1449 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1450 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1451};
6af0bf9c 1452
d73ee8a2
RH
1453static const char * const regnames_HI[] = {
1454 "HI0", "HI1", "HI2", "HI3",
1455};
4b2eb8d2 1456
d73ee8a2
RH
1457static const char * const regnames_LO[] = {
1458 "LO0", "LO1", "LO2", "LO3",
1459};
4b2eb8d2 1460
d73ee8a2
RH
1461static const char * const fregnames[] = {
1462 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1463 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1464 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1465 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1466};
958fb4a9 1467
863f264d
YK
1468static const char * const msaregnames[] = {
1469 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1470 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1471 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1472 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1473 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1474 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1475 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1476 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1477 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1478 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1479 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1480 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1481 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1482 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1483 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1484 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1485};
1486
9d68ac14 1487#define LOG_DISAS(...) \
fb7729e2
RH
1488 do { \
1489 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1490 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1491 } \
1492 } while (0)
1493
9d68ac14 1494#define MIPS_INVAL(op) \
fb7729e2
RH
1495 do { \
1496 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1497 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1498 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1499 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1500 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1501 } \
1502 } while (0)
958fb4a9 1503
8e9ade68
TS
1504/* General purpose registers moves. */
1505static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1506{
8e9ade68
TS
1507 if (reg == 0)
1508 tcg_gen_movi_tl(t, 0);
1509 else
4b2eb8d2 1510 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1511}
1512
8e9ade68 1513static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1514{
8e9ade68 1515 if (reg != 0)
4b2eb8d2 1516 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1517}
1518
8e9ade68 1519/* Moves to/from shadow registers. */
be24bb4f 1520static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1521{
d9bea114 1522 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1523
1524 if (from == 0)
d9bea114 1525 tcg_gen_movi_tl(t0, 0);
8e9ade68 1526 else {
d9bea114 1527 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1528 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1529
7db13fae 1530 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1531 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1532 tcg_gen_andi_i32(t2, t2, 0xf);
1533 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1534 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1535 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1536
d9bea114 1537 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1538 tcg_temp_free_ptr(addr);
d9bea114 1539 tcg_temp_free_i32(t2);
8e9ade68 1540 }
d9bea114
AJ
1541 gen_store_gpr(t0, to);
1542 tcg_temp_free(t0);
aaa9128a
TS
1543}
1544
be24bb4f 1545static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1546{
be24bb4f 1547 if (to != 0) {
d9bea114
AJ
1548 TCGv t0 = tcg_temp_new();
1549 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1550 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1551
d9bea114 1552 gen_load_gpr(t0, from);
7db13fae 1553 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1554 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1555 tcg_gen_andi_i32(t2, t2, 0xf);
1556 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1557 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1558 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1559
d9bea114 1560 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1561 tcg_temp_free_ptr(addr);
d9bea114
AJ
1562 tcg_temp_free_i32(t2);
1563 tcg_temp_free(t0);
8e9ade68 1564 }
aaa9128a
TS
1565}
1566
eab9944c
LA
1567/* Tests */
1568static inline void gen_save_pc(target_ulong pc)
1569{
1570 tcg_gen_movi_tl(cpu_PC, pc);
1571}
1572
1573static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1574{
1575 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1576 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1577 gen_save_pc(ctx->pc);
1578 ctx->saved_pc = ctx->pc;
1579 }
1580 if (ctx->hflags != ctx->saved_hflags) {
1581 tcg_gen_movi_i32(hflags, ctx->hflags);
1582 ctx->saved_hflags = ctx->hflags;
1583 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1584 case MIPS_HFLAG_BR:
1585 break;
1586 case MIPS_HFLAG_BC:
1587 case MIPS_HFLAG_BL:
1588 case MIPS_HFLAG_B:
1589 tcg_gen_movi_tl(btarget, ctx->btarget);
1590 break;
1591 }
1592 }
1593}
1594
1595static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1596{
1597 ctx->saved_hflags = ctx->hflags;
1598 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1599 case MIPS_HFLAG_BR:
1600 break;
1601 case MIPS_HFLAG_BC:
1602 case MIPS_HFLAG_BL:
1603 case MIPS_HFLAG_B:
1604 ctx->btarget = env->btarget;
1605 break;
1606 }
1607}
1608
1609static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1610{
1611 TCGv_i32 texcp = tcg_const_i32(excp);
1612 TCGv_i32 terr = tcg_const_i32(err);
1613 save_cpu_state(ctx, 1);
1614 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1615 tcg_temp_free_i32(terr);
1616 tcg_temp_free_i32(texcp);
9c708c7f 1617 ctx->bstate = BS_EXCP;
eab9944c
LA
1618}
1619
1620static inline void generate_exception(DisasContext *ctx, int excp)
1621{
eab9944c
LA
1622 gen_helper_0e0i(raise_exception, excp);
1623}
1624
9c708c7f
PD
1625static inline void generate_exception_end(DisasContext *ctx, int excp)
1626{
1627 generate_exception_err(ctx, excp, 0);
1628}
1629
aaa9128a 1630/* Floating point register moves. */
7c979afd 1631static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1632{
7c979afd
LA
1633 if (ctx->hflags & MIPS_HFLAG_FRE) {
1634 generate_exception(ctx, EXCP_RI);
1635 }
ecc7b3aa 1636 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1637}
1638
7c979afd 1639static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1640{
7c979afd
LA
1641 TCGv_i64 t64;
1642 if (ctx->hflags & MIPS_HFLAG_FRE) {
1643 generate_exception(ctx, EXCP_RI);
1644 }
1645 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1646 tcg_gen_extu_i32_i64(t64, t);
1647 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1648 tcg_temp_free_i64(t64);
6d066274
AJ
1649}
1650
7f6613ce 1651static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1652{
7f6613ce 1653 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1654 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1655 } else {
7c979afd 1656 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1657 }
6d066274
AJ
1658}
1659
7f6613ce 1660static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1661{
7f6613ce
PJ
1662 if (ctx->hflags & MIPS_HFLAG_F64) {
1663 TCGv_i64 t64 = tcg_temp_new_i64();
1664 tcg_gen_extu_i32_i64(t64, t);
1665 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1666 tcg_temp_free_i64(t64);
1667 } else {
7c979afd 1668 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1669 }
aa0bf00b 1670}
6ea83fed 1671
d73ee8a2 1672static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1673{
f364515c 1674 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1675 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1676 } else {
d73ee8a2 1677 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1678 }
1679}
6ea83fed 1680
d73ee8a2 1681static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1682{
f364515c 1683 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1684 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1685 } else {
d73ee8a2
RH
1686 TCGv_i64 t0;
1687 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1688 t0 = tcg_temp_new_i64();
6d066274 1689 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1690 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1691 tcg_temp_free_i64(t0);
aa0bf00b
TS
1692 }
1693}
6ea83fed 1694
d94536f4 1695static inline int get_fp_bit (int cc)
a16336e4 1696{
d94536f4
AJ
1697 if (cc)
1698 return 24 + cc;
1699 else
1700 return 23;
a16336e4
TS
1701}
1702
48d38ca5 1703/* Addresses computation */
941694d0 1704static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1705{
941694d0 1706 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1707
1708#if defined(TARGET_MIPS64)
01f72885 1709 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1710 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1711 }
1712#endif
4ad40f36
FB
1713}
1714
31837be3
YK
1715/* Addresses computation (translation time) */
1716static target_long addr_add(DisasContext *ctx, target_long base,
1717 target_long offset)
1718{
1719 target_long sum = base + offset;
1720
1721#if defined(TARGET_MIPS64)
1722 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1723 sum = (int32_t)sum;
1724 }
1725#endif
1726 return sum;
1727}
1728
71f303cd 1729/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1730static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1731{
1732#if defined(TARGET_MIPS64)
71f303cd
RH
1733 tcg_gen_ext32s_i64(ret, arg);
1734#else
1735 tcg_gen_extrl_i64_i32(ret, arg);
1736#endif
1737}
1738
1739/* Sign-extract the high 32-bits to a target_long. */
1740static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1741{
1742#if defined(TARGET_MIPS64)
1743 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1744#else
71f303cd 1745 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1746#endif
1747}
1748
356265ae 1749static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1750{
fe253235 1751 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1752 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1753}
1754
356265ae 1755static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1756{
fe253235 1757 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1758 generate_exception_err(ctx, EXCP_CpU, 1);
1759}
1760
b8aa4598
TS
1761/* Verify that the processor is running with COP1X instructions enabled.
1762 This is associated with the nabla symbol in the MIPS32 and MIPS64
1763 opcode tables. */
1764
356265ae 1765static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1766{
1767 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1768 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1769}
1770
1771/* Verify that the processor is running with 64-bit floating-point
1772 operations enabled. */
1773
356265ae 1774static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1775{
b8aa4598 1776 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1777 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1778}
1779
1780/*
1781 * Verify if floating point register is valid; an operation is not defined
1782 * if bit 0 of any register specification is set and the FR bit in the
1783 * Status register equals zero, since the register numbers specify an
1784 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1785 * in the Status register equals one, both even and odd register numbers
1786 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1787 *
1788 * Multiple 64 bit wide registers can be checked by calling
1789 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1790 */
356265ae 1791static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1792{
fe253235 1793 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1794 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1795}
1796
853c3240
JL
1797/* Verify that the processor is running with DSP instructions enabled.
1798 This is enabled by CP0 Status register MX(24) bit.
1799 */
1800
1801static inline void check_dsp(DisasContext *ctx)
1802{
1803 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1804 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1805 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1806 } else {
9c708c7f 1807 generate_exception_end(ctx, EXCP_RI);
ad153f15 1808 }
853c3240
JL
1809 }
1810}
1811
1812static inline void check_dspr2(DisasContext *ctx)
1813{
1814 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1815 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1816 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1817 } else {
9c708c7f 1818 generate_exception_end(ctx, EXCP_RI);
ad153f15 1819 }
853c3240
JL
1820 }
1821}
1822
3a95e3a7 1823/* This code generates a "reserved instruction" exception if the
e189e748 1824 CPU does not support the instruction set corresponding to flags. */
d75c135e 1825static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1826{
d75c135e 1827 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1828 generate_exception_end(ctx, EXCP_RI);
d75c135e 1829 }
3a95e3a7
TS
1830}
1831
fecd2646
LA
1832/* This code generates a "reserved instruction" exception if the
1833 CPU has corresponding flag set which indicates that the instruction
1834 has been removed. */
1835static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1836{
1837 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1838 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1839 }
1840}
1841
e29c9628
YK
1842/* This code generates a "reserved instruction" exception if the
1843 CPU does not support 64-bit paired-single (PS) floating point data type */
1844static inline void check_ps(DisasContext *ctx)
1845{
1846 if (unlikely(!ctx->ps)) {
1847 generate_exception(ctx, EXCP_RI);
1848 }
1849 check_cp1_64bitmode(ctx);
1850}
1851
c7986fd6 1852#ifdef TARGET_MIPS64
e189e748
TS
1853/* This code generates a "reserved instruction" exception if 64-bit
1854 instructions are not enabled. */
356265ae 1855static inline void check_mips_64(DisasContext *ctx)
e189e748 1856{
fe253235 1857 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1858 generate_exception_end(ctx, EXCP_RI);
e189e748 1859}
c7986fd6 1860#endif
e189e748 1861
5204ea79
LA
1862#ifndef CONFIG_USER_ONLY
1863static inline void check_mvh(DisasContext *ctx)
1864{
1865 if (unlikely(!ctx->mvh)) {
1866 generate_exception(ctx, EXCP_RI);
1867 }
1868}
1869#endif
1870
8153667c
NF
1871/* Define small wrappers for gen_load_fpr* so that we have a uniform
1872 calling interface for 32 and 64-bit FPRs. No sense in changing
1873 all callers for gen_load_fpr32 when we need the CTX parameter for
1874 this one use. */
7c979afd 1875#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1876#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1877#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1878static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1879 int ft, int fs, int cc) \
1880{ \
1881 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1882 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1883 switch (ifmt) { \
1884 case FMT_PS: \
e29c9628 1885 check_ps(ctx); \
8153667c
NF
1886 break; \
1887 case FMT_D: \
1888 if (abs) { \
1889 check_cop1x(ctx); \
1890 } \
1891 check_cp1_registers(ctx, fs | ft); \
1892 break; \
1893 case FMT_S: \
1894 if (abs) { \
1895 check_cop1x(ctx); \
1896 } \
1897 break; \
1898 } \
1899 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1900 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1901 switch (n) { \
895c2d04
BS
1902 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1903 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1904 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1905 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1906 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1907 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1908 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1909 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1910 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1911 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1912 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1913 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1914 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1915 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1916 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1917 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1918 default: abort(); \
1919 } \
1920 tcg_temp_free_i##bits (fp0); \
1921 tcg_temp_free_i##bits (fp1); \
1922}
1923
1924FOP_CONDS(, 0, d, FMT_D, 64)
1925FOP_CONDS(abs, 1, d, FMT_D, 64)
1926FOP_CONDS(, 0, s, FMT_S, 32)
1927FOP_CONDS(abs, 1, s, FMT_S, 32)
1928FOP_CONDS(, 0, ps, FMT_PS, 64)
1929FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1930#undef FOP_CONDS
3f493883
YK
1931
1932#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1933static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1934 int ft, int fs, int fd) \
1935{ \
1936 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1937 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1938 if (ifmt == FMT_D) { \
3f493883 1939 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1940 } \
1941 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1942 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1943 switch (n) { \
1944 case 0: \
1945 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 1: \
1948 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 2: \
1951 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 3: \
1954 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 4: \
1957 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 case 5: \
1960 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1961 break; \
1962 case 6: \
1963 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1964 break; \
1965 case 7: \
1966 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1967 break; \
1968 case 8: \
1969 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1970 break; \
1971 case 9: \
1972 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1973 break; \
1974 case 10: \
1975 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1976 break; \
1977 case 11: \
1978 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1979 break; \
1980 case 12: \
1981 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1982 break; \
1983 case 13: \
1984 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1985 break; \
1986 case 14: \
1987 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1988 break; \
1989 case 15: \
1990 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1991 break; \
1992 case 17: \
1993 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1994 break; \
1995 case 18: \
1996 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1997 break; \
1998 case 19: \
1999 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2000 break; \
2001 case 25: \
2002 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2003 break; \
2004 case 26: \
2005 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2006 break; \
2007 case 27: \
2008 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2009 break; \
2010 default: \
2011 abort(); \
2012 } \
2013 STORE; \
2014 tcg_temp_free_i ## bits (fp0); \
2015 tcg_temp_free_i ## bits (fp1); \
2016}
2017
2018FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2019FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2020#undef FOP_CONDNS
8153667c
NF
2021#undef gen_ldcmp_fpr32
2022#undef gen_ldcmp_fpr64
2023
958fb4a9 2024/* load/store instructions. */
e7139c44 2025#ifdef CONFIG_USER_ONLY
d9bea114 2026#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2027static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
2028{ \
2029 TCGv t0 = tcg_temp_new(); \
2030 tcg_gen_mov_tl(t0, arg1); \
2031 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2032 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2033 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2034 tcg_temp_free(t0); \
aaa9128a 2035}
e7139c44
AJ
2036#else
2037#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2038static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 2039{ \
895c2d04 2040 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
2041}
2042#endif
aaa9128a
TS
2043OP_LD_ATOMIC(ll,ld32s);
2044#if defined(TARGET_MIPS64)
2045OP_LD_ATOMIC(lld,ld64);
2046#endif
2047#undef OP_LD_ATOMIC
2048
590bc601
PB
2049#ifdef CONFIG_USER_ONLY
2050#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2051static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2052{ \
2053 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2054 TCGLabel *l1 = gen_new_label(); \
2055 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2056 \
2057 tcg_gen_andi_tl(t0, arg2, almask); \
2058 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2059 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2060 generate_exception(ctx, EXCP_AdES); \
2061 gen_set_label(l1); \
7db13fae 2062 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2063 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2064 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2065 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2066 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2067 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2068 gen_set_label(l2); \
2069 tcg_gen_movi_tl(t0, 0); \
2070 gen_store_gpr(t0, rt); \
2071 tcg_temp_free(t0); \
2072}
2073#else
2074#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2075static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2076{ \
2077 TCGv t0 = tcg_temp_new(); \
895c2d04 2078 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2079 gen_store_gpr(t0, rt); \
590bc601
PB
2080 tcg_temp_free(t0); \
2081}
2082#endif
590bc601 2083OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2084#if defined(TARGET_MIPS64)
590bc601 2085OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2086#endif
2087#undef OP_ST_ATOMIC
2088
662d7485
NF
2089static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2090 int base, int16_t offset)
2091{
2092 if (base == 0) {
2093 tcg_gen_movi_tl(addr, offset);
2094 } else if (offset == 0) {
2095 gen_load_gpr(addr, base);
2096 } else {
2097 tcg_gen_movi_tl(addr, offset);
2098 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2099 }
2100}
2101
364d4831
NF
2102static target_ulong pc_relative_pc (DisasContext *ctx)
2103{
2104 target_ulong pc = ctx->pc;
2105
2106 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2107 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2108
2109 pc -= branch_bytes;
2110 }
2111
2112 pc &= ~(target_ulong)3;
2113 return pc;
2114}
2115
5c13fdfd 2116/* Load */
d75c135e
AJ
2117static void gen_ld(DisasContext *ctx, uint32_t opc,
2118 int rt, int base, int16_t offset)
6af0bf9c 2119{
fc40787a 2120 TCGv t0, t1, t2;
afa88c3a 2121
d75c135e 2122 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2123 /* Loongson CPU uses a load to zero register for prefetch.
2124 We emulate it as a NOP. On other CPU we must perform the
2125 actual memory access. */
afa88c3a
AJ
2126 return;
2127 }
6af0bf9c 2128
afa88c3a 2129 t0 = tcg_temp_new();
662d7485 2130 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2131
6af0bf9c 2132 switch (opc) {
d26bc211 2133#if defined(TARGET_MIPS64)
6e473128 2134 case OPC_LWU:
be3a8c53
YK
2135 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2136 ctx->default_tcg_memop_mask);
78723684 2137 gen_store_gpr(t0, rt);
6e473128 2138 break;
6af0bf9c 2139 case OPC_LD:
be3a8c53
YK
2140 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2141 ctx->default_tcg_memop_mask);
78723684 2142 gen_store_gpr(t0, rt);
6af0bf9c 2143 break;
7a387fff 2144 case OPC_LLD:
bf7910c6 2145 case R6_OPC_LLD:
5c13fdfd 2146 op_ld_lld(t0, t0, ctx);
78723684 2147 gen_store_gpr(t0, rt);
7a387fff 2148 break;
6af0bf9c 2149 case OPC_LDL:
3cee3050 2150 t1 = tcg_temp_new();
908680c6
AJ
2151 /* Do a byte access to possibly trigger a page
2152 fault with the unaligned address. */
2153 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2154 tcg_gen_andi_tl(t1, t0, 7);
2155#ifndef TARGET_WORDS_BIGENDIAN
2156 tcg_gen_xori_tl(t1, t1, 7);
2157#endif
2158 tcg_gen_shli_tl(t1, t1, 3);
2159 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2160 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a 2161 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2162 t2 = tcg_const_tl(-1);
2163 tcg_gen_shl_tl(t2, t2, t1);
78723684 2164 gen_load_gpr(t1, rt);
eb02cc3f 2165 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2166 tcg_temp_free(t2);
2167 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2168 tcg_temp_free(t1);
fc40787a 2169 gen_store_gpr(t0, rt);
6af0bf9c 2170 break;
6af0bf9c 2171 case OPC_LDR:
3cee3050 2172 t1 = tcg_temp_new();
908680c6
AJ
2173 /* Do a byte access to possibly trigger a page
2174 fault with the unaligned address. */
2175 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2176 tcg_gen_andi_tl(t1, t0, 7);
2177#ifdef TARGET_WORDS_BIGENDIAN
2178 tcg_gen_xori_tl(t1, t1, 7);
2179#endif
2180 tcg_gen_shli_tl(t1, t1, 3);
2181 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2182 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2183 tcg_gen_shr_tl(t0, t0, t1);
2184 tcg_gen_xori_tl(t1, t1, 63);
2185 t2 = tcg_const_tl(0xfffffffffffffffeull);
2186 tcg_gen_shl_tl(t2, t2, t1);
78723684 2187 gen_load_gpr(t1, rt);
fc40787a
AJ
2188 tcg_gen_and_tl(t1, t1, t2);
2189 tcg_temp_free(t2);
2190 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2191 tcg_temp_free(t1);
fc40787a 2192 gen_store_gpr(t0, rt);
6af0bf9c 2193 break;
364d4831 2194 case OPC_LDPC:
3cee3050 2195 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2196 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2197 tcg_temp_free(t1);
5f68f5ae 2198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831
NF
2199 gen_store_gpr(t0, rt);
2200 break;
6af0bf9c 2201#endif
364d4831 2202 case OPC_LWPC:
3cee3050 2203 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2204 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2205 tcg_temp_free(t1);
5f68f5ae 2206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831
NF
2207 gen_store_gpr(t0, rt);
2208 break;
6af0bf9c 2209 case OPC_LW:
be3a8c53
YK
2210 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2211 ctx->default_tcg_memop_mask);
78723684 2212 gen_store_gpr(t0, rt);
6af0bf9c 2213 break;
6af0bf9c 2214 case OPC_LH:
be3a8c53
YK
2215 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2216 ctx->default_tcg_memop_mask);
78723684 2217 gen_store_gpr(t0, rt);
6af0bf9c 2218 break;
6af0bf9c 2219 case OPC_LHU:
be3a8c53
YK
2220 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2221 ctx->default_tcg_memop_mask);
78723684 2222 gen_store_gpr(t0, rt);
6af0bf9c
FB
2223 break;
2224 case OPC_LB:
5f68f5ae 2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2226 gen_store_gpr(t0, rt);
6af0bf9c 2227 break;
6af0bf9c 2228 case OPC_LBU:
5f68f5ae 2229 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2230 gen_store_gpr(t0, rt);
6af0bf9c
FB
2231 break;
2232 case OPC_LWL:
3cee3050 2233 t1 = tcg_temp_new();
908680c6
AJ
2234 /* Do a byte access to possibly trigger a page
2235 fault with the unaligned address. */
2236 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2237 tcg_gen_andi_tl(t1, t0, 3);
2238#ifndef TARGET_WORDS_BIGENDIAN
2239 tcg_gen_xori_tl(t1, t1, 3);
2240#endif
2241 tcg_gen_shli_tl(t1, t1, 3);
2242 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2243 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a 2244 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2245 t2 = tcg_const_tl(-1);
2246 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2247 gen_load_gpr(t1, rt);
eb02cc3f 2248 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2249 tcg_temp_free(t2);
2250 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2251 tcg_temp_free(t1);
fc40787a
AJ
2252 tcg_gen_ext32s_tl(t0, t0);
2253 gen_store_gpr(t0, rt);
6af0bf9c 2254 break;
6af0bf9c 2255 case OPC_LWR:
3cee3050 2256 t1 = tcg_temp_new();
908680c6
AJ
2257 /* Do a byte access to possibly trigger a page
2258 fault with the unaligned address. */
2259 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2260 tcg_gen_andi_tl(t1, t0, 3);
2261#ifdef TARGET_WORDS_BIGENDIAN
2262 tcg_gen_xori_tl(t1, t1, 3);
2263#endif
2264 tcg_gen_shli_tl(t1, t1, 3);
2265 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2266 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2267 tcg_gen_shr_tl(t0, t0, t1);
2268 tcg_gen_xori_tl(t1, t1, 31);
2269 t2 = tcg_const_tl(0xfffffffeull);
2270 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2271 gen_load_gpr(t1, rt);
fc40787a
AJ
2272 tcg_gen_and_tl(t1, t1, t2);
2273 tcg_temp_free(t2);
2274 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2275 tcg_temp_free(t1);
c728154b 2276 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2277 gen_store_gpr(t0, rt);
6af0bf9c 2278 break;
6af0bf9c 2279 case OPC_LL:
4368b29a 2280 case R6_OPC_LL:
5c13fdfd 2281 op_ld_ll(t0, t0, ctx);
78723684 2282 gen_store_gpr(t0, rt);
6af0bf9c 2283 break;
d66c7132 2284 }
d66c7132 2285 tcg_temp_free(t0);
d66c7132
AJ
2286}
2287
5c13fdfd
AJ
2288/* Store */
2289static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2290 int base, int16_t offset)
2291{
5c13fdfd
AJ
2292 TCGv t0 = tcg_temp_new();
2293 TCGv t1 = tcg_temp_new();
2294
2295 gen_base_offset_addr(ctx, t0, base, offset);
2296 gen_load_gpr(t1, rt);
2297 switch (opc) {
2298#if defined(TARGET_MIPS64)
2299 case OPC_SD:
be3a8c53
YK
2300 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2301 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2302 break;
2303 case OPC_SDL:
895c2d04 2304 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2305 break;
2306 case OPC_SDR:
895c2d04 2307 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2308 break;
2309#endif
2310 case OPC_SW:
be3a8c53
YK
2311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2312 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2313 break;
2314 case OPC_SH:
be3a8c53
YK
2315 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2316 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2317 break;
2318 case OPC_SB:
5f68f5ae 2319 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2320 break;
2321 case OPC_SWL:
895c2d04 2322 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2323 break;
2324 case OPC_SWR:
895c2d04 2325 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2326 break;
2327 }
5c13fdfd
AJ
2328 tcg_temp_free(t0);
2329 tcg_temp_free(t1);
2330}
2331
2332
d66c7132
AJ
2333/* Store conditional */
2334static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2335 int base, int16_t offset)
2336{
d66c7132
AJ
2337 TCGv t0, t1;
2338
2d2826b9 2339#ifdef CONFIG_USER_ONLY
d66c7132 2340 t0 = tcg_temp_local_new();
d66c7132 2341 t1 = tcg_temp_local_new();
2d2826b9
AJ
2342#else
2343 t0 = tcg_temp_new();
2344 t1 = tcg_temp_new();
2345#endif
2346 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2347 gen_load_gpr(t1, rt);
2348 switch (opc) {
2349#if defined(TARGET_MIPS64)
2350 case OPC_SCD:
bf7910c6 2351 case R6_OPC_SCD:
5c13fdfd 2352 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2353 break;
2354#endif
6af0bf9c 2355 case OPC_SC:
4368b29a 2356 case R6_OPC_SC:
5c13fdfd 2357 op_st_sc(t1, t0, rt, ctx);
6af0bf9c 2358 break;
6af0bf9c 2359 }
78723684 2360 tcg_temp_free(t1);
d66c7132 2361 tcg_temp_free(t0);
6af0bf9c
FB
2362}
2363
6ea83fed 2364/* Load and store */
7a387fff 2365static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2366 int base, int16_t offset)
6ea83fed 2367{
4e2474d6 2368 TCGv t0 = tcg_temp_new();
6ea83fed 2369
662d7485 2370 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2371 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2372 memory access. */
6ea83fed
FB
2373 switch (opc) {
2374 case OPC_LWC1:
b6d96bed 2375 {
a7812ae4 2376 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2377 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2378 ctx->default_tcg_memop_mask);
7c979afd 2379 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2380 tcg_temp_free_i32(fp0);
b6d96bed 2381 }
6ea83fed
FB
2382 break;
2383 case OPC_SWC1:
b6d96bed 2384 {
a7812ae4 2385 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2386 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2387 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2388 ctx->default_tcg_memop_mask);
a7812ae4 2389 tcg_temp_free_i32(fp0);
b6d96bed 2390 }
6ea83fed
FB
2391 break;
2392 case OPC_LDC1:
b6d96bed 2393 {
a7812ae4 2394 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2395 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2396 ctx->default_tcg_memop_mask);
b6d96bed 2397 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2398 tcg_temp_free_i64(fp0);
b6d96bed 2399 }
6ea83fed
FB
2400 break;
2401 case OPC_SDC1:
b6d96bed 2402 {
a7812ae4 2403 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2404 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2405 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2406 ctx->default_tcg_memop_mask);
a7812ae4 2407 tcg_temp_free_i64(fp0);
b6d96bed 2408 }
6ea83fed
FB
2409 break;
2410 default:
9d68ac14 2411 MIPS_INVAL("flt_ldst");
9c708c7f 2412 generate_exception_end(ctx, EXCP_RI);
78723684 2413 goto out;
6ea83fed 2414 }
78723684
TS
2415 out:
2416 tcg_temp_free(t0);
6ea83fed 2417}
6ea83fed 2418
5ab5c041
AJ
2419static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2420 int rs, int16_t imm)
26ebe468 2421{
5ab5c041 2422 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2423 check_cp1_enabled(ctx);
d9224450
MR
2424 switch (op) {
2425 case OPC_LDC1:
2426 case OPC_SDC1:
2427 check_insn(ctx, ISA_MIPS2);
2428 /* Fallthrough */
2429 default:
2430 gen_flt_ldst(ctx, op, rt, rs, imm);
2431 }
26ebe468
NF
2432 } else {
2433 generate_exception_err(ctx, EXCP_CpU, 1);
2434 }
2435}
2436
6af0bf9c 2437/* Arithmetic with immediate operand */
d75c135e
AJ
2438static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2439 int rt, int rs, int16_t imm)
6af0bf9c 2440{
324d9e32 2441 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2442
7a387fff 2443 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2444 /* If no destination, treat it as a NOP.
2445 For addi, we must generate the overflow exception when needed. */
324d9e32 2446 return;
6af0bf9c
FB
2447 }
2448 switch (opc) {
2449 case OPC_ADDI:
48d38ca5 2450 {
324d9e32
AJ
2451 TCGv t0 = tcg_temp_local_new();
2452 TCGv t1 = tcg_temp_new();
2453 TCGv t2 = tcg_temp_new();
42a268c2 2454 TCGLabel *l1 = gen_new_label();
48d38ca5 2455
324d9e32
AJ
2456 gen_load_gpr(t1, rs);
2457 tcg_gen_addi_tl(t0, t1, uimm);
2458 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2459
324d9e32
AJ
2460 tcg_gen_xori_tl(t1, t1, ~uimm);
2461 tcg_gen_xori_tl(t2, t0, uimm);
2462 tcg_gen_and_tl(t1, t1, t2);
2463 tcg_temp_free(t2);
2464 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2465 tcg_temp_free(t1);
48d38ca5
TS
2466 /* operands of same sign, result different sign */
2467 generate_exception(ctx, EXCP_OVERFLOW);
2468 gen_set_label(l1);
78723684 2469 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2470 gen_store_gpr(t0, rt);
2471 tcg_temp_free(t0);
48d38ca5 2472 }
6af0bf9c
FB
2473 break;
2474 case OPC_ADDIU:
324d9e32
AJ
2475 if (rs != 0) {
2476 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2477 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2478 } else {
2479 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2480 }
6af0bf9c 2481 break;
d26bc211 2482#if defined(TARGET_MIPS64)
7a387fff 2483 case OPC_DADDI:
48d38ca5 2484 {
324d9e32
AJ
2485 TCGv t0 = tcg_temp_local_new();
2486 TCGv t1 = tcg_temp_new();
2487 TCGv t2 = tcg_temp_new();
42a268c2 2488 TCGLabel *l1 = gen_new_label();
48d38ca5 2489
324d9e32
AJ
2490 gen_load_gpr(t1, rs);
2491 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2492
324d9e32
AJ
2493 tcg_gen_xori_tl(t1, t1, ~uimm);
2494 tcg_gen_xori_tl(t2, t0, uimm);
2495 tcg_gen_and_tl(t1, t1, t2);
2496 tcg_temp_free(t2);
2497 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2498 tcg_temp_free(t1);
48d38ca5
TS
2499 /* operands of same sign, result different sign */
2500 generate_exception(ctx, EXCP_OVERFLOW);
2501 gen_set_label(l1);
324d9e32
AJ
2502 gen_store_gpr(t0, rt);
2503 tcg_temp_free(t0);
48d38ca5 2504 }
7a387fff
TS
2505 break;
2506 case OPC_DADDIU:
324d9e32
AJ
2507 if (rs != 0) {
2508 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2509 } else {
2510 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2511 }
7a387fff
TS
2512 break;
2513#endif
324d9e32 2514 }
324d9e32
AJ
2515}
2516
2517/* Logic with immediate operand */
d75c135e 2518static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2519 int rt, int rs, int16_t imm)
324d9e32
AJ
2520{
2521 target_ulong uimm;
324d9e32
AJ
2522
2523 if (rt == 0) {
2524 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2525 return;
2526 }
2527 uimm = (uint16_t)imm;
2528 switch (opc) {
6af0bf9c 2529 case OPC_ANDI:
324d9e32
AJ
2530 if (likely(rs != 0))
2531 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2532 else
2533 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2534 break;
2535 case OPC_ORI:
324d9e32
AJ
2536 if (rs != 0)
2537 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2538 else
2539 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2540 break;
2541 case OPC_XORI:
324d9e32
AJ
2542 if (likely(rs != 0))
2543 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2544 else
2545 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2546 break;
2547 case OPC_LUI:
d4ea6acd
LA
2548 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2549 /* OPC_AUI */
2550 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2551 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2552 } else {
2553 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2554 }
7c2c3ea3
EJ
2555 break;
2556
2557 default:
6af0bf9c 2558 break;
324d9e32 2559 }
324d9e32
AJ
2560}
2561
2562/* Set on less than with immediate operand */
d75c135e 2563static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2564 int rt, int rs, int16_t imm)
324d9e32
AJ
2565{
2566 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2567 TCGv t0;
2568
2569 if (rt == 0) {
2570 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2571 return;
2572 }
2573 t0 = tcg_temp_new();
2574 gen_load_gpr(t0, rs);
2575 switch (opc) {
2576 case OPC_SLTI:
e68dd28f 2577 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2578 break;
2579 case OPC_SLTIU:
e68dd28f 2580 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2581 break;
2582 }
324d9e32
AJ
2583 tcg_temp_free(t0);
2584}
2585
2586/* Shifts with immediate operand */
d75c135e 2587static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2588 int rt, int rs, int16_t imm)
2589{
2590 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2591 TCGv t0;
2592
2593 if (rt == 0) {
2594 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2595 return;
2596 }
2597
2598 t0 = tcg_temp_new();
2599 gen_load_gpr(t0, rs);
2600 switch (opc) {
6af0bf9c 2601 case OPC_SLL:
78723684 2602 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2603 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2604 break;
2605 case OPC_SRA:
324d9e32 2606 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2607 break;
2608 case OPC_SRL:
ea63e2c3
NF
2609 if (uimm != 0) {
2610 tcg_gen_ext32u_tl(t0, t0);
2611 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2612 } else {
2613 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2614 }
ea63e2c3
NF
2615 break;
2616 case OPC_ROTR:
2617 if (uimm != 0) {
2618 TCGv_i32 t1 = tcg_temp_new_i32();
2619
2620 tcg_gen_trunc_tl_i32(t1, t0);
2621 tcg_gen_rotri_i32(t1, t1, uimm);
2622 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2623 tcg_temp_free_i32(t1);
3399e30f
NF
2624 } else {
2625 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2626 }
7a387fff 2627 break;
d26bc211 2628#if defined(TARGET_MIPS64)
7a387fff 2629 case OPC_DSLL:
324d9e32 2630 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2631 break;
2632 case OPC_DSRA:
324d9e32 2633 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2634 break;
2635 case OPC_DSRL:
ea63e2c3 2636 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2637 break;
2638 case OPC_DROTR:
2639 if (uimm != 0) {
2640 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2641 } else {
2642 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2643 }
7a387fff
TS
2644 break;
2645 case OPC_DSLL32:
324d9e32 2646 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2647 break;
2648 case OPC_DSRA32:
324d9e32 2649 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2650 break;
2651 case OPC_DSRL32:
ea63e2c3 2652 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2653 break;
2654 case OPC_DROTR32:
2655 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2656 break;
7a387fff 2657#endif
6af0bf9c 2658 }
78723684 2659 tcg_temp_free(t0);
6af0bf9c
FB
2660}
2661
2662/* Arithmetic */
d75c135e
AJ
2663static void gen_arith(DisasContext *ctx, uint32_t opc,
2664 int rd, int rs, int rt)
6af0bf9c 2665{
7a387fff
TS
2666 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2667 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2668 /* If no destination, treat it as a NOP.
2669 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2670 return;
185f0762 2671 }
460f00c4 2672
6af0bf9c
FB
2673 switch (opc) {
2674 case OPC_ADD:
48d38ca5 2675 {
460f00c4
AJ
2676 TCGv t0 = tcg_temp_local_new();
2677 TCGv t1 = tcg_temp_new();
2678 TCGv t2 = tcg_temp_new();
42a268c2 2679 TCGLabel *l1 = gen_new_label();
48d38ca5 2680
460f00c4
AJ
2681 gen_load_gpr(t1, rs);
2682 gen_load_gpr(t2, rt);
2683 tcg_gen_add_tl(t0, t1, t2);
2684 tcg_gen_ext32s_tl(t0, t0);
2685 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2686 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2687 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2688 tcg_temp_free(t2);
2689 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2690 tcg_temp_free(t1);
48d38ca5
TS
2691 /* operands of same sign, result different sign */
2692 generate_exception(ctx, EXCP_OVERFLOW);
2693 gen_set_label(l1);
460f00c4
AJ
2694 gen_store_gpr(t0, rd);
2695 tcg_temp_free(t0);
48d38ca5 2696 }
6af0bf9c
FB
2697 break;
2698 case OPC_ADDU:
460f00c4
AJ
2699 if (rs != 0 && rt != 0) {
2700 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2701 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2702 } else if (rs == 0 && rt != 0) {
2703 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2704 } else if (rs != 0 && rt == 0) {
2705 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2706 } else {
2707 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2708 }
6af0bf9c
FB
2709 break;
2710 case OPC_SUB:
48d38ca5 2711 {
460f00c4
AJ
2712 TCGv t0 = tcg_temp_local_new();
2713 TCGv t1 = tcg_temp_new();
2714 TCGv t2 = tcg_temp_new();
42a268c2 2715 TCGLabel *l1 = gen_new_label();
48d38ca5 2716
460f00c4
AJ
2717 gen_load_gpr(t1, rs);
2718 gen_load_gpr(t2, rt);
2719 tcg_gen_sub_tl(t0, t1, t2);
2720 tcg_gen_ext32s_tl(t0, t0);
2721 tcg_gen_xor_tl(t2, t1, t2);
2722 tcg_gen_xor_tl(t1, t0, t1);
2723 tcg_gen_and_tl(t1, t1, t2);
2724 tcg_temp_free(t2);
2725 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2726 tcg_temp_free(t1);
31e3104f 2727 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2728 generate_exception(ctx, EXCP_OVERFLOW);
2729 gen_set_label(l1);
460f00c4
AJ
2730 gen_store_gpr(t0, rd);
2731 tcg_temp_free(t0);
48d38ca5 2732 }
6af0bf9c
FB
2733 break;
2734 case OPC_SUBU:
460f00c4
AJ
2735 if (rs != 0 && rt != 0) {
2736 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2737 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2738 } else if (rs == 0 && rt != 0) {
2739 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2740 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2741 } else if (rs != 0 && rt == 0) {
2742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2743 } else {
2744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2745 }
6af0bf9c 2746 break;
d26bc211 2747#if defined(TARGET_MIPS64)
7a387fff 2748 case OPC_DADD:
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_xor_tl(t1, t1, t2);
460f00c4 2759 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2760 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2761 tcg_temp_free(t2);
2762 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2763 tcg_temp_free(t1);
48d38ca5
TS
2764 /* operands of same sign, result different sign */
2765 generate_exception(ctx, EXCP_OVERFLOW);
2766 gen_set_label(l1);
460f00c4
AJ
2767 gen_store_gpr(t0, rd);
2768 tcg_temp_free(t0);
48d38ca5 2769 }
7a387fff
TS
2770 break;
2771 case OPC_DADDU:
460f00c4
AJ
2772 if (rs != 0 && rt != 0) {
2773 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2774 } else if (rs == 0 && rt != 0) {
2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2776 } else if (rs != 0 && rt == 0) {
2777 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2778 } else {
2779 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780 }
7a387fff
TS
2781 break;
2782 case OPC_DSUB:
48d38ca5 2783 {
460f00c4
AJ
2784 TCGv t0 = tcg_temp_local_new();
2785 TCGv t1 = tcg_temp_new();
2786 TCGv t2 = tcg_temp_new();
42a268c2 2787 TCGLabel *l1 = gen_new_label();
48d38ca5 2788
460f00c4
AJ
2789 gen_load_gpr(t1, rs);
2790 gen_load_gpr(t2, rt);
2791 tcg_gen_sub_tl(t0, t1, t2);
2792 tcg_gen_xor_tl(t2, t1, t2);
2793 tcg_gen_xor_tl(t1, t0, t1);
2794 tcg_gen_and_tl(t1, t1, t2);
2795 tcg_temp_free(t2);
2796 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2797 tcg_temp_free(t1);
31e3104f 2798 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2799 generate_exception(ctx, EXCP_OVERFLOW);
2800 gen_set_label(l1);
460f00c4
AJ
2801 gen_store_gpr(t0, rd);
2802 tcg_temp_free(t0);
48d38ca5 2803 }
7a387fff
TS
2804 break;
2805 case OPC_DSUBU:
460f00c4
AJ
2806 if (rs != 0 && rt != 0) {
2807 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2808 } else if (rs == 0 && rt != 0) {
2809 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2810 } else if (rs != 0 && rt == 0) {
2811 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2812 } else {
2813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2814 }
7a387fff
TS
2815 break;
2816#endif
460f00c4
AJ
2817 case OPC_MUL:
2818 if (likely(rs != 0 && rt != 0)) {
2819 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2820 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2821 } else {
2822 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2823 }
6af0bf9c 2824 break;
460f00c4 2825 }
460f00c4
AJ
2826}
2827
2828/* Conditional move */
d75c135e 2829static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2830 int rd, int rs, int rt)
460f00c4 2831{
acf12465 2832 TCGv t0, t1, t2;
460f00c4
AJ
2833
2834 if (rd == 0) {
acf12465 2835 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2836 return;
2837 }
2838
acf12465
AJ
2839 t0 = tcg_temp_new();
2840 gen_load_gpr(t0, rt);
2841 t1 = tcg_const_tl(0);
2842 t2 = tcg_temp_new();
2843 gen_load_gpr(t2, rs);
460f00c4
AJ
2844 switch (opc) {
2845 case OPC_MOVN:
acf12465 2846 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2847 break;
460f00c4 2848 case OPC_MOVZ:
acf12465 2849 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2850 break;
b691d9d2
LA
2851 case OPC_SELNEZ:
2852 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2853 break;
2854 case OPC_SELEQZ:
2855 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2856 break;
460f00c4 2857 }
acf12465
AJ
2858 tcg_temp_free(t2);
2859 tcg_temp_free(t1);
2860 tcg_temp_free(t0);
460f00c4
AJ
2861}
2862
2863/* Logic */
d75c135e 2864static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2865 int rd, int rs, int rt)
460f00c4 2866{
460f00c4
AJ
2867 if (rd == 0) {
2868 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2869 return;
2870 }
2871
2872 switch (opc) {
6af0bf9c 2873 case OPC_AND:
460f00c4
AJ
2874 if (likely(rs != 0 && rt != 0)) {
2875 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2876 } else {
2877 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2878 }
6af0bf9c
FB
2879 break;
2880 case OPC_NOR:
460f00c4
AJ
2881 if (rs != 0 && rt != 0) {
2882 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2883 } else if (rs == 0 && rt != 0) {
2884 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2885 } else if (rs != 0 && rt == 0) {
2886 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2887 } else {
2888 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2889 }
6af0bf9c
FB
2890 break;
2891 case OPC_OR:
460f00c4
AJ
2892 if (likely(rs != 0 && rt != 0)) {
2893 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2894 } else if (rs == 0 && rt != 0) {
2895 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2896 } else if (rs != 0 && rt == 0) {
2897 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2898 } else {
2899 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2900 }
6af0bf9c
FB
2901 break;
2902 case OPC_XOR:
460f00c4
AJ
2903 if (likely(rs != 0 && rt != 0)) {
2904 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2905 } else if (rs == 0 && rt != 0) {
2906 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2907 } else if (rs != 0 && rt == 0) {
2908 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2909 } else {
2910 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2911 }
6af0bf9c 2912 break;
460f00c4 2913 }
460f00c4
AJ
2914}
2915
2916/* Set on lower than */
d75c135e 2917static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2918 int rd, int rs, int rt)
460f00c4 2919{
460f00c4
AJ
2920 TCGv t0, t1;
2921
2922 if (rd == 0) {
2923 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2924 return;
2925 }
2926
2927 t0 = tcg_temp_new();
2928 t1 = tcg_temp_new();
2929 gen_load_gpr(t0, rs);
2930 gen_load_gpr(t1, rt);
2931 switch (opc) {
2932 case OPC_SLT:
e68dd28f 2933 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2934 break;
460f00c4 2935 case OPC_SLTU:
e68dd28f 2936 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2937 break;
2938 }
460f00c4
AJ
2939 tcg_temp_free(t0);
2940 tcg_temp_free(t1);
2941}
20c4c97c 2942
460f00c4 2943/* Shifts */
d75c135e
AJ
2944static void gen_shift(DisasContext *ctx, uint32_t opc,
2945 int rd, int rs, int rt)
460f00c4 2946{
460f00c4 2947 TCGv t0, t1;
20c4c97c 2948
460f00c4
AJ
2949 if (rd == 0) {
2950 /* If no destination, treat it as a NOP.
2951 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
2952 return;
2953 }
2954
2955 t0 = tcg_temp_new();
2956 t1 = tcg_temp_new();
2957 gen_load_gpr(t0, rs);
2958 gen_load_gpr(t1, rt);
2959 switch (opc) {
6af0bf9c 2960 case OPC_SLLV:
78723684
TS
2961 tcg_gen_andi_tl(t0, t0, 0x1f);
2962 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2963 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2964 break;
2965 case OPC_SRAV:
78723684 2966 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2967 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2968 break;
2969 case OPC_SRLV:
ea63e2c3
NF
2970 tcg_gen_ext32u_tl(t1, t1);
2971 tcg_gen_andi_tl(t0, t0, 0x1f);
2972 tcg_gen_shr_tl(t0, t1, t0);
2973 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2974 break;
2975 case OPC_ROTRV:
2976 {
2977 TCGv_i32 t2 = tcg_temp_new_i32();
2978 TCGv_i32 t3 = tcg_temp_new_i32();
2979
2980 tcg_gen_trunc_tl_i32(t2, t0);
2981 tcg_gen_trunc_tl_i32(t3, t1);
2982 tcg_gen_andi_i32(t2, t2, 0x1f);
2983 tcg_gen_rotr_i32(t2, t3, t2);
2984 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2985 tcg_temp_free_i32(t2);
2986 tcg_temp_free_i32(t3);
5a63bcb2 2987 }
7a387fff 2988 break;
d26bc211 2989#if defined(TARGET_MIPS64)
7a387fff 2990 case OPC_DSLLV:
78723684 2991 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2992 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2993 break;
2994 case OPC_DSRAV:
78723684 2995 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2996 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2997 break;
2998 case OPC_DSRLV:
ea63e2c3
NF
2999 tcg_gen_andi_tl(t0, t0, 0x3f);
3000 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3001 break;
3002 case OPC_DROTRV:
3003 tcg_gen_andi_tl(t0, t0, 0x3f);
3004 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3005 break;
7a387fff 3006#endif
6af0bf9c 3007 }
78723684
TS
3008 tcg_temp_free(t0);
3009 tcg_temp_free(t1);
6af0bf9c
FB
3010}
3011
3012/* Arithmetic on HI/LO registers */
26135ead 3013static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3014{
6af0bf9c 3015 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3016 /* Treat as NOP. */
a1f6684d 3017 return;
6af0bf9c 3018 }
4133498f 3019
4133498f
JL
3020 if (acc != 0) {
3021 check_dsp(ctx);
3022 }
3023
6af0bf9c
FB
3024 switch (opc) {
3025 case OPC_MFHI:
4133498f
JL
3026#if defined(TARGET_MIPS64)
3027 if (acc != 0) {
3028 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3029 } else
3030#endif
3031 {
3032 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3033 }
6af0bf9c
FB
3034 break;
3035 case OPC_MFLO:
4133498f
JL
3036#if defined(TARGET_MIPS64)
3037 if (acc != 0) {
3038 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3039 } else
3040#endif
3041 {
3042 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3043 }
6af0bf9c
FB
3044 break;
3045 case OPC_MTHI:
4133498f
JL
3046 if (reg != 0) {
3047#if defined(TARGET_MIPS64)
3048 if (acc != 0) {
3049 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3050 } else
3051#endif
3052 {
3053 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3054 }
3055 } else {
3056 tcg_gen_movi_tl(cpu_HI[acc], 0);
3057 }
6af0bf9c
FB
3058 break;
3059 case OPC_MTLO:
4133498f
JL
3060 if (reg != 0) {
3061#if defined(TARGET_MIPS64)
3062 if (acc != 0) {
3063 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3064 } else
3065#endif
3066 {
3067 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3068 }
3069 } else {
3070 tcg_gen_movi_tl(cpu_LO[acc], 0);
3071 }
6af0bf9c 3072 break;
6af0bf9c 3073 }
6af0bf9c
FB
3074}
3075
d4ea6acd
LA
3076static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3077 TCGMemOp memop)
3078{
3079 TCGv t0 = tcg_const_tl(addr);
3080 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3081 gen_store_gpr(t0, reg);
3082 tcg_temp_free(t0);
3083}
3084
ab39ee45
YK
3085static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3086 int rs)
d4ea6acd
LA
3087{
3088 target_long offset;
3089 target_long addr;
3090
ab39ee45 3091 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3092 case OPC_ADDIUPC:
3093 if (rs != 0) {
3094 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3095 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3096 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3097 }
3098 break;
3099 case R6_OPC_LWPC:
3100 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3101 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3102 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3103 break;
3104#if defined(TARGET_MIPS64)
3105 case OPC_LWUPC:
3106 check_mips_64(ctx);
3107 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3108 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3109 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3110 break;
3111#endif
3112 default:
ab39ee45 3113 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3114 case OPC_AUIPC:
3115 if (rs != 0) {
ab39ee45
YK
3116 offset = sextract32(ctx->opcode, 0, 16) << 16;
3117 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3118 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3119 }
3120 break;
3121 case OPC_ALUIPC:
3122 if (rs != 0) {
ab39ee45
YK
3123 offset = sextract32(ctx->opcode, 0, 16) << 16;
3124 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3125 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3126 }
3127 break;
3128#if defined(TARGET_MIPS64)
3129 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3130 case R6_OPC_LDPC + (1 << 16):
3131 case R6_OPC_LDPC + (2 << 16):
3132 case R6_OPC_LDPC + (3 << 16):
3133 check_mips_64(ctx);
3134 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3135 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3136 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3137 break;
3138#endif
3139 default:
3140 MIPS_INVAL("OPC_PCREL");
9c708c7f 3141 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3142 break;
3143 }
3144 break;
3145 }
3146}
3147
b42ee5e1
LA
3148static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3149{
b42ee5e1
LA
3150 TCGv t0, t1;
3151
3152 if (rd == 0) {
3153 /* Treat as NOP. */
b42ee5e1
LA
3154 return;
3155 }
3156
3157 t0 = tcg_temp_new();
3158 t1 = tcg_temp_new();
3159
3160 gen_load_gpr(t0, rs);
3161 gen_load_gpr(t1, rt);
3162
3163 switch (opc) {
3164 case R6_OPC_DIV:
3165 {
3166 TCGv t2 = tcg_temp_new();
3167 TCGv t3 = tcg_temp_new();
3168 tcg_gen_ext32s_tl(t0, t0);
3169 tcg_gen_ext32s_tl(t1, t1);
3170 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3171 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3172 tcg_gen_and_tl(t2, t2, t3);
3173 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3174 tcg_gen_or_tl(t2, t2, t3);
3175 tcg_gen_movi_tl(t3, 0);
3176 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3177 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3178 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3179 tcg_temp_free(t3);
3180 tcg_temp_free(t2);
3181 }
b42ee5e1
LA
3182 break;
3183 case R6_OPC_MOD:
3184 {
3185 TCGv t2 = tcg_temp_new();
3186 TCGv t3 = tcg_temp_new();
3187 tcg_gen_ext32s_tl(t0, t0);
3188 tcg_gen_ext32s_tl(t1, t1);
3189 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3190 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3191 tcg_gen_and_tl(t2, t2, t3);
3192 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3193 tcg_gen_or_tl(t2, t2, t3);
3194 tcg_gen_movi_tl(t3, 0);
3195 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3196 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3197 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3198 tcg_temp_free(t3);
3199 tcg_temp_free(t2);
3200 }
b42ee5e1
LA
3201 break;
3202 case R6_OPC_DIVU:
3203 {
3204 TCGv t2 = tcg_const_tl(0);
3205 TCGv t3 = tcg_const_tl(1);
3206 tcg_gen_ext32u_tl(t0, t0);
3207 tcg_gen_ext32u_tl(t1, t1);
3208 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3209 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3210 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3211 tcg_temp_free(t3);
3212 tcg_temp_free(t2);
3213 }
b42ee5e1
LA
3214 break;
3215 case R6_OPC_MODU:
3216 {
3217 TCGv t2 = tcg_const_tl(0);
3218 TCGv t3 = tcg_const_tl(1);
3219 tcg_gen_ext32u_tl(t0, t0);
3220 tcg_gen_ext32u_tl(t1, t1);
3221 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3222 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3223 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3224 tcg_temp_free(t3);
3225 tcg_temp_free(t2);
3226 }
b42ee5e1
LA
3227 break;
3228 case R6_OPC_MUL:
3229 {
3230 TCGv_i32 t2 = tcg_temp_new_i32();
3231 TCGv_i32 t3 = tcg_temp_new_i32();
3232 tcg_gen_trunc_tl_i32(t2, t0);
3233 tcg_gen_trunc_tl_i32(t3, t1);
3234 tcg_gen_mul_i32(t2, t2, t3);
3235 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3236 tcg_temp_free_i32(t2);
3237 tcg_temp_free_i32(t3);
3238 }
b42ee5e1
LA
3239 break;
3240 case R6_OPC_MUH:
3241 {
3242 TCGv_i32 t2 = tcg_temp_new_i32();
3243 TCGv_i32 t3 = tcg_temp_new_i32();
3244 tcg_gen_trunc_tl_i32(t2, t0);
3245 tcg_gen_trunc_tl_i32(t3, t1);
3246 tcg_gen_muls2_i32(t2, t3, t2, t3);
3247 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3248 tcg_temp_free_i32(t2);
3249 tcg_temp_free_i32(t3);
3250 }
b42ee5e1
LA
3251 break;
3252 case R6_OPC_MULU:
3253 {
3254 TCGv_i32 t2 = tcg_temp_new_i32();
3255 TCGv_i32 t3 = tcg_temp_new_i32();
3256 tcg_gen_trunc_tl_i32(t2, t0);
3257 tcg_gen_trunc_tl_i32(t3, t1);
3258 tcg_gen_mul_i32(t2, t2, t3);
3259 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3260 tcg_temp_free_i32(t2);
3261 tcg_temp_free_i32(t3);
3262 }
b42ee5e1
LA
3263 break;
3264 case R6_OPC_MUHU:
3265 {
3266 TCGv_i32 t2 = tcg_temp_new_i32();
3267 TCGv_i32 t3 = tcg_temp_new_i32();
3268 tcg_gen_trunc_tl_i32(t2, t0);
3269 tcg_gen_trunc_tl_i32(t3, t1);
3270 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3271 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3272 tcg_temp_free_i32(t2);
3273 tcg_temp_free_i32(t3);
3274 }
b42ee5e1
LA
3275 break;
3276#if defined(TARGET_MIPS64)
3277 case R6_OPC_DDIV:
3278 {
3279 TCGv t2 = tcg_temp_new();
3280 TCGv t3 = tcg_temp_new();
3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3282 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3283 tcg_gen_and_tl(t2, t2, t3);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3285 tcg_gen_or_tl(t2, t2, t3);
3286 tcg_gen_movi_tl(t3, 0);
3287 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3288 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3289 tcg_temp_free(t3);
3290 tcg_temp_free(t2);
3291 }
b42ee5e1
LA
3292 break;
3293 case R6_OPC_DMOD:
3294 {
3295 TCGv t2 = tcg_temp_new();
3296 TCGv t3 = tcg_temp_new();
3297 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3298 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3299 tcg_gen_and_tl(t2, t2, t3);
3300 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3301 tcg_gen_or_tl(t2, t2, t3);
3302 tcg_gen_movi_tl(t3, 0);
3303 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3304 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3305 tcg_temp_free(t3);
3306 tcg_temp_free(t2);
3307 }
b42ee5e1
LA
3308 break;
3309 case R6_OPC_DDIVU:
3310 {
3311 TCGv t2 = tcg_const_tl(0);
3312 TCGv t3 = tcg_const_tl(1);
3313 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3314 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3315 tcg_temp_free(t3);
3316 tcg_temp_free(t2);
3317 }
b42ee5e1
LA
3318 break;
3319 case R6_OPC_DMODU:
3320 {
3321 TCGv t2 = tcg_const_tl(0);
3322 TCGv t3 = tcg_const_tl(1);
3323 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3324 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3325 tcg_temp_free(t3);
3326 tcg_temp_free(t2);
3327 }
b42ee5e1
LA
3328 break;
3329 case R6_OPC_DMUL:
3330 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3331 break;
3332 case R6_OPC_DMUH:
3333 {
3334 TCGv t2 = tcg_temp_new();
3335 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3336 tcg_temp_free(t2);
3337 }
b42ee5e1
LA
3338 break;
3339 case R6_OPC_DMULU:
3340 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3341 break;
3342 case R6_OPC_DMUHU:
3343 {
3344 TCGv t2 = tcg_temp_new();
3345 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3346 tcg_temp_free(t2);
3347 }
b42ee5e1
LA
3348 break;
3349#endif
3350 default:
9d68ac14 3351 MIPS_INVAL("r6 mul/div");
9c708c7f 3352 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3353 goto out;
3354 }
b42ee5e1
LA
3355 out:
3356 tcg_temp_free(t0);
3357 tcg_temp_free(t1);
3358}
3359
26135ead
RS
3360static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3361 int acc, int rs, int rt)
6af0bf9c 3362{
d45f89f4
AJ
3363 TCGv t0, t1;
3364
51127181
AJ
3365 t0 = tcg_temp_new();
3366 t1 = tcg_temp_new();
6af0bf9c 3367
78723684
TS
3368 gen_load_gpr(t0, rs);
3369 gen_load_gpr(t1, rt);
51127181 3370
26135ead
RS
3371 if (acc != 0) {
3372 check_dsp(ctx);
3373 }
3374
6af0bf9c
FB
3375 switch (opc) {
3376 case OPC_DIV:
48d38ca5 3377 {
51127181
AJ
3378 TCGv t2 = tcg_temp_new();
3379 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3380 tcg_gen_ext32s_tl(t0, t0);
3381 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3384 tcg_gen_and_tl(t2, t2, t3);
3385 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3386 tcg_gen_or_tl(t2, t2, t3);
3387 tcg_gen_movi_tl(t3, 0);
3388 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3389 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3390 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3391 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3392 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3393 tcg_temp_free(t3);
3394 tcg_temp_free(t2);
48d38ca5 3395 }
6af0bf9c
FB
3396 break;
3397 case OPC_DIVU:
48d38ca5 3398 {
51127181
AJ
3399 TCGv t2 = tcg_const_tl(0);
3400 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3401 tcg_gen_ext32u_tl(t0, t0);
3402 tcg_gen_ext32u_tl(t1, t1);
51127181 3403 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3404 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3405 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3406 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3407 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3408 tcg_temp_free(t3);
3409 tcg_temp_free(t2);
48d38ca5 3410 }
6af0bf9c
FB
3411 break;
3412 case OPC_MULT:
214c465f 3413 {
ce1dd5d1
RH
3414 TCGv_i32 t2 = tcg_temp_new_i32();
3415 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3416 tcg_gen_trunc_tl_i32(t2, t0);
3417 tcg_gen_trunc_tl_i32(t3, t1);
3418 tcg_gen_muls2_i32(t2, t3, t2, t3);
3419 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3420 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3421 tcg_temp_free_i32(t2);
3422 tcg_temp_free_i32(t3);
214c465f 3423 }
6af0bf9c
FB
3424 break;
3425 case OPC_MULTU:
214c465f 3426 {
ce1dd5d1
RH
3427 TCGv_i32 t2 = tcg_temp_new_i32();
3428 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3429 tcg_gen_trunc_tl_i32(t2, t0);
3430 tcg_gen_trunc_tl_i32(t3, t1);
3431 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3432 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3433 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3434 tcg_temp_free_i32(t2);
3435 tcg_temp_free_i32(t3);
214c465f 3436 }
6af0bf9c 3437 break;
d26bc211 3438#if defined(TARGET_MIPS64)
7a387fff 3439 case OPC_DDIV:
48d38ca5 3440 {
51127181
AJ
3441 TCGv t2 = tcg_temp_new();
3442 TCGv t3 = tcg_temp_new();
3443 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3444 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3445 tcg_gen_and_tl(t2, t2, t3);
3446 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3447 tcg_gen_or_tl(t2, t2, t3);
3448 tcg_gen_movi_tl(t3, 0);
3449 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3450 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3451 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3452 tcg_temp_free(t3);
3453 tcg_temp_free(t2);
48d38ca5 3454 }
7a387fff
TS
3455 break;
3456 case OPC_DDIVU:
48d38ca5 3457 {
51127181
AJ
3458 TCGv t2 = tcg_const_tl(0);
3459 TCGv t3 = tcg_const_tl(1);
3460 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3461 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3462 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3463 tcg_temp_free(t3);
3464 tcg_temp_free(t2);
48d38ca5 3465 }
7a387fff
TS
3466 break;
3467 case OPC_DMULT:
26135ead 3468 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3469 break;
3470 case OPC_DMULTU:
26135ead 3471 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3472 break;
3473#endif
6af0bf9c 3474 case OPC_MADD:
214c465f 3475 {
d45f89f4
AJ
3476 TCGv_i64 t2 = tcg_temp_new_i64();
3477 TCGv_i64 t3 = tcg_temp_new_i64();
3478
3479 tcg_gen_ext_tl_i64(t2, t0);
3480 tcg_gen_ext_tl_i64(t3, t1);
3481 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3482 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3483 tcg_gen_add_i64(t2, t2, t3);
3484 tcg_temp_free_i64(t3);
71f303cd
RH
3485 gen_move_low32(cpu_LO[acc], t2);
3486 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3487 tcg_temp_free_i64(t2);
214c465f 3488 }
6af0bf9c
FB
3489 break;
3490 case OPC_MADDU:
4133498f 3491 {
d45f89f4
AJ
3492 TCGv_i64 t2 = tcg_temp_new_i64();
3493 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3494
78723684
TS
3495 tcg_gen_ext32u_tl(t0, t0);
3496 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3497 tcg_gen_extu_tl_i64(t2, t0);
3498 tcg_gen_extu_tl_i64(t3, t1);
3499 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3500 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3501 tcg_gen_add_i64(t2, t2, t3);
3502 tcg_temp_free_i64(t3);
71f303cd
RH
3503 gen_move_low32(cpu_LO[acc], t2);
3504 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3505 tcg_temp_free_i64(t2);
214c465f 3506 }
6af0bf9c
FB
3507 break;
3508 case OPC_MSUB:
214c465f 3509 {
d45f89f4
AJ
3510 TCGv_i64 t2 = tcg_temp_new_i64();
3511 TCGv_i64 t3 = tcg_temp_new_i64();
3512
3513 tcg_gen_ext_tl_i64(t2, t0);
3514 tcg_gen_ext_tl_i64(t3, t1);
3515 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3516 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3517 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3518 tcg_temp_free_i64(t3);
71f303cd
RH
3519 gen_move_low32(cpu_LO[acc], t2);
3520 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3521 tcg_temp_free_i64(t2);
214c465f 3522 }
6af0bf9c
FB
3523 break;
3524 case OPC_MSUBU:
214c465f 3525 {
d45f89f4
AJ
3526 TCGv_i64 t2 = tcg_temp_new_i64();
3527 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3528
78723684
TS
3529 tcg_gen_ext32u_tl(t0, t0);
3530 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3531 tcg_gen_extu_tl_i64(t2, t0);
3532 tcg_gen_extu_tl_i64(t3, t1);
3533 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3534 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3535 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3536 tcg_temp_free_i64(t3);
71f303cd
RH
3537 gen_move_low32(cpu_LO[acc], t2);
3538 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3539 tcg_temp_free_i64(t2);
214c465f 3540 }
6af0bf9c
FB
3541 break;
3542 default:
9d68ac14 3543 MIPS_INVAL("mul/div");
9c708c7f 3544 generate_exception_end(ctx, EXCP_RI);
78723684 3545 goto out;
6af0bf9c 3546 }
78723684
TS
3547 out:
3548 tcg_temp_free(t0);
3549 tcg_temp_free(t1);
6af0bf9c
FB
3550}
3551
e9c71dd1
TS
3552static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3553 int rd, int rs, int rt)
3554{
f157bfe1
AJ
3555 TCGv t0 = tcg_temp_new();
3556 TCGv t1 = tcg_temp_new();
e9c71dd1 3557
6c5c1e20
TS
3558 gen_load_gpr(t0, rs);
3559 gen_load_gpr(t1, rt);
e9c71dd1
TS
3560
3561 switch (opc) {
3562 case OPC_VR54XX_MULS:
895c2d04 3563 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3564 break;
e9c71dd1 3565 case OPC_VR54XX_MULSU:
895c2d04 3566 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3567 break;
e9c71dd1 3568 case OPC_VR54XX_MACC:
895c2d04 3569 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3570 break;
e9c71dd1 3571 case OPC_VR54XX_MACCU:
895c2d04 3572 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3573 break;
e9c71dd1 3574 case OPC_VR54XX_MSAC:
895c2d04 3575 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3576 break;
e9c71dd1 3577 case OPC_VR54XX_MSACU:
895c2d04 3578 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3579 break;
e9c71dd1 3580 case OPC_VR54XX_MULHI:
895c2d04 3581 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3582 break;
e9c71dd1 3583 case OPC_VR54XX_MULHIU:
895c2d04 3584 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3585 break;
e9c71dd1 3586 case OPC_VR54XX_MULSHI:
895c2d04 3587 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3588 break;
e9c71dd1 3589 case OPC_VR54XX_MULSHIU:
895c2d04 3590 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3591 break;
e9c71dd1 3592 case OPC_VR54XX_MACCHI:
895c2d04 3593 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3594 break;
e9c71dd1 3595 case OPC_VR54XX_MACCHIU:
895c2d04 3596 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3597 break;
e9c71dd1 3598 case OPC_VR54XX_MSACHI:
895c2d04 3599 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3600 break;
e9c71dd1 3601 case OPC_VR54XX_MSACHIU:
895c2d04 3602 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3603 break;
e9c71dd1
TS
3604 default:
3605 MIPS_INVAL("mul vr54xx");
9c708c7f 3606 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3607 goto out;
e9c71dd1 3608 }
6c5c1e20 3609 gen_store_gpr(t0, rd);
6c5c1e20
TS
3610
3611 out:
3612 tcg_temp_free(t0);
3613 tcg_temp_free(t1);
e9c71dd1
TS
3614}
3615
7a387fff 3616static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3617 int rd, int rs)
3618{
20e1fb52 3619 TCGv t0;
6c5c1e20 3620
6af0bf9c 3621 if (rd == 0) {
ead9360e 3622 /* Treat as NOP. */
20e1fb52 3623 return;
6af0bf9c 3624 }
20e1fb52 3625 t0 = tcg_temp_new();
6c5c1e20 3626 gen_load_gpr(t0, rs);
6af0bf9c
FB
3627 switch (opc) {
3628 case OPC_CLO:
4267d3e6 3629 case R6_OPC_CLO:
20e1fb52 3630 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3631 break;
3632 case OPC_CLZ:
4267d3e6 3633 case R6_OPC_CLZ:
20e1fb52 3634 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c 3635 break;
d26bc211 3636#if defined(TARGET_MIPS64)
7a387fff 3637 case OPC_DCLO:
4267d3e6 3638 case R6_OPC_DCLO:
20e1fb52 3639 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3640 break;
3641 case OPC_DCLZ:
4267d3e6 3642 case R6_OPC_DCLZ:
20e1fb52 3643 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3644 break;
3645#endif
6af0bf9c 3646 }
6c5c1e20 3647 tcg_temp_free(t0);
6af0bf9c
FB
3648}
3649
161f85e6 3650/* Godson integer instructions */
bd277fa1
RH
3651static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3652 int rd, int rs, int rt)
161f85e6 3653{
161f85e6
AJ
3654 TCGv t0, t1;
3655
3656 if (rd == 0) {
3657 /* Treat as NOP. */
161f85e6
AJ
3658 return;
3659 }
3660
3661 switch (opc) {
3662 case OPC_MULT_G_2E:
3663 case OPC_MULT_G_2F:
3664 case OPC_MULTU_G_2E:
3665 case OPC_MULTU_G_2F:
3666#if defined(TARGET_MIPS64)
3667 case OPC_DMULT_G_2E:
3668 case OPC_DMULT_G_2F:
3669 case OPC_DMULTU_G_2E:
3670 case OPC_DMULTU_G_2F:
3671#endif
3672 t0 = tcg_temp_new();
3673 t1 = tcg_temp_new();
3674 break;
3675 default:
3676 t0 = tcg_temp_local_new();
3677 t1 = tcg_temp_local_new();
3678 break;
3679 }
3680
3681 gen_load_gpr(t0, rs);
3682 gen_load_gpr(t1, rt);
3683
3684 switch (opc) {
3685 case OPC_MULT_G_2E:
3686 case OPC_MULT_G_2F:
3687 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3688 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3689 break;
3690 case OPC_MULTU_G_2E:
3691 case OPC_MULTU_G_2F:
3692 tcg_gen_ext32u_tl(t0, t0);
3693 tcg_gen_ext32u_tl(t1, t1);
3694 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3695 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3696 break;
3697 case OPC_DIV_G_2E:
3698 case OPC_DIV_G_2F:
3699 {
42a268c2
RH
3700 TCGLabel *l1 = gen_new_label();
3701 TCGLabel *l2 = gen_new_label();
3702 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3703 tcg_gen_ext32s_tl(t0, t0);
3704 tcg_gen_ext32s_tl(t1, t1);
3705 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3706 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3707 tcg_gen_br(l3);
3708 gen_set_label(l1);
3709 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3710 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3711 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3712 tcg_gen_br(l3);
3713 gen_set_label(l2);
3714 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3715 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3716 gen_set_label(l3);
3717 }
161f85e6
AJ
3718 break;
3719 case OPC_DIVU_G_2E:
3720 case OPC_DIVU_G_2F:
3721 {
42a268c2
RH
3722 TCGLabel *l1 = gen_new_label();
3723 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3724 tcg_gen_ext32u_tl(t0, t0);
3725 tcg_gen_ext32u_tl(t1, t1);
3726 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3727 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3728 tcg_gen_br(l2);
3729 gen_set_label(l1);
3730 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3731 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3732 gen_set_label(l2);
3733 }
161f85e6
AJ
3734 break;
3735 case OPC_MOD_G_2E:
3736 case OPC_MOD_G_2F:
3737 {
42a268c2
RH
3738 TCGLabel *l1 = gen_new_label();
3739 TCGLabel *l2 = gen_new_label();
3740 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3741 tcg_gen_ext32u_tl(t0, t0);
3742 tcg_gen_ext32u_tl(t1, t1);
3743 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3744 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3745 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3746 gen_set_label(l1);
3747 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3748 tcg_gen_br(l3);
3749 gen_set_label(l2);
3750 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3751 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3752 gen_set_label(l3);
3753 }
161f85e6
AJ
3754 break;
3755 case OPC_MODU_G_2E:
3756 case OPC_MODU_G_2F:
3757 {
42a268c2
RH
3758 TCGLabel *l1 = gen_new_label();
3759 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3760 tcg_gen_ext32u_tl(t0, t0);
3761 tcg_gen_ext32u_tl(t1, t1);
3762 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3763 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3764 tcg_gen_br(l2);
3765 gen_set_label(l1);
3766 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3767 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3768 gen_set_label(l2);
3769 }
161f85e6
AJ
3770 break;
3771#if defined(TARGET_MIPS64)
3772 case OPC_DMULT_G_2E:
3773 case OPC_DMULT_G_2F:
3774 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3775 break;
3776 case OPC_DMULTU_G_2E:
3777 case OPC_DMULTU_G_2F:
3778 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3779 break;
3780 case OPC_DDIV_G_2E:
3781 case OPC_DDIV_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_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3787 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3788 tcg_gen_br(l3);
3789 gen_set_label(l1);
3790 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3791 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3792 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3793 tcg_gen_br(l3);
3794 gen_set_label(l2);
3795 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3796 gen_set_label(l3);
3797 }
161f85e6
AJ
3798 break;
3799 case OPC_DDIVU_G_2E:
3800 case OPC_DDIVU_G_2F:
3801 {
42a268c2
RH
3802 TCGLabel *l1 = gen_new_label();
3803 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3805 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3806 tcg_gen_br(l2);
3807 gen_set_label(l1);
3808 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3809 gen_set_label(l2);
3810 }
161f85e6
AJ
3811 break;
3812 case OPC_DMOD_G_2E:
3813 case OPC_DMOD_G_2F:
3814 {
42a268c2
RH
3815 TCGLabel *l1 = gen_new_label();
3816 TCGLabel *l2 = gen_new_label();
3817 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3818 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3819 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3820 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3821 gen_set_label(l1);
3822 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3823 tcg_gen_br(l3);
3824 gen_set_label(l2);
3825 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3826 gen_set_label(l3);
3827 }
161f85e6
AJ
3828 break;
3829 case OPC_DMODU_G_2E:
3830 case OPC_DMODU_G_2F:
3831 {
42a268c2
RH
3832 TCGLabel *l1 = gen_new_label();
3833 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3834 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3835 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3836 tcg_gen_br(l2);
3837 gen_set_label(l1);
3838 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3839 gen_set_label(l2);
3840 }
161f85e6
AJ
3841 break;
3842#endif
3843 }
3844
161f85e6
AJ
3845 tcg_temp_free(t0);
3846 tcg_temp_free(t1);
3847}
3848
bd277fa1
RH
3849/* Loongson multimedia instructions */
3850static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3851{
bd277fa1
RH
3852 uint32_t opc, shift_max;
3853 TCGv_i64 t0, t1;
3854
3855 opc = MASK_LMI(ctx->opcode);
3856 switch (opc) {
3857 case OPC_ADD_CP2:
3858 case OPC_SUB_CP2:
3859 case OPC_DADD_CP2:
3860 case OPC_DSUB_CP2:
3861 t0 = tcg_temp_local_new_i64();
3862 t1 = tcg_temp_local_new_i64();
3863 break;
3864 default:
3865 t0 = tcg_temp_new_i64();
3866 t1 = tcg_temp_new_i64();
3867 break;
3868 }
3869
3870 gen_load_fpr64(ctx, t0, rs);
3871 gen_load_fpr64(ctx, t1, rt);
3872
3873#define LMI_HELPER(UP, LO) \
9d68ac14 3874 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3875#define LMI_HELPER_1(UP, LO) \
9d68ac14 3876 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3877#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3878 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3879
3880 switch (opc) {
3881 LMI_HELPER(PADDSH, paddsh);
3882 LMI_HELPER(PADDUSH, paddush);
3883 LMI_HELPER(PADDH, paddh);
3884 LMI_HELPER(PADDW, paddw);
3885 LMI_HELPER(PADDSB, paddsb);
3886 LMI_HELPER(PADDUSB, paddusb);
3887 LMI_HELPER(PADDB, paddb);
3888
3889 LMI_HELPER(PSUBSH, psubsh);
3890 LMI_HELPER(PSUBUSH, psubush);
3891 LMI_HELPER(PSUBH, psubh);
3892 LMI_HELPER(PSUBW, psubw);
3893 LMI_HELPER(PSUBSB, psubsb);
3894 LMI_HELPER(PSUBUSB, psubusb);
3895 LMI_HELPER(PSUBB, psubb);
3896
3897 LMI_HELPER(PSHUFH, pshufh);
3898 LMI_HELPER(PACKSSWH, packsswh);
3899 LMI_HELPER(PACKSSHB, packsshb);
3900 LMI_HELPER(PACKUSHB, packushb);
3901
3902 LMI_HELPER(PUNPCKLHW, punpcklhw);
3903 LMI_HELPER(PUNPCKHHW, punpckhhw);
3904 LMI_HELPER(PUNPCKLBH, punpcklbh);
3905 LMI_HELPER(PUNPCKHBH, punpckhbh);
3906 LMI_HELPER(PUNPCKLWD, punpcklwd);
3907 LMI_HELPER(PUNPCKHWD, punpckhwd);
3908
3909 LMI_HELPER(PAVGH, pavgh);
3910 LMI_HELPER(PAVGB, pavgb);
3911 LMI_HELPER(PMAXSH, pmaxsh);
3912 LMI_HELPER(PMINSH, pminsh);
3913 LMI_HELPER(PMAXUB, pmaxub);
3914 LMI_HELPER(PMINUB, pminub);
3915
3916 LMI_HELPER(PCMPEQW, pcmpeqw);
3917 LMI_HELPER(PCMPGTW, pcmpgtw);
3918 LMI_HELPER(PCMPEQH, pcmpeqh);
3919 LMI_HELPER(PCMPGTH, pcmpgth);
3920 LMI_HELPER(PCMPEQB, pcmpeqb);
3921 LMI_HELPER(PCMPGTB, pcmpgtb);
3922
3923 LMI_HELPER(PSLLW, psllw);
3924 LMI_HELPER(PSLLH, psllh);
3925 LMI_HELPER(PSRLW, psrlw);
3926 LMI_HELPER(PSRLH, psrlh);
3927 LMI_HELPER(PSRAW, psraw);
3928 LMI_HELPER(PSRAH, psrah);
3929
3930 LMI_HELPER(PMULLH, pmullh);
3931 LMI_HELPER(PMULHH, pmulhh);
3932 LMI_HELPER(PMULHUH, pmulhuh);
3933 LMI_HELPER(PMADDHW, pmaddhw);
3934
3935 LMI_HELPER(PASUBUB, pasubub);
3936 LMI_HELPER_1(BIADD, biadd);
3937 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3938
3939 LMI_DIRECT(PADDD, paddd, add);
3940 LMI_DIRECT(PSUBD, psubd, sub);
3941 LMI_DIRECT(XOR_CP2, xor, xor);
3942 LMI_DIRECT(NOR_CP2, nor, nor);
3943 LMI_DIRECT(AND_CP2, and, and);
3944 LMI_DIRECT(PANDN, pandn, andc);
3945 LMI_DIRECT(OR, or, or);
3946
3947 case OPC_PINSRH_0:
3948 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
3949 break;
3950 case OPC_PINSRH_1:
3951 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
3952 break;
3953 case OPC_PINSRH_2:
3954 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
3955 break;
3956 case OPC_PINSRH_3:
3957 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
3958 break;
3959
3960 case OPC_PEXTRH:
3961 tcg_gen_andi_i64(t1, t1, 3);
3962 tcg_gen_shli_i64(t1, t1, 4);
3963 tcg_gen_shr_i64(t0, t0, t1);
3964 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
3965 break;
3966
3967 case OPC_ADDU_CP2:
3968 tcg_gen_add_i64(t0, t0, t1);
3969 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3970 break;
3971 case OPC_SUBU_CP2:
3972 tcg_gen_sub_i64(t0, t0, t1);
3973 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3974 break;
3975
3976 case OPC_SLL_CP2:
bd277fa1
RH
3977 shift_max = 32;
3978 goto do_shift;
3979 case OPC_SRL_CP2:
bd277fa1
RH
3980 shift_max = 32;
3981 goto do_shift;
3982 case OPC_SRA_CP2:
bd277fa1
RH
3983 shift_max = 32;
3984 goto do_shift;
3985 case OPC_DSLL_CP2:
bd277fa1
RH
3986 shift_max = 64;
3987 goto do_shift;
3988 case OPC_DSRL_CP2:
bd277fa1
RH
3989 shift_max = 64;
3990 goto do_shift;
3991 case OPC_DSRA_CP2:
bd277fa1
RH
3992 shift_max = 64;
3993 goto do_shift;
3994 do_shift:
3995 /* Make sure shift count isn't TCG undefined behaviour. */
3996 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3997
3998 switch (opc) {
3999 case OPC_SLL_CP2:
4000 case OPC_DSLL_CP2:
4001 tcg_gen_shl_i64(t0, t0, t1);
4002 break;
4003 case OPC_SRA_CP2:
4004 case OPC_DSRA_CP2:
4005 /* Since SRA is UndefinedResult without sign-extended inputs,
4006 we can treat SRA and DSRA the same. */
4007 tcg_gen_sar_i64(t0, t0, t1);
4008 break;
4009 case OPC_SRL_CP2:
4010 /* We want to shift in zeros for SRL; zero-extend first. */
4011 tcg_gen_ext32u_i64(t0, t0);
4012 /* FALLTHRU */
4013 case OPC_DSRL_CP2:
4014 tcg_gen_shr_i64(t0, t0, t1);
4015 break;
4016 }
4017
4018 if (shift_max == 32) {
4019 tcg_gen_ext32s_i64(t0, t0);
4020 }
4021
4022 /* Shifts larger than MAX produce zero. */
4023 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4024 tcg_gen_neg_i64(t1, t1);
4025 tcg_gen_and_i64(t0, t0, t1);
4026 break;
4027
4028 case OPC_ADD_CP2:
4029 case OPC_DADD_CP2:
4030 {
4031 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4032 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4033
4034 tcg_gen_mov_i64(t2, t0);
4035 tcg_gen_add_i64(t0, t1, t2);
4036 if (opc == OPC_ADD_CP2) {
4037 tcg_gen_ext32s_i64(t0, t0);
4038 }
4039 tcg_gen_xor_i64(t1, t1, t2);
4040 tcg_gen_xor_i64(t2, t2, t0);
4041 tcg_gen_andc_i64(t1, t2, t1);
4042 tcg_temp_free_i64(t2);
4043 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4044 generate_exception(ctx, EXCP_OVERFLOW);
4045 gen_set_label(lab);
bd277fa1
RH
4046 break;
4047 }
4048
4049 case OPC_SUB_CP2:
4050 case OPC_DSUB_CP2:
4051 {
4052 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4053 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4054
4055 tcg_gen_mov_i64(t2, t0);
4056 tcg_gen_sub_i64(t0, t1, t2);
4057 if (opc == OPC_SUB_CP2) {
4058 tcg_gen_ext32s_i64(t0, t0);
4059 }
4060 tcg_gen_xor_i64(t1, t1, t2);
4061 tcg_gen_xor_i64(t2, t2, t0);
4062 tcg_gen_and_i64(t1, t1, t2);
4063 tcg_temp_free_i64(t2);
4064 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4065 generate_exception(ctx, EXCP_OVERFLOW);
4066 gen_set_label(lab);
bd277fa1
RH
4067 break;
4068 }
4069
4070 case OPC_PMULUW:
4071 tcg_gen_ext32u_i64(t0, t0);
4072 tcg_gen_ext32u_i64(t1, t1);
4073 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4074 break;
4075
4076 case OPC_SEQU_CP2:
4077 case OPC_SEQ_CP2:
4078 case OPC_SLTU_CP2:
4079 case OPC_SLT_CP2:
4080 case OPC_SLEU_CP2:
4081 case OPC_SLE_CP2:
4082 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4083 FD field is the CC field? */
4084 default:
9d68ac14 4085 MIPS_INVAL("loongson_cp2");
9c708c7f 4086 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4087 return;
4088 }
4089
4090#undef LMI_HELPER
4091#undef LMI_DIRECT
4092
4093 gen_store_fpr64(ctx, t0, rd);
4094
bd277fa1
RH
4095 tcg_temp_free_i64(t0);
4096 tcg_temp_free_i64(t1);
4097}
4098
6af0bf9c 4099/* Traps */
7a387fff 4100static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4101 int rs, int rt, int16_t imm)
4102{
4103 int cond;
cdc0faa6 4104 TCGv t0 = tcg_temp_new();
1ba74fb8 4105 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4106
4107 cond = 0;
4108 /* Load needed operands */
4109 switch (opc) {
4110 case OPC_TEQ:
4111 case OPC_TGE:
4112 case OPC_TGEU:
4113 case OPC_TLT:
4114 case OPC_TLTU:
4115 case OPC_TNE:
4116 /* Compare two registers */
4117 if (rs != rt) {
be24bb4f
TS
4118 gen_load_gpr(t0, rs);
4119 gen_load_gpr(t1, rt);
6af0bf9c
FB
4120 cond = 1;
4121 }
179e32bb 4122 break;
6af0bf9c
FB
4123 case OPC_TEQI:
4124 case OPC_TGEI:
4125 case OPC_TGEIU:
4126 case OPC_TLTI:
4127 case OPC_TLTIU:
4128 case OPC_TNEI:
4129 /* Compare register to immediate */
4130 if (rs != 0 || imm != 0) {
be24bb4f
TS
4131 gen_load_gpr(t0, rs);
4132 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4133 cond = 1;
4134 }
4135 break;
4136 }
4137 if (cond == 0) {
4138 switch (opc) {
4139 case OPC_TEQ: /* rs == rs */
4140 case OPC_TEQI: /* r0 == 0 */
4141 case OPC_TGE: /* rs >= rs */
4142 case OPC_TGEI: /* r0 >= 0 */
4143 case OPC_TGEU: /* rs >= rs unsigned */
4144 case OPC_TGEIU: /* r0 >= 0 unsigned */
4145 /* Always trap */
9c708c7f 4146 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4147 break;
4148 case OPC_TLT: /* rs < rs */
4149 case OPC_TLTI: /* r0 < 0 */
4150 case OPC_TLTU: /* rs < rs unsigned */
4151 case OPC_TLTIU: /* r0 < 0 unsigned */
4152 case OPC_TNE: /* rs != rs */
4153 case OPC_TNEI: /* r0 != 0 */
ead9360e 4154 /* Never trap: treat as NOP. */
cdc0faa6 4155 break;
6af0bf9c
FB
4156 }
4157 } else {
42a268c2 4158 TCGLabel *l1 = gen_new_label();
cdc0faa6 4159
6af0bf9c
FB
4160 switch (opc) {
4161 case OPC_TEQ:
4162 case OPC_TEQI:
cdc0faa6 4163 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4164 break;
4165 case OPC_TGE:
4166 case OPC_TGEI:
cdc0faa6 4167 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4168 break;
4169 case OPC_TGEU:
4170 case OPC_TGEIU:
cdc0faa6 4171 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4172 break;
4173 case OPC_TLT:
4174 case OPC_TLTI:
cdc0faa6 4175 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4176 break;
4177 case OPC_TLTU:
4178 case OPC_TLTIU:
cdc0faa6 4179 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4180 break;
4181 case OPC_TNE:
4182 case OPC_TNEI:
cdc0faa6 4183 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4184 break;
6af0bf9c 4185 }
cdc0faa6 4186 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4187 gen_set_label(l1);
4188 }
be24bb4f
TS
4189 tcg_temp_free(t0);
4190 tcg_temp_free(t1);
6af0bf9c
FB
4191}
4192
356265ae 4193static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4194{
6e256c93
FB
4195 TranslationBlock *tb;
4196 tb = ctx->tb;
7b270ef2
NF
4197 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4198 likely(!ctx->singlestep_enabled)) {
57fec1fe 4199 tcg_gen_goto_tb(n);
9b9e4393 4200 gen_save_pc(dest);
8cfd0495 4201 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4202 } else {
9b9e4393 4203 gen_save_pc(dest);
7b270ef2
NF
4204 if (ctx->singlestep_enabled) {
4205 save_cpu_state(ctx, 0);
9c708c7f 4206 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4207 }
57fec1fe 4208 tcg_gen_exit_tb(0);
6e256c93 4209 }
c53be334
FB
4210}
4211
6af0bf9c 4212/* Branches (before delay slot) */
7a387fff 4213static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4214 int insn_bytes,
b231c103
YK
4215 int rs, int rt, int32_t offset,
4216 int delayslot_size)
6af0bf9c 4217{
d077b6f7 4218 target_ulong btgt = -1;
3ad4bb2d 4219 int blink = 0;
2fdbad25 4220 int bcond_compute = 0;
1ba74fb8
AJ
4221 TCGv t0 = tcg_temp_new();
4222 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4223
4224 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4225#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4226 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4227 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4228#endif
9c708c7f 4229 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4230 goto out;
3ad4bb2d 4231 }
6af0bf9c 4232
6af0bf9c
FB
4233 /* Load needed operands */
4234 switch (opc) {
4235 case OPC_BEQ:
4236 case OPC_BEQL:
4237 case OPC_BNE:
4238 case OPC_BNEL:
4239 /* Compare two registers */
4240 if (rs != rt) {
6c5c1e20
TS
4241 gen_load_gpr(t0, rs);
4242 gen_load_gpr(t1, rt);
2fdbad25 4243 bcond_compute = 1;
6af0bf9c 4244 }
7dca4ad0 4245 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4246 break;
4247 case OPC_BGEZ:
4248 case OPC_BGEZAL:
4249 case OPC_BGEZALL:
4250 case OPC_BGEZL:
4251 case OPC_BGTZ:
4252 case OPC_BGTZL:
4253 case OPC_BLEZ:
4254 case OPC_BLEZL:
4255 case OPC_BLTZ:
4256 case OPC_BLTZAL:
4257 case OPC_BLTZALL:
4258 case OPC_BLTZL:
4259 /* Compare to zero */
4260 if (rs != 0) {
6c5c1e20 4261 gen_load_gpr(t0, rs);
2fdbad25 4262 bcond_compute = 1;
6af0bf9c 4263 }
7dca4ad0 4264 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4265 break;
e45a93e2
JL
4266 case OPC_BPOSGE32:
4267#if defined(TARGET_MIPS64)
4268 case OPC_BPOSGE64:
4269 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4270#else
4271 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4272#endif
4273 bcond_compute = 1;
4274 btgt = ctx->pc + insn_bytes + offset;
4275 break;
6af0bf9c
FB
4276 case OPC_J:
4277 case OPC_JAL:
364d4831 4278 case OPC_JALX:
6af0bf9c 4279 /* Jump to immediate */
7dca4ad0 4280 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4281 break;
4282 case OPC_JR:
4283 case OPC_JALR:
4284 /* Jump to register */
7a387fff
TS
4285 if (offset != 0 && offset != 16) {
4286 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4287 others are reserved. */
923617a3 4288 MIPS_INVAL("jump hint");
9c708c7f 4289 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4290 goto out;
6af0bf9c 4291 }
d077b6f7 4292 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4293 break;
4294 default:
4295 MIPS_INVAL("branch/jump");
9c708c7f 4296 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4297 goto out;
6af0bf9c 4298 }
2fdbad25 4299 if (bcond_compute == 0) {
6af0bf9c
FB
4300 /* No condition to be computed */
4301 switch (opc) {
4302 case OPC_BEQ: /* rx == rx */
4303 case OPC_BEQL: /* rx == rx likely */
4304 case OPC_BGEZ: /* 0 >= 0 */
4305 case OPC_BGEZL: /* 0 >= 0 likely */
4306 case OPC_BLEZ: /* 0 <= 0 */
4307 case OPC_BLEZL: /* 0 <= 0 likely */
4308 /* Always take */
4ad40f36 4309 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4310 break;
4311 case OPC_BGEZAL: /* 0 >= 0 */
4312 case OPC_BGEZALL: /* 0 >= 0 likely */
4313 /* Always take and link */
4314 blink = 31;
4ad40f36 4315 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4316 break;
4317 case OPC_BNE: /* rx != rx */
4318 case OPC_BGTZ: /* 0 > 0 */
4319 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4320 /* Treat as NOP. */
6c5c1e20 4321 goto out;
eeef26cd 4322 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4323 /* Handle as an unconditional branch to get correct delay
4324 slot checking. */
4325 blink = 31;
b231c103 4326 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4327 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4328 break;
eeef26cd 4329 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4330 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4331 /* Skip the instruction in the delay slot */
9898128f 4332 ctx->pc += 4;
6c5c1e20 4333 goto out;
6af0bf9c
FB
4334 case OPC_BNEL: /* rx != rx likely */
4335 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4336 case OPC_BLTZL: /* 0 < 0 likely */
4337 /* Skip the instruction in the delay slot */
9898128f 4338 ctx->pc += 4;
6c5c1e20 4339 goto out;
6af0bf9c 4340 case OPC_J:
4ad40f36 4341 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4342 break;
364d4831
NF
4343 case OPC_JALX:
4344 ctx->hflags |= MIPS_HFLAG_BX;
4345 /* Fallthrough */
6af0bf9c
FB
4346 case OPC_JAL:
4347 blink = 31;
4ad40f36 4348 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4349 break;
4350 case OPC_JR:
4ad40f36 4351 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4352 break;
4353 case OPC_JALR:
4354 blink = rt;
4ad40f36 4355 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4356 break;
4357 default:
4358 MIPS_INVAL("branch/jump");
9c708c7f 4359 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4360 goto out;
6af0bf9c
FB
4361 }
4362 } else {
4363 switch (opc) {
4364 case OPC_BEQ:
e68dd28f 4365 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4366 goto not_likely;
4367 case OPC_BEQL:
e68dd28f 4368 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4369 goto likely;
4370 case OPC_BNE:
e68dd28f 4371 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4372 goto not_likely;
4373 case OPC_BNEL:
e68dd28f 4374 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4375 goto likely;
4376 case OPC_BGEZ:
e68dd28f 4377 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4378 goto not_likely;
4379 case OPC_BGEZL:
e68dd28f 4380 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4381 goto likely;
4382 case OPC_BGEZAL:
e68dd28f 4383 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4384 blink = 31;
4385 goto not_likely;
4386 case OPC_BGEZALL:
e68dd28f 4387 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4388 blink = 31;
6af0bf9c
FB
4389 goto likely;
4390 case OPC_BGTZ:
e68dd28f 4391 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4392 goto not_likely;
4393 case OPC_BGTZL:
e68dd28f 4394 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4395 goto likely;
4396 case OPC_BLEZ:
e68dd28f 4397 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4398 goto not_likely;
4399 case OPC_BLEZL:
e68dd28f 4400 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4401 goto likely;
4402 case OPC_BLTZ:
e68dd28f 4403 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4404 goto not_likely;
4405 case OPC_BLTZL:
e68dd28f 4406 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4407 goto likely;
e45a93e2
JL
4408 case OPC_BPOSGE32:
4409 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4410 goto not_likely;
4411#if defined(TARGET_MIPS64)
4412 case OPC_BPOSGE64:
4413 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4414 goto not_likely;
4415#endif
6af0bf9c 4416 case OPC_BLTZAL:
e68dd28f 4417 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4418 blink = 31;
6af0bf9c 4419 not_likely:
4ad40f36 4420 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4421 break;
4422 case OPC_BLTZALL:
e68dd28f 4423 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4424 blink = 31;
6af0bf9c 4425 likely:
4ad40f36 4426 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4427 break;
c53f4a62
TS
4428 default:
4429 MIPS_INVAL("conditional branch/jump");
9c708c7f 4430 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4431 goto out;
6af0bf9c 4432 }
6af0bf9c 4433 }
9b9e4393 4434
d077b6f7 4435 ctx->btarget = btgt;
b231c103
YK
4436
4437 switch (delayslot_size) {
4438 case 2:
4439 ctx->hflags |= MIPS_HFLAG_BDS16;
4440 break;
4441 case 4:
4442 ctx->hflags |= MIPS_HFLAG_BDS32;
4443 break;
4444 }
4445
6af0bf9c 4446 if (blink > 0) {
b231c103 4447 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4448 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4449
364d4831 4450 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4451 }
6c5c1e20
TS
4452
4453 out:
364d4831
NF
4454 if (insn_bytes == 2)
4455 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4456 tcg_temp_free(t0);
4457 tcg_temp_free(t1);
6af0bf9c
FB
4458}
4459
7a387fff
TS
4460/* special3 bitfield operations */
4461static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4462 int rs, int lsb, int msb)
7a387fff 4463{
a7812ae4
PB
4464 TCGv t0 = tcg_temp_new();
4465 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4466
4467 gen_load_gpr(t1, rs);
7a387fff
TS
4468 switch (opc) {
4469 case OPC_EXT:
b7f26e52 4470 if (lsb + msb > 31) {
7a387fff 4471 goto fail;
b7f26e52 4472 }
505ad7c2
AJ
4473 tcg_gen_shri_tl(t0, t1, lsb);
4474 if (msb != 31) {
b7f26e52 4475 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
505ad7c2
AJ
4476 } else {
4477 tcg_gen_ext32s_tl(t0, t0);
4478 }
7a387fff 4479 break;
c6d6dd7c 4480#if defined(TARGET_MIPS64)
7a387fff 4481 case OPC_DEXTU:
b7f26e52
RH
4482 lsb += 32;
4483 goto do_dext;
4484 case OPC_DEXTM:
4485 msb += 32;
4486 goto do_dext;
7a387fff 4487 case OPC_DEXT:
b7f26e52
RH
4488 do_dext:
4489 if (lsb + msb > 63) {
4490 goto fail;
4491 }
505ad7c2 4492 tcg_gen_shri_tl(t0, t1, lsb);
b7f26e52
RH
4493 if (msb != 63) {
4494 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4495 }
7a387fff 4496 break;
c6d6dd7c 4497#endif
7a387fff 4498 case OPC_INS:
b7f26e52 4499 if (lsb > msb) {
7a387fff 4500 goto fail;
b7f26e52 4501 }
6c5c1e20 4502 gen_load_gpr(t0, rt);
e0d002f1 4503 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4504 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4505 break;
c6d6dd7c 4506#if defined(TARGET_MIPS64)
7a387fff 4507 case OPC_DINSU:
b7f26e52
RH
4508 lsb += 32;
4509 /* FALLTHRU */
4510 case OPC_DINSM:
4511 msb += 32;
4512 /* FALLTHRU */
7a387fff 4513 case OPC_DINS:
b7f26e52
RH
4514 if (lsb > msb) {
4515 goto fail;
4516 }
6c5c1e20 4517 gen_load_gpr(t0, rt);
e0d002f1 4518 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4519 break;
c6d6dd7c 4520#endif
7a387fff
TS
4521 default:
4522fail:
4523 MIPS_INVAL("bitops");
9c708c7f 4524 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4525 tcg_temp_free(t0);
4526 tcg_temp_free(t1);
7a387fff
TS
4527 return;
4528 }
6c5c1e20
TS
4529 gen_store_gpr(t0, rt);
4530 tcg_temp_free(t0);
4531 tcg_temp_free(t1);
7a387fff
TS
4532}
4533
49bcf33c
AJ
4534static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4535{
3a55fa47 4536 TCGv t0;
49bcf33c 4537
3a55fa47
AJ
4538 if (rd == 0) {
4539 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4540 return;
4541 }
4542
4543 t0 = tcg_temp_new();
4544 gen_load_gpr(t0, rt);
49bcf33c
AJ
4545 switch (op2) {
4546 case OPC_WSBH:
3a55fa47
AJ
4547 {
4548 TCGv t1 = tcg_temp_new();
4549
4550 tcg_gen_shri_tl(t1, t0, 8);
4551 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4552 tcg_gen_shli_tl(t0, t0, 8);
4553 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4554 tcg_gen_or_tl(t0, t0, t1);
4555 tcg_temp_free(t1);
4556 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4557 }
49bcf33c
AJ
4558 break;
4559 case OPC_SEB:
3a55fa47 4560 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4561 break;
4562 case OPC_SEH:
3a55fa47 4563 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4564 break;
4565#if defined(TARGET_MIPS64)
4566 case OPC_DSBH:
3a55fa47
AJ
4567 {
4568 TCGv t1 = tcg_temp_new();
4569
4570 tcg_gen_shri_tl(t1, t0, 8);
4571 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4572 tcg_gen_shli_tl(t0, t0, 8);
4573 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4574 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4575 tcg_temp_free(t1);
4576 }
49bcf33c
AJ
4577 break;
4578 case OPC_DSHD:
3a55fa47
AJ
4579 {
4580 TCGv t1 = tcg_temp_new();
4581
4582 tcg_gen_shri_tl(t1, t0, 16);
4583 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4584 tcg_gen_shli_tl(t0, t0, 16);
4585 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4586 tcg_gen_or_tl(t0, t0, t1);
4587 tcg_gen_shri_tl(t1, t0, 32);
4588 tcg_gen_shli_tl(t0, t0, 32);
4589 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4590 tcg_temp_free(t1);
4591 }
49bcf33c
AJ
4592 break;
4593#endif
4594 default:
4595 MIPS_INVAL("bsfhl");
9c708c7f 4596 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4597 tcg_temp_free(t0);
49bcf33c
AJ
4598 return;
4599 }
49bcf33c 4600 tcg_temp_free(t0);
49bcf33c
AJ
4601}
4602
1f1b4c00
YK
4603static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4604 int imm2)
4605{
4606 TCGv t0;
4607 TCGv t1;
4608 if (rd == 0) {
4609 /* Treat as NOP. */
4610 return;
4611 }
4612 t0 = tcg_temp_new();
4613 t1 = tcg_temp_new();
4614 gen_load_gpr(t0, rs);
4615 gen_load_gpr(t1, rt);
4616 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4617 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4618 if (opc == OPC_LSA) {
4619 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4620 }
4621
4622 tcg_temp_free(t1);
4623 tcg_temp_free(t0);
4624
4625 return;
4626}
4627
4628static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4629 int bp)
284b731a 4630{
1f1b4c00
YK
4631 TCGv t0;
4632 if (rd == 0) {
4633 /* Treat as NOP. */
4634 return;
4635 }
4636 t0 = tcg_temp_new();
4637 gen_load_gpr(t0, rt);
4638 if (bp == 0) {
51243852
MD
4639 switch (opc) {
4640 case OPC_ALIGN:
4641 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4642 break;
4643#if defined(TARGET_MIPS64)
4644 case OPC_DALIGN:
4645 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4646 break;
4647#endif
4648 }
1f1b4c00
YK
4649 } else {
4650 TCGv t1 = tcg_temp_new();
4651 gen_load_gpr(t1, rs);
4652 switch (opc) {
4653 case OPC_ALIGN:
4654 {
4655 TCGv_i64 t2 = tcg_temp_new_i64();
4656 tcg_gen_concat_tl_i64(t2, t1, t0);
4657 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4658 gen_move_low32(cpu_gpr[rd], t2);
4659 tcg_temp_free_i64(t2);
4660 }
4661 break;
284b731a 4662#if defined(TARGET_MIPS64)
1f1b4c00
YK
4663 case OPC_DALIGN:
4664 tcg_gen_shli_tl(t0, t0, 8 * bp);
4665 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4666 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4667 break;
284b731a 4668#endif
1f1b4c00
YK
4669 }
4670 tcg_temp_free(t1);
4671 }
4672
4673 tcg_temp_free(t0);
4674}
4675
4676static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4677{
4678 TCGv t0;
4679 if (rd == 0) {
4680 /* Treat as NOP. */
4681 return;
4682 }
4683 t0 = tcg_temp_new();
4684 gen_load_gpr(t0, rt);
4685 switch (opc) {
4686 case OPC_BITSWAP:
4687 gen_helper_bitswap(cpu_gpr[rd], t0);
4688 break;
4689#if defined(TARGET_MIPS64)
4690 case OPC_DBITSWAP:
4691 gen_helper_dbitswap(cpu_gpr[rd], t0);
4692 break;
4693#endif
4694 }
4695 tcg_temp_free(t0);
284b731a
LA
4696}
4697
1f1b4c00
YK
4698#ifndef CONFIG_USER_ONLY
4699/* CP0 (MMU and control) */
5204ea79
LA
4700static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4701{
4702 TCGv_i64 t0 = tcg_temp_new_i64();
4703 TCGv_i64 t1 = tcg_temp_new_i64();
4704
4705 tcg_gen_ext_tl_i64(t0, arg);
4706 tcg_gen_ld_i64(t1, cpu_env, off);
4707#if defined(TARGET_MIPS64)
4708 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4709#else
4710 tcg_gen_concat32_i64(t1, t1, t0);
4711#endif
4712 tcg_gen_st_i64(t1, cpu_env, off);
4713 tcg_temp_free_i64(t1);
4714 tcg_temp_free_i64(t0);
4715}
4716
4717static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4718{
4719 TCGv_i64 t0 = tcg_temp_new_i64();
4720 TCGv_i64 t1 = tcg_temp_new_i64();
4721
4722 tcg_gen_ext_tl_i64(t0, arg);
4723 tcg_gen_ld_i64(t1, cpu_env, off);
4724 tcg_gen_concat32_i64(t1, t1, t0);
4725 tcg_gen_st_i64(t1, cpu_env, off);
4726 tcg_temp_free_i64(t1);
4727 tcg_temp_free_i64(t0);
4728}
4729
4730static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4731{
4732 TCGv_i64 t0 = tcg_temp_new_i64();
4733
4734 tcg_gen_ld_i64(t0, cpu_env, off);
4735#if defined(TARGET_MIPS64)
4736 tcg_gen_shri_i64(t0, t0, 30);
4737#else
4738 tcg_gen_shri_i64(t0, t0, 32);
4739#endif
4740 gen_move_low32(arg, t0);
4741 tcg_temp_free_i64(t0);
4742}
4743
4744static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4745{
4746 TCGv_i64 t0 = tcg_temp_new_i64();
4747
4748 tcg_gen_ld_i64(t0, cpu_env, off);
4749 tcg_gen_shri_i64(t0, t0, 32 + shift);
4750 gen_move_low32(arg, t0);
4751 tcg_temp_free_i64(t0);
4752}
4753
d9bea114 4754static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4755{
d9bea114 4756 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4757
d9bea114
AJ
4758 tcg_gen_ld_i32(t0, cpu_env, off);
4759 tcg_gen_ext_i32_tl(arg, t0);
4760 tcg_temp_free_i32(t0);
4f57689a
TS
4761}
4762
d9bea114 4763static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4764{
d9bea114
AJ
4765 tcg_gen_ld_tl(arg, cpu_env, off);
4766 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4767}
4768
d9bea114 4769static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4770{
d9bea114 4771 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4772
d9bea114
AJ
4773 tcg_gen_trunc_tl_i32(t0, arg);
4774 tcg_gen_st_i32(t0, cpu_env, off);
4775 tcg_temp_free_i32(t0);
f1aa6320
TS
4776}
4777
5204ea79
LA
4778static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4779{
4780 const char *rn = "invalid";
4781
4782 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4783 goto mfhc0_read_zero;
4784 }
4785
4786 switch (reg) {
4787 case 2:
4788 switch (sel) {
4789 case 0:
4790 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4791 rn = "EntryLo0";
4792 break;
4793 default:
4794 goto mfhc0_read_zero;
4795 }
4796 break;
4797 case 3:
4798 switch (sel) {
4799 case 0:
4800 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4801 rn = "EntryLo1";
4802 break;
4803 default:
4804 goto mfhc0_read_zero;
4805 }
4806 break;
4807 case 17:
4808 switch (sel) {
4809 case 0:
4810 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4811 ctx->CP0_LLAddr_shift);
4812 rn = "LLAddr";
4813 break;
4814 default:
4815 goto mfhc0_read_zero;
4816 }
4817 break;
4818 case 28:
4819 switch (sel) {
4820 case 0:
4821 case 2:
4822 case 4:
4823 case 6:
4824 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4825 rn = "TagLo";
4826 break;
4827 default:
4828 goto mfhc0_read_zero;
4829 }
4830 break;
4831 default:
4832 goto mfhc0_read_zero;
4833 }
4834
4835 (void)rn; /* avoid a compiler warning */
4836 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4837 return;
4838
4839mfhc0_read_zero:
4840 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4841 tcg_gen_movi_tl(arg, 0);
4842}
4843
4844static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4845{
4846 const char *rn = "invalid";
4847 uint64_t mask = ctx->PAMask >> 36;
4848
4849 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4850 goto mthc0_nop;
4851 }
4852
4853 switch (reg) {
4854 case 2:
4855 switch (sel) {
4856 case 0:
4857 tcg_gen_andi_tl(arg, arg, mask);
4858 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4859 rn = "EntryLo0";
4860 break;
4861 default:
4862 goto mthc0_nop;
4863 }
4864 break;
4865 case 3:
4866 switch (sel) {
4867 case 0:
4868 tcg_gen_andi_tl(arg, arg, mask);
4869 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4870 rn = "EntryLo1";
4871 break;
4872 default:
4873 goto mthc0_nop;
4874 }
4875 break;
4876 case 17:
4877 switch (sel) {
4878 case 0:
4879 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4880 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4881 relevant for modern MIPS cores supporting MTHC0, therefore
4882 treating MTHC0 to LLAddr as NOP. */
4883 rn = "LLAddr";
4884 break;
4885 default:
4886 goto mthc0_nop;
4887 }
4888 break;
4889 case 28:
4890 switch (sel) {
4891 case 0:
4892 case 2:
4893 case 4:
4894 case 6:
4895 tcg_gen_andi_tl(arg, arg, mask);
4896 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4897 rn = "TagLo";
4898 break;
4899 default:
4900 goto mthc0_nop;
4901 }
4902 break;
4903 default:
4904 goto mthc0_nop;
4905 }
4906
4907 (void)rn; /* avoid a compiler warning */
4908mthc0_nop:
4909 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4910}
4911
e98c0d17
LA
4912static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4913{
4914 if (ctx->insn_flags & ISA_MIPS32R6) {
4915 tcg_gen_movi_tl(arg, 0);
4916 } else {
4917 tcg_gen_movi_tl(arg, ~0);
4918 }
4919}
4920
f31b035a
LA
4921#define CP0_CHECK(c) \
4922 do { \
4923 if (!(c)) { \
4924 goto cp0_unimplemented; \
4925 } \
4926 } while (0)
4927
d75c135e 4928static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4929{
7a387fff 4930 const char *rn = "invalid";
873eb012 4931
e189e748 4932 if (sel != 0)
d75c135e 4933 check_insn(ctx, ISA_MIPS32);
e189e748 4934
873eb012
TS
4935 switch (reg) {
4936 case 0:
7a387fff
TS
4937 switch (sel) {
4938 case 0:
7db13fae 4939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4940 rn = "Index";
4941 break;
4942 case 1:
f31b035a 4943 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4944 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4945 rn = "MVPControl";
ead9360e 4946 break;
7a387fff 4947 case 2:
f31b035a 4948 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4949 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4950 rn = "MVPConf0";
ead9360e 4951 break;
7a387fff 4952 case 3:
f31b035a 4953 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4954 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4955 rn = "MVPConf1";
ead9360e 4956 break;
01bc435b
YK
4957 case 4:
4958 CP0_CHECK(ctx->vp);
4959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4960 rn = "VPControl";
4961 break;
7a387fff 4962 default:
f31b035a 4963 goto cp0_unimplemented;
7a387fff 4964 }
873eb012
TS
4965 break;
4966 case 1:
7a387fff
TS
4967 switch (sel) {
4968 case 0:
f31b035a 4969 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4970 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4971 rn = "Random";
2423f660 4972 break;
7a387fff 4973 case 1:
f31b035a 4974 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4975 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4976 rn = "VPEControl";
ead9360e 4977 break;
7a387fff 4978 case 2:
f31b035a 4979 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4980 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4981 rn = "VPEConf0";
ead9360e 4982 break;
7a387fff 4983 case 3:
f31b035a 4984 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4985 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4986 rn = "VPEConf1";
ead9360e 4987 break;
7a387fff 4988 case 4:
f31b035a 4989 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4990 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4991 rn = "YQMask";
ead9360e 4992 break;
7a387fff 4993 case 5:
f31b035a 4994 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4995 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4996 rn = "VPESchedule";
ead9360e 4997 break;
7a387fff 4998 case 6:
f31b035a 4999 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5000 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5001 rn = "VPEScheFBack";
ead9360e 5002 break;
7a387fff 5003 case 7:
f31b035a 5004 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5006 rn = "VPEOpt";
ead9360e 5007 break;
7a387fff 5008 default:
f31b035a 5009 goto cp0_unimplemented;
7a387fff 5010 }
873eb012
TS
5011 break;
5012 case 2:
7a387fff
TS
5013 switch (sel) {
5014 case 0:
284b731a
LA
5015 {
5016 TCGv_i64 tmp = tcg_temp_new_i64();
5017 tcg_gen_ld_i64(tmp, cpu_env,
5018 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5019#if defined(TARGET_MIPS64)
284b731a
LA
5020 if (ctx->rxi) {
5021 /* Move RI/XI fields to bits 31:30 */
5022 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5023 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5024 }
7207c7f9 5025#endif
284b731a
LA
5026 gen_move_low32(arg, tmp);
5027 tcg_temp_free_i64(tmp);
5028 }
2423f660
TS
5029 rn = "EntryLo0";
5030 break;
7a387fff 5031 case 1:
f31b035a 5032 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5033 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5034 rn = "TCStatus";
ead9360e 5035 break;
7a387fff 5036 case 2:
f31b035a 5037 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5038 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5039 rn = "TCBind";
ead9360e 5040 break;
7a387fff 5041 case 3:
f31b035a 5042 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5043 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5044 rn = "TCRestart";
ead9360e 5045 break;
7a387fff 5046 case 4:
f31b035a 5047 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5048 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5049 rn = "TCHalt";
ead9360e 5050 break;
7a387fff 5051 case 5:
f31b035a 5052 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5053 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5054 rn = "TCContext";
ead9360e 5055 break;
7a387fff 5056 case 6:
f31b035a 5057 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5058 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5059 rn = "TCSchedule";
ead9360e 5060 break;
7a387fff 5061 case 7:
f31b035a 5062 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5063 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5064 rn = "TCScheFBack";
ead9360e 5065 break;
7a387fff 5066 default:
f31b035a 5067 goto cp0_unimplemented;
7a387fff 5068 }
873eb012
TS
5069 break;
5070 case 3:
7a387fff
TS
5071 switch (sel) {
5072 case 0:
284b731a
LA
5073 {
5074 TCGv_i64 tmp = tcg_temp_new_i64();
5075 tcg_gen_ld_i64(tmp, cpu_env,
5076 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5077#if defined(TARGET_MIPS64)
284b731a
LA
5078 if (ctx->rxi) {
5079 /* Move RI/XI fields to bits 31:30 */
5080 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5081 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5082 }
7207c7f9 5083#endif
284b731a
LA
5084 gen_move_low32(arg, tmp);
5085 tcg_temp_free_i64(tmp);
5086 }
2423f660
TS
5087 rn = "EntryLo1";
5088 break;
01bc435b
YK
5089 case 1:
5090 CP0_CHECK(ctx->vp);
5091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5092 rn = "GlobalNumber";
5093 break;
7a387fff 5094 default:
f31b035a 5095 goto cp0_unimplemented;
1579a72e 5096 }
873eb012
TS
5097 break;
5098 case 4:
7a387fff
TS
5099 switch (sel) {
5100 case 0:
7db13fae 5101 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5102 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5103 rn = "Context";
5104 break;
7a387fff 5105 case 1:
d9bea114 5106// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5107 rn = "ContextConfig";
f31b035a 5108 goto cp0_unimplemented;
2423f660 5109// break;
d279279e 5110 case 2:
f31b035a
LA
5111 CP0_CHECK(ctx->ulri);
5112 tcg_gen_ld32s_tl(arg, cpu_env,
5113 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5114 rn = "UserLocal";
d279279e 5115 break;
7a387fff 5116 default:
f31b035a 5117 goto cp0_unimplemented;
1579a72e 5118 }
873eb012
TS
5119 break;
5120 case 5:
7a387fff
TS
5121 switch (sel) {
5122 case 0:
7db13fae 5123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5124 rn = "PageMask";
5125 break;
7a387fff 5126 case 1:
d75c135e 5127 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5128 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5129 rn = "PageGrain";
5130 break;
7a387fff 5131 default:
f31b035a 5132 goto cp0_unimplemented;
1579a72e 5133 }
873eb012
TS
5134 break;
5135 case 6:
7a387fff
TS
5136 switch (sel) {
5137 case 0:
7db13fae 5138 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5139 rn = "Wired";
5140 break;
7a387fff 5141 case 1:
d75c135e 5142 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5144 rn = "SRSConf0";
ead9360e 5145 break;
7a387fff 5146 case 2:
d75c135e 5147 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5149 rn = "SRSConf1";
ead9360e 5150 break;
7a387fff 5151 case 3:
d75c135e 5152 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5154 rn = "SRSConf2";
ead9360e 5155 break;
7a387fff 5156 case 4:
d75c135e 5157 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5159 rn = "SRSConf3";
ead9360e 5160 break;
7a387fff 5161 case 5:
d75c135e 5162 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5164 rn = "SRSConf4";
ead9360e 5165 break;
7a387fff 5166 default:
f31b035a 5167 goto cp0_unimplemented;
1579a72e 5168 }
873eb012 5169 break;
8c0fdd85 5170 case 7:
7a387fff
TS
5171 switch (sel) {
5172 case 0:
d75c135e 5173 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5175 rn = "HWREna";
5176 break;
7a387fff 5177 default:
f31b035a 5178 goto cp0_unimplemented;
1579a72e 5179 }
8c0fdd85 5180 break;
873eb012 5181 case 8:
7a387fff
TS
5182 switch (sel) {
5183 case 0:
7db13fae 5184 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5185 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5186 rn = "BadVAddr";
2423f660 5187 break;
aea14095 5188 case 1:
f31b035a
LA
5189 CP0_CHECK(ctx->bi);
5190 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5191 rn = "BadInstr";
aea14095
LA
5192 break;
5193 case 2:
f31b035a
LA
5194 CP0_CHECK(ctx->bp);
5195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5196 rn = "BadInstrP";
aea14095 5197 break;
7a387fff 5198 default:
f31b035a 5199 goto cp0_unimplemented;
aea14095 5200 }
873eb012
TS
5201 break;
5202 case 9:
7a387fff
TS
5203 switch (sel) {
5204 case 0:
2e70f6ef 5205 /* Mark as an IO operation because we read the time. */
bd79255d 5206 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5207 gen_io_start();
bd79255d 5208 }
895c2d04 5209 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5210 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5211 gen_io_end();
2e70f6ef 5212 }
55807224
EI
5213 /* Break the TB to be able to take timer interrupts immediately
5214 after reading count. */
5215 ctx->bstate = BS_STOP;
2423f660
TS
5216 rn = "Count";
5217 break;
5218 /* 6,7 are implementation dependent */
7a387fff 5219 default:
f31b035a 5220 goto cp0_unimplemented;
2423f660 5221 }
873eb012
TS
5222 break;
5223 case 10:
7a387fff
TS
5224 switch (sel) {
5225 case 0:
7db13fae 5226 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5227 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5228 rn = "EntryHi";
5229 break;
7a387fff 5230 default:
f31b035a 5231 goto cp0_unimplemented;
1579a72e 5232 }
873eb012
TS
5233 break;
5234 case 11:
7a387fff
TS
5235 switch (sel) {
5236 case 0:
7db13fae 5237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5238 rn = "Compare";
5239 break;
5240 /* 6,7 are implementation dependent */
7a387fff 5241 default:
f31b035a 5242 goto cp0_unimplemented;
2423f660 5243 }
873eb012
TS
5244 break;
5245 case 12:
7a387fff
TS
5246 switch (sel) {
5247 case 0:
7db13fae 5248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5249 rn = "Status";
5250 break;
7a387fff 5251 case 1:
d75c135e 5252 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5254 rn = "IntCtl";
5255 break;
7a387fff 5256 case 2:
d75c135e 5257 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5259 rn = "SRSCtl";
5260 break;
7a387fff 5261 case 3:
d75c135e 5262 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5264 rn = "SRSMap";
fd88b6ab 5265 break;
7a387fff 5266 default:
f31b035a 5267 goto cp0_unimplemented;
7a387fff 5268 }
873eb012
TS
5269 break;
5270 case 13:
7a387fff
TS
5271 switch (sel) {
5272 case 0:
7db13fae 5273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5274 rn = "Cause";
5275 break;
7a387fff 5276 default:
f31b035a 5277 goto cp0_unimplemented;
7a387fff 5278 }
873eb012
TS
5279 break;
5280 case 14:
7a387fff
TS
5281 switch (sel) {
5282 case 0:
7db13fae 5283 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5284 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5285 rn = "EPC";
5286 break;
7a387fff 5287 default:
f31b035a 5288 goto cp0_unimplemented;
1579a72e 5289 }
873eb012
TS
5290 break;
5291 case 15:
7a387fff
TS
5292 switch (sel) {
5293 case 0:
7db13fae 5294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5295 rn = "PRid";
5296 break;
7a387fff 5297 case 1:
d75c135e 5298 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5300 rn = "EBase";
5301 break;
c870e3f5
YK
5302 case 3:
5303 check_insn(ctx, ISA_MIPS32R2);
5304 CP0_CHECK(ctx->cmgcr);
5305 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5306 tcg_gen_ext32s_tl(arg, arg);
5307 rn = "CMGCRBase";
5308 break;
7a387fff 5309 default:
f31b035a 5310 goto cp0_unimplemented;
7a387fff 5311 }
873eb012
TS
5312 break;
5313 case 16:
5314 switch (sel) {
5315 case 0:
7db13fae 5316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5317 rn = "Config";
5318 break;
5319 case 1:
7db13fae 5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5321 rn = "Config1";
5322 break;
7a387fff 5323 case 2:
7db13fae 5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5325 rn = "Config2";
5326 break;
5327 case 3:
7db13fae 5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5329 rn = "Config3";
5330 break;
b4160af1
PJ
5331 case 4:
5332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5333 rn = "Config4";
5334 break;
b4dd99a3
PJ
5335 case 5:
5336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5337 rn = "Config5";
5338 break;
e397ee33
TS
5339 /* 6,7 are implementation dependent */
5340 case 6:
7db13fae 5341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5342 rn = "Config6";
5343 break;
5344 case 7:
7db13fae 5345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5346 rn = "Config7";
5347 break;
873eb012 5348 default:
f31b035a 5349 goto cp0_unimplemented;
873eb012
TS
5350 }
5351 break;
5352 case 17:
7a387fff
TS
5353 switch (sel) {
5354 case 0:
895c2d04 5355 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5356 rn = "LLAddr";
5357 break;
7a387fff 5358 default:
f31b035a 5359 goto cp0_unimplemented;
7a387fff 5360 }
873eb012
TS
5361 break;
5362 case 18:
7a387fff 5363 switch (sel) {
fd88b6ab 5364 case 0 ... 7:
895c2d04 5365 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5366 rn = "WatchLo";
5367 break;
7a387fff 5368 default:
f31b035a 5369 goto cp0_unimplemented;
7a387fff 5370 }
873eb012
TS
5371 break;
5372 case 19:
7a387fff 5373 switch (sel) {
fd88b6ab 5374 case 0 ...7:
895c2d04 5375 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5376 rn = "WatchHi";
5377 break;
7a387fff 5378 default:
f31b035a 5379 goto cp0_unimplemented;
7a387fff 5380 }
873eb012 5381 break;
8c0fdd85 5382 case 20:
7a387fff
TS
5383 switch (sel) {
5384 case 0:
d26bc211 5385#if defined(TARGET_MIPS64)
d75c135e 5386 check_insn(ctx, ISA_MIPS3);
7db13fae 5387 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5388 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5389 rn = "XContext";
5390 break;
703eaf37 5391#endif
7a387fff 5392 default:
f31b035a 5393 goto cp0_unimplemented;
7a387fff 5394 }
8c0fdd85
TS
5395 break;
5396 case 21:
7a387fff 5397 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5398 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5399 switch (sel) {
5400 case 0:
7db13fae 5401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5402 rn = "Framemask";
5403 break;
7a387fff 5404 default:
f31b035a 5405 goto cp0_unimplemented;
7a387fff 5406 }
8c0fdd85
TS
5407 break;
5408 case 22:
d9bea114 5409 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5410 rn = "'Diagnostic"; /* implementation dependent */
5411 break;
873eb012 5412 case 23:
7a387fff
TS
5413 switch (sel) {
5414 case 0:
895c2d04 5415 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5416 rn = "Debug";
5417 break;
7a387fff 5418 case 1:
d9bea114 5419// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5420 rn = "TraceControl";
5421// break;
7a387fff 5422 case 2:
d9bea114 5423// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5424 rn = "TraceControl2";
5425// break;
7a387fff 5426 case 3:
d9bea114 5427// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5428 rn = "UserTraceData";
5429// break;
7a387fff 5430 case 4:
d9bea114 5431// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5432 rn = "TraceBPC";
5433// break;
7a387fff 5434 default:
f31b035a 5435 goto cp0_unimplemented;
7a387fff 5436 }
873eb012
TS
5437 break;
5438 case 24:
7a387fff
TS
5439 switch (sel) {
5440 case 0:
f0b3f3ae 5441 /* EJTAG support */
7db13fae 5442 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5443 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5444 rn = "DEPC";
5445 break;
7a387fff 5446 default:
f31b035a 5447 goto cp0_unimplemented;
7a387fff 5448 }
873eb012 5449 break;
8c0fdd85 5450 case 25:
7a387fff
TS
5451 switch (sel) {
5452 case 0:
7db13fae 5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5454 rn = "Performance0";
7a387fff
TS
5455 break;
5456 case 1:
d9bea114 5457// gen_helper_mfc0_performance1(arg);
2423f660
TS
5458 rn = "Performance1";
5459// break;
7a387fff 5460 case 2:
d9bea114 5461// gen_helper_mfc0_performance2(arg);
2423f660
TS
5462 rn = "Performance2";
5463// break;
7a387fff 5464 case 3:
d9bea114 5465// gen_helper_mfc0_performance3(arg);
2423f660
TS
5466 rn = "Performance3";
5467// break;
7a387fff 5468 case 4:
d9bea114 5469// gen_helper_mfc0_performance4(arg);
2423f660
TS
5470 rn = "Performance4";
5471// break;
7a387fff 5472 case 5:
d9bea114 5473// gen_helper_mfc0_performance5(arg);
2423f660
TS
5474 rn = "Performance5";
5475// break;
7a387fff 5476 case 6:
d9bea114 5477// gen_helper_mfc0_performance6(arg);
2423f660
TS
5478 rn = "Performance6";
5479// break;
7a387fff 5480 case 7:
d9bea114 5481// gen_helper_mfc0_performance7(arg);
2423f660
TS
5482 rn = "Performance7";
5483// break;
7a387fff 5484 default:
f31b035a 5485 goto cp0_unimplemented;
7a387fff 5486 }
8c0fdd85
TS
5487 break;
5488 case 26:
d9bea114 5489 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5490 rn = "ECC";
5491 break;
8c0fdd85 5492 case 27:
7a387fff 5493 switch (sel) {
7a387fff 5494 case 0 ... 3:
d9bea114 5495 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5496 rn = "CacheErr";
5497 break;
7a387fff 5498 default:
f31b035a 5499 goto cp0_unimplemented;
7a387fff 5500 }
8c0fdd85 5501 break;
873eb012
TS
5502 case 28:
5503 switch (sel) {
5504 case 0:
7a387fff
TS
5505 case 2:
5506 case 4:
5507 case 6:
284b731a
LA
5508 {
5509 TCGv_i64 tmp = tcg_temp_new_i64();
5510 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5511 gen_move_low32(arg, tmp);
5512 tcg_temp_free_i64(tmp);
5513 }
873eb012
TS
5514 rn = "TagLo";
5515 break;
5516 case 1:
7a387fff
TS
5517 case 3:
5518 case 5:
5519 case 7:
7db13fae 5520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5521 rn = "DataLo";
5522 break;
5523 default:
f31b035a 5524 goto cp0_unimplemented;
873eb012
TS
5525 }
5526 break;
8c0fdd85 5527 case 29:
7a387fff
TS
5528 switch (sel) {
5529 case 0:
5530 case 2:
5531 case 4:
5532 case 6:
7db13fae 5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5534 rn = "TagHi";
5535 break;
5536 case 1:
5537 case 3:
5538 case 5:
5539 case 7:
7db13fae 5540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5541 rn = "DataHi";
5542 break;
5543 default:
f31b035a 5544 goto cp0_unimplemented;
7a387fff 5545 }
8c0fdd85 5546 break;
873eb012 5547 case 30:
7a387fff
TS
5548 switch (sel) {
5549 case 0:
7db13fae 5550 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5551 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5552 rn = "ErrorEPC";
5553 break;
7a387fff 5554 default:
f31b035a 5555 goto cp0_unimplemented;
7a387fff 5556 }
873eb012
TS
5557 break;
5558 case 31:
7a387fff
TS
5559 switch (sel) {
5560 case 0:
f0b3f3ae 5561 /* EJTAG support */
7db13fae 5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5563 rn = "DESAVE";
5564 break;
e98c0d17 5565 case 2 ... 7:
f31b035a
LA
5566 CP0_CHECK(ctx->kscrexist & (1 << sel));
5567 tcg_gen_ld_tl(arg, cpu_env,
5568 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5569 tcg_gen_ext32s_tl(arg, arg);
5570 rn = "KScratch";
e98c0d17 5571 break;
7a387fff 5572 default:
f31b035a 5573 goto cp0_unimplemented;
7a387fff 5574 }
873eb012
TS
5575 break;
5576 default:
f31b035a 5577 goto cp0_unimplemented;
873eb012 5578 }
2abf314d 5579 (void)rn; /* avoid a compiler warning */
d12d51d5 5580 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5581 return;
5582
f31b035a 5583cp0_unimplemented:
d12d51d5 5584 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5585 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5586}
5587
d75c135e 5588static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5589{
7a387fff
TS
5590 const char *rn = "invalid";
5591
e189e748 5592 if (sel != 0)
d75c135e 5593 check_insn(ctx, ISA_MIPS32);
e189e748 5594
bd79255d 5595 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5596 gen_io_start();
bd79255d 5597 }
2e70f6ef 5598
8c0fdd85
TS
5599 switch (reg) {
5600 case 0:
7a387fff
TS
5601 switch (sel) {
5602 case 0:
895c2d04 5603 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5604 rn = "Index";
5605 break;
5606 case 1:
f31b035a 5607 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5608 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5609 rn = "MVPControl";
ead9360e 5610 break;
7a387fff 5611 case 2:
f31b035a 5612 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5613 /* ignored */
7a387fff 5614 rn = "MVPConf0";
ead9360e 5615 break;
7a387fff 5616 case 3:
f31b035a 5617 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5618 /* ignored */
7a387fff 5619 rn = "MVPConf1";
ead9360e 5620 break;
01bc435b
YK
5621 case 4:
5622 CP0_CHECK(ctx->vp);
5623 /* ignored */
5624 rn = "VPControl";
5625 break;
7a387fff 5626 default:
f31b035a 5627 goto cp0_unimplemented;
7a387fff 5628 }
8c0fdd85
TS
5629 break;
5630 case 1:
7a387fff
TS
5631 switch (sel) {
5632 case 0:
2423f660 5633 /* ignored */
7a387fff 5634 rn = "Random";
2423f660 5635 break;
7a387fff 5636 case 1:
f31b035a 5637 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5638 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5639 rn = "VPEControl";
ead9360e 5640 break;
7a387fff 5641 case 2:
f31b035a 5642 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5643 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5644 rn = "VPEConf0";
ead9360e 5645 break;
7a387fff 5646 case 3:
f31b035a 5647 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5648 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5649 rn = "VPEConf1";
ead9360e 5650 break;
7a387fff 5651 case 4:
f31b035a 5652 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5653 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5654 rn = "YQMask";
ead9360e 5655 break;
7a387fff 5656 case 5:
f31b035a 5657 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5658 tcg_gen_st_tl(arg, cpu_env,
5659 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5660 rn = "VPESchedule";
ead9360e 5661 break;
7a387fff 5662 case 6:
f31b035a 5663 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5664 tcg_gen_st_tl(arg, cpu_env,
5665 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5666 rn = "VPEScheFBack";
ead9360e 5667 break;
7a387fff 5668 case 7:
f31b035a 5669 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5670 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5671 rn = "VPEOpt";
ead9360e 5672 break;
7a387fff 5673 default:
f31b035a 5674 goto cp0_unimplemented;
7a387fff 5675 }
8c0fdd85
TS
5676 break;
5677 case 2:
7a387fff
TS
5678 switch (sel) {
5679 case 0:
895c2d04 5680 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5681 rn = "EntryLo0";
5682 break;
7a387fff 5683 case 1:
f31b035a 5684 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5685 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5686 rn = "TCStatus";
ead9360e 5687 break;
7a387fff 5688 case 2:
f31b035a 5689 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5690 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5691 rn = "TCBind";
ead9360e 5692 break;
7a387fff 5693 case 3:
f31b035a 5694 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5695 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5696 rn = "TCRestart";
ead9360e 5697 break;
7a387fff 5698 case 4:
f31b035a 5699 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5700 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5701 rn = "TCHalt";
ead9360e 5702 break;
7a387fff 5703 case 5:
f31b035a 5704 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5705 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5706 rn = "TCContext";
ead9360e 5707 break;
7a387fff 5708 case 6:
f31b035a 5709 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5710 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5711 rn = "TCSchedule";
ead9360e 5712 break;
7a387fff 5713 case 7:
f31b035a 5714 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5715 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5716 rn = "TCScheFBack";
ead9360e 5717 break;
7a387fff 5718 default:
f31b035a 5719 goto cp0_unimplemented;
7a387fff 5720 }
8c0fdd85
TS
5721 break;
5722 case 3:
7a387fff
TS
5723 switch (sel) {
5724 case 0:
895c2d04 5725 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5726 rn = "EntryLo1";
5727 break;
01bc435b
YK
5728 case 1:
5729 CP0_CHECK(ctx->vp);
5730 /* ignored */
5731 rn = "GlobalNumber";
5732 break;
7a387fff 5733 default:
f31b035a 5734 goto cp0_unimplemented;
876d4b07 5735 }
8c0fdd85
TS
5736 break;
5737 case 4:
7a387fff
TS
5738 switch (sel) {
5739 case 0:
895c2d04 5740 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5741 rn = "Context";
5742 break;
7a387fff 5743 case 1:
895c2d04 5744// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5745 rn = "ContextConfig";
f31b035a 5746 goto cp0_unimplemented;
2423f660 5747// break;
d279279e 5748 case 2:
f31b035a
LA
5749 CP0_CHECK(ctx->ulri);
5750 tcg_gen_st_tl(arg, cpu_env,
5751 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5752 rn = "UserLocal";
d279279e 5753 break;
7a387fff 5754 default:
f31b035a 5755 goto cp0_unimplemented;
876d4b07 5756 }
8c0fdd85
TS
5757 break;
5758 case 5:
7a387fff
TS
5759 switch (sel) {
5760 case 0:
895c2d04 5761 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5762 rn = "PageMask";
5763 break;
7a387fff 5764 case 1:
d75c135e 5765 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5766 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5767 rn = "PageGrain";
e117f526 5768 ctx->bstate = BS_STOP;
2423f660 5769 break;
7a387fff 5770 default:
f31b035a 5771 goto cp0_unimplemented;
876d4b07 5772 }
8c0fdd85
TS
5773 break;
5774 case 6:
7a387fff
TS
5775 switch (sel) {
5776 case 0:
895c2d04 5777 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5778 rn = "Wired";
5779 break;
7a387fff 5780 case 1:
d75c135e 5781 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5782 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5783 rn = "SRSConf0";
ead9360e 5784 break;
7a387fff 5785 case 2:
d75c135e 5786 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5787 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5788 rn = "SRSConf1";
ead9360e 5789 break;
7a387fff 5790 case 3:
d75c135e 5791 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5792 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5793 rn = "SRSConf2";
ead9360e 5794 break;
7a387fff 5795 case 4:
d75c135e 5796 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5797 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5798 rn = "SRSConf3";
ead9360e 5799 break;
7a387fff 5800 case 5:
d75c135e 5801 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5802 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5803 rn = "SRSConf4";
ead9360e 5804 break;
7a387fff 5805 default:
f31b035a 5806 goto cp0_unimplemented;
876d4b07 5807 }
8c0fdd85
TS
5808 break;
5809 case 7:
7a387fff
TS
5810 switch (sel) {
5811 case 0:
d75c135e 5812 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5813 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5814 ctx->bstate = BS_STOP;
2423f660
TS
5815 rn = "HWREna";
5816 break;
7a387fff 5817 default:
f31b035a 5818 goto cp0_unimplemented;
876d4b07 5819 }
8c0fdd85
TS
5820 break;
5821 case 8:
aea14095
LA
5822 switch (sel) {
5823 case 0:
5824 /* ignored */
5825 rn = "BadVAddr";
5826 break;
5827 case 1:
5828 /* ignored */
5829 rn = "BadInstr";
5830 break;
5831 case 2:
5832 /* ignored */
5833 rn = "BadInstrP";
5834 break;
5835 default:
f31b035a 5836 goto cp0_unimplemented;
aea14095 5837 }
8c0fdd85
TS
5838 break;
5839 case 9:
7a387fff
TS
5840 switch (sel) {
5841 case 0:
895c2d04 5842 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5843 rn = "Count";
5844 break;
876d4b07 5845 /* 6,7 are implementation dependent */
7a387fff 5846 default:
f31b035a 5847 goto cp0_unimplemented;
876d4b07 5848 }
8c0fdd85
TS
5849 break;
5850 case 10:
7a387fff
TS
5851 switch (sel) {
5852 case 0:
895c2d04 5853 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5854 rn = "EntryHi";
5855 break;
7a387fff 5856 default:
f31b035a 5857 goto cp0_unimplemented;
876d4b07 5858 }
8c0fdd85
TS
5859 break;
5860 case 11:
7a387fff
TS
5861 switch (sel) {
5862 case 0:
895c2d04 5863 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5864 rn = "Compare";
5865 break;
5866 /* 6,7 are implementation dependent */
7a387fff 5867 default:
f31b035a 5868 goto cp0_unimplemented;
876d4b07 5869 }
8c0fdd85
TS
5870 break;
5871 case 12:
7a387fff
TS
5872 switch (sel) {
5873 case 0:
867abc7e 5874 save_cpu_state(ctx, 1);
895c2d04 5875 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5876 /* BS_STOP isn't good enough here, hflags may have changed. */
5877 gen_save_pc(ctx->pc + 4);
5878 ctx->bstate = BS_EXCP;
2423f660
TS
5879 rn = "Status";
5880 break;
7a387fff 5881 case 1:
d75c135e 5882 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5883 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5884 /* Stop translation as we may have switched the execution mode */
5885 ctx->bstate = BS_STOP;
2423f660
TS
5886 rn = "IntCtl";
5887 break;
7a387fff 5888 case 2:
d75c135e 5889 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5890 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5891 /* Stop translation as we may have switched the execution mode */
5892 ctx->bstate = BS_STOP;
2423f660
TS
5893 rn = "SRSCtl";
5894 break;
7a387fff 5895 case 3:
d75c135e 5896 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5897 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5898 /* Stop translation as we may have switched the execution mode */
5899 ctx->bstate = BS_STOP;
2423f660 5900 rn = "SRSMap";
fd88b6ab 5901 break;
7a387fff 5902 default:
f31b035a 5903 goto cp0_unimplemented;
876d4b07 5904 }
8c0fdd85
TS
5905 break;
5906 case 13:
7a387fff
TS
5907 switch (sel) {
5908 case 0:
867abc7e 5909 save_cpu_state(ctx, 1);
895c2d04 5910 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5911 rn = "Cause";
5912 break;
7a387fff 5913 default:
f31b035a 5914 goto cp0_unimplemented;
876d4b07 5915 }
8c0fdd85
TS
5916 break;
5917 case 14:
7a387fff
TS
5918 switch (sel) {
5919 case 0:
d54a299b 5920 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5921 rn = "EPC";
5922 break;
7a387fff 5923 default:
f31b035a 5924 goto cp0_unimplemented;
876d4b07 5925 }
8c0fdd85
TS
5926 break;
5927 case 15:
7a387fff
TS
5928 switch (sel) {
5929 case 0:
2423f660
TS
5930 /* ignored */
5931 rn = "PRid";
5932 break;
7a387fff 5933 case 1:
d75c135e 5934 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5935 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5936 rn = "EBase";
5937 break;
7a387fff 5938 default:
f31b035a 5939 goto cp0_unimplemented;
1579a72e 5940 }
8c0fdd85
TS
5941 break;
5942 case 16:
5943 switch (sel) {
5944 case 0:
895c2d04 5945 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5946 rn = "Config";
2423f660
TS
5947 /* Stop translation as we may have switched the execution mode */
5948 ctx->bstate = BS_STOP;
7a387fff
TS
5949 break;
5950 case 1:
e397ee33 5951 /* ignored, read only */
7a387fff
TS
5952 rn = "Config1";
5953 break;
5954 case 2:
895c2d04 5955 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5956 rn = "Config2";
2423f660
TS
5957 /* Stop translation as we may have switched the execution mode */
5958 ctx->bstate = BS_STOP;
8c0fdd85 5959 break;
7a387fff 5960 case 3:
90f12d73 5961 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5962 rn = "Config3";
90f12d73
MR
5963 /* Stop translation as we may have switched the execution mode */
5964 ctx->bstate = BS_STOP;
7a387fff 5965 break;
b4160af1
PJ
5966 case 4:
5967 gen_helper_mtc0_config4(cpu_env, arg);
5968 rn = "Config4";
5969 ctx->bstate = BS_STOP;
5970 break;
b4dd99a3
PJ
5971 case 5:
5972 gen_helper_mtc0_config5(cpu_env, arg);
5973 rn = "Config5";
5974 /* Stop translation as we may have switched the execution mode */
5975 ctx->bstate = BS_STOP;
5976 break;
e397ee33
TS
5977 /* 6,7 are implementation dependent */
5978 case 6:
5979 /* ignored */
5980 rn = "Config6";
5981 break;
5982 case 7:
5983 /* ignored */
5984 rn = "Config7";
5985 break;
8c0fdd85
TS
5986 default:
5987 rn = "Invalid config selector";
f31b035a 5988 goto cp0_unimplemented;
8c0fdd85
TS
5989 }
5990 break;
5991 case 17:
7a387fff
TS
5992 switch (sel) {
5993 case 0:
895c2d04 5994 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5995 rn = "LLAddr";
5996 break;
7a387fff 5997 default:
f31b035a 5998 goto cp0_unimplemented;
7a387fff 5999 }
8c0fdd85
TS
6000 break;
6001 case 18:
7a387fff 6002 switch (sel) {
fd88b6ab 6003 case 0 ... 7:
895c2d04 6004 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6005 rn = "WatchLo";
6006 break;
7a387fff 6007 default:
f31b035a 6008 goto cp0_unimplemented;
7a387fff 6009 }
8c0fdd85
TS
6010 break;
6011 case 19:
7a387fff 6012 switch (sel) {
fd88b6ab 6013 case 0 ... 7:
895c2d04 6014 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6015 rn = "WatchHi";
6016 break;
7a387fff 6017 default:
f31b035a 6018 goto cp0_unimplemented;
7a387fff 6019 }
8c0fdd85
TS
6020 break;
6021 case 20:
7a387fff
TS
6022 switch (sel) {
6023 case 0:
d26bc211 6024#if defined(TARGET_MIPS64)
d75c135e 6025 check_insn(ctx, ISA_MIPS3);
895c2d04 6026 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6027 rn = "XContext";
6028 break;
703eaf37 6029#endif
7a387fff 6030 default:
f31b035a 6031 goto cp0_unimplemented;
7a387fff 6032 }
8c0fdd85
TS
6033 break;
6034 case 21:
7a387fff 6035 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6036 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6037 switch (sel) {
6038 case 0:
895c2d04 6039 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6040 rn = "Framemask";
6041 break;
7a387fff 6042 default:
f31b035a 6043 goto cp0_unimplemented;
7a387fff
TS
6044 }
6045 break;
8c0fdd85 6046 case 22:
7a387fff
TS
6047 /* ignored */
6048 rn = "Diagnostic"; /* implementation dependent */
2423f660 6049 break;
8c0fdd85 6050 case 23:
7a387fff
TS
6051 switch (sel) {
6052 case 0:
895c2d04 6053 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6054 /* BS_STOP isn't good enough here, hflags may have changed. */
6055 gen_save_pc(ctx->pc + 4);
6056 ctx->bstate = BS_EXCP;
2423f660
TS
6057 rn = "Debug";
6058 break;
7a387fff 6059 case 1:
895c2d04 6060// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6061 rn = "TraceControl";
8487327a
TS
6062 /* Stop translation as we may have switched the execution mode */
6063 ctx->bstate = BS_STOP;
2423f660 6064// break;
7a387fff 6065 case 2:
895c2d04 6066// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6067 rn = "TraceControl2";
8487327a
TS
6068 /* Stop translation as we may have switched the execution mode */
6069 ctx->bstate = BS_STOP;
2423f660 6070// break;
7a387fff 6071 case 3:
8487327a
TS
6072 /* Stop translation as we may have switched the execution mode */
6073 ctx->bstate = BS_STOP;
895c2d04 6074// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6075 rn = "UserTraceData";
8487327a
TS
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx->bstate = BS_STOP;
2423f660 6078// break;
7a387fff 6079 case 4:
895c2d04 6080// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6081 /* Stop translation as we may have switched the execution mode */
6082 ctx->bstate = BS_STOP;
2423f660
TS
6083 rn = "TraceBPC";
6084// break;
7a387fff 6085 default:
f31b035a 6086 goto cp0_unimplemented;
7a387fff 6087 }
8c0fdd85
TS
6088 break;
6089 case 24:
7a387fff
TS
6090 switch (sel) {
6091 case 0:
f1aa6320 6092 /* EJTAG support */
d54a299b 6093 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6094 rn = "DEPC";
6095 break;
7a387fff 6096 default:
f31b035a 6097 goto cp0_unimplemented;
7a387fff 6098 }
8c0fdd85
TS
6099 break;
6100 case 25:
7a387fff
TS
6101 switch (sel) {
6102 case 0:
895c2d04 6103 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6104 rn = "Performance0";
6105 break;
7a387fff 6106 case 1:
d9bea114 6107// gen_helper_mtc0_performance1(arg);
2423f660
TS
6108 rn = "Performance1";
6109// break;
7a387fff 6110 case 2:
d9bea114 6111// gen_helper_mtc0_performance2(arg);
2423f660
TS
6112 rn = "Performance2";
6113// break;
7a387fff 6114 case 3:
d9bea114 6115// gen_helper_mtc0_performance3(arg);
2423f660
TS
6116 rn = "Performance3";
6117// break;
7a387fff 6118 case 4:
d9bea114 6119// gen_helper_mtc0_performance4(arg);
2423f660
TS
6120 rn = "Performance4";
6121// break;
7a387fff 6122 case 5:
d9bea114 6123// gen_helper_mtc0_performance5(arg);
2423f660
TS
6124 rn = "Performance5";
6125// break;
7a387fff 6126 case 6:
d9bea114 6127// gen_helper_mtc0_performance6(arg);
2423f660
TS
6128 rn = "Performance6";
6129// break;
7a387fff 6130 case 7:
d9bea114 6131// gen_helper_mtc0_performance7(arg);
2423f660
TS
6132 rn = "Performance7";
6133// break;
7a387fff 6134 default:
f31b035a 6135 goto cp0_unimplemented;
7a387fff 6136 }
8c0fdd85
TS
6137 break;
6138 case 26:
2423f660 6139 /* ignored */
8c0fdd85 6140 rn = "ECC";
2423f660 6141 break;
8c0fdd85 6142 case 27:
7a387fff
TS
6143 switch (sel) {
6144 case 0 ... 3:
2423f660
TS
6145 /* ignored */
6146 rn = "CacheErr";
6147 break;
7a387fff 6148 default:
f31b035a 6149 goto cp0_unimplemented;
7a387fff 6150 }
8c0fdd85
TS
6151 break;
6152 case 28:
6153 switch (sel) {
6154 case 0:
7a387fff
TS
6155 case 2:
6156 case 4:
6157 case 6:
895c2d04 6158 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6159 rn = "TagLo";
6160 break;
7a387fff
TS
6161 case 1:
6162 case 3:
6163 case 5:
6164 case 7:
895c2d04 6165 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6166 rn = "DataLo";
6167 break;
8c0fdd85 6168 default:
f31b035a 6169 goto cp0_unimplemented;
8c0fdd85
TS
6170 }
6171 break;
6172 case 29:
7a387fff
TS
6173 switch (sel) {
6174 case 0:
6175 case 2:
6176 case 4:
6177 case 6:
895c2d04 6178 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6179 rn = "TagHi";
6180 break;
6181 case 1:
6182 case 3:
6183 case 5:
6184 case 7:
895c2d04 6185 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6186 rn = "DataHi";
6187 break;
6188 default:
6189 rn = "invalid sel";
f31b035a 6190 goto cp0_unimplemented;
7a387fff 6191 }
8c0fdd85
TS
6192 break;
6193 case 30:
7a387fff
TS
6194 switch (sel) {
6195 case 0:
d54a299b 6196 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6197 rn = "ErrorEPC";
6198 break;
7a387fff 6199 default:
f31b035a 6200 goto cp0_unimplemented;
7a387fff 6201 }
8c0fdd85
TS
6202 break;
6203 case 31:
7a387fff
TS
6204 switch (sel) {
6205 case 0:
f1aa6320 6206 /* EJTAG support */
7db13fae 6207 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6208 rn = "DESAVE";
6209 break;
e98c0d17 6210 case 2 ... 7:
f31b035a
LA
6211 CP0_CHECK(ctx->kscrexist & (1 << sel));
6212 tcg_gen_st_tl(arg, cpu_env,
6213 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6214 rn = "KScratch";
e98c0d17 6215 break;
7a387fff 6216 default:
f31b035a 6217 goto cp0_unimplemented;
7a387fff 6218 }
2423f660
TS
6219 /* Stop translation as we may have switched the execution mode */
6220 ctx->bstate = BS_STOP;
8c0fdd85
TS
6221 break;
6222 default:
f31b035a 6223 goto cp0_unimplemented;
8c0fdd85 6224 }
2abf314d 6225 (void)rn; /* avoid a compiler warning */
d12d51d5 6226 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6227 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6228 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6229 gen_io_end();
6230 ctx->bstate = BS_STOP;
6231 }
8c0fdd85
TS
6232 return;
6233
f31b035a 6234cp0_unimplemented:
d12d51d5 6235 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6236}
6237
d26bc211 6238#if defined(TARGET_MIPS64)
d75c135e 6239static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6240{
6241 const char *rn = "invalid";
6242
e189e748 6243 if (sel != 0)
d75c135e 6244 check_insn(ctx, ISA_MIPS64);
e189e748 6245
9c2149c8
TS
6246 switch (reg) {
6247 case 0:
6248 switch (sel) {
6249 case 0:
7db13fae 6250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6251 rn = "Index";
6252 break;
6253 case 1:
f31b035a 6254 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6255 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6256 rn = "MVPControl";
ead9360e 6257 break;
9c2149c8 6258 case 2:
f31b035a 6259 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6260 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6261 rn = "MVPConf0";
ead9360e 6262 break;
9c2149c8 6263 case 3:
f31b035a 6264 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6265 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6266 rn = "MVPConf1";
ead9360e 6267 break;
01bc435b
YK
6268 case 4:
6269 CP0_CHECK(ctx->vp);
6270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6271 rn = "VPControl";
6272 break;
9c2149c8 6273 default:
f31b035a 6274 goto cp0_unimplemented;
9c2149c8
TS
6275 }
6276 break;
6277 case 1:
6278 switch (sel) {
6279 case 0:
f31b035a 6280 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6281 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6282 rn = "Random";
2423f660 6283 break;
9c2149c8 6284 case 1:
f31b035a 6285 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6287 rn = "VPEControl";
ead9360e 6288 break;
9c2149c8 6289 case 2:
f31b035a 6290 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6292 rn = "VPEConf0";
ead9360e 6293 break;
9c2149c8 6294 case 3:
f31b035a 6295 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6297 rn = "VPEConf1";
ead9360e 6298 break;
9c2149c8 6299 case 4:
f31b035a 6300 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6302 rn = "YQMask";
ead9360e 6303 break;
9c2149c8 6304 case 5:
f31b035a 6305 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6306 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6307 rn = "VPESchedule";
ead9360e 6308 break;
9c2149c8 6309 case 6:
f31b035a 6310 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6311 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6312 rn = "VPEScheFBack";
ead9360e 6313 break;
9c2149c8 6314 case 7:
f31b035a 6315 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6317 rn = "VPEOpt";
ead9360e 6318 break;
9c2149c8 6319 default:
f31b035a 6320 goto cp0_unimplemented;
9c2149c8
TS
6321 }
6322 break;
6323 case 2:
6324 switch (sel) {
6325 case 0:
7db13fae 6326 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6327 rn = "EntryLo0";
6328 break;
9c2149c8 6329 case 1:
f31b035a 6330 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6331 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6332 rn = "TCStatus";
ead9360e 6333 break;
9c2149c8 6334 case 2:
f31b035a 6335 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6336 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6337 rn = "TCBind";
ead9360e 6338 break;
9c2149c8 6339 case 3:
f31b035a 6340 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6341 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6342 rn = "TCRestart";
ead9360e 6343 break;
9c2149c8 6344 case 4:
f31b035a 6345 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6346 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6347 rn = "TCHalt";
ead9360e 6348 break;
9c2149c8 6349 case 5:
f31b035a 6350 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6351 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6352 rn = "TCContext";
ead9360e 6353 break;
9c2149c8 6354 case 6:
f31b035a 6355 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6356 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6357 rn = "TCSchedule";
ead9360e 6358 break;
9c2149c8 6359 case 7:
f31b035a 6360 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6361 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6362 rn = "TCScheFBack";
ead9360e 6363 break;
9c2149c8 6364 default:
f31b035a 6365 goto cp0_unimplemented;
9c2149c8
TS
6366 }
6367 break;
6368 case 3:
6369 switch (sel) {
6370 case 0:
7db13fae 6371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6372 rn = "EntryLo1";
6373 break;
01bc435b
YK
6374 case 1:
6375 CP0_CHECK(ctx->vp);
6376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6377 rn = "GlobalNumber";
6378 break;
9c2149c8 6379 default:
f31b035a 6380 goto cp0_unimplemented;
1579a72e 6381 }
9c2149c8
TS
6382 break;
6383 case 4:
6384 switch (sel) {
6385 case 0:
7db13fae 6386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6387 rn = "Context";
6388 break;
9c2149c8 6389 case 1:
d9bea114 6390// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6391 rn = "ContextConfig";
f31b035a 6392 goto cp0_unimplemented;
2423f660 6393// break;
d279279e 6394 case 2:
f31b035a
LA
6395 CP0_CHECK(ctx->ulri);
6396 tcg_gen_ld_tl(arg, cpu_env,
6397 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6398 rn = "UserLocal";
d279279e 6399 break;
9c2149c8 6400 default:
f31b035a 6401 goto cp0_unimplemented;
876d4b07 6402 }
9c2149c8
TS
6403 break;
6404 case 5:
6405 switch (sel) {
6406 case 0:
7db13fae 6407 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6408 rn = "PageMask";
6409 break;
9c2149c8 6410 case 1:
d75c135e 6411 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6413 rn = "PageGrain";
6414 break;
9c2149c8 6415 default:
f31b035a 6416 goto cp0_unimplemented;
876d4b07 6417 }
9c2149c8
TS
6418 break;
6419 case 6:
6420 switch (sel) {
6421 case 0:
7db13fae 6422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6423 rn = "Wired";
6424 break;
9c2149c8 6425 case 1:
d75c135e 6426 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6428 rn = "SRSConf0";
ead9360e 6429 break;
9c2149c8 6430 case 2:
d75c135e 6431 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6433 rn = "SRSConf1";
ead9360e 6434 break;
9c2149c8 6435 case 3:
d75c135e 6436 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6438 rn = "SRSConf2";
ead9360e 6439 break;
9c2149c8 6440 case 4:
d75c135e 6441 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6443 rn = "SRSConf3";
ead9360e 6444 break;
9c2149c8 6445 case 5:
d75c135e 6446 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6448 rn = "SRSConf4";
ead9360e 6449 break;
9c2149c8 6450 default:
f31b035a 6451 goto cp0_unimplemented;
876d4b07 6452 }
9c2149c8
TS
6453 break;
6454 case 7:
6455 switch (sel) {
6456 case 0:
d75c135e 6457 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6459 rn = "HWREna";
6460 break;
9c2149c8 6461 default:
f31b035a 6462 goto cp0_unimplemented;
876d4b07 6463 }
9c2149c8
TS
6464 break;
6465 case 8:
6466 switch (sel) {
6467 case 0:
7db13fae 6468 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6469 rn = "BadVAddr";
2423f660 6470 break;
aea14095 6471 case 1:
f31b035a
LA
6472 CP0_CHECK(ctx->bi);
6473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6474 rn = "BadInstr";
aea14095
LA
6475 break;
6476 case 2:
f31b035a
LA
6477 CP0_CHECK(ctx->bp);
6478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6479 rn = "BadInstrP";
aea14095 6480 break;
9c2149c8 6481 default:
f31b035a 6482 goto cp0_unimplemented;
876d4b07 6483 }
9c2149c8
TS
6484 break;
6485 case 9:
6486 switch (sel) {
6487 case 0:
2e70f6ef 6488 /* Mark as an IO operation because we read the time. */
bd79255d 6489 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6490 gen_io_start();
bd79255d 6491 }
895c2d04 6492 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6493 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6494 gen_io_end();
2e70f6ef 6495 }
55807224
EI
6496 /* Break the TB to be able to take timer interrupts immediately
6497 after reading count. */
6498 ctx->bstate = BS_STOP;
2423f660
TS
6499 rn = "Count";
6500 break;
6501 /* 6,7 are implementation dependent */
9c2149c8 6502 default:
f31b035a 6503 goto cp0_unimplemented;
876d4b07 6504 }
9c2149c8
TS
6505 break;
6506 case 10:
6507 switch (sel) {
6508 case 0:
7db13fae 6509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6510 rn = "EntryHi";
6511 break;
9c2149c8 6512 default:
f31b035a 6513 goto cp0_unimplemented;
876d4b07 6514 }
9c2149c8
TS
6515 break;
6516 case 11:
6517 switch (sel) {
6518 case 0:
7db13fae 6519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6520 rn = "Compare";
6521 break;
876d4b07 6522 /* 6,7 are implementation dependent */
9c2149c8 6523 default:
f31b035a 6524 goto cp0_unimplemented;
876d4b07 6525 }
9c2149c8
TS
6526 break;
6527 case 12:
6528 switch (sel) {
6529 case 0:
7db13fae 6530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6531 rn = "Status";
6532 break;
9c2149c8 6533 case 1:
d75c135e 6534 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6536 rn = "IntCtl";
6537 break;
9c2149c8 6538 case 2:
d75c135e 6539 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6541 rn = "SRSCtl";
6542 break;
9c2149c8 6543 case 3:
d75c135e 6544 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6546 rn = "SRSMap";
6547 break;
9c2149c8 6548 default:
f31b035a 6549 goto cp0_unimplemented;
876d4b07 6550 }
9c2149c8
TS
6551 break;
6552 case 13:
6553 switch (sel) {
6554 case 0:
7db13fae 6555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6556 rn = "Cause";
6557 break;
9c2149c8 6558 default:
f31b035a 6559 goto cp0_unimplemented;
876d4b07 6560 }
9c2149c8
TS
6561 break;
6562 case 14:
6563 switch (sel) {
6564 case 0:
7db13fae 6565 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6566 rn = "EPC";
6567 break;
9c2149c8 6568 default:
f31b035a 6569 goto cp0_unimplemented;
876d4b07 6570 }
9c2149c8
TS
6571 break;
6572 case 15:
6573 switch (sel) {
6574 case 0:
7db13fae 6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6576 rn = "PRid";
6577 break;
9c2149c8 6578 case 1:
d75c135e 6579 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6581 rn = "EBase";
6582 break;
c870e3f5
YK
6583 case 3:
6584 check_insn(ctx, ISA_MIPS32R2);
6585 CP0_CHECK(ctx->cmgcr);
6586 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6587 rn = "CMGCRBase";
6588 break;
9c2149c8 6589 default:
f31b035a 6590 goto cp0_unimplemented;
876d4b07 6591 }
9c2149c8
TS
6592 break;
6593 case 16:
6594 switch (sel) {
6595 case 0:
7db13fae 6596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6597 rn = "Config";
6598 break;
6599 case 1:
7db13fae 6600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6601 rn = "Config1";
6602 break;
6603 case 2:
7db13fae 6604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6605 rn = "Config2";
6606 break;
6607 case 3:
7db13fae 6608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6609 rn = "Config3";
6610 break;
faf1f68b
LA
6611 case 4:
6612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6613 rn = "Config4";
6614 break;
6615 case 5:
6616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6617 rn = "Config5";
6618 break;
9c2149c8 6619 /* 6,7 are implementation dependent */
f0b3f3ae 6620 case 6:
7db13fae 6621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6622 rn = "Config6";
6623 break;
6624 case 7:
7db13fae 6625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6626 rn = "Config7";
6627 break;
9c2149c8 6628 default:
f31b035a 6629 goto cp0_unimplemented;
9c2149c8
TS
6630 }
6631 break;
6632 case 17:
6633 switch (sel) {
6634 case 0:
895c2d04 6635 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6636 rn = "LLAddr";
6637 break;
9c2149c8 6638 default:
f31b035a 6639 goto cp0_unimplemented;
9c2149c8
TS
6640 }
6641 break;
6642 case 18:
6643 switch (sel) {
fd88b6ab 6644 case 0 ... 7:
895c2d04 6645 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6646 rn = "WatchLo";
6647 break;
9c2149c8 6648 default:
f31b035a 6649 goto cp0_unimplemented;
9c2149c8
TS
6650 }
6651 break;
6652 case 19:
6653 switch (sel) {
fd88b6ab 6654 case 0 ... 7:
895c2d04 6655 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6656 rn = "WatchHi";
6657 break;
9c2149c8 6658 default:
f31b035a 6659 goto cp0_unimplemented;
9c2149c8
TS
6660 }
6661 break;
6662 case 20:
6663 switch (sel) {
6664 case 0:
d75c135e 6665 check_insn(ctx, ISA_MIPS3);
7db13fae 6666 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6667 rn = "XContext";
6668 break;
9c2149c8 6669 default:
f31b035a 6670 goto cp0_unimplemented;
9c2149c8
TS
6671 }
6672 break;
6673 case 21:
6674 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6675 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6676 switch (sel) {
6677 case 0:
7db13fae 6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6679 rn = "Framemask";
6680 break;
9c2149c8 6681 default:
f31b035a 6682 goto cp0_unimplemented;
9c2149c8
TS
6683 }
6684 break;
6685 case 22:
d9bea114 6686 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6687 rn = "'Diagnostic"; /* implementation dependent */
6688 break;
9c2149c8
TS
6689 case 23:
6690 switch (sel) {
6691 case 0:
895c2d04 6692 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6693 rn = "Debug";
6694 break;
9c2149c8 6695 case 1:
895c2d04 6696// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6697 rn = "TraceControl";
6698// break;
9c2149c8 6699 case 2:
895c2d04 6700// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6701 rn = "TraceControl2";
6702// break;
9c2149c8 6703 case 3:
895c2d04 6704// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6705 rn = "UserTraceData";
6706// break;
9c2149c8 6707 case 4:
895c2d04 6708// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6709 rn = "TraceBPC";
6710// break;
9c2149c8 6711 default:
f31b035a 6712 goto cp0_unimplemented;
9c2149c8
TS
6713 }
6714 break;
6715 case 24:
6716 switch (sel) {
6717 case 0:
f0b3f3ae 6718 /* EJTAG support */
7db13fae 6719 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6720 rn = "DEPC";
6721 break;
9c2149c8 6722 default:
f31b035a 6723 goto cp0_unimplemented;
9c2149c8
TS
6724 }
6725 break;
6726 case 25:
6727 switch (sel) {
6728 case 0:
7db13fae 6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6730 rn = "Performance0";
9c2149c8
TS
6731 break;
6732 case 1:
d9bea114 6733// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6734 rn = "Performance1";
6735// break;
9c2149c8 6736 case 2:
d9bea114 6737// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6738 rn = "Performance2";
6739// break;
9c2149c8 6740 case 3:
d9bea114 6741// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6742 rn = "Performance3";
6743// break;
9c2149c8 6744 case 4:
d9bea114 6745// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6746 rn = "Performance4";
6747// break;
9c2149c8 6748 case 5:
d9bea114 6749// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6750 rn = "Performance5";
6751// break;
9c2149c8 6752 case 6:
d9bea114 6753// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6754 rn = "Performance6";
6755// break;
9c2149c8 6756 case 7:
d9bea114 6757// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6758 rn = "Performance7";
6759// break;
9c2149c8 6760 default:
f31b035a 6761 goto cp0_unimplemented;
9c2149c8
TS
6762 }
6763 break;
6764 case 26:
d9bea114 6765 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6766 rn = "ECC";
6767 break;
9c2149c8
TS
6768 case 27:
6769 switch (sel) {
6770 /* ignored */
6771 case 0 ... 3:
d9bea114 6772 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6773 rn = "CacheErr";
6774 break;
9c2149c8 6775 default:
f31b035a 6776 goto cp0_unimplemented;
9c2149c8
TS
6777 }
6778 break;
6779 case 28:
6780 switch (sel) {
6781 case 0:
6782 case 2:
6783 case 4:
6784 case 6:
7db13fae 6785 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6786 rn = "TagLo";
6787 break;
6788 case 1:
6789 case 3:
6790 case 5:
6791 case 7:
7db13fae 6792 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6793 rn = "DataLo";
6794 break;
6795 default:
f31b035a 6796 goto cp0_unimplemented;
9c2149c8
TS
6797 }
6798 break;
6799 case 29:
6800 switch (sel) {
6801 case 0:
6802 case 2:
6803 case 4:
6804 case 6:
7db13fae 6805 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6806 rn = "TagHi";
6807 break;
6808 case 1:
6809 case 3:
6810 case 5:
6811 case 7:
7db13fae 6812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6813 rn = "DataHi";
6814 break;
6815 default:
f31b035a 6816 goto cp0_unimplemented;
9c2149c8
TS
6817 }
6818 break;
6819 case 30:
6820 switch (sel) {
6821 case 0:
7db13fae 6822 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6823 rn = "ErrorEPC";
6824 break;
9c2149c8 6825 default:
f31b035a 6826 goto cp0_unimplemented;
9c2149c8
TS
6827 }
6828 break;
6829 case 31:
6830 switch (sel) {
6831 case 0:
f0b3f3ae 6832 /* EJTAG support */
7db13fae 6833 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6834 rn = "DESAVE";
6835 break;
e98c0d17 6836 case 2 ... 7:
f31b035a
LA
6837 CP0_CHECK(ctx->kscrexist & (1 << sel));
6838 tcg_gen_ld_tl(arg, cpu_env,
6839 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6840 rn = "KScratch";
e98c0d17 6841 break;
9c2149c8 6842 default:
f31b035a 6843 goto cp0_unimplemented;
9c2149c8
TS
6844 }
6845 break;
6846 default:
f31b035a 6847 goto cp0_unimplemented;
9c2149c8 6848 }
2abf314d 6849 (void)rn; /* avoid a compiler warning */
d12d51d5 6850 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6851 return;
6852
f31b035a 6853cp0_unimplemented:
d12d51d5 6854 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6855 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6856}
6857
d75c135e 6858static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6859{
6860 const char *rn = "invalid";
6861
e189e748 6862 if (sel != 0)
d75c135e 6863 check_insn(ctx, ISA_MIPS64);
e189e748 6864
bd79255d 6865 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6866 gen_io_start();
bd79255d 6867 }
2e70f6ef 6868
9c2149c8
TS
6869 switch (reg) {
6870 case 0:
6871 switch (sel) {
6872 case 0:
895c2d04 6873 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6874 rn = "Index";
6875 break;
6876 case 1:
f31b035a 6877 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6878 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6879 rn = "MVPControl";
ead9360e 6880 break;
9c2149c8 6881 case 2:
f31b035a 6882 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6883 /* ignored */
9c2149c8 6884 rn = "MVPConf0";
ead9360e 6885 break;
9c2149c8 6886 case 3:
f31b035a 6887 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6888 /* ignored */
9c2149c8 6889 rn = "MVPConf1";
ead9360e 6890 break;
01bc435b
YK
6891 case 4:
6892 CP0_CHECK(ctx->vp);
6893 /* ignored */
6894 rn = "VPControl";
6895 break;
9c2149c8 6896 default:
f31b035a 6897 goto cp0_unimplemented;
9c2149c8
TS
6898 }
6899 break;
6900 case 1:
6901 switch (sel) {
6902 case 0:
2423f660 6903 /* ignored */
9c2149c8 6904 rn = "Random";
2423f660 6905 break;
9c2149c8 6906 case 1:
f31b035a 6907 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6908 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6909 rn = "VPEControl";
ead9360e 6910 break;
9c2149c8 6911 case 2:
f31b035a 6912 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6913 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6914 rn = "VPEConf0";
ead9360e 6915 break;
9c2149c8 6916 case 3:
f31b035a 6917 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6918 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6919 rn = "VPEConf1";
ead9360e 6920 break;
9c2149c8 6921 case 4:
f31b035a 6922 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6923 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6924 rn = "YQMask";
ead9360e 6925 break;
9c2149c8 6926 case 5:
f31b035a 6927 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6928 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6929 rn = "VPESchedule";
ead9360e 6930 break;
9c2149c8 6931 case 6:
f31b035a 6932 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6933 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6934 rn = "VPEScheFBack";
ead9360e 6935 break;
9c2149c8 6936 case 7:
f31b035a 6937 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6938 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6939 rn = "VPEOpt";
ead9360e 6940 break;
9c2149c8 6941 default:
f31b035a 6942 goto cp0_unimplemented;
9c2149c8
TS
6943 }
6944 break;
6945 case 2:
6946 switch (sel) {
6947 case 0:
7207c7f9 6948 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6949 rn = "EntryLo0";
6950 break;
9c2149c8 6951 case 1:
f31b035a 6952 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6953 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6954 rn = "TCStatus";
ead9360e 6955 break;
9c2149c8 6956 case 2:
f31b035a 6957 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6958 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6959 rn = "TCBind";
ead9360e 6960 break;
9c2149c8 6961 case 3:
f31b035a 6962 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6963 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6964 rn = "TCRestart";
ead9360e 6965 break;
9c2149c8 6966 case 4:
f31b035a 6967 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6968 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6969 rn = "TCHalt";
ead9360e 6970 break;
9c2149c8 6971 case 5:
f31b035a 6972 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6973 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6974 rn = "TCContext";
ead9360e 6975 break;
9c2149c8 6976 case 6:
f31b035a 6977 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6978 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6979 rn = "TCSchedule";
ead9360e 6980 break;
9c2149c8 6981 case 7:
f31b035a 6982 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6983 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6984 rn = "TCScheFBack";
ead9360e 6985 break;
9c2149c8 6986 default:
f31b035a 6987 goto cp0_unimplemented;
9c2149c8
TS
6988 }
6989 break;
6990 case 3:
6991 switch (sel) {
6992 case 0:
7207c7f9 6993 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6994 rn = "EntryLo1";
6995 break;
01bc435b
YK
6996 case 1:
6997 CP0_CHECK(ctx->vp);
6998 /* ignored */
6999 rn = "GlobalNumber";
7000 break;
9c2149c8 7001 default:
f31b035a 7002 goto cp0_unimplemented;
876d4b07 7003 }
9c2149c8
TS
7004 break;
7005 case 4:
7006 switch (sel) {
7007 case 0:
895c2d04 7008 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7009 rn = "Context";
7010 break;
9c2149c8 7011 case 1:
895c2d04 7012// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7013 rn = "ContextConfig";
f31b035a 7014 goto cp0_unimplemented;
2423f660 7015// break;
d279279e 7016 case 2:
f31b035a
LA
7017 CP0_CHECK(ctx->ulri);
7018 tcg_gen_st_tl(arg, cpu_env,
7019 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7020 rn = "UserLocal";
d279279e 7021 break;
9c2149c8 7022 default:
f31b035a 7023 goto cp0_unimplemented;
876d4b07 7024 }
9c2149c8
TS
7025 break;
7026 case 5:
7027 switch (sel) {
7028 case 0:
895c2d04 7029 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7030 rn = "PageMask";
7031 break;
9c2149c8 7032 case 1:
d75c135e 7033 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7034 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7035 rn = "PageGrain";
7036 break;
9c2149c8 7037 default:
f31b035a 7038 goto cp0_unimplemented;
876d4b07 7039 }
9c2149c8
TS
7040 break;
7041 case 6:
7042 switch (sel) {
7043 case 0:
895c2d04 7044 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7045 rn = "Wired";
7046 break;
9c2149c8 7047 case 1:
d75c135e 7048 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7049 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7050 rn = "SRSConf0";
ead9360e 7051 break;
9c2149c8 7052 case 2:
d75c135e 7053 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7054 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7055 rn = "SRSConf1";
ead9360e 7056 break;
9c2149c8 7057 case 3:
d75c135e 7058 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7059 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7060 rn = "SRSConf2";
ead9360e 7061 break;
9c2149c8 7062 case 4:
d75c135e 7063 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7064 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7065 rn = "SRSConf3";
ead9360e 7066 break;
9c2149c8 7067 case 5:
d75c135e 7068 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7069 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7070 rn = "SRSConf4";
ead9360e 7071 break;
9c2149c8 7072 default:
f31b035a 7073 goto cp0_unimplemented;
876d4b07 7074 }
9c2149c8
TS
7075 break;
7076 case 7:
7077 switch (sel) {
7078 case 0:
d75c135e 7079 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7080 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7081 ctx->bstate = BS_STOP;
2423f660
TS
7082 rn = "HWREna";
7083 break;
9c2149c8 7084 default:
f31b035a 7085 goto cp0_unimplemented;
876d4b07 7086 }
9c2149c8
TS
7087 break;
7088 case 8:
aea14095
LA
7089 switch (sel) {
7090 case 0:
7091 /* ignored */
7092 rn = "BadVAddr";
7093 break;
7094 case 1:
7095 /* ignored */
7096 rn = "BadInstr";
7097 break;
7098 case 2:
7099 /* ignored */
7100 rn = "BadInstrP";
7101 break;
7102 default:
f31b035a 7103 goto cp0_unimplemented;
aea14095 7104 }
9c2149c8
TS
7105 break;
7106 case 9:
7107 switch (sel) {
7108 case 0:
895c2d04 7109 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7110 rn = "Count";
7111 break;
876d4b07 7112 /* 6,7 are implementation dependent */
9c2149c8 7113 default:
f31b035a 7114 goto cp0_unimplemented;
876d4b07
TS
7115 }
7116 /* Stop translation as we may have switched the execution mode */
7117 ctx->bstate = BS_STOP;
9c2149c8
TS
7118 break;
7119 case 10:
7120 switch (sel) {
7121 case 0:
895c2d04 7122 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7123 rn = "EntryHi";
7124 break;
9c2149c8 7125 default:
f31b035a 7126 goto cp0_unimplemented;
876d4b07 7127 }
9c2149c8
TS
7128 break;
7129 case 11:
7130 switch (sel) {
7131 case 0:
895c2d04 7132 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7133 rn = "Compare";
7134 break;
876d4b07 7135 /* 6,7 are implementation dependent */
9c2149c8 7136 default:
f31b035a 7137 goto cp0_unimplemented;
876d4b07 7138 }
de9a95f0
AJ
7139 /* Stop translation as we may have switched the execution mode */
7140 ctx->bstate = BS_STOP;
9c2149c8
TS
7141 break;
7142 case 12:
7143 switch (sel) {
7144 case 0:
867abc7e 7145 save_cpu_state(ctx, 1);
895c2d04 7146 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7147 /* BS_STOP isn't good enough here, hflags may have changed. */
7148 gen_save_pc(ctx->pc + 4);
7149 ctx->bstate = BS_EXCP;
2423f660
TS
7150 rn = "Status";
7151 break;
9c2149c8 7152 case 1:
d75c135e 7153 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7154 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7155 /* Stop translation as we may have switched the execution mode */
7156 ctx->bstate = BS_STOP;
2423f660
TS
7157 rn = "IntCtl";
7158 break;
9c2149c8 7159 case 2:
d75c135e 7160 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7161 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7162 /* Stop translation as we may have switched the execution mode */
7163 ctx->bstate = BS_STOP;
2423f660
TS
7164 rn = "SRSCtl";
7165 break;
9c2149c8 7166 case 3:
d75c135e 7167 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7168 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7169 /* Stop translation as we may have switched the execution mode */
7170 ctx->bstate = BS_STOP;
2423f660
TS
7171 rn = "SRSMap";
7172 break;
7173 default:
f31b035a 7174 goto cp0_unimplemented;
876d4b07 7175 }
9c2149c8
TS
7176 break;
7177 case 13:
7178 switch (sel) {
7179 case 0:
867abc7e 7180 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7181 /* Mark as an IO operation because we may trigger a software
7182 interrupt. */
bd79255d 7183 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7184 gen_io_start();
7185 }
895c2d04 7186 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7187 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7188 gen_io_end();
7189 }
7190 /* Stop translation as we may have triggered an intetrupt */
7191 ctx->bstate = BS_STOP;
2423f660
TS
7192 rn = "Cause";
7193 break;
9c2149c8 7194 default:
f31b035a 7195 goto cp0_unimplemented;
876d4b07 7196 }
9c2149c8
TS
7197 break;
7198 case 14:
7199 switch (sel) {
7200 case 0:
7db13fae 7201 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7202 rn = "EPC";
7203 break;
9c2149c8 7204 default:
f31b035a 7205 goto cp0_unimplemented;
876d4b07 7206 }
9c2149c8
TS
7207 break;
7208 case 15:
7209 switch (sel) {
7210 case 0:
2423f660
TS
7211 /* ignored */
7212 rn = "PRid";
7213 break;
9c2149c8 7214 case 1:
d75c135e 7215 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7216 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7217 rn = "EBase";
7218 break;
9c2149c8 7219 default:
f31b035a 7220 goto cp0_unimplemented;
876d4b07 7221 }
9c2149c8
TS
7222 break;
7223 case 16:
7224 switch (sel) {
7225 case 0:
895c2d04 7226 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7227 rn = "Config";
2423f660
TS
7228 /* Stop translation as we may have switched the execution mode */
7229 ctx->bstate = BS_STOP;
9c2149c8
TS
7230 break;
7231 case 1:
1fc7bf6e 7232 /* ignored, read only */
9c2149c8
TS
7233 rn = "Config1";
7234 break;
7235 case 2:
895c2d04 7236 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7237 rn = "Config2";
2423f660
TS
7238 /* Stop translation as we may have switched the execution mode */
7239 ctx->bstate = BS_STOP;
9c2149c8
TS
7240 break;
7241 case 3:
90f12d73 7242 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7243 rn = "Config3";
90f12d73
MR
7244 /* Stop translation as we may have switched the execution mode */
7245 ctx->bstate = BS_STOP;
9c2149c8 7246 break;
faf1f68b
LA
7247 case 4:
7248 /* currently ignored */
7249 rn = "Config4";
7250 break;
7251 case 5:
7252 gen_helper_mtc0_config5(cpu_env, arg);
7253 rn = "Config5";
7254 /* Stop translation as we may have switched the execution mode */
7255 ctx->bstate = BS_STOP;
7256 break;
9c2149c8
TS
7257 /* 6,7 are implementation dependent */
7258 default:
7259 rn = "Invalid config selector";
f31b035a 7260 goto cp0_unimplemented;
9c2149c8 7261 }
9c2149c8
TS
7262 break;
7263 case 17:
7264 switch (sel) {
7265 case 0:
895c2d04 7266 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7267 rn = "LLAddr";
7268 break;
9c2149c8 7269 default:
f31b035a 7270 goto cp0_unimplemented;
9c2149c8
TS
7271 }
7272 break;
7273 case 18:
7274 switch (sel) {
fd88b6ab 7275 case 0 ... 7:
895c2d04 7276 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7277 rn = "WatchLo";
7278 break;
9c2149c8 7279 default:
f31b035a 7280 goto cp0_unimplemented;
9c2149c8
TS
7281 }
7282 break;
7283 case 19:
7284 switch (sel) {
fd88b6ab 7285 case 0 ... 7:
895c2d04 7286 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7287 rn = "WatchHi";
7288 break;
9c2149c8 7289 default:
f31b035a 7290 goto cp0_unimplemented;
9c2149c8
TS
7291 }
7292 break;
7293 case 20:
7294 switch (sel) {
7295 case 0:
d75c135e 7296 check_insn(ctx, ISA_MIPS3);
895c2d04 7297 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7298 rn = "XContext";
7299 break;
9c2149c8 7300 default:
f31b035a 7301 goto cp0_unimplemented;
9c2149c8
TS
7302 }
7303 break;
7304 case 21:
7305 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7306 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7307 switch (sel) {
7308 case 0:
895c2d04 7309 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7310 rn = "Framemask";
7311 break;
9c2149c8 7312 default:
f31b035a 7313 goto cp0_unimplemented;
9c2149c8
TS
7314 }
7315 break;
7316 case 22:
7317 /* ignored */
7318 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7319 break;
9c2149c8
TS
7320 case 23:
7321 switch (sel) {
7322 case 0:
895c2d04 7323 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7324 /* BS_STOP isn't good enough here, hflags may have changed. */
7325 gen_save_pc(ctx->pc + 4);
7326 ctx->bstate = BS_EXCP;
2423f660
TS
7327 rn = "Debug";
7328 break;
9c2149c8 7329 case 1:
895c2d04 7330// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7331 /* Stop translation as we may have switched the execution mode */
7332 ctx->bstate = BS_STOP;
2423f660
TS
7333 rn = "TraceControl";
7334// break;
9c2149c8 7335 case 2:
895c2d04 7336// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7337 /* Stop translation as we may have switched the execution mode */
7338 ctx->bstate = BS_STOP;
2423f660
TS
7339 rn = "TraceControl2";
7340// break;
9c2149c8 7341 case 3:
895c2d04 7342// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7343 /* Stop translation as we may have switched the execution mode */
7344 ctx->bstate = BS_STOP;
2423f660
TS
7345 rn = "UserTraceData";
7346// break;
9c2149c8 7347 case 4:
895c2d04 7348// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7349 /* Stop translation as we may have switched the execution mode */
7350 ctx->bstate = BS_STOP;
2423f660
TS
7351 rn = "TraceBPC";
7352// break;
9c2149c8 7353 default:
f31b035a 7354 goto cp0_unimplemented;
9c2149c8 7355 }
9c2149c8
TS
7356 break;
7357 case 24:
7358 switch (sel) {
7359 case 0:
f1aa6320 7360 /* EJTAG support */
7db13fae 7361 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7362 rn = "DEPC";
7363 break;
9c2149c8 7364 default:
f31b035a 7365 goto cp0_unimplemented;
9c2149c8
TS
7366 }
7367 break;
7368 case 25:
7369 switch (sel) {
7370 case 0:
895c2d04 7371 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7372 rn = "Performance0";
7373 break;
9c2149c8 7374 case 1:
895c2d04 7375// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7376 rn = "Performance1";
7377// break;
9c2149c8 7378 case 2:
895c2d04 7379// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7380 rn = "Performance2";
7381// break;
9c2149c8 7382 case 3:
895c2d04 7383// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7384 rn = "Performance3";
7385// break;
9c2149c8 7386 case 4:
895c2d04 7387// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7388 rn = "Performance4";
7389// break;
9c2149c8 7390 case 5:
895c2d04 7391// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7392 rn = "Performance5";
7393// break;
9c2149c8 7394 case 6:
895c2d04 7395// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7396 rn = "Performance6";
7397// break;
9c2149c8 7398 case 7:
895c2d04 7399// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7400 rn = "Performance7";
7401// break;
9c2149c8 7402 default:
f31b035a 7403 goto cp0_unimplemented;
9c2149c8 7404 }
876d4b07 7405 break;
9c2149c8 7406 case 26:
876d4b07 7407 /* ignored */
9c2149c8 7408 rn = "ECC";
876d4b07 7409 break;
9c2149c8
TS
7410 case 27:
7411 switch (sel) {
7412 case 0 ... 3:
2423f660
TS
7413 /* ignored */
7414 rn = "CacheErr";
7415 break;
9c2149c8 7416 default:
f31b035a 7417 goto cp0_unimplemented;
9c2149c8 7418 }
876d4b07 7419 break;
9c2149c8
TS
7420 case 28:
7421 switch (sel) {
7422 case 0:
7423 case 2:
7424 case 4:
7425 case 6:
895c2d04 7426 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7427 rn = "TagLo";
7428 break;
7429 case 1:
7430 case 3:
7431 case 5:
7432 case 7:
895c2d04 7433 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7434 rn = "DataLo";
7435 break;
7436 default:
f31b035a 7437 goto cp0_unimplemented;
9c2149c8
TS
7438 }
7439 break;
7440 case 29:
7441 switch (sel) {
7442 case 0:
7443 case 2:
7444 case 4:
7445 case 6:
895c2d04 7446 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7447 rn = "TagHi";
7448 break;
7449 case 1:
7450 case 3:
7451 case 5:
7452 case 7:
895c2d04 7453 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7454 rn = "DataHi";
7455 break;
7456 default:
7457 rn = "invalid sel";
f31b035a 7458 goto cp0_unimplemented;
9c2149c8 7459 }
876d4b07 7460 break;
9c2149c8
TS
7461 case 30:
7462 switch (sel) {
7463 case 0:
7db13fae 7464 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7465 rn = "ErrorEPC";
7466 break;
9c2149c8 7467 default:
f31b035a 7468 goto cp0_unimplemented;
9c2149c8
TS
7469 }
7470 break;
7471 case 31:
7472 switch (sel) {
7473 case 0:
f1aa6320 7474 /* EJTAG support */
7db13fae 7475 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7476 rn = "DESAVE";
7477 break;
e98c0d17 7478 case 2 ... 7:
f31b035a
LA
7479 CP0_CHECK(ctx->kscrexist & (1 << sel));
7480 tcg_gen_st_tl(arg, cpu_env,
7481 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7482 rn = "KScratch";
e98c0d17 7483 break;
9c2149c8 7484 default:
f31b035a 7485 goto cp0_unimplemented;
9c2149c8 7486 }
876d4b07
TS
7487 /* Stop translation as we may have switched the execution mode */
7488 ctx->bstate = BS_STOP;
9c2149c8
TS
7489 break;
7490 default:
f31b035a 7491 goto cp0_unimplemented;
9c2149c8 7492 }
2abf314d 7493 (void)rn; /* avoid a compiler warning */
d12d51d5 7494 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7495 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7496 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7497 gen_io_end();
7498 ctx->bstate = BS_STOP;
7499 }
9c2149c8
TS
7500 return;
7501
f31b035a 7502cp0_unimplemented:
d12d51d5 7503 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7504}
d26bc211 7505#endif /* TARGET_MIPS64 */
9c2149c8 7506
7db13fae 7507static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7508 int u, int sel, int h)
7509{
7510 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7511 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7512
7513 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7514 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7515 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7516 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7517 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7518 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7519 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7520 else if (u == 0) {
7521 switch (rt) {
5a25ce94
EI
7522 case 1:
7523 switch (sel) {
7524 case 1:
895c2d04 7525 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7526 break;
7527 case 2:
895c2d04 7528 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7529 break;
7530 default:
7531 goto die;
7532 break;
7533 }
7534 break;
ead9360e
TS
7535 case 2:
7536 switch (sel) {
7537 case 1:
895c2d04 7538 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7539 break;
7540 case 2:
895c2d04 7541 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7542 break;
7543 case 3:
895c2d04 7544 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7545 break;
7546 case 4:
895c2d04 7547 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7548 break;
7549 case 5:
895c2d04 7550 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7551 break;
7552 case 6:
895c2d04 7553 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7554 break;
7555 case 7:
895c2d04 7556 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7557 break;
7558 default:
d75c135e 7559 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7560 break;
7561 }
7562 break;
7563 case 10:
7564 switch (sel) {
7565 case 0:
895c2d04 7566 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7567 break;
7568 default:
d75c135e 7569 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7570 break;
7571 }
7572 case 12:
7573 switch (sel) {
7574 case 0:
895c2d04 7575 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7576 break;
7577 default:
d75c135e 7578 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7579 break;
7580 }
5a25ce94
EI
7581 case 13:
7582 switch (sel) {
7583 case 0:
895c2d04 7584 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7585 break;
7586 default:
7587 goto die;
7588 break;
7589 }
7590 break;
7591 case 14:
7592 switch (sel) {
7593 case 0:
895c2d04 7594 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7595 break;
7596 default:
7597 goto die;
7598 break;
7599 }
7600 break;
7601 case 15:
7602 switch (sel) {
7603 case 1:
895c2d04 7604 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7605 break;
7606 default:
7607 goto die;
7608 break;
7609 }
7610 break;
7611 case 16:
7612 switch (sel) {
7613 case 0 ... 7:
895c2d04 7614 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7615 break;
7616 default:
7617 goto die;
7618 break;
7619 }
7620 break;
ead9360e
TS
7621 case 23:
7622 switch (sel) {
7623 case 0:
895c2d04 7624 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7625 break;
7626 default:
d75c135e 7627 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7628 break;
7629 }
7630 break;
7631 default:
d75c135e 7632 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7633 }
7634 } else switch (sel) {
7635 /* GPR registers. */
7636 case 0:
895c2d04 7637 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7638 break;
7639 /* Auxiliary CPU registers */
7640 case 1:
7641 switch (rt) {
7642 case 0:
895c2d04 7643 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7644 break;
7645 case 1:
895c2d04 7646 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7647 break;
7648 case 2:
895c2d04 7649 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7650 break;
7651 case 4:
895c2d04 7652 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7653 break;
7654 case 5:
895c2d04 7655 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7656 break;
7657 case 6:
895c2d04 7658 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7659 break;
7660 case 8:
895c2d04 7661 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7662 break;
7663 case 9:
895c2d04 7664 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7665 break;
7666 case 10:
895c2d04 7667 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7668 break;
7669 case 12:
895c2d04 7670 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7671 break;
7672 case 13:
895c2d04 7673 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7674 break;
7675 case 14:
895c2d04 7676 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7677 break;
7678 case 16:
895c2d04 7679 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7680 break;
7681 default:
7682 goto die;
7683 }
7684 break;
7685 /* Floating point (COP1). */
7686 case 2:
7687 /* XXX: For now we support only a single FPU context. */
7688 if (h == 0) {
a7812ae4 7689 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7690
7c979afd 7691 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7692 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7693 tcg_temp_free_i32(fp0);
ead9360e 7694 } else {
a7812ae4 7695 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7696
7f6613ce 7697 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7698 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7699 tcg_temp_free_i32(fp0);
ead9360e
TS
7700 }
7701 break;
7702 case 3:
7703 /* XXX: For now we support only a single FPU context. */
895c2d04 7704 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7705 break;
7706 /* COP2: Not implemented. */
7707 case 4:
7708 case 5:
7709 /* fall through */
7710 default:
7711 goto die;
7712 }
d12d51d5 7713 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7714 gen_store_gpr(t0, rd);
7715 tcg_temp_free(t0);
ead9360e
TS
7716 return;
7717
7718die:
1a3fd9c3 7719 tcg_temp_free(t0);
d12d51d5 7720 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7721 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7722}
7723
7db13fae 7724static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7725 int u, int sel, int h)
7726{
7727 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7728 TCGv t0 = tcg_temp_local_new();
ead9360e 7729
1a3fd9c3 7730 gen_load_gpr(t0, rt);
ead9360e 7731 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7732 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7733 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7734 /* NOP */ ;
7735 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7736 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7737 /* NOP */ ;
7738 else if (u == 0) {
7739 switch (rd) {
5a25ce94
EI
7740 case 1:
7741 switch (sel) {
7742 case 1:
895c2d04 7743 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7744 break;
7745 case 2:
895c2d04 7746 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7747 break;
7748 default:
7749 goto die;
7750 break;
7751 }
7752 break;
ead9360e
TS
7753 case 2:
7754 switch (sel) {
7755 case 1:
895c2d04 7756 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7757 break;
7758 case 2:
895c2d04 7759 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7760 break;
7761 case 3:
895c2d04 7762 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7763 break;
7764 case 4:
895c2d04 7765 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7766 break;
7767 case 5:
895c2d04 7768 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7769 break;
7770 case 6:
895c2d04 7771 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7772 break;
7773 case 7:
895c2d04 7774 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7775 break;
7776 default:
d75c135e 7777 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7778 break;
7779 }
7780 break;
7781 case 10:
7782 switch (sel) {
7783 case 0:
895c2d04 7784 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7785 break;
7786 default:
d75c135e 7787 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7788 break;
7789 }
7790 case 12:
7791 switch (sel) {
7792 case 0:
895c2d04 7793 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7794 break;
7795 default:
d75c135e 7796 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7797 break;
7798 }
5a25ce94
EI
7799 case 13:
7800 switch (sel) {
7801 case 0:
895c2d04 7802 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7803 break;
7804 default:
7805 goto die;
7806 break;
7807 }
7808 break;
7809 case 15:
7810 switch (sel) {
7811 case 1:
895c2d04 7812 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7813 break;
7814 default:
7815 goto die;
7816 break;
7817 }
7818 break;
ead9360e
TS
7819 case 23:
7820 switch (sel) {
7821 case 0:
895c2d04 7822 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7823 break;
7824 default:
d75c135e 7825 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7826 break;
7827 }
7828 break;
7829 default:
d75c135e 7830 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7831 }
7832 } else switch (sel) {
7833 /* GPR registers. */
7834 case 0:
895c2d04 7835 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7836 break;
7837 /* Auxiliary CPU registers */
7838 case 1:
7839 switch (rd) {
7840 case 0:
895c2d04 7841 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7842 break;
7843 case 1:
895c2d04 7844 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7845 break;
7846 case 2:
895c2d04 7847 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7848 break;
7849 case 4:
895c2d04 7850 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7851 break;
7852 case 5:
895c2d04 7853 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7854 break;
7855 case 6:
895c2d04 7856 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7857 break;
7858 case 8:
895c2d04 7859 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7860 break;
7861 case 9:
895c2d04 7862 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7863 break;
7864 case 10:
895c2d04 7865 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7866 break;
7867 case 12:
895c2d04 7868 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7869 break;
7870 case 13:
895c2d04 7871 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7872 break;
7873 case 14:
895c2d04 7874 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7875 break;
7876 case 16:
895c2d04 7877 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7878 break;
7879 default:
7880 goto die;
7881 }
7882 break;
7883 /* Floating point (COP1). */
7884 case 2:
7885 /* XXX: For now we support only a single FPU context. */
7886 if (h == 0) {
a7812ae4 7887 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7888
7889 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7890 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7891 tcg_temp_free_i32(fp0);
ead9360e 7892 } else {
a7812ae4 7893 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7894
7895 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7896 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7897 tcg_temp_free_i32(fp0);
ead9360e
TS
7898 }
7899 break;
7900 case 3:
7901 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7902 {
7903 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7904
7905 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7906 tcg_temp_free_i32(fs_tmp);
7907 }
4cf8a45f
YK
7908 /* Stop translation as we may have changed hflags */
7909 ctx->bstate = BS_STOP;
ead9360e
TS
7910 break;
7911 /* COP2: Not implemented. */
7912 case 4:
7913 case 5:
7914 /* fall through */
7915 default:
7916 goto die;
7917 }
d12d51d5 7918 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7919 tcg_temp_free(t0);
ead9360e
TS
7920 return;
7921
7922die:
1a3fd9c3 7923 tcg_temp_free(t0);
d12d51d5 7924 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 7925 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7926}
7927
7db13fae 7928static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7929{
287c4b84 7930 const char *opn = "ldst";
6af0bf9c 7931
2e15497c 7932 check_cp0_enabled(ctx);
6af0bf9c
FB
7933 switch (opc) {
7934 case OPC_MFC0:
7935 if (rt == 0) {
ead9360e 7936 /* Treat as NOP. */
6af0bf9c
FB
7937 return;
7938 }
d75c135e 7939 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7940 opn = "mfc0";
7941 break;
7942 case OPC_MTC0:
1a3fd9c3 7943 {
1fc7bf6e 7944 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7945
7946 gen_load_gpr(t0, rt);
d75c135e 7947 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7948 tcg_temp_free(t0);
7949 }
6af0bf9c
FB
7950 opn = "mtc0";
7951 break;
d26bc211 7952#if defined(TARGET_MIPS64)
9c2149c8 7953 case OPC_DMFC0:
d75c135e 7954 check_insn(ctx, ISA_MIPS3);
9c2149c8 7955 if (rt == 0) {
ead9360e 7956 /* Treat as NOP. */
9c2149c8
TS
7957 return;
7958 }
d75c135e 7959 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7960 opn = "dmfc0";
7961 break;
7962 case OPC_DMTC0:
d75c135e 7963 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7964 {
1fc7bf6e 7965 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7966
7967 gen_load_gpr(t0, rt);
d75c135e 7968 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7969 tcg_temp_free(t0);
7970 }
9c2149c8
TS
7971 opn = "dmtc0";
7972 break;
534ce69f 7973#endif
5204ea79
LA
7974 case OPC_MFHC0:
7975 check_mvh(ctx);
7976 if (rt == 0) {
7977 /* Treat as NOP. */
7978 return;
7979 }
7980 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7981 opn = "mfhc0";
7982 break;
7983 case OPC_MTHC0:
7984 check_mvh(ctx);
7985 {
7986 TCGv t0 = tcg_temp_new();
7987 gen_load_gpr(t0, rt);
7988 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7989 tcg_temp_free(t0);
7990 }
7991 opn = "mthc0";
7992 break;
ead9360e 7993 case OPC_MFTR:
d75c135e 7994 check_insn(ctx, ASE_MT);
ead9360e
TS
7995 if (rd == 0) {
7996 /* Treat as NOP. */
7997 return;
7998 }
6c5c1e20 7999 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8000 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8001 opn = "mftr";
8002 break;
8003 case OPC_MTTR:
d75c135e 8004 check_insn(ctx, ASE_MT);
6c5c1e20 8005 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8006 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8007 opn = "mttr";
8008 break;
6af0bf9c 8009 case OPC_TLBWI:
6af0bf9c 8010 opn = "tlbwi";
c01fccd2 8011 if (!env->tlb->helper_tlbwi)
29929e34 8012 goto die;
895c2d04 8013 gen_helper_tlbwi(cpu_env);
6af0bf9c 8014 break;
9456c2fb
LA
8015 case OPC_TLBINV:
8016 opn = "tlbinv";
8017 if (ctx->ie >= 2) {
8018 if (!env->tlb->helper_tlbinv) {
8019 goto die;
8020 }
8021 gen_helper_tlbinv(cpu_env);
8022 } /* treat as nop if TLBINV not supported */
8023 break;
8024 case OPC_TLBINVF:
8025 opn = "tlbinvf";
8026 if (ctx->ie >= 2) {
8027 if (!env->tlb->helper_tlbinvf) {
8028 goto die;
8029 }
8030 gen_helper_tlbinvf(cpu_env);
8031 } /* treat as nop if TLBINV not supported */
8032 break;
6af0bf9c 8033 case OPC_TLBWR:
6af0bf9c 8034 opn = "tlbwr";
c01fccd2 8035 if (!env->tlb->helper_tlbwr)
29929e34 8036 goto die;
895c2d04 8037 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8038 break;
8039 case OPC_TLBP:
6af0bf9c 8040 opn = "tlbp";
c01fccd2 8041 if (!env->tlb->helper_tlbp)
29929e34 8042 goto die;
895c2d04 8043 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8044 break;
8045 case OPC_TLBR:
6af0bf9c 8046 opn = "tlbr";
c01fccd2 8047 if (!env->tlb->helper_tlbr)
29929e34 8048 goto die;
895c2d04 8049 gen_helper_tlbr(cpu_env);
6af0bf9c 8050 break;
ce9782f4 8051 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8052 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8053 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8054 goto die;
ce9782f4
LA
8055 } else {
8056 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8057 if (ctx->opcode & (1 << bit_shift)) {
8058 /* OPC_ERETNC */
8059 opn = "eretnc";
8060 check_insn(ctx, ISA_MIPS32R5);
8061 gen_helper_eretnc(cpu_env);
8062 } else {
8063 /* OPC_ERET */
8064 opn = "eret";
8065 check_insn(ctx, ISA_MIPS2);
8066 gen_helper_eret(cpu_env);
8067 }
8068 ctx->bstate = BS_EXCP;
339cd2a8 8069 }
6af0bf9c
FB
8070 break;
8071 case OPC_DERET:
8072 opn = "deret";
d75c135e 8073 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8074 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8075 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8076 goto die;
8077 }
6af0bf9c 8078 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8079 MIPS_INVAL(opn);
9c708c7f 8080 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8081 } else {
895c2d04 8082 gen_helper_deret(cpu_env);
6af0bf9c
FB
8083 ctx->bstate = BS_EXCP;
8084 }
8085 break;
4ad40f36
FB
8086 case OPC_WAIT:
8087 opn = "wait";
d75c135e 8088 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8089 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8090 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8091 goto die;
8092 }
4ad40f36
FB
8093 /* If we get an exception, we want to restart at next instruction */
8094 ctx->pc += 4;
8095 save_cpu_state(ctx, 1);
8096 ctx->pc -= 4;
895c2d04 8097 gen_helper_wait(cpu_env);
4ad40f36
FB
8098 ctx->bstate = BS_EXCP;
8099 break;
6af0bf9c 8100 default:
29929e34 8101 die:
923617a3 8102 MIPS_INVAL(opn);
9c708c7f 8103 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8104 return;
8105 }
2abf314d 8106 (void)opn; /* avoid a compiler warning */
6af0bf9c 8107}
f1aa6320 8108#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8109
6ea83fed 8110/* CP1 Branches (before delay slot) */
d75c135e
AJ
8111static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8112 int32_t cc, int32_t offset)
6ea83fed
FB
8113{
8114 target_ulong btarget;
a7812ae4 8115 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8116
339cd2a8 8117 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8118 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8119 goto out;
8120 }
8121
e189e748 8122 if (cc != 0)
d75c135e 8123 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8124
6ea83fed
FB
8125 btarget = ctx->pc + 4 + offset;
8126
7a387fff
TS
8127 switch (op) {
8128 case OPC_BC1F:
d94536f4
AJ
8129 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8130 tcg_gen_not_i32(t0, t0);
8131 tcg_gen_andi_i32(t0, t0, 1);
8132 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8133 goto not_likely;
7a387fff 8134 case OPC_BC1FL:
d94536f4
AJ
8135 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8136 tcg_gen_not_i32(t0, t0);
8137 tcg_gen_andi_i32(t0, t0, 1);
8138 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8139 goto likely;
7a387fff 8140 case OPC_BC1T:
d94536f4
AJ
8141 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8142 tcg_gen_andi_i32(t0, t0, 1);
8143 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8144 goto not_likely;
7a387fff 8145 case OPC_BC1TL:
d94536f4
AJ
8146 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8147 tcg_gen_andi_i32(t0, t0, 1);
8148 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8149 likely:
8150 ctx->hflags |= MIPS_HFLAG_BL;
8151 break;
5a5012ec 8152 case OPC_BC1FANY2:
a16336e4 8153 {
d94536f4
AJ
8154 TCGv_i32 t1 = tcg_temp_new_i32();
8155 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8156 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8157 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8158 tcg_temp_free_i32(t1);
d94536f4
AJ
8159 tcg_gen_andi_i32(t0, t0, 1);
8160 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8161 }
5a5012ec
TS
8162 goto not_likely;
8163 case OPC_BC1TANY2:
a16336e4 8164 {
d94536f4
AJ
8165 TCGv_i32 t1 = tcg_temp_new_i32();
8166 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8167 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8168 tcg_gen_or_i32(t0, t0, t1);
8169 tcg_temp_free_i32(t1);
8170 tcg_gen_andi_i32(t0, t0, 1);
8171 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8172 }
5a5012ec
TS
8173 goto not_likely;
8174 case OPC_BC1FANY4:
a16336e4 8175 {
d94536f4
AJ
8176 TCGv_i32 t1 = tcg_temp_new_i32();
8177 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8178 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8179 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8180 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8181 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8182 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8183 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8184 tcg_temp_free_i32(t1);
d94536f4
AJ
8185 tcg_gen_andi_i32(t0, t0, 1);
8186 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8187 }
5a5012ec
TS
8188 goto not_likely;
8189 case OPC_BC1TANY4:
a16336e4 8190 {
d94536f4
AJ
8191 TCGv_i32 t1 = tcg_temp_new_i32();
8192 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8193 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8194 tcg_gen_or_i32(t0, t0, t1);
8195 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8196 tcg_gen_or_i32(t0, t0, t1);
8197 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8198 tcg_gen_or_i32(t0, t0, t1);
8199 tcg_temp_free_i32(t1);
8200 tcg_gen_andi_i32(t0, t0, 1);
8201 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8202 }
5a5012ec
TS
8203 not_likely:
8204 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8205 break;
8206 default:
9d68ac14 8207 MIPS_INVAL("cp1 cond branch");
9c708c7f 8208 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8209 goto out;
6ea83fed 8210 }
6ea83fed 8211 ctx->btarget = btarget;
b231c103 8212 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8213 out:
a7812ae4 8214 tcg_temp_free_i32(t0);
6ea83fed
FB
8215}
8216
31837be3
YK
8217/* R6 CP1 Branches */
8218static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8219 int32_t ft, int32_t offset,
8220 int delayslot_size)
31837be3
YK
8221{
8222 target_ulong btarget;
31837be3
YK
8223 TCGv_i64 t0 = tcg_temp_new_i64();
8224
8225 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8226#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8227 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8228 "\n", ctx->pc);
31837be3 8229#endif
9c708c7f 8230 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8231 goto out;
8232 }
8233
8234 gen_load_fpr64(ctx, t0, ft);
8235 tcg_gen_andi_i64(t0, t0, 1);
8236
8237 btarget = addr_add(ctx, ctx->pc + 4, offset);
8238
8239 switch (op) {
8240 case OPC_BC1EQZ:
8241 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8242 ctx->hflags |= MIPS_HFLAG_BC;
8243 break;
8244 case OPC_BC1NEZ:
8245 /* t0 already set */
31837be3
YK
8246 ctx->hflags |= MIPS_HFLAG_BC;
8247 break;
8248 default:
9d68ac14 8249 MIPS_INVAL("cp1 cond branch");
9c708c7f 8250 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8251 goto out;
8252 }
8253
8254 tcg_gen_trunc_i64_tl(bcond, t0);
8255
31837be3 8256 ctx->btarget = btarget;
65935f07
YK
8257
8258 switch (delayslot_size) {
8259 case 2:
8260 ctx->hflags |= MIPS_HFLAG_BDS16;
8261 break;
8262 case 4:
8263 ctx->hflags |= MIPS_HFLAG_BDS32;
8264 break;
8265 }
31837be3
YK
8266
8267out:
8268 tcg_temp_free_i64(t0);
8269}
8270
6af0bf9c 8271/* Coprocessor 1 (FPU) */
5a5012ec 8272
5a5012ec
TS
8273#define FOP(func, fmt) (((fmt) << 21) | (func))
8274
bf4120ad
NF
8275enum fopcode {
8276 OPC_ADD_S = FOP(0, FMT_S),
8277 OPC_SUB_S = FOP(1, FMT_S),
8278 OPC_MUL_S = FOP(2, FMT_S),
8279 OPC_DIV_S = FOP(3, FMT_S),
8280 OPC_SQRT_S = FOP(4, FMT_S),
8281 OPC_ABS_S = FOP(5, FMT_S),
8282 OPC_MOV_S = FOP(6, FMT_S),
8283 OPC_NEG_S = FOP(7, FMT_S),
8284 OPC_ROUND_L_S = FOP(8, FMT_S),
8285 OPC_TRUNC_L_S = FOP(9, FMT_S),
8286 OPC_CEIL_L_S = FOP(10, FMT_S),
8287 OPC_FLOOR_L_S = FOP(11, FMT_S),
8288 OPC_ROUND_W_S = FOP(12, FMT_S),
8289 OPC_TRUNC_W_S = FOP(13, FMT_S),
8290 OPC_CEIL_W_S = FOP(14, FMT_S),
8291 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8292 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8293 OPC_MOVCF_S = FOP(17, FMT_S),
8294 OPC_MOVZ_S = FOP(18, FMT_S),
8295 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8296 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8297 OPC_RECIP_S = FOP(21, FMT_S),
8298 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8299 OPC_SELNEZ_S = FOP(23, FMT_S),
8300 OPC_MADDF_S = FOP(24, FMT_S),
8301 OPC_MSUBF_S = FOP(25, FMT_S),
8302 OPC_RINT_S = FOP(26, FMT_S),
8303 OPC_CLASS_S = FOP(27, FMT_S),
8304 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8305 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8306 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8307 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8308 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8309 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8310 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8311 OPC_RSQRT2_S = FOP(31, FMT_S),
8312 OPC_CVT_D_S = FOP(33, FMT_S),
8313 OPC_CVT_W_S = FOP(36, FMT_S),
8314 OPC_CVT_L_S = FOP(37, FMT_S),
8315 OPC_CVT_PS_S = FOP(38, FMT_S),
8316 OPC_CMP_F_S = FOP (48, FMT_S),
8317 OPC_CMP_UN_S = FOP (49, FMT_S),
8318 OPC_CMP_EQ_S = FOP (50, FMT_S),
8319 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8320 OPC_CMP_OLT_S = FOP (52, FMT_S),
8321 OPC_CMP_ULT_S = FOP (53, FMT_S),
8322 OPC_CMP_OLE_S = FOP (54, FMT_S),
8323 OPC_CMP_ULE_S = FOP (55, FMT_S),
8324 OPC_CMP_SF_S = FOP (56, FMT_S),
8325 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8326 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8327 OPC_CMP_NGL_S = FOP (59, FMT_S),
8328 OPC_CMP_LT_S = FOP (60, FMT_S),
8329 OPC_CMP_NGE_S = FOP (61, FMT_S),
8330 OPC_CMP_LE_S = FOP (62, FMT_S),
8331 OPC_CMP_NGT_S = FOP (63, FMT_S),
8332
8333 OPC_ADD_D = FOP(0, FMT_D),
8334 OPC_SUB_D = FOP(1, FMT_D),
8335 OPC_MUL_D = FOP(2, FMT_D),
8336 OPC_DIV_D = FOP(3, FMT_D),
8337 OPC_SQRT_D = FOP(4, FMT_D),
8338 OPC_ABS_D = FOP(5, FMT_D),
8339 OPC_MOV_D = FOP(6, FMT_D),
8340 OPC_NEG_D = FOP(7, FMT_D),
8341 OPC_ROUND_L_D = FOP(8, FMT_D),
8342 OPC_TRUNC_L_D = FOP(9, FMT_D),
8343 OPC_CEIL_L_D = FOP(10, FMT_D),
8344 OPC_FLOOR_L_D = FOP(11, FMT_D),
8345 OPC_ROUND_W_D = FOP(12, FMT_D),
8346 OPC_TRUNC_W_D = FOP(13, FMT_D),
8347 OPC_CEIL_W_D = FOP(14, FMT_D),
8348 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8349 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8350 OPC_MOVCF_D = FOP(17, FMT_D),
8351 OPC_MOVZ_D = FOP(18, FMT_D),
8352 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8353 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8354 OPC_RECIP_D = FOP(21, FMT_D),
8355 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8356 OPC_SELNEZ_D = FOP(23, FMT_D),
8357 OPC_MADDF_D = FOP(24, FMT_D),
8358 OPC_MSUBF_D = FOP(25, FMT_D),
8359 OPC_RINT_D = FOP(26, FMT_D),
8360 OPC_CLASS_D = FOP(27, FMT_D),
8361 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8362 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8363 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8364 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8365 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8366 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8367 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8368 OPC_RSQRT2_D = FOP(31, FMT_D),
8369 OPC_CVT_S_D = FOP(32, FMT_D),
8370 OPC_CVT_W_D = FOP(36, FMT_D),
8371 OPC_CVT_L_D = FOP(37, FMT_D),
8372 OPC_CMP_F_D = FOP (48, FMT_D),
8373 OPC_CMP_UN_D = FOP (49, FMT_D),
8374 OPC_CMP_EQ_D = FOP (50, FMT_D),
8375 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8376 OPC_CMP_OLT_D = FOP (52, FMT_D),
8377 OPC_CMP_ULT_D = FOP (53, FMT_D),
8378 OPC_CMP_OLE_D = FOP (54, FMT_D),
8379 OPC_CMP_ULE_D = FOP (55, FMT_D),
8380 OPC_CMP_SF_D = FOP (56, FMT_D),
8381 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8382 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8383 OPC_CMP_NGL_D = FOP (59, FMT_D),
8384 OPC_CMP_LT_D = FOP (60, FMT_D),
8385 OPC_CMP_NGE_D = FOP (61, FMT_D),
8386 OPC_CMP_LE_D = FOP (62, FMT_D),
8387 OPC_CMP_NGT_D = FOP (63, FMT_D),
8388
8389 OPC_CVT_S_W = FOP(32, FMT_W),
8390 OPC_CVT_D_W = FOP(33, FMT_W),
8391 OPC_CVT_S_L = FOP(32, FMT_L),
8392 OPC_CVT_D_L = FOP(33, FMT_L),
8393 OPC_CVT_PS_PW = FOP(38, FMT_W),
8394
8395 OPC_ADD_PS = FOP(0, FMT_PS),
8396 OPC_SUB_PS = FOP(1, FMT_PS),
8397 OPC_MUL_PS = FOP(2, FMT_PS),
8398 OPC_DIV_PS = FOP(3, FMT_PS),
8399 OPC_ABS_PS = FOP(5, FMT_PS),
8400 OPC_MOV_PS = FOP(6, FMT_PS),
8401 OPC_NEG_PS = FOP(7, FMT_PS),
8402 OPC_MOVCF_PS = FOP(17, FMT_PS),
8403 OPC_MOVZ_PS = FOP(18, FMT_PS),
8404 OPC_MOVN_PS = FOP(19, FMT_PS),
8405 OPC_ADDR_PS = FOP(24, FMT_PS),
8406 OPC_MULR_PS = FOP(26, FMT_PS),
8407 OPC_RECIP2_PS = FOP(28, FMT_PS),
8408 OPC_RECIP1_PS = FOP(29, FMT_PS),
8409 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8410 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8411
8412 OPC_CVT_S_PU = FOP(32, FMT_PS),
8413 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8414 OPC_CVT_S_PL = FOP(40, FMT_PS),
8415 OPC_PLL_PS = FOP(44, FMT_PS),
8416 OPC_PLU_PS = FOP(45, FMT_PS),
8417 OPC_PUL_PS = FOP(46, FMT_PS),
8418 OPC_PUU_PS = FOP(47, FMT_PS),
8419 OPC_CMP_F_PS = FOP (48, FMT_PS),
8420 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8421 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8422 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8423 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8424 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8425 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8426 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8427 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8428 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8429 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8430 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8431 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8432 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8433 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8434 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8435};
8436
3f493883
YK
8437enum r6_f_cmp_op {
8438 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8439 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8440 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8441 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8442 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8443 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8444 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8445 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8446 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8447 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8448 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8449 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8450 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8451 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8452 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8453 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8454 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8455 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8456 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8457 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8458 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8459 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8460
8461 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8462 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8463 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8464 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8465 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8466 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8467 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8468 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8469 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8470 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8471 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8472 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8473 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8474 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8475 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8476 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8477 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8478 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8479 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8480 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8481 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8482 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8483};
7a387fff 8484static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8485{
72c3a3ee 8486 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8487
8488 switch (opc) {
8489 case OPC_MFC1:
b6d96bed 8490 {
a7812ae4 8491 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8492
7c979afd 8493 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8494 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8495 tcg_temp_free_i32(fp0);
6958549d 8496 }
6c5c1e20 8497 gen_store_gpr(t0, rt);
6ea83fed
FB
8498 break;
8499 case OPC_MTC1:
6c5c1e20 8500 gen_load_gpr(t0, rt);
b6d96bed 8501 {
a7812ae4 8502 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8503
8504 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8505 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8506 tcg_temp_free_i32(fp0);
6958549d 8507 }
6ea83fed
FB
8508 break;
8509 case OPC_CFC1:
895c2d04 8510 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8511 gen_store_gpr(t0, rt);
6ea83fed
FB
8512 break;
8513 case OPC_CTC1:
6c5c1e20 8514 gen_load_gpr(t0, rt);
9c708c7f 8515 save_cpu_state(ctx, 0);
736d120a
PJ
8516 {
8517 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8518
8519 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8520 tcg_temp_free_i32(fs_tmp);
8521 }
4cf8a45f
YK
8522 /* Stop translation as we may have changed hflags */
8523 ctx->bstate = BS_STOP;
6ea83fed 8524 break;
72c3a3ee 8525#if defined(TARGET_MIPS64)
9c2149c8 8526 case OPC_DMFC1:
72c3a3ee 8527 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8528 gen_store_gpr(t0, rt);
5a5012ec 8529 break;
9c2149c8 8530 case OPC_DMTC1:
6c5c1e20 8531 gen_load_gpr(t0, rt);
72c3a3ee 8532 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8533 break;
72c3a3ee 8534#endif
5a5012ec 8535 case OPC_MFHC1:
b6d96bed 8536 {
a7812ae4 8537 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8538
7f6613ce 8539 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8540 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8541 tcg_temp_free_i32(fp0);
6958549d 8542 }
6c5c1e20 8543 gen_store_gpr(t0, rt);
5a5012ec
TS
8544 break;
8545 case OPC_MTHC1:
6c5c1e20 8546 gen_load_gpr(t0, rt);
b6d96bed 8547 {
a7812ae4 8548 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8549
8550 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8551 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8552 tcg_temp_free_i32(fp0);
6958549d 8553 }
5a5012ec 8554 break;
6ea83fed 8555 default:
9d68ac14 8556 MIPS_INVAL("cp1 move");
9c708c7f 8557 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8558 goto out;
6ea83fed 8559 }
6c5c1e20
TS
8560
8561 out:
8562 tcg_temp_free(t0);
6ea83fed
FB
8563}
8564
5a5012ec
TS
8565static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8566{
42a268c2 8567 TCGLabel *l1;
e214b9bb 8568 TCGCond cond;
af58f9ca
AJ
8569 TCGv_i32 t0;
8570
8571 if (rd == 0) {
8572 /* Treat as NOP. */
8573 return;
8574 }
6ea83fed 8575
e214b9bb 8576 if (tf)
e214b9bb 8577 cond = TCG_COND_EQ;
27848470
TS
8578 else
8579 cond = TCG_COND_NE;
8580
af58f9ca
AJ
8581 l1 = gen_new_label();
8582 t0 = tcg_temp_new_i32();
fa31af0e 8583 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8584 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8585 tcg_temp_free_i32(t0);
af58f9ca
AJ
8586 if (rs == 0) {
8587 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8588 } else {
8589 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8590 }
e214b9bb 8591 gen_set_label(l1);
5a5012ec
TS
8592}
8593
7c979afd
LA
8594static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8595 int tf)
a16336e4 8596{
a16336e4 8597 int cond;
cbc37b28 8598 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8599 TCGLabel *l1 = gen_new_label();
a16336e4 8600
a16336e4
TS
8601 if (tf)
8602 cond = TCG_COND_EQ;
8603 else
8604 cond = TCG_COND_NE;
8605
fa31af0e 8606 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8607 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8608 gen_load_fpr32(ctx, t0, fs);
8609 gen_store_fpr32(ctx, t0, fd);
a16336e4 8610 gen_set_label(l1);
cbc37b28 8611 tcg_temp_free_i32(t0);
5a5012ec 8612}
a16336e4 8613
b6d96bed 8614static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8615{
a16336e4 8616 int cond;
cbc37b28
AJ
8617 TCGv_i32 t0 = tcg_temp_new_i32();
8618 TCGv_i64 fp0;
42a268c2 8619 TCGLabel *l1 = gen_new_label();
a16336e4 8620
a16336e4
TS
8621 if (tf)
8622 cond = TCG_COND_EQ;
8623 else
8624 cond = TCG_COND_NE;
8625
fa31af0e 8626 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8627 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8628 tcg_temp_free_i32(t0);
11f94258 8629 fp0 = tcg_temp_new_i64();
9bf3eb2c 8630 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8631 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8632 tcg_temp_free_i64(fp0);
cbc37b28 8633 gen_set_label(l1);
a16336e4
TS
8634}
8635
7f6613ce
PJ
8636static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8637 int cc, int tf)
a16336e4
TS
8638{
8639 int cond;
cbc37b28 8640 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8641 TCGLabel *l1 = gen_new_label();
8642 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8643
8644 if (tf)
8645 cond = TCG_COND_EQ;
8646 else
8647 cond = TCG_COND_NE;
8648
fa31af0e 8649 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8650 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8651 gen_load_fpr32(ctx, t0, fs);
8652 gen_store_fpr32(ctx, t0, fd);
a16336e4 8653 gen_set_label(l1);
9bf3eb2c 8654
fa31af0e 8655 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8656 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8657 gen_load_fpr32h(ctx, t0, fs);
8658 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8659 tcg_temp_free_i32(t0);
a16336e4 8660 gen_set_label(l2);
a16336e4
TS
8661}
8662
e7f16abb
LA
8663static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8664 int fs)
8665{
8666 TCGv_i32 t1 = tcg_const_i32(0);
8667 TCGv_i32 fp0 = tcg_temp_new_i32();
8668 TCGv_i32 fp1 = tcg_temp_new_i32();
8669 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8670 gen_load_fpr32(ctx, fp0, fd);
8671 gen_load_fpr32(ctx, fp1, ft);
8672 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8673
8674 switch (op1) {
8675 case OPC_SEL_S:
8676 tcg_gen_andi_i32(fp0, fp0, 1);
8677 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8678 break;
8679 case OPC_SELEQZ_S:
8680 tcg_gen_andi_i32(fp1, fp1, 1);
8681 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8682 break;
8683 case OPC_SELNEZ_S:
8684 tcg_gen_andi_i32(fp1, fp1, 1);
8685 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8686 break;
8687 default:
8688 MIPS_INVAL("gen_sel_s");
9c708c7f 8689 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8690 break;
8691 }
8692
7c979afd 8693 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8694 tcg_temp_free_i32(fp2);
8695 tcg_temp_free_i32(fp1);
8696 tcg_temp_free_i32(fp0);
8697 tcg_temp_free_i32(t1);
8698}
8699
8700static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8701 int fs)
8702{
8703 TCGv_i64 t1 = tcg_const_i64(0);
8704 TCGv_i64 fp0 = tcg_temp_new_i64();
8705 TCGv_i64 fp1 = tcg_temp_new_i64();
8706 TCGv_i64 fp2 = tcg_temp_new_i64();
8707 gen_load_fpr64(ctx, fp0, fd);
8708 gen_load_fpr64(ctx, fp1, ft);
8709 gen_load_fpr64(ctx, fp2, fs);
8710
8711 switch (op1) {
8712 case OPC_SEL_D:
8713 tcg_gen_andi_i64(fp0, fp0, 1);
8714 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8715 break;
8716 case OPC_SELEQZ_D:
8717 tcg_gen_andi_i64(fp1, fp1, 1);
8718 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8719 break;
8720 case OPC_SELNEZ_D:
8721 tcg_gen_andi_i64(fp1, fp1, 1);
8722 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8723 break;
8724 default:
8725 MIPS_INVAL("gen_sel_d");
9c708c7f 8726 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8727 break;
8728 }
8729
8730 gen_store_fpr64(ctx, fp0, fd);
8731 tcg_temp_free_i64(fp2);
8732 tcg_temp_free_i64(fp1);
8733 tcg_temp_free_i64(fp0);
8734 tcg_temp_free_i64(t1);
8735}
6ea83fed 8736
bf4120ad 8737static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8738 int ft, int fs, int fd, int cc)
6ea83fed 8739{
7a387fff 8740 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8741 switch (op1) {
8742 case OPC_ADD_S:
b6d96bed 8743 {
a7812ae4
PB
8744 TCGv_i32 fp0 = tcg_temp_new_i32();
8745 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8746
7c979afd
LA
8747 gen_load_fpr32(ctx, fp0, fs);
8748 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8749 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8750 tcg_temp_free_i32(fp1);
7c979afd 8751 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8752 tcg_temp_free_i32(fp0);
b6d96bed 8753 }
5a5012ec 8754 break;
bf4120ad 8755 case OPC_SUB_S:
b6d96bed 8756 {
a7812ae4
PB
8757 TCGv_i32 fp0 = tcg_temp_new_i32();
8758 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8759
7c979afd
LA
8760 gen_load_fpr32(ctx, fp0, fs);
8761 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8762 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8763 tcg_temp_free_i32(fp1);
7c979afd 8764 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8765 tcg_temp_free_i32(fp0);
b6d96bed 8766 }
5a5012ec 8767 break;
bf4120ad 8768 case OPC_MUL_S:
b6d96bed 8769 {
a7812ae4
PB
8770 TCGv_i32 fp0 = tcg_temp_new_i32();
8771 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8772
7c979afd
LA
8773 gen_load_fpr32(ctx, fp0, fs);
8774 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8775 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8776 tcg_temp_free_i32(fp1);
7c979afd 8777 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8778 tcg_temp_free_i32(fp0);
b6d96bed 8779 }
5a5012ec 8780 break;
bf4120ad 8781 case OPC_DIV_S:
b6d96bed 8782 {
a7812ae4
PB
8783 TCGv_i32 fp0 = tcg_temp_new_i32();
8784 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8785
7c979afd
LA
8786 gen_load_fpr32(ctx, fp0, fs);
8787 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8788 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8789 tcg_temp_free_i32(fp1);
7c979afd 8790 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8791 tcg_temp_free_i32(fp0);
b6d96bed 8792 }
5a5012ec 8793 break;
bf4120ad 8794 case OPC_SQRT_S:
b6d96bed 8795 {
a7812ae4 8796 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8797
7c979afd 8798 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8799 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8800 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8801 tcg_temp_free_i32(fp0);
b6d96bed 8802 }
5a5012ec 8803 break;
bf4120ad 8804 case OPC_ABS_S:
b6d96bed 8805 {
a7812ae4 8806 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8807
7c979afd 8808 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8809 gen_helper_float_abs_s(fp0, fp0);
7c979afd 8810 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8811 tcg_temp_free_i32(fp0);
b6d96bed 8812 }
5a5012ec 8813 break;
bf4120ad 8814 case OPC_MOV_S:
b6d96bed 8815 {
a7812ae4 8816 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8817
7c979afd
LA
8818 gen_load_fpr32(ctx, fp0, fs);
8819 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8820 tcg_temp_free_i32(fp0);
b6d96bed 8821 }
5a5012ec 8822 break;
bf4120ad 8823 case OPC_NEG_S:
b6d96bed 8824 {
a7812ae4 8825 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8826
7c979afd 8827 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8828 gen_helper_float_chs_s(fp0, fp0);
7c979afd 8829 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8830 tcg_temp_free_i32(fp0);
b6d96bed 8831 }
5a5012ec 8832 break;
bf4120ad 8833 case OPC_ROUND_L_S:
5e755519 8834 check_cp1_64bitmode(ctx);
b6d96bed 8835 {
a7812ae4
PB
8836 TCGv_i32 fp32 = tcg_temp_new_i32();
8837 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8838
7c979afd 8839 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8840 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8841 tcg_temp_free_i32(fp32);
b6d96bed 8842 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8843 tcg_temp_free_i64(fp64);
b6d96bed 8844 }
5a5012ec 8845 break;
bf4120ad 8846 case OPC_TRUNC_L_S:
5e755519 8847 check_cp1_64bitmode(ctx);
b6d96bed 8848 {
a7812ae4
PB
8849 TCGv_i32 fp32 = tcg_temp_new_i32();
8850 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8851
7c979afd 8852 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8853 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8854 tcg_temp_free_i32(fp32);
b6d96bed 8855 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8856 tcg_temp_free_i64(fp64);
b6d96bed 8857 }
5a5012ec 8858 break;
bf4120ad 8859 case OPC_CEIL_L_S:
5e755519 8860 check_cp1_64bitmode(ctx);
b6d96bed 8861 {
a7812ae4
PB
8862 TCGv_i32 fp32 = tcg_temp_new_i32();
8863 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8864
7c979afd 8865 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8866 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8867 tcg_temp_free_i32(fp32);
b6d96bed 8868 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8869 tcg_temp_free_i64(fp64);
b6d96bed 8870 }
5a5012ec 8871 break;
bf4120ad 8872 case OPC_FLOOR_L_S:
5e755519 8873 check_cp1_64bitmode(ctx);
b6d96bed 8874 {
a7812ae4
PB
8875 TCGv_i32 fp32 = tcg_temp_new_i32();
8876 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8877
7c979afd 8878 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8879 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8880 tcg_temp_free_i32(fp32);
b6d96bed 8881 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8882 tcg_temp_free_i64(fp64);
b6d96bed 8883 }
5a5012ec 8884 break;
bf4120ad 8885 case OPC_ROUND_W_S:
b6d96bed 8886 {
a7812ae4 8887 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8888
7c979afd 8889 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8890 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 8891 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8892 tcg_temp_free_i32(fp0);
b6d96bed 8893 }
5a5012ec 8894 break;
bf4120ad 8895 case OPC_TRUNC_W_S:
b6d96bed 8896 {
a7812ae4 8897 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8898
7c979afd 8899 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8900 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 8901 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8902 tcg_temp_free_i32(fp0);
b6d96bed 8903 }
5a5012ec 8904 break;
bf4120ad 8905 case OPC_CEIL_W_S:
b6d96bed 8906 {
a7812ae4 8907 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8908
7c979afd 8909 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8910 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 8911 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8912 tcg_temp_free_i32(fp0);
b6d96bed 8913 }
5a5012ec 8914 break;
bf4120ad 8915 case OPC_FLOOR_W_S:
b6d96bed 8916 {
a7812ae4 8917 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8918
7c979afd 8919 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8920 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 8921 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8922 tcg_temp_free_i32(fp0);
b6d96bed 8923 }
5a5012ec 8924 break;
e7f16abb
LA
8925 case OPC_SEL_S:
8926 check_insn(ctx, ISA_MIPS32R6);
8927 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8928 break;
8929 case OPC_SELEQZ_S:
8930 check_insn(ctx, ISA_MIPS32R6);
8931 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8932 break;
8933 case OPC_SELNEZ_S:
8934 check_insn(ctx, ISA_MIPS32R6);
8935 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 8936 break;
bf4120ad 8937 case OPC_MOVCF_S:
fecd2646 8938 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 8939 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8940 break;
bf4120ad 8941 case OPC_MOVZ_S:
fecd2646 8942 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8943 {
42a268c2 8944 TCGLabel *l1 = gen_new_label();
c9297f4d 8945 TCGv_i32 fp0;
a16336e4 8946
c9297f4d
AJ
8947 if (ft != 0) {
8948 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8949 }
8950 fp0 = tcg_temp_new_i32();
7c979afd
LA
8951 gen_load_fpr32(ctx, fp0, fs);
8952 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8953 tcg_temp_free_i32(fp0);
a16336e4
TS
8954 gen_set_label(l1);
8955 }
5a5012ec 8956 break;
bf4120ad 8957 case OPC_MOVN_S:
fecd2646 8958 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8959 {
42a268c2 8960 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8961 TCGv_i32 fp0;
8962
8963 if (ft != 0) {
8964 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8965 fp0 = tcg_temp_new_i32();
7c979afd
LA
8966 gen_load_fpr32(ctx, fp0, fs);
8967 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
8968 tcg_temp_free_i32(fp0);
8969 gen_set_label(l1);
8970 }
a16336e4 8971 }
5a5012ec 8972 break;
bf4120ad 8973 case OPC_RECIP_S:
b6d96bed 8974 {
a7812ae4 8975 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8976
7c979afd 8977 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8978 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 8979 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8980 tcg_temp_free_i32(fp0);
b6d96bed 8981 }
57fa1fb3 8982 break;
bf4120ad 8983 case OPC_RSQRT_S:
b6d96bed 8984 {
a7812ae4 8985 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8986
7c979afd 8987 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8988 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 8989 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8990 tcg_temp_free_i32(fp0);
b6d96bed 8991 }
57fa1fb3 8992 break;
e7f16abb
LA
8993 case OPC_MADDF_S:
8994 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8995 {
a7812ae4
PB
8996 TCGv_i32 fp0 = tcg_temp_new_i32();
8997 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8998 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8999 gen_load_fpr32(ctx, fp0, fs);
9000 gen_load_fpr32(ctx, fp1, ft);
9001 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9002 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9003 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9004 tcg_temp_free_i32(fp2);
a7812ae4 9005 tcg_temp_free_i32(fp1);
a7812ae4 9006 tcg_temp_free_i32(fp0);
b6d96bed 9007 }
57fa1fb3 9008 break;
e7f16abb
LA
9009 case OPC_MSUBF_S:
9010 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9011 {
a7812ae4 9012 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9013 TCGv_i32 fp1 = tcg_temp_new_i32();
9014 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9015 gen_load_fpr32(ctx, fp0, fs);
9016 gen_load_fpr32(ctx, fp1, ft);
9017 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9018 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9019 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9020 tcg_temp_free_i32(fp2);
9021 tcg_temp_free_i32(fp1);
a7812ae4 9022 tcg_temp_free_i32(fp0);
b6d96bed 9023 }
57fa1fb3 9024 break;
e7f16abb
LA
9025 case OPC_RINT_S:
9026 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9027 {
a7812ae4 9028 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9029 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9030 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9031 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9032 tcg_temp_free_i32(fp0);
b6d96bed 9033 }
57fa1fb3 9034 break;
e7f16abb
LA
9035 case OPC_CLASS_S:
9036 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9037 {
e7f16abb 9038 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9039 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9040 gen_helper_float_class_s(fp0, fp0);
7c979afd 9041 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9042 tcg_temp_free_i32(fp0);
e7f16abb
LA
9043 }
9044 break;
9045 case OPC_MIN_S: /* OPC_RECIP2_S */
9046 if (ctx->insn_flags & ISA_MIPS32R6) {
9047 /* OPC_MIN_S */
a7812ae4
PB
9048 TCGv_i32 fp0 = tcg_temp_new_i32();
9049 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9050 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9051 gen_load_fpr32(ctx, fp0, fs);
9052 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9053 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9054 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9055 tcg_temp_free_i32(fp2);
9056 tcg_temp_free_i32(fp1);
9057 tcg_temp_free_i32(fp0);
e7f16abb
LA
9058 } else {
9059 /* OPC_RECIP2_S */
9060 check_cp1_64bitmode(ctx);
9061 {
9062 TCGv_i32 fp0 = tcg_temp_new_i32();
9063 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9064
7c979afd
LA
9065 gen_load_fpr32(ctx, fp0, fs);
9066 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9067 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9068 tcg_temp_free_i32(fp1);
7c979afd 9069 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9070 tcg_temp_free_i32(fp0);
9071 }
e7f16abb
LA
9072 }
9073 break;
9074 case OPC_MINA_S: /* OPC_RECIP1_S */
9075 if (ctx->insn_flags & ISA_MIPS32R6) {
9076 /* OPC_MINA_S */
9077 TCGv_i32 fp0 = tcg_temp_new_i32();
9078 TCGv_i32 fp1 = tcg_temp_new_i32();
9079 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9080 gen_load_fpr32(ctx, fp0, fs);
9081 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9082 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9083 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9084 tcg_temp_free_i32(fp2);
9085 tcg_temp_free_i32(fp1);
9086 tcg_temp_free_i32(fp0);
e7f16abb
LA
9087 } else {
9088 /* OPC_RECIP1_S */
9089 check_cp1_64bitmode(ctx);
9090 {
9091 TCGv_i32 fp0 = tcg_temp_new_i32();
9092
7c979afd 9093 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9094 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9095 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9096 tcg_temp_free_i32(fp0);
9097 }
e7f16abb
LA
9098 }
9099 break;
9100 case OPC_MAX_S: /* OPC_RSQRT1_S */
9101 if (ctx->insn_flags & ISA_MIPS32R6) {
9102 /* OPC_MAX_S */
9103 TCGv_i32 fp0 = tcg_temp_new_i32();
9104 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9105 gen_load_fpr32(ctx, fp0, fs);
9106 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9107 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9108 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9109 tcg_temp_free_i32(fp1);
9110 tcg_temp_free_i32(fp0);
e7f16abb
LA
9111 } else {
9112 /* OPC_RSQRT1_S */
9113 check_cp1_64bitmode(ctx);
9114 {
9115 TCGv_i32 fp0 = tcg_temp_new_i32();
9116
7c979afd 9117 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9118 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9119 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9120 tcg_temp_free_i32(fp0);
9121 }
e7f16abb
LA
9122 }
9123 break;
9124 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9125 if (ctx->insn_flags & ISA_MIPS32R6) {
9126 /* OPC_MAXA_S */
9127 TCGv_i32 fp0 = tcg_temp_new_i32();
9128 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9129 gen_load_fpr32(ctx, fp0, fs);
9130 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9131 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9132 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9133 tcg_temp_free_i32(fp1);
a7812ae4 9134 tcg_temp_free_i32(fp0);
e7f16abb
LA
9135 } else {
9136 /* OPC_RSQRT2_S */
9137 check_cp1_64bitmode(ctx);
9138 {
9139 TCGv_i32 fp0 = tcg_temp_new_i32();
9140 TCGv_i32 fp1 = tcg_temp_new_i32();
9141
7c979afd
LA
9142 gen_load_fpr32(ctx, fp0, fs);
9143 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9144 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9145 tcg_temp_free_i32(fp1);
7c979afd 9146 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9147 tcg_temp_free_i32(fp0);
9148 }
b6d96bed 9149 }
57fa1fb3 9150 break;
bf4120ad 9151 case OPC_CVT_D_S:
5e755519 9152 check_cp1_registers(ctx, fd);
b6d96bed 9153 {
a7812ae4
PB
9154 TCGv_i32 fp32 = tcg_temp_new_i32();
9155 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9156
7c979afd 9157 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9158 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9159 tcg_temp_free_i32(fp32);
b6d96bed 9160 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9161 tcg_temp_free_i64(fp64);
b6d96bed 9162 }
5a5012ec 9163 break;
bf4120ad 9164 case OPC_CVT_W_S:
b6d96bed 9165 {
a7812ae4 9166 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9167
7c979afd 9168 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9169 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9170 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9171 tcg_temp_free_i32(fp0);
b6d96bed 9172 }
5a5012ec 9173 break;
bf4120ad 9174 case OPC_CVT_L_S:
5e755519 9175 check_cp1_64bitmode(ctx);
b6d96bed 9176 {
a7812ae4
PB
9177 TCGv_i32 fp32 = tcg_temp_new_i32();
9178 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9179
7c979afd 9180 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9181 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9182 tcg_temp_free_i32(fp32);
b6d96bed 9183 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9184 tcg_temp_free_i64(fp64);
b6d96bed 9185 }
5a5012ec 9186 break;
bf4120ad 9187 case OPC_CVT_PS_S:
e29c9628 9188 check_ps(ctx);
b6d96bed 9189 {
a7812ae4
PB
9190 TCGv_i64 fp64 = tcg_temp_new_i64();
9191 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9192 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9193
7c979afd
LA
9194 gen_load_fpr32(ctx, fp32_0, fs);
9195 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9196 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9197 tcg_temp_free_i32(fp32_1);
9198 tcg_temp_free_i32(fp32_0);
36aa55dc 9199 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9200 tcg_temp_free_i64(fp64);
b6d96bed 9201 }
5a5012ec 9202 break;
bf4120ad
NF
9203 case OPC_CMP_F_S:
9204 case OPC_CMP_UN_S:
9205 case OPC_CMP_EQ_S:
9206 case OPC_CMP_UEQ_S:
9207 case OPC_CMP_OLT_S:
9208 case OPC_CMP_ULT_S:
9209 case OPC_CMP_OLE_S:
9210 case OPC_CMP_ULE_S:
9211 case OPC_CMP_SF_S:
9212 case OPC_CMP_NGLE_S:
9213 case OPC_CMP_SEQ_S:
9214 case OPC_CMP_NGL_S:
9215 case OPC_CMP_LT_S:
9216 case OPC_CMP_NGE_S:
9217 case OPC_CMP_LE_S:
9218 case OPC_CMP_NGT_S:
fecd2646 9219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9220 if (ctx->opcode & (1 << 6)) {
9221 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9222 } else {
9223 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9224 }
5a5012ec 9225 break;
bf4120ad 9226 case OPC_ADD_D:
5e755519 9227 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9228 {
a7812ae4
PB
9229 TCGv_i64 fp0 = tcg_temp_new_i64();
9230 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9231
9232 gen_load_fpr64(ctx, fp0, fs);
9233 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9234 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9235 tcg_temp_free_i64(fp1);
b6d96bed 9236 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9237 tcg_temp_free_i64(fp0);
b6d96bed 9238 }
6ea83fed 9239 break;
bf4120ad 9240 case OPC_SUB_D:
5e755519 9241 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9242 {
a7812ae4
PB
9243 TCGv_i64 fp0 = tcg_temp_new_i64();
9244 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9245
9246 gen_load_fpr64(ctx, fp0, fs);
9247 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9248 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9249 tcg_temp_free_i64(fp1);
b6d96bed 9250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9251 tcg_temp_free_i64(fp0);
b6d96bed 9252 }
6ea83fed 9253 break;
bf4120ad 9254 case OPC_MUL_D:
5e755519 9255 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9256 {
a7812ae4
PB
9257 TCGv_i64 fp0 = tcg_temp_new_i64();
9258 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9259
9260 gen_load_fpr64(ctx, fp0, fs);
9261 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9262 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9263 tcg_temp_free_i64(fp1);
b6d96bed 9264 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9265 tcg_temp_free_i64(fp0);
b6d96bed 9266 }
6ea83fed 9267 break;
bf4120ad 9268 case OPC_DIV_D:
5e755519 9269 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9270 {
a7812ae4
PB
9271 TCGv_i64 fp0 = tcg_temp_new_i64();
9272 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9273
9274 gen_load_fpr64(ctx, fp0, fs);
9275 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9276 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9277 tcg_temp_free_i64(fp1);
b6d96bed 9278 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9279 tcg_temp_free_i64(fp0);
b6d96bed 9280 }
6ea83fed 9281 break;
bf4120ad 9282 case OPC_SQRT_D:
5e755519 9283 check_cp1_registers(ctx, fs | fd);
b6d96bed 9284 {
a7812ae4 9285 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9286
9287 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9288 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9289 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9290 tcg_temp_free_i64(fp0);
b6d96bed 9291 }
6ea83fed 9292 break;
bf4120ad 9293 case OPC_ABS_D:
5e755519 9294 check_cp1_registers(ctx, fs | fd);
b6d96bed 9295 {
a7812ae4 9296 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9297
9298 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9299 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9300 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9301 tcg_temp_free_i64(fp0);
b6d96bed 9302 }
6ea83fed 9303 break;
bf4120ad 9304 case OPC_MOV_D:
5e755519 9305 check_cp1_registers(ctx, fs | fd);
b6d96bed 9306 {
a7812ae4 9307 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9308
9309 gen_load_fpr64(ctx, fp0, fs);
9310 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9311 tcg_temp_free_i64(fp0);
b6d96bed 9312 }
6ea83fed 9313 break;
bf4120ad 9314 case OPC_NEG_D:
5e755519 9315 check_cp1_registers(ctx, fs | fd);
b6d96bed 9316 {
a7812ae4 9317 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9318
9319 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9320 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9321 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9322 tcg_temp_free_i64(fp0);
b6d96bed 9323 }
6ea83fed 9324 break;
bf4120ad 9325 case OPC_ROUND_L_D:
5e755519 9326 check_cp1_64bitmode(ctx);
b6d96bed 9327 {
a7812ae4 9328 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9329
9330 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9331 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9332 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9333 tcg_temp_free_i64(fp0);
b6d96bed 9334 }
5a5012ec 9335 break;
bf4120ad 9336 case OPC_TRUNC_L_D:
5e755519 9337 check_cp1_64bitmode(ctx);
b6d96bed 9338 {
a7812ae4 9339 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9340
9341 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9342 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9343 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9344 tcg_temp_free_i64(fp0);
b6d96bed 9345 }
5a5012ec 9346 break;
bf4120ad 9347 case OPC_CEIL_L_D:
5e755519 9348 check_cp1_64bitmode(ctx);
b6d96bed 9349 {
a7812ae4 9350 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9351
9352 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9353 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9355 tcg_temp_free_i64(fp0);
b6d96bed 9356 }
5a5012ec 9357 break;
bf4120ad 9358 case OPC_FLOOR_L_D:
5e755519 9359 check_cp1_64bitmode(ctx);
b6d96bed 9360 {
a7812ae4 9361 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9362
9363 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9364 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9365 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9366 tcg_temp_free_i64(fp0);
b6d96bed 9367 }
5a5012ec 9368 break;
bf4120ad 9369 case OPC_ROUND_W_D:
5e755519 9370 check_cp1_registers(ctx, fs);
b6d96bed 9371 {
a7812ae4
PB
9372 TCGv_i32 fp32 = tcg_temp_new_i32();
9373 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9374
9375 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9376 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9377 tcg_temp_free_i64(fp64);
7c979afd 9378 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9379 tcg_temp_free_i32(fp32);
b6d96bed 9380 }
6ea83fed 9381 break;
bf4120ad 9382 case OPC_TRUNC_W_D:
5e755519 9383 check_cp1_registers(ctx, fs);
b6d96bed 9384 {
a7812ae4
PB
9385 TCGv_i32 fp32 = tcg_temp_new_i32();
9386 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9387
9388 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9389 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9390 tcg_temp_free_i64(fp64);
7c979afd 9391 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9392 tcg_temp_free_i32(fp32);
b6d96bed 9393 }
6ea83fed 9394 break;
bf4120ad 9395 case OPC_CEIL_W_D:
5e755519 9396 check_cp1_registers(ctx, fs);
b6d96bed 9397 {
a7812ae4
PB
9398 TCGv_i32 fp32 = tcg_temp_new_i32();
9399 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9400
9401 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9402 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9403 tcg_temp_free_i64(fp64);
7c979afd 9404 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9405 tcg_temp_free_i32(fp32);
b6d96bed 9406 }
6ea83fed 9407 break;
bf4120ad 9408 case OPC_FLOOR_W_D:
5e755519 9409 check_cp1_registers(ctx, fs);
b6d96bed 9410 {
a7812ae4
PB
9411 TCGv_i32 fp32 = tcg_temp_new_i32();
9412 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9413
9414 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9415 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9416 tcg_temp_free_i64(fp64);
7c979afd 9417 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9418 tcg_temp_free_i32(fp32);
b6d96bed 9419 }
6ea83fed 9420 break;
e7f16abb
LA
9421 case OPC_SEL_D:
9422 check_insn(ctx, ISA_MIPS32R6);
9423 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9424 break;
9425 case OPC_SELEQZ_D:
9426 check_insn(ctx, ISA_MIPS32R6);
9427 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9428 break;
9429 case OPC_SELNEZ_D:
9430 check_insn(ctx, ISA_MIPS32R6);
9431 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9432 break;
bf4120ad 9433 case OPC_MOVCF_D:
fecd2646 9434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9435 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9436 break;
bf4120ad 9437 case OPC_MOVZ_D:
fecd2646 9438 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9439 {
42a268c2 9440 TCGLabel *l1 = gen_new_label();
c9297f4d 9441 TCGv_i64 fp0;
a16336e4 9442
c9297f4d
AJ
9443 if (ft != 0) {
9444 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9445 }
9446 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9447 gen_load_fpr64(ctx, fp0, fs);
9448 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9449 tcg_temp_free_i64(fp0);
a16336e4
TS
9450 gen_set_label(l1);
9451 }
5a5012ec 9452 break;
bf4120ad 9453 case OPC_MOVN_D:
fecd2646 9454 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9455 {
42a268c2 9456 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9457 TCGv_i64 fp0;
9458
9459 if (ft != 0) {
9460 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9461 fp0 = tcg_temp_new_i64();
9462 gen_load_fpr64(ctx, fp0, fs);
9463 gen_store_fpr64(ctx, fp0, fd);
9464 tcg_temp_free_i64(fp0);
9465 gen_set_label(l1);
9466 }
a16336e4 9467 }
6ea83fed 9468 break;
bf4120ad 9469 case OPC_RECIP_D:
ca6c7803 9470 check_cp1_registers(ctx, fs | fd);
b6d96bed 9471 {
a7812ae4 9472 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9473
9474 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9475 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9476 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9477 tcg_temp_free_i64(fp0);
b6d96bed 9478 }
57fa1fb3 9479 break;
bf4120ad 9480 case OPC_RSQRT_D:
ca6c7803 9481 check_cp1_registers(ctx, fs | fd);
b6d96bed 9482 {
a7812ae4 9483 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9484
9485 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9486 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9487 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9488 tcg_temp_free_i64(fp0);
b6d96bed 9489 }
57fa1fb3 9490 break;
e7f16abb
LA
9491 case OPC_MADDF_D:
9492 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9493 {
a7812ae4
PB
9494 TCGv_i64 fp0 = tcg_temp_new_i64();
9495 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9496 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9497 gen_load_fpr64(ctx, fp0, fs);
9498 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9499 gen_load_fpr64(ctx, fp2, fd);
9500 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9501 gen_store_fpr64(ctx, fp2, fd);
9502 tcg_temp_free_i64(fp2);
a7812ae4 9503 tcg_temp_free_i64(fp1);
a7812ae4 9504 tcg_temp_free_i64(fp0);
b6d96bed 9505 }
57fa1fb3 9506 break;
e7f16abb
LA
9507 case OPC_MSUBF_D:
9508 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9509 {
a7812ae4 9510 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9511 TCGv_i64 fp1 = tcg_temp_new_i64();
9512 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9513 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9514 gen_load_fpr64(ctx, fp1, ft);
9515 gen_load_fpr64(ctx, fp2, fd);
9516 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9517 gen_store_fpr64(ctx, fp2, fd);
9518 tcg_temp_free_i64(fp2);
9519 tcg_temp_free_i64(fp1);
a7812ae4 9520 tcg_temp_free_i64(fp0);
b6d96bed 9521 }
57fa1fb3 9522 break;
e7f16abb
LA
9523 case OPC_RINT_D:
9524 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9525 {
a7812ae4 9526 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9527 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9528 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9529 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9530 tcg_temp_free_i64(fp0);
b6d96bed 9531 }
57fa1fb3 9532 break;
e7f16abb
LA
9533 case OPC_CLASS_D:
9534 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9535 {
e7f16abb
LA
9536 TCGv_i64 fp0 = tcg_temp_new_i64();
9537 gen_load_fpr64(ctx, fp0, fs);
9538 gen_helper_float_class_d(fp0, fp0);
9539 gen_store_fpr64(ctx, fp0, fd);
9540 tcg_temp_free_i64(fp0);
e7f16abb
LA
9541 }
9542 break;
9543 case OPC_MIN_D: /* OPC_RECIP2_D */
9544 if (ctx->insn_flags & ISA_MIPS32R6) {
9545 /* OPC_MIN_D */
a7812ae4
PB
9546 TCGv_i64 fp0 = tcg_temp_new_i64();
9547 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9548 gen_load_fpr64(ctx, fp0, fs);
9549 gen_load_fpr64(ctx, fp1, ft);
9550 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9551 gen_store_fpr64(ctx, fp1, fd);
9552 tcg_temp_free_i64(fp1);
9553 tcg_temp_free_i64(fp0);
e7f16abb
LA
9554 } else {
9555 /* OPC_RECIP2_D */
9556 check_cp1_64bitmode(ctx);
9557 {
9558 TCGv_i64 fp0 = tcg_temp_new_i64();
9559 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9560
e7f16abb
LA
9561 gen_load_fpr64(ctx, fp0, fs);
9562 gen_load_fpr64(ctx, fp1, ft);
9563 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9564 tcg_temp_free_i64(fp1);
9565 gen_store_fpr64(ctx, fp0, fd);
9566 tcg_temp_free_i64(fp0);
9567 }
e7f16abb
LA
9568 }
9569 break;
9570 case OPC_MINA_D: /* OPC_RECIP1_D */
9571 if (ctx->insn_flags & ISA_MIPS32R6) {
9572 /* OPC_MINA_D */
9573 TCGv_i64 fp0 = tcg_temp_new_i64();
9574 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9575 gen_load_fpr64(ctx, fp0, fs);
9576 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9577 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9578 gen_store_fpr64(ctx, fp1, fd);
9579 tcg_temp_free_i64(fp1);
9580 tcg_temp_free_i64(fp0);
e7f16abb
LA
9581 } else {
9582 /* OPC_RECIP1_D */
9583 check_cp1_64bitmode(ctx);
9584 {
9585 TCGv_i64 fp0 = tcg_temp_new_i64();
9586
9587 gen_load_fpr64(ctx, fp0, fs);
9588 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9589 gen_store_fpr64(ctx, fp0, fd);
9590 tcg_temp_free_i64(fp0);
9591 }
e7f16abb
LA
9592 }
9593 break;
9594 case OPC_MAX_D: /* OPC_RSQRT1_D */
9595 if (ctx->insn_flags & ISA_MIPS32R6) {
9596 /* OPC_MAX_D */
9597 TCGv_i64 fp0 = tcg_temp_new_i64();
9598 TCGv_i64 fp1 = tcg_temp_new_i64();
9599 gen_load_fpr64(ctx, fp0, fs);
9600 gen_load_fpr64(ctx, fp1, ft);
9601 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9602 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9603 tcg_temp_free_i64(fp1);
a7812ae4 9604 tcg_temp_free_i64(fp0);
e7f16abb
LA
9605 } else {
9606 /* OPC_RSQRT1_D */
9607 check_cp1_64bitmode(ctx);
9608 {
9609 TCGv_i64 fp0 = tcg_temp_new_i64();
9610
9611 gen_load_fpr64(ctx, fp0, fs);
9612 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9613 gen_store_fpr64(ctx, fp0, fd);
9614 tcg_temp_free_i64(fp0);
9615 }
e7f16abb
LA
9616 }
9617 break;
9618 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9619 if (ctx->insn_flags & ISA_MIPS32R6) {
9620 /* OPC_MAXA_D */
9621 TCGv_i64 fp0 = tcg_temp_new_i64();
9622 TCGv_i64 fp1 = tcg_temp_new_i64();
9623 gen_load_fpr64(ctx, fp0, fs);
9624 gen_load_fpr64(ctx, fp1, ft);
9625 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9626 gen_store_fpr64(ctx, fp1, fd);
9627 tcg_temp_free_i64(fp1);
9628 tcg_temp_free_i64(fp0);
e7f16abb
LA
9629 } else {
9630 /* OPC_RSQRT2_D */
9631 check_cp1_64bitmode(ctx);
9632 {
9633 TCGv_i64 fp0 = tcg_temp_new_i64();
9634 TCGv_i64 fp1 = tcg_temp_new_i64();
9635
9636 gen_load_fpr64(ctx, fp0, fs);
9637 gen_load_fpr64(ctx, fp1, ft);
9638 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9639 tcg_temp_free_i64(fp1);
9640 gen_store_fpr64(ctx, fp0, fd);
9641 tcg_temp_free_i64(fp0);
9642 }
b6d96bed 9643 }
57fa1fb3 9644 break;
bf4120ad
NF
9645 case OPC_CMP_F_D:
9646 case OPC_CMP_UN_D:
9647 case OPC_CMP_EQ_D:
9648 case OPC_CMP_UEQ_D:
9649 case OPC_CMP_OLT_D:
9650 case OPC_CMP_ULT_D:
9651 case OPC_CMP_OLE_D:
9652 case OPC_CMP_ULE_D:
9653 case OPC_CMP_SF_D:
9654 case OPC_CMP_NGLE_D:
9655 case OPC_CMP_SEQ_D:
9656 case OPC_CMP_NGL_D:
9657 case OPC_CMP_LT_D:
9658 case OPC_CMP_NGE_D:
9659 case OPC_CMP_LE_D:
9660 case OPC_CMP_NGT_D:
fecd2646 9661 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9662 if (ctx->opcode & (1 << 6)) {
9663 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9664 } else {
9665 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9666 }
6ea83fed 9667 break;
bf4120ad 9668 case OPC_CVT_S_D:
5e755519 9669 check_cp1_registers(ctx, fs);
b6d96bed 9670 {
a7812ae4
PB
9671 TCGv_i32 fp32 = tcg_temp_new_i32();
9672 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9673
9674 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9675 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9676 tcg_temp_free_i64(fp64);
7c979afd 9677 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9678 tcg_temp_free_i32(fp32);
b6d96bed 9679 }
5a5012ec 9680 break;
bf4120ad 9681 case OPC_CVT_W_D:
5e755519 9682 check_cp1_registers(ctx, fs);
b6d96bed 9683 {
a7812ae4
PB
9684 TCGv_i32 fp32 = tcg_temp_new_i32();
9685 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9686
9687 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9688 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9689 tcg_temp_free_i64(fp64);
7c979afd 9690 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9691 tcg_temp_free_i32(fp32);
b6d96bed 9692 }
5a5012ec 9693 break;
bf4120ad 9694 case OPC_CVT_L_D:
5e755519 9695 check_cp1_64bitmode(ctx);
b6d96bed 9696 {
a7812ae4 9697 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9698
9699 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9700 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9701 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9702 tcg_temp_free_i64(fp0);
b6d96bed 9703 }
5a5012ec 9704 break;
bf4120ad 9705 case OPC_CVT_S_W:
b6d96bed 9706 {
a7812ae4 9707 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9708
7c979afd 9709 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9710 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9711 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9712 tcg_temp_free_i32(fp0);
b6d96bed 9713 }
6ea83fed 9714 break;
bf4120ad 9715 case OPC_CVT_D_W:
5e755519 9716 check_cp1_registers(ctx, fd);
b6d96bed 9717 {
a7812ae4
PB
9718 TCGv_i32 fp32 = tcg_temp_new_i32();
9719 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9720
7c979afd 9721 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9722 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9723 tcg_temp_free_i32(fp32);
b6d96bed 9724 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9725 tcg_temp_free_i64(fp64);
b6d96bed 9726 }
5a5012ec 9727 break;
bf4120ad 9728 case OPC_CVT_S_L:
5e755519 9729 check_cp1_64bitmode(ctx);
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);
895c2d04 9735 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9736 tcg_temp_free_i64(fp64);
7c979afd 9737 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9738 tcg_temp_free_i32(fp32);
b6d96bed 9739 }
5a5012ec 9740 break;
bf4120ad 9741 case OPC_CVT_D_L:
5e755519 9742 check_cp1_64bitmode(ctx);
b6d96bed 9743 {
a7812ae4 9744 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9745
9746 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9747 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9749 tcg_temp_free_i64(fp0);
b6d96bed 9750 }
5a5012ec 9751 break;
bf4120ad 9752 case OPC_CVT_PS_PW:
e29c9628 9753 check_ps(ctx);
b6d96bed 9754 {
a7812ae4 9755 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9756
9757 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9758 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9759 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9760 tcg_temp_free_i64(fp0);
b6d96bed 9761 }
5a5012ec 9762 break;
bf4120ad 9763 case OPC_ADD_PS:
e29c9628 9764 check_ps(ctx);
b6d96bed 9765 {
a7812ae4
PB
9766 TCGv_i64 fp0 = tcg_temp_new_i64();
9767 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9768
9769 gen_load_fpr64(ctx, fp0, fs);
9770 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9771 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9772 tcg_temp_free_i64(fp1);
b6d96bed 9773 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9774 tcg_temp_free_i64(fp0);
b6d96bed 9775 }
6ea83fed 9776 break;
bf4120ad 9777 case OPC_SUB_PS:
e29c9628 9778 check_ps(ctx);
b6d96bed 9779 {
a7812ae4
PB
9780 TCGv_i64 fp0 = tcg_temp_new_i64();
9781 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9782
9783 gen_load_fpr64(ctx, fp0, fs);
9784 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9785 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9786 tcg_temp_free_i64(fp1);
b6d96bed 9787 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9788 tcg_temp_free_i64(fp0);
b6d96bed 9789 }
6ea83fed 9790 break;
bf4120ad 9791 case OPC_MUL_PS:
e29c9628 9792 check_ps(ctx);
b6d96bed 9793 {
a7812ae4
PB
9794 TCGv_i64 fp0 = tcg_temp_new_i64();
9795 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9796
9797 gen_load_fpr64(ctx, fp0, fs);
9798 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9799 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9800 tcg_temp_free_i64(fp1);
b6d96bed 9801 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9802 tcg_temp_free_i64(fp0);
b6d96bed 9803 }
6ea83fed 9804 break;
bf4120ad 9805 case OPC_ABS_PS:
e29c9628 9806 check_ps(ctx);
b6d96bed 9807 {
a7812ae4 9808 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9809
9810 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9811 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9812 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9813 tcg_temp_free_i64(fp0);
b6d96bed 9814 }
6ea83fed 9815 break;
bf4120ad 9816 case OPC_MOV_PS:
e29c9628 9817 check_ps(ctx);
b6d96bed 9818 {
a7812ae4 9819 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9820
9821 gen_load_fpr64(ctx, fp0, fs);
9822 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9823 tcg_temp_free_i64(fp0);
b6d96bed 9824 }
6ea83fed 9825 break;
bf4120ad 9826 case OPC_NEG_PS:
e29c9628 9827 check_ps(ctx);
b6d96bed 9828 {
a7812ae4 9829 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9830
9831 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9832 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9833 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9834 tcg_temp_free_i64(fp0);
b6d96bed 9835 }
6ea83fed 9836 break;
bf4120ad 9837 case OPC_MOVCF_PS:
e29c9628 9838 check_ps(ctx);
7f6613ce 9839 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 9840 break;
bf4120ad 9841 case OPC_MOVZ_PS:
e29c9628 9842 check_ps(ctx);
a16336e4 9843 {
42a268c2 9844 TCGLabel *l1 = gen_new_label();
30a3848b 9845 TCGv_i64 fp0;
a16336e4 9846
c9297f4d
AJ
9847 if (ft != 0)
9848 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9849 fp0 = tcg_temp_new_i64();
9850 gen_load_fpr64(ctx, fp0, fs);
9851 gen_store_fpr64(ctx, fp0, fd);
9852 tcg_temp_free_i64(fp0);
a16336e4
TS
9853 gen_set_label(l1);
9854 }
6ea83fed 9855 break;
bf4120ad 9856 case OPC_MOVN_PS:
e29c9628 9857 check_ps(ctx);
a16336e4 9858 {
42a268c2 9859 TCGLabel *l1 = gen_new_label();
30a3848b 9860 TCGv_i64 fp0;
c9297f4d
AJ
9861
9862 if (ft != 0) {
9863 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9864 fp0 = tcg_temp_new_i64();
9865 gen_load_fpr64(ctx, fp0, fs);
9866 gen_store_fpr64(ctx, fp0, fd);
9867 tcg_temp_free_i64(fp0);
9868 gen_set_label(l1);
9869 }
a16336e4 9870 }
6ea83fed 9871 break;
bf4120ad 9872 case OPC_ADDR_PS:
e29c9628 9873 check_ps(ctx);
b6d96bed 9874 {
a7812ae4
PB
9875 TCGv_i64 fp0 = tcg_temp_new_i64();
9876 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9877
9878 gen_load_fpr64(ctx, fp0, ft);
9879 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9880 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9881 tcg_temp_free_i64(fp1);
b6d96bed 9882 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9883 tcg_temp_free_i64(fp0);
b6d96bed 9884 }
fbcc6828 9885 break;
bf4120ad 9886 case OPC_MULR_PS:
e29c9628 9887 check_ps(ctx);
b6d96bed 9888 {
a7812ae4
PB
9889 TCGv_i64 fp0 = tcg_temp_new_i64();
9890 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9891
9892 gen_load_fpr64(ctx, fp0, ft);
9893 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9894 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9895 tcg_temp_free_i64(fp1);
b6d96bed 9896 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9897 tcg_temp_free_i64(fp0);
b6d96bed 9898 }
57fa1fb3 9899 break;
bf4120ad 9900 case OPC_RECIP2_PS:
e29c9628 9901 check_ps(ctx);
b6d96bed 9902 {
a7812ae4
PB
9903 TCGv_i64 fp0 = tcg_temp_new_i64();
9904 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9905
9906 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9907 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9908 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9909 tcg_temp_free_i64(fp1);
b6d96bed 9910 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9911 tcg_temp_free_i64(fp0);
b6d96bed 9912 }
57fa1fb3 9913 break;
bf4120ad 9914 case OPC_RECIP1_PS:
e29c9628 9915 check_ps(ctx);
b6d96bed 9916 {
a7812ae4 9917 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9918
9919 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9920 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9921 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9922 tcg_temp_free_i64(fp0);
b6d96bed 9923 }
57fa1fb3 9924 break;
bf4120ad 9925 case OPC_RSQRT1_PS:
e29c9628 9926 check_ps(ctx);
b6d96bed 9927 {
a7812ae4 9928 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9929
9930 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9931 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9932 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9933 tcg_temp_free_i64(fp0);
b6d96bed 9934 }
57fa1fb3 9935 break;
bf4120ad 9936 case OPC_RSQRT2_PS:
e29c9628 9937 check_ps(ctx);
b6d96bed 9938 {
a7812ae4
PB
9939 TCGv_i64 fp0 = tcg_temp_new_i64();
9940 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9941
9942 gen_load_fpr64(ctx, fp0, fs);
9943 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9944 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9945 tcg_temp_free_i64(fp1);
b6d96bed 9946 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9947 tcg_temp_free_i64(fp0);
b6d96bed 9948 }
57fa1fb3 9949 break;
bf4120ad 9950 case OPC_CVT_S_PU:
5e755519 9951 check_cp1_64bitmode(ctx);
b6d96bed 9952 {
a7812ae4 9953 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9954
7f6613ce 9955 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9956 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 9957 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9958 tcg_temp_free_i32(fp0);
b6d96bed 9959 }
dd016883 9960 break;
bf4120ad 9961 case OPC_CVT_PW_PS:
e29c9628 9962 check_ps(ctx);
b6d96bed 9963 {
a7812ae4 9964 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9965
9966 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9967 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9968 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9969 tcg_temp_free_i64(fp0);
b6d96bed 9970 }
6ea83fed 9971 break;
bf4120ad 9972 case OPC_CVT_S_PL:
5e755519 9973 check_cp1_64bitmode(ctx);
b6d96bed 9974 {
a7812ae4 9975 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9976
7c979afd 9977 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9978 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 9979 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9980 tcg_temp_free_i32(fp0);
b6d96bed 9981 }
6ea83fed 9982 break;
bf4120ad 9983 case OPC_PLL_PS:
e29c9628 9984 check_ps(ctx);
b6d96bed 9985 {
a7812ae4
PB
9986 TCGv_i32 fp0 = tcg_temp_new_i32();
9987 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9988
7c979afd
LA
9989 gen_load_fpr32(ctx, fp0, fs);
9990 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 9991 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 9992 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
9993 tcg_temp_free_i32(fp0);
9994 tcg_temp_free_i32(fp1);
b6d96bed 9995 }
6ea83fed 9996 break;
bf4120ad 9997 case OPC_PLU_PS:
e29c9628 9998 check_ps(ctx);
b6d96bed 9999 {
a7812ae4
PB
10000 TCGv_i32 fp0 = tcg_temp_new_i32();
10001 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10002
7c979afd 10003 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10004 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10005 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10006 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10007 tcg_temp_free_i32(fp0);
10008 tcg_temp_free_i32(fp1);
b6d96bed 10009 }
5a5012ec 10010 break;
bf4120ad 10011 case OPC_PUL_PS:
e29c9628 10012 check_ps(ctx);
b6d96bed 10013 {
a7812ae4
PB
10014 TCGv_i32 fp0 = tcg_temp_new_i32();
10015 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10016
7f6613ce 10017 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10018 gen_load_fpr32(ctx, fp1, ft);
10019 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10020 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10021 tcg_temp_free_i32(fp0);
10022 tcg_temp_free_i32(fp1);
b6d96bed 10023 }
5a5012ec 10024 break;
bf4120ad 10025 case OPC_PUU_PS:
e29c9628 10026 check_ps(ctx);
b6d96bed 10027 {
a7812ae4
PB
10028 TCGv_i32 fp0 = tcg_temp_new_i32();
10029 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10030
7f6613ce
PJ
10031 gen_load_fpr32h(ctx, fp0, fs);
10032 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10033 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10034 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10035 tcg_temp_free_i32(fp0);
10036 tcg_temp_free_i32(fp1);
b6d96bed 10037 }
5a5012ec 10038 break;
bf4120ad
NF
10039 case OPC_CMP_F_PS:
10040 case OPC_CMP_UN_PS:
10041 case OPC_CMP_EQ_PS:
10042 case OPC_CMP_UEQ_PS:
10043 case OPC_CMP_OLT_PS:
10044 case OPC_CMP_ULT_PS:
10045 case OPC_CMP_OLE_PS:
10046 case OPC_CMP_ULE_PS:
10047 case OPC_CMP_SF_PS:
10048 case OPC_CMP_NGLE_PS:
10049 case OPC_CMP_SEQ_PS:
10050 case OPC_CMP_NGL_PS:
10051 case OPC_CMP_LT_PS:
10052 case OPC_CMP_NGE_PS:
10053 case OPC_CMP_LE_PS:
10054 case OPC_CMP_NGT_PS:
8153667c
NF
10055 if (ctx->opcode & (1 << 6)) {
10056 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10057 } else {
10058 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10059 }
6ea83fed 10060 break;
5a5012ec 10061 default:
9d68ac14 10062 MIPS_INVAL("farith");
9c708c7f 10063 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10064 return;
10065 }
6ea83fed 10066}
6af0bf9c 10067
5a5012ec 10068/* Coprocessor 3 (FPU) */
5e755519
TS
10069static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10070 int fd, int fs, int base, int index)
7a387fff 10071{
4e2474d6 10072 TCGv t0 = tcg_temp_new();
7a387fff 10073
93b12ccc 10074 if (base == 0) {
6c5c1e20 10075 gen_load_gpr(t0, index);
93b12ccc 10076 } else if (index == 0) {
6c5c1e20 10077 gen_load_gpr(t0, base);
93b12ccc 10078 } else {
05168674 10079 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10080 }
5a5012ec 10081 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10082 memory access. */
5a5012ec
TS
10083 switch (opc) {
10084 case OPC_LWXC1:
8c0ab41f 10085 check_cop1x(ctx);
b6d96bed 10086 {
a7812ae4 10087 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10088
5f68f5ae 10089 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10090 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10091 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10092 tcg_temp_free_i32(fp0);
b6d96bed 10093 }
5a5012ec
TS
10094 break;
10095 case OPC_LDXC1:
8c0ab41f
AJ
10096 check_cop1x(ctx);
10097 check_cp1_registers(ctx, fd);
b6d96bed 10098 {
a7812ae4 10099 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10100 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10101 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10102 tcg_temp_free_i64(fp0);
b6d96bed 10103 }
5a5012ec
TS
10104 break;
10105 case OPC_LUXC1:
8c0ab41f 10106 check_cp1_64bitmode(ctx);
6c5c1e20 10107 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10108 {
a7812ae4 10109 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10110
5f68f5ae 10111 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10112 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10113 tcg_temp_free_i64(fp0);
b6d96bed 10114 }
5a5012ec
TS
10115 break;
10116 case OPC_SWXC1:
8c0ab41f 10117 check_cop1x(ctx);
b6d96bed 10118 {
a7812ae4 10119 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10120 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10121 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10122 tcg_temp_free_i32(fp0);
b6d96bed 10123 }
5a5012ec
TS
10124 break;
10125 case OPC_SDXC1:
8c0ab41f
AJ
10126 check_cop1x(ctx);
10127 check_cp1_registers(ctx, fs);
b6d96bed 10128 {
a7812ae4 10129 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10130 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10131 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10132 tcg_temp_free_i64(fp0);
b6d96bed 10133 }
5a5012ec
TS
10134 break;
10135 case OPC_SUXC1:
8c0ab41f 10136 check_cp1_64bitmode(ctx);
6c5c1e20 10137 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10138 {
a7812ae4 10139 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10140 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10141 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10142 tcg_temp_free_i64(fp0);
b6d96bed 10143 }
5a5012ec 10144 break;
5a5012ec 10145 }
6c5c1e20 10146 tcg_temp_free(t0);
5a5012ec
TS
10147}
10148
5e755519
TS
10149static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10150 int fd, int fr, int fs, int ft)
5a5012ec 10151{
5a5012ec
TS
10152 switch (opc) {
10153 case OPC_ALNV_PS:
e29c9628 10154 check_ps(ctx);
a16336e4 10155 {
a7812ae4 10156 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10157 TCGv_i32 fp = tcg_temp_new_i32();
10158 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10159 TCGLabel *l1 = gen_new_label();
10160 TCGLabel *l2 = gen_new_label();
a16336e4 10161
6c5c1e20
TS
10162 gen_load_gpr(t0, fr);
10163 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10164
10165 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10166 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10167 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10168 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10169 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10170 tcg_gen_br(l2);
10171 gen_set_label(l1);
6c5c1e20
TS
10172 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10173 tcg_temp_free(t0);
a16336e4 10174#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10175 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10176 gen_load_fpr32h(ctx, fph, ft);
10177 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10178 gen_store_fpr32(ctx, fph, fd);
a16336e4 10179#else
7f6613ce 10180 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10181 gen_load_fpr32(ctx, fp, ft);
10182 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10183 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10184#endif
10185 gen_set_label(l2);
c905fdac
AJ
10186 tcg_temp_free_i32(fp);
10187 tcg_temp_free_i32(fph);
a16336e4 10188 }
5a5012ec
TS
10189 break;
10190 case OPC_MADD_S:
b8aa4598 10191 check_cop1x(ctx);
b6d96bed 10192 {
a7812ae4
PB
10193 TCGv_i32 fp0 = tcg_temp_new_i32();
10194 TCGv_i32 fp1 = tcg_temp_new_i32();
10195 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10196
7c979afd
LA
10197 gen_load_fpr32(ctx, fp0, fs);
10198 gen_load_fpr32(ctx, fp1, ft);
10199 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10200 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10201 tcg_temp_free_i32(fp0);
10202 tcg_temp_free_i32(fp1);
7c979afd 10203 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10204 tcg_temp_free_i32(fp2);
b6d96bed 10205 }
5a5012ec
TS
10206 break;
10207 case OPC_MADD_D:
b8aa4598
TS
10208 check_cop1x(ctx);
10209 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10210 {
a7812ae4
PB
10211 TCGv_i64 fp0 = tcg_temp_new_i64();
10212 TCGv_i64 fp1 = tcg_temp_new_i64();
10213 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10214
10215 gen_load_fpr64(ctx, fp0, fs);
10216 gen_load_fpr64(ctx, fp1, ft);
10217 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10218 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10219 tcg_temp_free_i64(fp0);
10220 tcg_temp_free_i64(fp1);
b6d96bed 10221 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10222 tcg_temp_free_i64(fp2);
b6d96bed 10223 }
5a5012ec
TS
10224 break;
10225 case OPC_MADD_PS:
e29c9628 10226 check_ps(ctx);
b6d96bed 10227 {
a7812ae4
PB
10228 TCGv_i64 fp0 = tcg_temp_new_i64();
10229 TCGv_i64 fp1 = tcg_temp_new_i64();
10230 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10231
10232 gen_load_fpr64(ctx, fp0, fs);
10233 gen_load_fpr64(ctx, fp1, ft);
10234 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10235 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10236 tcg_temp_free_i64(fp0);
10237 tcg_temp_free_i64(fp1);
b6d96bed 10238 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10239 tcg_temp_free_i64(fp2);
b6d96bed 10240 }
5a5012ec
TS
10241 break;
10242 case OPC_MSUB_S:
b8aa4598 10243 check_cop1x(ctx);
b6d96bed 10244 {
a7812ae4
PB
10245 TCGv_i32 fp0 = tcg_temp_new_i32();
10246 TCGv_i32 fp1 = tcg_temp_new_i32();
10247 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10248
7c979afd
LA
10249 gen_load_fpr32(ctx, fp0, fs);
10250 gen_load_fpr32(ctx, fp1, ft);
10251 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10252 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10253 tcg_temp_free_i32(fp0);
10254 tcg_temp_free_i32(fp1);
7c979afd 10255 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10256 tcg_temp_free_i32(fp2);
b6d96bed 10257 }
5a5012ec
TS
10258 break;
10259 case OPC_MSUB_D:
b8aa4598
TS
10260 check_cop1x(ctx);
10261 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10262 {
a7812ae4
PB
10263 TCGv_i64 fp0 = tcg_temp_new_i64();
10264 TCGv_i64 fp1 = tcg_temp_new_i64();
10265 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10266
10267 gen_load_fpr64(ctx, fp0, fs);
10268 gen_load_fpr64(ctx, fp1, ft);
10269 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10270 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10271 tcg_temp_free_i64(fp0);
10272 tcg_temp_free_i64(fp1);
b6d96bed 10273 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10274 tcg_temp_free_i64(fp2);
b6d96bed 10275 }
5a5012ec
TS
10276 break;
10277 case OPC_MSUB_PS:
e29c9628 10278 check_ps(ctx);
b6d96bed 10279 {
a7812ae4
PB
10280 TCGv_i64 fp0 = tcg_temp_new_i64();
10281 TCGv_i64 fp1 = tcg_temp_new_i64();
10282 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10283
10284 gen_load_fpr64(ctx, fp0, fs);
10285 gen_load_fpr64(ctx, fp1, ft);
10286 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10287 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10288 tcg_temp_free_i64(fp0);
10289 tcg_temp_free_i64(fp1);
b6d96bed 10290 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10291 tcg_temp_free_i64(fp2);
b6d96bed 10292 }
5a5012ec
TS
10293 break;
10294 case OPC_NMADD_S:
b8aa4598 10295 check_cop1x(ctx);
b6d96bed 10296 {
a7812ae4
PB
10297 TCGv_i32 fp0 = tcg_temp_new_i32();
10298 TCGv_i32 fp1 = tcg_temp_new_i32();
10299 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10300
7c979afd
LA
10301 gen_load_fpr32(ctx, fp0, fs);
10302 gen_load_fpr32(ctx, fp1, ft);
10303 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10304 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10305 tcg_temp_free_i32(fp0);
10306 tcg_temp_free_i32(fp1);
7c979afd 10307 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10308 tcg_temp_free_i32(fp2);
b6d96bed 10309 }
5a5012ec
TS
10310 break;
10311 case OPC_NMADD_D:
b8aa4598
TS
10312 check_cop1x(ctx);
10313 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10314 {
a7812ae4
PB
10315 TCGv_i64 fp0 = tcg_temp_new_i64();
10316 TCGv_i64 fp1 = tcg_temp_new_i64();
10317 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10318
10319 gen_load_fpr64(ctx, fp0, fs);
10320 gen_load_fpr64(ctx, fp1, ft);
10321 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10322 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10323 tcg_temp_free_i64(fp0);
10324 tcg_temp_free_i64(fp1);
b6d96bed 10325 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10326 tcg_temp_free_i64(fp2);
b6d96bed 10327 }
5a5012ec
TS
10328 break;
10329 case OPC_NMADD_PS:
e29c9628 10330 check_ps(ctx);
b6d96bed 10331 {
a7812ae4
PB
10332 TCGv_i64 fp0 = tcg_temp_new_i64();
10333 TCGv_i64 fp1 = tcg_temp_new_i64();
10334 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10335
10336 gen_load_fpr64(ctx, fp0, fs);
10337 gen_load_fpr64(ctx, fp1, ft);
10338 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10339 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10340 tcg_temp_free_i64(fp0);
10341 tcg_temp_free_i64(fp1);
b6d96bed 10342 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10343 tcg_temp_free_i64(fp2);
b6d96bed 10344 }
5a5012ec
TS
10345 break;
10346 case OPC_NMSUB_S:
b8aa4598 10347 check_cop1x(ctx);
b6d96bed 10348 {
a7812ae4
PB
10349 TCGv_i32 fp0 = tcg_temp_new_i32();
10350 TCGv_i32 fp1 = tcg_temp_new_i32();
10351 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10352
7c979afd
LA
10353 gen_load_fpr32(ctx, fp0, fs);
10354 gen_load_fpr32(ctx, fp1, ft);
10355 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10356 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10357 tcg_temp_free_i32(fp0);
10358 tcg_temp_free_i32(fp1);
7c979afd 10359 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10360 tcg_temp_free_i32(fp2);
b6d96bed 10361 }
5a5012ec
TS
10362 break;
10363 case OPC_NMSUB_D:
b8aa4598
TS
10364 check_cop1x(ctx);
10365 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10366 {
a7812ae4
PB
10367 TCGv_i64 fp0 = tcg_temp_new_i64();
10368 TCGv_i64 fp1 = tcg_temp_new_i64();
10369 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10370
10371 gen_load_fpr64(ctx, fp0, fs);
10372 gen_load_fpr64(ctx, fp1, ft);
10373 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10374 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10375 tcg_temp_free_i64(fp0);
10376 tcg_temp_free_i64(fp1);
b6d96bed 10377 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10378 tcg_temp_free_i64(fp2);
b6d96bed 10379 }
5a5012ec
TS
10380 break;
10381 case OPC_NMSUB_PS:
e29c9628 10382 check_ps(ctx);
b6d96bed 10383 {
a7812ae4
PB
10384 TCGv_i64 fp0 = tcg_temp_new_i64();
10385 TCGv_i64 fp1 = tcg_temp_new_i64();
10386 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10387
10388 gen_load_fpr64(ctx, fp0, fs);
10389 gen_load_fpr64(ctx, fp1, ft);
10390 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10391 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10392 tcg_temp_free_i64(fp0);
10393 tcg_temp_free_i64(fp1);
b6d96bed 10394 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10395 tcg_temp_free_i64(fp2);
b6d96bed 10396 }
5a5012ec 10397 break;
923617a3 10398 default:
9d68ac14 10399 MIPS_INVAL("flt3_arith");
9c708c7f 10400 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10401 return;
10402 }
7a387fff
TS
10403}
10404
b00c7218 10405static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10406{
10407 TCGv t0;
10408
b3167288
RH
10409#if !defined(CONFIG_USER_ONLY)
10410 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10411 Therefore only check the ISA in system mode. */
d75c135e 10412 check_insn(ctx, ISA_MIPS32R2);
b3167288 10413#endif
26ebe468
NF
10414 t0 = tcg_temp_new();
10415
10416 switch (rd) {
10417 case 0:
895c2d04 10418 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10419 gen_store_gpr(t0, rt);
10420 break;
10421 case 1:
895c2d04 10422 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10423 gen_store_gpr(t0, rt);
10424 break;
10425 case 2:
895c2d04 10426 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10427 gen_store_gpr(t0, rt);
10428 break;
10429 case 3:
895c2d04 10430 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10431 gen_store_gpr(t0, rt);
10432 break;
b00c7218
YK
10433 case 4:
10434 check_insn(ctx, ISA_MIPS32R6);
10435 if (sel != 0) {
10436 /* Performance counter registers are not implemented other than
10437 * control register 0.
10438 */
10439 generate_exception(ctx, EXCP_RI);
10440 }
10441 gen_helper_rdhwr_performance(t0, cpu_env);
10442 gen_store_gpr(t0, rt);
10443 break;
10444 case 5:
10445 check_insn(ctx, ISA_MIPS32R6);
10446 gen_helper_rdhwr_xnp(t0, cpu_env);
10447 gen_store_gpr(t0, rt);
10448 break;
26ebe468
NF
10449 case 29:
10450#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10451 tcg_gen_ld_tl(t0, cpu_env,
10452 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10453 gen_store_gpr(t0, rt);
10454 break;
10455#else
d279279e
PJ
10456 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10457 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10458 tcg_gen_ld_tl(t0, cpu_env,
10459 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10460 gen_store_gpr(t0, rt);
10461 } else {
9c708c7f 10462 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10463 }
10464 break;
26ebe468
NF
10465#endif
10466 default: /* Invalid */
10467 MIPS_INVAL("rdhwr");
9c708c7f 10468 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10469 break;
10470 }
10471 tcg_temp_free(t0);
10472}
10473
a5f53390
LA
10474static inline void clear_branch_hflags(DisasContext *ctx)
10475{
10476 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10477 if (ctx->bstate == BS_NONE) {
10478 save_cpu_state(ctx, 0);
10479 } else {
10480 /* it is not safe to save ctx->hflags as hflags may be changed
10481 in execution time by the instruction in delay / forbidden slot. */
10482 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10483 }
10484}
10485
31837be3 10486static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10487{
10488 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10489 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10490 /* Branches completion */
a5f53390 10491 clear_branch_hflags(ctx);
c9602061 10492 ctx->bstate = BS_BRANCH;
c9602061 10493 /* FIXME: Need to clear can_do_io. */
364d4831 10494 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10495 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10496 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10497 break;
c9602061
NF
10498 case MIPS_HFLAG_B:
10499 /* unconditional branch */
364d4831
NF
10500 if (proc_hflags & MIPS_HFLAG_BX) {
10501 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10502 }
c9602061
NF
10503 gen_goto_tb(ctx, 0, ctx->btarget);
10504 break;
10505 case MIPS_HFLAG_BL:
10506 /* blikely taken case */
c9602061
NF
10507 gen_goto_tb(ctx, 0, ctx->btarget);
10508 break;
10509 case MIPS_HFLAG_BC:
10510 /* Conditional branch */
c9602061 10511 {
42a268c2 10512 TCGLabel *l1 = gen_new_label();
c9602061
NF
10513
10514 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10515 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10516 gen_set_label(l1);
10517 gen_goto_tb(ctx, 0, ctx->btarget);
10518 }
10519 break;
10520 case MIPS_HFLAG_BR:
10521 /* unconditional branch to register */
d75c135e 10522 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10523 TCGv t0 = tcg_temp_new();
10524 TCGv_i32 t1 = tcg_temp_new_i32();
10525
10526 tcg_gen_andi_tl(t0, btarget, 0x1);
10527 tcg_gen_trunc_tl_i32(t1, t0);
10528 tcg_temp_free(t0);
10529 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10530 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10531 tcg_gen_or_i32(hflags, hflags, t1);
10532 tcg_temp_free_i32(t1);
10533
10534 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10535 } else {
10536 tcg_gen_mov_tl(cpu_PC, btarget);
10537 }
c9602061
NF
10538 if (ctx->singlestep_enabled) {
10539 save_cpu_state(ctx, 0);
9c708c7f 10540 gen_helper_raise_exception_debug(cpu_env);
c9602061
NF
10541 }
10542 tcg_gen_exit_tb(0);
10543 break;
10544 default:
a5f53390
LA
10545 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10546 abort();
c9602061
NF
10547 }
10548 }
10549}
10550
6893f074
YK
10551/* Compact Branches */
10552static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10553 int rs, int rt, int32_t offset)
10554{
10555 int bcond_compute = 0;
10556 TCGv t0 = tcg_temp_new();
10557 TCGv t1 = tcg_temp_new();
65935f07 10558 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10559
10560 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10561#ifdef MIPS_DEBUG_DISAS
10562 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10563 "\n", ctx->pc);
10564#endif
9c708c7f 10565 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10566 goto out;
10567 }
10568
10569 /* Load needed operands and calculate btarget */
10570 switch (opc) {
10571 /* compact branch */
10572 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10573 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10574 gen_load_gpr(t0, rs);
10575 gen_load_gpr(t1, rt);
10576 bcond_compute = 1;
10577 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10578 if (rs <= rt && rs == 0) {
10579 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10580 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10581 }
10582 break;
10583 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10584 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10585 gen_load_gpr(t0, rs);
10586 gen_load_gpr(t1, rt);
10587 bcond_compute = 1;
10588 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10589 break;
10590 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10591 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10592 if (rs == 0 || rs == rt) {
10593 /* OPC_BLEZALC, OPC_BGEZALC */
10594 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10595 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10596 }
10597 gen_load_gpr(t0, rs);
10598 gen_load_gpr(t1, rt);
10599 bcond_compute = 1;
10600 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10601 break;
10602 case OPC_BC:
10603 case OPC_BALC:
10604 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10605 break;
10606 case OPC_BEQZC:
10607 case OPC_BNEZC:
10608 if (rs != 0) {
10609 /* OPC_BEQZC, OPC_BNEZC */
10610 gen_load_gpr(t0, rs);
10611 bcond_compute = 1;
10612 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10613 } else {
10614 /* OPC_JIC, OPC_JIALC */
10615 TCGv tbase = tcg_temp_new();
10616 TCGv toffset = tcg_temp_new();
10617
10618 gen_load_gpr(tbase, rt);
10619 tcg_gen_movi_tl(toffset, offset);
10620 gen_op_addr_add(ctx, btarget, tbase, toffset);
10621 tcg_temp_free(tbase);
10622 tcg_temp_free(toffset);
10623 }
10624 break;
10625 default:
10626 MIPS_INVAL("Compact branch/jump");
9c708c7f 10627 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10628 goto out;
10629 }
10630
10631 if (bcond_compute == 0) {
10632 /* Uncoditional compact branch */
10633 switch (opc) {
10634 case OPC_JIALC:
65935f07 10635 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10636 /* Fallthrough */
10637 case OPC_JIC:
10638 ctx->hflags |= MIPS_HFLAG_BR;
10639 break;
10640 case OPC_BALC:
65935f07 10641 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10642 /* Fallthrough */
10643 case OPC_BC:
10644 ctx->hflags |= MIPS_HFLAG_B;
10645 break;
10646 default:
10647 MIPS_INVAL("Compact branch/jump");
9c708c7f 10648 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10649 goto out;
10650 }
10651
10652 /* Generating branch here as compact branches don't have delay slot */
10653 gen_branch(ctx, 4);
10654 } else {
10655 /* Conditional compact branch */
10656 TCGLabel *fs = gen_new_label();
10657 save_cpu_state(ctx, 0);
10658
10659 switch (opc) {
10660 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10661 if (rs == 0 && rt != 0) {
10662 /* OPC_BLEZALC */
10663 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10664 } else if (rs != 0 && rt != 0 && rs == rt) {
10665 /* OPC_BGEZALC */
10666 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10667 } else {
10668 /* OPC_BGEUC */
10669 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10670 }
10671 break;
10672 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10673 if (rs == 0 && rt != 0) {
10674 /* OPC_BGTZALC */
10675 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10676 } else if (rs != 0 && rt != 0 && rs == rt) {
10677 /* OPC_BLTZALC */
10678 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10679 } else {
10680 /* OPC_BLTUC */
10681 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10682 }
10683 break;
10684 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10685 if (rs == 0 && rt != 0) {
10686 /* OPC_BLEZC */
10687 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10688 } else if (rs != 0 && rt != 0 && rs == rt) {
10689 /* OPC_BGEZC */
10690 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10691 } else {
10692 /* OPC_BGEC */
10693 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10694 }
10695 break;
10696 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10697 if (rs == 0 && rt != 0) {
10698 /* OPC_BGTZC */
10699 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10700 } else if (rs != 0 && rt != 0 && rs == rt) {
10701 /* OPC_BLTZC */
10702 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10703 } else {
10704 /* OPC_BLTC */
10705 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10706 }
10707 break;
10708 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10709 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10710 if (rs >= rt) {
10711 /* OPC_BOVC, OPC_BNVC */
10712 TCGv t2 = tcg_temp_new();
10713 TCGv t3 = tcg_temp_new();
10714 TCGv t4 = tcg_temp_new();
10715 TCGv input_overflow = tcg_temp_new();
10716
10717 gen_load_gpr(t0, rs);
10718 gen_load_gpr(t1, rt);
10719 tcg_gen_ext32s_tl(t2, t0);
10720 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10721 tcg_gen_ext32s_tl(t3, t1);
10722 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10723 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10724
10725 tcg_gen_add_tl(t4, t2, t3);
10726 tcg_gen_ext32s_tl(t4, t4);
10727 tcg_gen_xor_tl(t2, t2, t3);
10728 tcg_gen_xor_tl(t3, t4, t3);
10729 tcg_gen_andc_tl(t2, t3, t2);
10730 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10731 tcg_gen_or_tl(t4, t4, input_overflow);
10732 if (opc == OPC_BOVC) {
10733 /* OPC_BOVC */
10734 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10735 } else {
10736 /* OPC_BNVC */
10737 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10738 }
10739 tcg_temp_free(input_overflow);
10740 tcg_temp_free(t4);
10741 tcg_temp_free(t3);
10742 tcg_temp_free(t2);
10743 } else if (rs < rt && rs == 0) {
10744 /* OPC_BEQZALC, OPC_BNEZALC */
10745 if (opc == OPC_BEQZALC) {
10746 /* OPC_BEQZALC */
10747 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10748 } else {
10749 /* OPC_BNEZALC */
10750 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10751 }
10752 } else {
10753 /* OPC_BEQC, OPC_BNEC */
10754 if (opc == OPC_BEQC) {
10755 /* OPC_BEQC */
10756 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10757 } else {
10758 /* OPC_BNEC */
10759 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10760 }
10761 }
10762 break;
10763 case OPC_BEQZC:
10764 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10765 break;
10766 case OPC_BNEZC:
10767 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10768 break;
10769 default:
10770 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 10771 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10772 goto out;
10773 }
10774
10775 /* Generating branch here as compact branches don't have delay slot */
10776 gen_goto_tb(ctx, 1, ctx->btarget);
10777 gen_set_label(fs);
10778
10779 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
10780 }
10781
10782out:
10783 tcg_temp_free(t0);
10784 tcg_temp_free(t1);
10785}
10786
7a387fff 10787/* ISA extensions (ASEs) */
6af0bf9c 10788/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10789
10790/* MIPS16 major opcodes */
10791enum {
10792 M16_OPC_ADDIUSP = 0x00,
10793 M16_OPC_ADDIUPC = 0x01,
10794 M16_OPC_B = 0x02,
10795 M16_OPC_JAL = 0x03,
10796 M16_OPC_BEQZ = 0x04,
10797 M16_OPC_BNEQZ = 0x05,
10798 M16_OPC_SHIFT = 0x06,
10799 M16_OPC_LD = 0x07,
10800 M16_OPC_RRIA = 0x08,
10801 M16_OPC_ADDIU8 = 0x09,
10802 M16_OPC_SLTI = 0x0a,
10803 M16_OPC_SLTIU = 0x0b,
10804 M16_OPC_I8 = 0x0c,
10805 M16_OPC_LI = 0x0d,
10806 M16_OPC_CMPI = 0x0e,
10807 M16_OPC_SD = 0x0f,
10808 M16_OPC_LB = 0x10,
10809 M16_OPC_LH = 0x11,
10810 M16_OPC_LWSP = 0x12,
10811 M16_OPC_LW = 0x13,
10812 M16_OPC_LBU = 0x14,
10813 M16_OPC_LHU = 0x15,
10814 M16_OPC_LWPC = 0x16,
10815 M16_OPC_LWU = 0x17,
10816 M16_OPC_SB = 0x18,
10817 M16_OPC_SH = 0x19,
10818 M16_OPC_SWSP = 0x1a,
10819 M16_OPC_SW = 0x1b,
10820 M16_OPC_RRR = 0x1c,
10821 M16_OPC_RR = 0x1d,
10822 M16_OPC_EXTEND = 0x1e,
10823 M16_OPC_I64 = 0x1f
10824};
10825
10826/* I8 funct field */
10827enum {
10828 I8_BTEQZ = 0x0,
10829 I8_BTNEZ = 0x1,
10830 I8_SWRASP = 0x2,
10831 I8_ADJSP = 0x3,
10832 I8_SVRS = 0x4,
10833 I8_MOV32R = 0x5,
10834 I8_MOVR32 = 0x7
10835};
10836
10837/* RRR f field */
10838enum {
10839 RRR_DADDU = 0x0,
10840 RRR_ADDU = 0x1,
10841 RRR_DSUBU = 0x2,
10842 RRR_SUBU = 0x3
10843};
10844
10845/* RR funct field */
10846enum {
10847 RR_JR = 0x00,
10848 RR_SDBBP = 0x01,
10849 RR_SLT = 0x02,
10850 RR_SLTU = 0x03,
10851 RR_SLLV = 0x04,
10852 RR_BREAK = 0x05,
10853 RR_SRLV = 0x06,
10854 RR_SRAV = 0x07,
10855 RR_DSRL = 0x08,
10856 RR_CMP = 0x0a,
10857 RR_NEG = 0x0b,
10858 RR_AND = 0x0c,
10859 RR_OR = 0x0d,
10860 RR_XOR = 0x0e,
10861 RR_NOT = 0x0f,
10862 RR_MFHI = 0x10,
10863 RR_CNVT = 0x11,
10864 RR_MFLO = 0x12,
10865 RR_DSRA = 0x13,
10866 RR_DSLLV = 0x14,
10867 RR_DSRLV = 0x16,
10868 RR_DSRAV = 0x17,
10869 RR_MULT = 0x18,
10870 RR_MULTU = 0x19,
10871 RR_DIV = 0x1a,
10872 RR_DIVU = 0x1b,
10873 RR_DMULT = 0x1c,
10874 RR_DMULTU = 0x1d,
10875 RR_DDIV = 0x1e,
10876 RR_DDIVU = 0x1f
10877};
10878
10879/* I64 funct field */
10880enum {
10881 I64_LDSP = 0x0,
10882 I64_SDSP = 0x1,
10883 I64_SDRASP = 0x2,
10884 I64_DADJSP = 0x3,
10885 I64_LDPC = 0x4,
364d4831 10886 I64_DADDIU5 = 0x5,
6ea219d0
NF
10887 I64_DADDIUPC = 0x6,
10888 I64_DADDIUSP = 0x7
10889};
10890
10891/* RR ry field for CNVT */
10892enum {
10893 RR_RY_CNVT_ZEB = 0x0,
10894 RR_RY_CNVT_ZEH = 0x1,
10895 RR_RY_CNVT_ZEW = 0x2,
10896 RR_RY_CNVT_SEB = 0x4,
10897 RR_RY_CNVT_SEH = 0x5,
10898 RR_RY_CNVT_SEW = 0x6,
10899};
10900
364d4831
NF
10901static int xlat (int r)
10902{
10903 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10904
10905 return map[r];
10906}
10907
10908static void gen_mips16_save (DisasContext *ctx,
10909 int xsregs, int aregs,
10910 int do_ra, int do_s0, int do_s1,
10911 int framesize)
10912{
10913 TCGv t0 = tcg_temp_new();
10914 TCGv t1 = tcg_temp_new();
c48245f0 10915 TCGv t2 = tcg_temp_new();
364d4831
NF
10916 int args, astatic;
10917
10918 switch (aregs) {
10919 case 0:
10920 case 1:
10921 case 2:
10922 case 3:
10923 case 11:
10924 args = 0;
10925 break;
10926 case 4:
10927 case 5:
10928 case 6:
10929 case 7:
10930 args = 1;
10931 break;
10932 case 8:
10933 case 9:
10934 case 10:
10935 args = 2;
10936 break;
10937 case 12:
10938 case 13:
10939 args = 3;
10940 break;
10941 case 14:
10942 args = 4;
10943 break;
10944 default:
9c708c7f 10945 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
10946 return;
10947 }
10948
10949 switch (args) {
10950 case 4:
10951 gen_base_offset_addr(ctx, t0, 29, 12);
10952 gen_load_gpr(t1, 7);
5f68f5ae 10953 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10954 /* Fall through */
10955 case 3:
10956 gen_base_offset_addr(ctx, t0, 29, 8);
10957 gen_load_gpr(t1, 6);
5f68f5ae 10958 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10959 /* Fall through */
10960 case 2:
10961 gen_base_offset_addr(ctx, t0, 29, 4);
10962 gen_load_gpr(t1, 5);
5f68f5ae 10963 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10964 /* Fall through */
10965 case 1:
10966 gen_base_offset_addr(ctx, t0, 29, 0);
10967 gen_load_gpr(t1, 4);
5f68f5ae 10968 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10969 }
10970
10971 gen_load_gpr(t0, 29);
10972
5f68f5ae 10973#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10974 tcg_gen_movi_tl(t2, -4); \
10975 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10976 gen_load_gpr(t1, reg); \
10977 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10978 } while (0)
10979
10980 if (do_ra) {
10981 DECR_AND_STORE(31);
10982 }
10983
10984 switch (xsregs) {
10985 case 7:
10986 DECR_AND_STORE(30);
10987 /* Fall through */
10988 case 6:
10989 DECR_AND_STORE(23);
10990 /* Fall through */
10991 case 5:
10992 DECR_AND_STORE(22);
10993 /* Fall through */
10994 case 4:
10995 DECR_AND_STORE(21);
10996 /* Fall through */
10997 case 3:
10998 DECR_AND_STORE(20);
10999 /* Fall through */
11000 case 2:
11001 DECR_AND_STORE(19);
11002 /* Fall through */
11003 case 1:
11004 DECR_AND_STORE(18);
11005 }
11006
11007 if (do_s1) {
11008 DECR_AND_STORE(17);
11009 }
11010 if (do_s0) {
11011 DECR_AND_STORE(16);
11012 }
11013
11014 switch (aregs) {
11015 case 0:
11016 case 4:
11017 case 8:
11018 case 12:
11019 case 14:
11020 astatic = 0;
11021 break;
11022 case 1:
11023 case 5:
11024 case 9:
11025 case 13:
11026 astatic = 1;
11027 break;
11028 case 2:
11029 case 6:
11030 case 10:
11031 astatic = 2;
11032 break;
11033 case 3:
11034 case 7:
11035 astatic = 3;
11036 break;
11037 case 11:
11038 astatic = 4;
11039 break;
11040 default:
9c708c7f 11041 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11042 return;
11043 }
11044
11045 if (astatic > 0) {
11046 DECR_AND_STORE(7);
11047 if (astatic > 1) {
11048 DECR_AND_STORE(6);
11049 if (astatic > 2) {
11050 DECR_AND_STORE(5);
11051 if (astatic > 3) {
11052 DECR_AND_STORE(4);
11053 }
11054 }
11055 }
11056 }
11057#undef DECR_AND_STORE
11058
c48245f0
MR
11059 tcg_gen_movi_tl(t2, -framesize);
11060 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11061 tcg_temp_free(t0);
11062 tcg_temp_free(t1);
c48245f0 11063 tcg_temp_free(t2);
364d4831
NF
11064}
11065
11066static void gen_mips16_restore (DisasContext *ctx,
11067 int xsregs, int aregs,
11068 int do_ra, int do_s0, int do_s1,
11069 int framesize)
11070{
11071 int astatic;
11072 TCGv t0 = tcg_temp_new();
11073 TCGv t1 = tcg_temp_new();
c48245f0 11074 TCGv t2 = tcg_temp_new();
364d4831 11075
c48245f0
MR
11076 tcg_gen_movi_tl(t2, framesize);
11077 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11078
5f68f5ae 11079#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11080 tcg_gen_movi_tl(t2, -4); \
11081 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11082 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11083 gen_store_gpr(t1, reg); \
364d4831
NF
11084 } while (0)
11085
11086 if (do_ra) {
11087 DECR_AND_LOAD(31);
11088 }
11089
11090 switch (xsregs) {
11091 case 7:
11092 DECR_AND_LOAD(30);
11093 /* Fall through */
11094 case 6:
11095 DECR_AND_LOAD(23);
11096 /* Fall through */
11097 case 5:
11098 DECR_AND_LOAD(22);
11099 /* Fall through */
11100 case 4:
11101 DECR_AND_LOAD(21);
11102 /* Fall through */
11103 case 3:
11104 DECR_AND_LOAD(20);
11105 /* Fall through */
11106 case 2:
11107 DECR_AND_LOAD(19);
11108 /* Fall through */
11109 case 1:
11110 DECR_AND_LOAD(18);
11111 }
11112
11113 if (do_s1) {
11114 DECR_AND_LOAD(17);
11115 }
11116 if (do_s0) {
11117 DECR_AND_LOAD(16);
11118 }
11119
11120 switch (aregs) {
11121 case 0:
11122 case 4:
11123 case 8:
11124 case 12:
11125 case 14:
11126 astatic = 0;
11127 break;
11128 case 1:
11129 case 5:
11130 case 9:
11131 case 13:
11132 astatic = 1;
11133 break;
11134 case 2:
11135 case 6:
11136 case 10:
11137 astatic = 2;
11138 break;
11139 case 3:
11140 case 7:
11141 astatic = 3;
11142 break;
11143 case 11:
11144 astatic = 4;
11145 break;
11146 default:
9c708c7f 11147 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11148 return;
11149 }
11150
11151 if (astatic > 0) {
11152 DECR_AND_LOAD(7);
11153 if (astatic > 1) {
11154 DECR_AND_LOAD(6);
11155 if (astatic > 2) {
11156 DECR_AND_LOAD(5);
11157 if (astatic > 3) {
11158 DECR_AND_LOAD(4);
11159 }
11160 }
11161 }
11162 }
11163#undef DECR_AND_LOAD
11164
c48245f0
MR
11165 tcg_gen_movi_tl(t2, framesize);
11166 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11167 tcg_temp_free(t0);
11168 tcg_temp_free(t1);
c48245f0 11169 tcg_temp_free(t2);
364d4831
NF
11170}
11171
11172static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11173 int is_64_bit, int extended)
11174{
11175 TCGv t0;
11176
11177 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11178 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11179 return;
11180 }
11181
11182 t0 = tcg_temp_new();
11183
11184 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11185 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11186 if (!is_64_bit) {
11187 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11188 }
11189
11190 tcg_temp_free(t0);
11191}
11192
11193#if defined(TARGET_MIPS64)
d75c135e 11194static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11195 int ry, int funct, int16_t offset,
11196 int extended)
11197{
11198 switch (funct) {
11199 case I64_LDSP:
d9224450 11200 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11201 check_mips_64(ctx);
11202 offset = extended ? offset : offset << 3;
d75c135e 11203 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11204 break;
11205 case I64_SDSP:
d9224450 11206 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11207 check_mips_64(ctx);
11208 offset = extended ? offset : offset << 3;
5c13fdfd 11209 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11210 break;
11211 case I64_SDRASP:
d9224450 11212 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11213 check_mips_64(ctx);
11214 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11215 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11216 break;
11217 case I64_DADJSP:
d9224450 11218 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11219 check_mips_64(ctx);
11220 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11221 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11222 break;
11223 case I64_LDPC:
d9224450
MR
11224 check_insn(ctx, ISA_MIPS3);
11225 check_mips_64(ctx);
364d4831 11226 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11227 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11228 } else {
11229 offset = extended ? offset : offset << 3;
d75c135e 11230 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11231 }
11232 break;
11233 case I64_DADDIU5:
d9224450 11234 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11235 check_mips_64(ctx);
11236 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11237 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11238 break;
11239 case I64_DADDIUPC:
d9224450 11240 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11241 check_mips_64(ctx);
11242 offset = extended ? offset : offset << 2;
11243 gen_addiupc(ctx, ry, offset, 1, extended);
11244 break;
11245 case I64_DADDIUSP:
d9224450 11246 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11247 check_mips_64(ctx);
11248 offset = extended ? offset : offset << 2;
d75c135e 11249 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11250 break;
11251 }
11252}
11253#endif
11254
240ce26a 11255static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11256{
895c2d04 11257 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11258 int op, rx, ry, funct, sa;
11259 int16_t imm, offset;
11260
11261 ctx->opcode = (ctx->opcode << 16) | extend;
11262 op = (ctx->opcode >> 11) & 0x1f;
11263 sa = (ctx->opcode >> 22) & 0x1f;
11264 funct = (ctx->opcode >> 8) & 0x7;
11265 rx = xlat((ctx->opcode >> 8) & 0x7);
11266 ry = xlat((ctx->opcode >> 5) & 0x7);
11267 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11268 | ((ctx->opcode >> 21) & 0x3f) << 5
11269 | (ctx->opcode & 0x1f));
11270
11271 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11272 counterparts. */
11273 switch (op) {
11274 case M16_OPC_ADDIUSP:
d75c135e 11275 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11276 break;
11277 case M16_OPC_ADDIUPC:
11278 gen_addiupc(ctx, rx, imm, 0, 1);
11279 break;
11280 case M16_OPC_B:
b231c103 11281 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11282 /* No delay slot, so just process as a normal instruction */
11283 break;
11284 case M16_OPC_BEQZ:
b231c103 11285 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11286 /* No delay slot, so just process as a normal instruction */
11287 break;
11288 case M16_OPC_BNEQZ:
b231c103 11289 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11290 /* No delay slot, so just process as a normal instruction */
11291 break;
11292 case M16_OPC_SHIFT:
11293 switch (ctx->opcode & 0x3) {
11294 case 0x0:
d75c135e 11295 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11296 break;
11297 case 0x1:
11298#if defined(TARGET_MIPS64)
11299 check_mips_64(ctx);
d75c135e 11300 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11301#else
9c708c7f 11302 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11303#endif
11304 break;
11305 case 0x2:
d75c135e 11306 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11307 break;
11308 case 0x3:
d75c135e 11309 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11310 break;
11311 }
11312 break;
11313#if defined(TARGET_MIPS64)
11314 case M16_OPC_LD:
d9224450 11315 check_insn(ctx, ISA_MIPS3);
d75de749 11316 check_mips_64(ctx);
d75c135e 11317 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11318 break;
11319#endif
11320 case M16_OPC_RRIA:
11321 imm = ctx->opcode & 0xf;
11322 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11323 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11324 imm = (int16_t) (imm << 1) >> 1;
11325 if ((ctx->opcode >> 4) & 0x1) {
11326#if defined(TARGET_MIPS64)
11327 check_mips_64(ctx);
d75c135e 11328 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11329#else
9c708c7f 11330 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11331#endif
11332 } else {
d75c135e 11333 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11334 }
11335 break;
11336 case M16_OPC_ADDIU8:
d75c135e 11337 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11338 break;
11339 case M16_OPC_SLTI:
d75c135e 11340 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11341 break;
11342 case M16_OPC_SLTIU:
d75c135e 11343 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11344 break;
11345 case M16_OPC_I8:
11346 switch (funct) {
11347 case I8_BTEQZ:
b231c103 11348 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11349 break;
11350 case I8_BTNEZ:
b231c103 11351 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11352 break;
11353 case I8_SWRASP:
5c13fdfd 11354 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11355 break;
11356 case I8_ADJSP:
d75c135e 11357 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11358 break;
11359 case I8_SVRS:
d9224450 11360 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11361 {
11362 int xsregs = (ctx->opcode >> 24) & 0x7;
11363 int aregs = (ctx->opcode >> 16) & 0xf;
11364 int do_ra = (ctx->opcode >> 6) & 0x1;
11365 int do_s0 = (ctx->opcode >> 5) & 0x1;
11366 int do_s1 = (ctx->opcode >> 4) & 0x1;
11367 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11368 | (ctx->opcode & 0xf)) << 3;
11369
11370 if (ctx->opcode & (1 << 7)) {
11371 gen_mips16_save(ctx, xsregs, aregs,
11372 do_ra, do_s0, do_s1,
11373 framesize);
11374 } else {
11375 gen_mips16_restore(ctx, xsregs, aregs,
11376 do_ra, do_s0, do_s1,
11377 framesize);
11378 }
11379 }
11380 break;
11381 default:
9c708c7f 11382 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11383 break;
11384 }
11385 break;
11386 case M16_OPC_LI:
11387 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11388 break;
11389 case M16_OPC_CMPI:
11390 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11391 break;
11392#if defined(TARGET_MIPS64)
11393 case M16_OPC_SD:
d9224450
MR
11394 check_insn(ctx, ISA_MIPS3);
11395 check_mips_64(ctx);
5c13fdfd 11396 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11397 break;
11398#endif
11399 case M16_OPC_LB:
d75c135e 11400 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11401 break;
11402 case M16_OPC_LH:
d75c135e 11403 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11404 break;
11405 case M16_OPC_LWSP:
d75c135e 11406 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11407 break;
11408 case M16_OPC_LW:
d75c135e 11409 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11410 break;
11411 case M16_OPC_LBU:
d75c135e 11412 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11413 break;
11414 case M16_OPC_LHU:
d75c135e 11415 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11416 break;
11417 case M16_OPC_LWPC:
d75c135e 11418 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11419 break;
11420#if defined(TARGET_MIPS64)
11421 case M16_OPC_LWU:
d9224450
MR
11422 check_insn(ctx, ISA_MIPS3);
11423 check_mips_64(ctx);
d75c135e 11424 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11425 break;
11426#endif
11427 case M16_OPC_SB:
5c13fdfd 11428 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11429 break;
11430 case M16_OPC_SH:
5c13fdfd 11431 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11432 break;
11433 case M16_OPC_SWSP:
5c13fdfd 11434 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11435 break;
11436 case M16_OPC_SW:
5c13fdfd 11437 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11438 break;
11439#if defined(TARGET_MIPS64)
11440 case M16_OPC_I64:
d75c135e 11441 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11442 break;
11443#endif
11444 default:
9c708c7f 11445 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11446 break;
11447 }
11448
11449 return 4;
11450}
11451
3b3c1694
LA
11452static inline bool is_uhi(int sdbbp_code)
11453{
11454#ifdef CONFIG_USER_ONLY
11455 return false;
11456#else
11457 return semihosting_enabled() && sdbbp_code == 1;
11458#endif
11459}
11460
240ce26a 11461static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11462{
11463 int rx, ry;
11464 int sa;
11465 int op, cnvt_op, op1, offset;
11466 int funct;
11467 int n_bytes;
11468
11469 op = (ctx->opcode >> 11) & 0x1f;
11470 sa = (ctx->opcode >> 2) & 0x7;
11471 sa = sa == 0 ? 8 : sa;
11472 rx = xlat((ctx->opcode >> 8) & 0x7);
11473 cnvt_op = (ctx->opcode >> 5) & 0x7;
11474 ry = xlat((ctx->opcode >> 5) & 0x7);
11475 op1 = offset = ctx->opcode & 0x1f;
11476
11477 n_bytes = 2;
11478
11479 switch (op) {
11480 case M16_OPC_ADDIUSP:
11481 {
11482 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11483
d75c135e 11484 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11485 }
11486 break;
11487 case M16_OPC_ADDIUPC:
11488 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11489 break;
11490 case M16_OPC_B:
11491 offset = (ctx->opcode & 0x7ff) << 1;
11492 offset = (int16_t)(offset << 4) >> 4;
b231c103 11493 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11494 /* No delay slot, so just process as a normal instruction */
11495 break;
11496 case M16_OPC_JAL:
895c2d04 11497 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11498 offset = (((ctx->opcode & 0x1f) << 21)
11499 | ((ctx->opcode >> 5) & 0x1f) << 16
11500 | offset) << 2;
b231c103
YK
11501 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11502 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11503 n_bytes = 4;
364d4831
NF
11504 break;
11505 case M16_OPC_BEQZ:
b231c103
YK
11506 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11507 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11508 /* No delay slot, so just process as a normal instruction */
11509 break;
11510 case M16_OPC_BNEQZ:
b231c103
YK
11511 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11512 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11513 /* No delay slot, so just process as a normal instruction */
11514 break;
11515 case M16_OPC_SHIFT:
11516 switch (ctx->opcode & 0x3) {
11517 case 0x0:
d75c135e 11518 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11519 break;
11520 case 0x1:
11521#if defined(TARGET_MIPS64)
d9224450 11522 check_insn(ctx, ISA_MIPS3);
364d4831 11523 check_mips_64(ctx);
d75c135e 11524 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11525#else
9c708c7f 11526 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11527#endif
11528 break;
11529 case 0x2:
d75c135e 11530 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11531 break;
11532 case 0x3:
d75c135e 11533 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11534 break;
11535 }
11536 break;
11537#if defined(TARGET_MIPS64)
11538 case M16_OPC_LD:
d9224450 11539 check_insn(ctx, ISA_MIPS3);
364d4831 11540 check_mips_64(ctx);
d75c135e 11541 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11542 break;
11543#endif
11544 case M16_OPC_RRIA:
11545 {
11546 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11547
11548 if ((ctx->opcode >> 4) & 1) {
11549#if defined(TARGET_MIPS64)
d9224450 11550 check_insn(ctx, ISA_MIPS3);
364d4831 11551 check_mips_64(ctx);
d75c135e 11552 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11553#else
9c708c7f 11554 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11555#endif
11556 } else {
d75c135e 11557 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11558 }
11559 }
11560 break;
11561 case M16_OPC_ADDIU8:
11562 {
11563 int16_t imm = (int8_t) ctx->opcode;
11564
d75c135e 11565 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11566 }
11567 break;
11568 case M16_OPC_SLTI:
11569 {
11570 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11571 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11572 }
11573 break;
11574 case M16_OPC_SLTIU:
11575 {
11576 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11577 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11578 }
11579 break;
11580 case M16_OPC_I8:
11581 {
11582 int reg32;
11583
11584 funct = (ctx->opcode >> 8) & 0x7;
11585 switch (funct) {
11586 case I8_BTEQZ:
11587 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11588 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11589 break;
11590 case I8_BTNEZ:
11591 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11592 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11593 break;
11594 case I8_SWRASP:
5c13fdfd 11595 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11596 break;
11597 case I8_ADJSP:
d75c135e 11598 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11599 ((int8_t)ctx->opcode) << 3);
11600 break;
11601 case I8_SVRS:
d9224450 11602 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11603 {
11604 int do_ra = ctx->opcode & (1 << 6);
11605 int do_s0 = ctx->opcode & (1 << 5);
11606 int do_s1 = ctx->opcode & (1 << 4);
11607 int framesize = ctx->opcode & 0xf;
11608
11609 if (framesize == 0) {
11610 framesize = 128;
11611 } else {
11612 framesize = framesize << 3;
11613 }
11614
11615 if (ctx->opcode & (1 << 7)) {
11616 gen_mips16_save(ctx, 0, 0,
11617 do_ra, do_s0, do_s1, framesize);
11618 } else {
11619 gen_mips16_restore(ctx, 0, 0,
11620 do_ra, do_s0, do_s1, framesize);
11621 }
11622 }
11623 break;
11624 case I8_MOV32R:
11625 {
11626 int rz = xlat(ctx->opcode & 0x7);
11627
11628 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11629 ((ctx->opcode >> 5) & 0x7);
d75c135e 11630 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11631 }
11632 break;
11633 case I8_MOVR32:
11634 reg32 = ctx->opcode & 0x1f;
d75c135e 11635 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11636 break;
11637 default:
9c708c7f 11638 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11639 break;
11640 }
11641 }
11642 break;
11643 case M16_OPC_LI:
11644 {
11645 int16_t imm = (uint8_t) ctx->opcode;
11646
d75c135e 11647 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11648 }
11649 break;
11650 case M16_OPC_CMPI:
11651 {
11652 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11653 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11654 }
11655 break;
11656#if defined(TARGET_MIPS64)
11657 case M16_OPC_SD:
d9224450 11658 check_insn(ctx, ISA_MIPS3);
364d4831 11659 check_mips_64(ctx);
5c13fdfd 11660 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11661 break;
11662#endif
11663 case M16_OPC_LB:
d75c135e 11664 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11665 break;
11666 case M16_OPC_LH:
d75c135e 11667 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11668 break;
11669 case M16_OPC_LWSP:
d75c135e 11670 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11671 break;
11672 case M16_OPC_LW:
d75c135e 11673 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11674 break;
11675 case M16_OPC_LBU:
d75c135e 11676 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11677 break;
11678 case M16_OPC_LHU:
d75c135e 11679 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11680 break;
11681 case M16_OPC_LWPC:
d75c135e 11682 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11683 break;
11684#if defined (TARGET_MIPS64)
11685 case M16_OPC_LWU:
d9224450 11686 check_insn(ctx, ISA_MIPS3);
364d4831 11687 check_mips_64(ctx);
d75c135e 11688 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11689 break;
11690#endif
11691 case M16_OPC_SB:
5c13fdfd 11692 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11693 break;
11694 case M16_OPC_SH:
5c13fdfd 11695 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11696 break;
11697 case M16_OPC_SWSP:
5c13fdfd 11698 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11699 break;
11700 case M16_OPC_SW:
5c13fdfd 11701 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11702 break;
11703 case M16_OPC_RRR:
11704 {
11705 int rz = xlat((ctx->opcode >> 2) & 0x7);
11706 int mips32_op;
11707
11708 switch (ctx->opcode & 0x3) {
11709 case RRR_ADDU:
11710 mips32_op = OPC_ADDU;
11711 break;
11712 case RRR_SUBU:
11713 mips32_op = OPC_SUBU;
11714 break;
11715#if defined(TARGET_MIPS64)
11716 case RRR_DADDU:
11717 mips32_op = OPC_DADDU;
d9224450 11718 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11719 check_mips_64(ctx);
11720 break;
11721 case RRR_DSUBU:
11722 mips32_op = OPC_DSUBU;
d9224450 11723 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11724 check_mips_64(ctx);
11725 break;
11726#endif
11727 default:
9c708c7f 11728 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11729 goto done;
11730 }
11731
d75c135e 11732 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11733 done:
11734 ;
11735 }
11736 break;
11737 case M16_OPC_RR:
11738 switch (op1) {
11739 case RR_JR:
11740 {
11741 int nd = (ctx->opcode >> 7) & 0x1;
11742 int link = (ctx->opcode >> 6) & 0x1;
11743 int ra = (ctx->opcode >> 5) & 0x1;
11744
d9224450
MR
11745 if (nd) {
11746 check_insn(ctx, ISA_MIPS32);
11747 }
11748
364d4831 11749 if (link) {
b231c103 11750 op = OPC_JALR;
364d4831
NF
11751 } else {
11752 op = OPC_JR;
11753 }
11754
b231c103
YK
11755 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11756 (nd ? 0 : 2));
364d4831
NF
11757 }
11758 break;
11759 case RR_SDBBP:
3b3c1694
LA
11760 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11761 gen_helper_do_semihosting(cpu_env);
11762 } else {
11763 /* XXX: not clear which exception should be raised
11764 * when in debug mode...
11765 */
11766 check_insn(ctx, ISA_MIPS32);
9c708c7f 11767 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 11768 }
364d4831
NF
11769 break;
11770 case RR_SLT:
d75c135e 11771 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11772 break;
11773 case RR_SLTU:
d75c135e 11774 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11775 break;
11776 case RR_BREAK:
9c708c7f 11777 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
11778 break;
11779 case RR_SLLV:
d75c135e 11780 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11781 break;
11782 case RR_SRLV:
d75c135e 11783 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11784 break;
11785 case RR_SRAV:
d75c135e 11786 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11787 break;
11788#if defined (TARGET_MIPS64)
11789 case RR_DSRL:
d9224450 11790 check_insn(ctx, ISA_MIPS3);
364d4831 11791 check_mips_64(ctx);
d75c135e 11792 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11793 break;
11794#endif
11795 case RR_CMP:
d75c135e 11796 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11797 break;
11798 case RR_NEG:
d75c135e 11799 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11800 break;
11801 case RR_AND:
d75c135e 11802 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11803 break;
11804 case RR_OR:
d75c135e 11805 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11806 break;
11807 case RR_XOR:
d75c135e 11808 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11809 break;
11810 case RR_NOT:
d75c135e 11811 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11812 break;
11813 case RR_MFHI:
26135ead 11814 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11815 break;
11816 case RR_CNVT:
d9224450 11817 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11818 switch (cnvt_op) {
11819 case RR_RY_CNVT_ZEB:
11820 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11821 break;
11822 case RR_RY_CNVT_ZEH:
11823 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11824 break;
11825 case RR_RY_CNVT_SEB:
11826 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11827 break;
11828 case RR_RY_CNVT_SEH:
11829 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11830 break;
11831#if defined (TARGET_MIPS64)
11832 case RR_RY_CNVT_ZEW:
d9224450 11833 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11834 check_mips_64(ctx);
11835 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11836 break;
11837 case RR_RY_CNVT_SEW:
d9224450 11838 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11839 check_mips_64(ctx);
11840 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11841 break;
11842#endif
11843 default:
9c708c7f 11844 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11845 break;
11846 }
11847 break;
11848 case RR_MFLO:
26135ead 11849 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11850 break;
11851#if defined (TARGET_MIPS64)
11852 case RR_DSRA:
d9224450 11853 check_insn(ctx, ISA_MIPS3);
364d4831 11854 check_mips_64(ctx);
d75c135e 11855 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11856 break;
11857 case RR_DSLLV:
d9224450 11858 check_insn(ctx, ISA_MIPS3);
364d4831 11859 check_mips_64(ctx);
d75c135e 11860 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11861 break;
11862 case RR_DSRLV:
d9224450 11863 check_insn(ctx, ISA_MIPS3);
364d4831 11864 check_mips_64(ctx);
d75c135e 11865 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11866 break;
11867 case RR_DSRAV:
d9224450 11868 check_insn(ctx, ISA_MIPS3);
364d4831 11869 check_mips_64(ctx);
d75c135e 11870 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11871 break;
11872#endif
11873 case RR_MULT:
26135ead 11874 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11875 break;
11876 case RR_MULTU:
26135ead 11877 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11878 break;
11879 case RR_DIV:
26135ead 11880 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11881 break;
11882 case RR_DIVU:
26135ead 11883 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11884 break;
11885#if defined (TARGET_MIPS64)
11886 case RR_DMULT:
d9224450 11887 check_insn(ctx, ISA_MIPS3);
364d4831 11888 check_mips_64(ctx);
26135ead 11889 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11890 break;
11891 case RR_DMULTU:
d9224450 11892 check_insn(ctx, ISA_MIPS3);
364d4831 11893 check_mips_64(ctx);
26135ead 11894 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11895 break;
11896 case RR_DDIV:
d9224450 11897 check_insn(ctx, ISA_MIPS3);
364d4831 11898 check_mips_64(ctx);
26135ead 11899 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11900 break;
11901 case RR_DDIVU:
d9224450 11902 check_insn(ctx, ISA_MIPS3);
364d4831 11903 check_mips_64(ctx);
26135ead 11904 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11905 break;
11906#endif
11907 default:
9c708c7f 11908 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11909 break;
11910 }
11911 break;
11912 case M16_OPC_EXTEND:
240ce26a 11913 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11914 n_bytes = 4;
11915 break;
11916#if defined(TARGET_MIPS64)
11917 case M16_OPC_I64:
11918 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11919 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11920 break;
11921#endif
11922 default:
9c708c7f 11923 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11924 break;
11925 }
11926
11927 return n_bytes;
11928}
11929
211da992 11930/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11931
211da992
CWR
11932/*
11933 * microMIPS32/microMIPS64 major opcodes
11934 *
11935 * 1. MIPS Architecture for Programmers Volume II-B:
11936 * The microMIPS32 Instruction Set (Revision 3.05)
11937 *
11938 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11939 *
11940 * 2. MIPS Architecture For Programmers Volume II-A:
11941 * The MIPS64 Instruction Set (Revision 3.51)
11942 */
6af0bf9c 11943
3c824109
NF
11944enum {
11945 POOL32A = 0x00,
11946 POOL16A = 0x01,
11947 LBU16 = 0x02,
11948 MOVE16 = 0x03,
11949 ADDI32 = 0x04,
3a1f4268
YK
11950 R6_LUI = 0x04,
11951 AUI = 0x04,
3c824109
NF
11952 LBU32 = 0x05,
11953 SB32 = 0x06,
11954 LB32 = 0x07,
11955
11956 POOL32B = 0x08,
11957 POOL16B = 0x09,
11958 LHU16 = 0x0a,
11959 ANDI16 = 0x0b,
11960 ADDIU32 = 0x0c,
11961 LHU32 = 0x0d,
11962 SH32 = 0x0e,
11963 LH32 = 0x0f,
11964
11965 POOL32I = 0x10,
11966 POOL16C = 0x11,
11967 LWSP16 = 0x12,
11968 POOL16D = 0x13,
11969 ORI32 = 0x14,
11970 POOL32F = 0x15,
211da992
CWR
11971 POOL32S = 0x16, /* MIPS64 */
11972 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
11973
11974 POOL32C = 0x18,
11975 LWGP16 = 0x19,
11976 LW16 = 0x1a,
11977 POOL16E = 0x1b,
11978 XORI32 = 0x1c,
11979 JALS32 = 0x1d,
3a1f4268
YK
11980 BOVC = 0x1d,
11981 BEQC = 0x1d,
11982 BEQZALC = 0x1d,
3c824109 11983 ADDIUPC = 0x1e,
3a1f4268
YK
11984 PCREL = 0x1e,
11985 BNVC = 0x1f,
11986 BNEC = 0x1f,
11987 BNEZALC = 0x1f,
3c824109 11988
3a1f4268
YK
11989 R6_BEQZC = 0x20,
11990 JIC = 0x20,
3c824109
NF
11991 POOL16F = 0x21,
11992 SB16 = 0x22,
11993 BEQZ16 = 0x23,
3a1f4268 11994 BEQZC16 = 0x23,
3c824109
NF
11995 SLTI32 = 0x24,
11996 BEQ32 = 0x25,
3a1f4268 11997 BC = 0x25,
3c824109
NF
11998 SWC132 = 0x26,
11999 LWC132 = 0x27,
12000
3a1f4268 12001 /* 0x29 is reserved */
3c824109 12002 RES_29 = 0x29,
3a1f4268
YK
12003 R6_BNEZC = 0x28,
12004 JIALC = 0x28,
3c824109
NF
12005 SH16 = 0x2a,
12006 BNEZ16 = 0x2b,
3a1f4268 12007 BNEZC16 = 0x2b,
3c824109
NF
12008 SLTIU32 = 0x2c,
12009 BNE32 = 0x2d,
3a1f4268 12010 BALC = 0x2d,
3c824109
NF
12011 SDC132 = 0x2e,
12012 LDC132 = 0x2f,
12013
3a1f4268 12014 /* 0x31 is reserved */
3c824109 12015 RES_31 = 0x31,
3a1f4268
YK
12016 BLEZALC = 0x30,
12017 BGEZALC = 0x30,
12018 BGEUC = 0x30,
3c824109
NF
12019 SWSP16 = 0x32,
12020 B16 = 0x33,
3a1f4268 12021 BC16 = 0x33,
3c824109
NF
12022 ANDI32 = 0x34,
12023 J32 = 0x35,
3a1f4268
YK
12024 BGTZC = 0x35,
12025 BLTZC = 0x35,
12026 BLTC = 0x35,
211da992
CWR
12027 SD32 = 0x36, /* MIPS64 */
12028 LD32 = 0x37, /* MIPS64 */
3c824109 12029
3a1f4268 12030 /* 0x39 is reserved */
3c824109 12031 RES_39 = 0x39,
3a1f4268
YK
12032 BGTZALC = 0x38,
12033 BLTZALC = 0x38,
12034 BLTUC = 0x38,
3c824109
NF
12035 SW16 = 0x3a,
12036 LI16 = 0x3b,
12037 JALX32 = 0x3c,
12038 JAL32 = 0x3d,
3a1f4268
YK
12039 BLEZC = 0x3d,
12040 BGEZC = 0x3d,
12041 BGEC = 0x3d,
3c824109
NF
12042 SW32 = 0x3e,
12043 LW32 = 0x3f
12044};
12045
3a1f4268
YK
12046/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12047enum {
12048 ADDIUPC_00 = 0x00,
12049 ADDIUPC_07 = 0x07,
12050 AUIPC = 0x1e,
12051 ALUIPC = 0x1f,
12052 LWPC_08 = 0x08,
12053 LWPC_0F = 0x0F,
12054};
12055
3c824109
NF
12056/* POOL32A encoding of minor opcode field */
12057
12058enum {
12059 /* These opcodes are distinguished only by bits 9..6; those bits are
12060 * what are recorded below. */
12061 SLL32 = 0x0,
12062 SRL32 = 0x1,
12063 SRA = 0x2,
12064 ROTR = 0x3,
3a1f4268
YK
12065 SELEQZ = 0x5,
12066 SELNEZ = 0x6,
b00c7218 12067 R6_RDHWR = 0x7,
3c824109
NF
12068
12069 SLLV = 0x0,
12070 SRLV = 0x1,
12071 SRAV = 0x2,
12072 ROTRV = 0x3,
12073 ADD = 0x4,
12074 ADDU32 = 0x5,
12075 SUB = 0x6,
12076 SUBU32 = 0x7,
12077 MUL = 0x8,
12078 AND = 0x9,
12079 OR32 = 0xa,
12080 NOR = 0xb,
12081 XOR32 = 0xc,
12082 SLT = 0xd,
12083 SLTU = 0xe,
12084
12085 MOVN = 0x0,
3a1f4268 12086 R6_MUL = 0x0,
3c824109 12087 MOVZ = 0x1,
3a1f4268
YK
12088 MUH = 0x1,
12089 MULU = 0x2,
12090 MUHU = 0x3,
3c824109 12091 LWXS = 0x4,
3a1f4268
YK
12092 R6_DIV = 0x4,
12093 MOD = 0x5,
12094 R6_DIVU = 0x6,
12095 MODU = 0x7,
3c824109
NF
12096
12097 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12098 BREAK32 = 0x07,
3c824109 12099 INS = 0x0c,
3a1f4268
YK
12100 LSA = 0x0f,
12101 ALIGN = 0x1f,
3c824109 12102 EXT = 0x2c,
bb238210
YK
12103 POOL32AXF = 0x3c,
12104 SIGRIE = 0x3f
3c824109
NF
12105};
12106
12107/* POOL32AXF encoding of minor opcode field extension */
12108
d132c79f
CWR
12109/*
12110 * 1. MIPS Architecture for Programmers Volume II-B:
12111 * The microMIPS32 Instruction Set (Revision 3.05)
12112 *
12113 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12114 *
12115 * 2. MIPS Architecture for Programmers VolumeIV-e:
12116 * The MIPS DSP Application-Specific Extension
12117 * to the microMIPS32 Architecture (Revision 2.34)
12118 *
12119 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12120 */
12121
3c824109
NF
12122enum {
12123 /* bits 11..6 */
12124 TEQ = 0x00,
12125 TGE = 0x08,
12126 TGEU = 0x10,
12127 TLT = 0x20,
12128 TLTU = 0x28,
12129 TNE = 0x30,
12130
12131 MFC0 = 0x03,
12132 MTC0 = 0x0b,
12133
d132c79f
CWR
12134 /* begin of microMIPS32 DSP */
12135
3c824109
NF
12136 /* bits 13..12 for 0x01 */
12137 MFHI_ACC = 0x0,
12138 MFLO_ACC = 0x1,
12139 MTHI_ACC = 0x2,
12140 MTLO_ACC = 0x3,
12141
12142 /* bits 13..12 for 0x2a */
12143 MADD_ACC = 0x0,
12144 MADDU_ACC = 0x1,
12145 MSUB_ACC = 0x2,
12146 MSUBU_ACC = 0x3,
12147
12148 /* bits 13..12 for 0x32 */
12149 MULT_ACC = 0x0,
6801038b 12150 MULTU_ACC = 0x1,
3c824109 12151
d132c79f
CWR
12152 /* end of microMIPS32 DSP */
12153
3c824109 12154 /* bits 15..12 for 0x2c */
3a1f4268 12155 BITSWAP = 0x0,
3c824109
NF
12156 SEB = 0x2,
12157 SEH = 0x3,
12158 CLO = 0x4,
12159 CLZ = 0x5,
12160 RDHWR = 0x6,
12161 WSBH = 0x7,
12162 MULT = 0x8,
12163 MULTU = 0x9,
12164 DIV = 0xa,
12165 DIVU = 0xb,
12166 MADD = 0xc,
12167 MADDU = 0xd,
12168 MSUB = 0xe,
12169 MSUBU = 0xf,
12170
12171 /* bits 15..12 for 0x34 */
12172 MFC2 = 0x4,
12173 MTC2 = 0x5,
12174 MFHC2 = 0x8,
12175 MTHC2 = 0x9,
12176 CFC2 = 0xc,
12177 CTC2 = 0xd,
12178
12179 /* bits 15..12 for 0x3c */
12180 JALR = 0x0,
12181 JR = 0x0, /* alias */
3a1f4268
YK
12182 JALRC = 0x0,
12183 JRC = 0x0,
3c824109 12184 JALR_HB = 0x1,
3a1f4268 12185 JALRC_HB = 0x1,
3c824109
NF
12186 JALRS = 0x4,
12187 JALRS_HB = 0x5,
12188
12189 /* bits 15..12 for 0x05 */
12190 RDPGPR = 0xe,
12191 WRPGPR = 0xf,
12192
12193 /* bits 15..12 for 0x0d */
12194 TLBP = 0x0,
12195 TLBR = 0x1,
12196 TLBWI = 0x2,
12197 TLBWR = 0x3,
e60ec063
YK
12198 TLBINV = 0x4,
12199 TLBINVF = 0x5,
3c824109
NF
12200 WAIT = 0x9,
12201 IRET = 0xd,
12202 DERET = 0xe,
12203 ERET = 0xf,
12204
12205 /* bits 15..12 for 0x15 */
12206 DMT = 0x0,
12207 DVPE = 0x1,
12208 EMT = 0x2,
12209 EVPE = 0x3,
12210
12211 /* bits 15..12 for 0x1d */
12212 DI = 0x4,
12213 EI = 0x5,
12214
12215 /* bits 15..12 for 0x2d */
12216 SYNC = 0x6,
12217 SYSCALL = 0x8,
12218 SDBBP = 0xd,
12219
12220 /* bits 15..12 for 0x35 */
12221 MFHI32 = 0x0,
12222 MFLO32 = 0x1,
12223 MTHI32 = 0x2,
12224 MTLO32 = 0x3,
12225};
12226
12227/* POOL32B encoding of minor opcode field (bits 15..12) */
12228
12229enum {
12230 LWC2 = 0x0,
12231 LWP = 0x1,
12232 LDP = 0x4,
12233 LWM32 = 0x5,
12234 CACHE = 0x6,
12235 LDM = 0x7,
12236 SWC2 = 0x8,
12237 SWP = 0x9,
12238 SDP = 0xc,
12239 SWM32 = 0xd,
12240 SDM = 0xf
12241};
12242
12243/* POOL32C encoding of minor opcode field (bits 15..12) */
12244
12245enum {
12246 LWL = 0x0,
12247 SWL = 0x8,
12248 LWR = 0x1,
12249 SWR = 0x9,
12250 PREF = 0x2,
12251 /* 0xa is reserved */
12252 LL = 0x3,
12253 SC = 0xb,
12254 LDL = 0x4,
12255 SDL = 0xc,
12256 LDR = 0x5,
12257 SDR = 0xd,
12258 /* 0x6 is reserved */
12259 LWU = 0xe,
12260 LLD = 0x7,
12261 SCD = 0xf
12262};
12263
12264/* POOL32F encoding of minor opcode field (bits 5..0) */
12265
12266enum {
12267 /* These are the bit 7..6 values */
12268 ADD_FMT = 0x0,
3c824109
NF
12269
12270 SUB_FMT = 0x1,
3c824109
NF
12271
12272 MUL_FMT = 0x2,
12273
12274 DIV_FMT = 0x3,
12275
12276 /* These are the bit 8..6 values */
3a1f4268 12277 MOVN_FMT = 0x0,
3c824109
NF
12278 RSQRT2_FMT = 0x0,
12279 MOVF_FMT = 0x0,
3a1f4268
YK
12280 RINT_FMT = 0x0,
12281 SELNEZ_FMT = 0x0,
3c824109 12282
3a1f4268 12283 MOVZ_FMT = 0x1,
3c824109
NF
12284 LWXC1 = 0x1,
12285 MOVT_FMT = 0x1,
3a1f4268
YK
12286 CLASS_FMT = 0x1,
12287 SELEQZ_FMT = 0x1,
3c824109
NF
12288
12289 PLL_PS = 0x2,
12290 SWXC1 = 0x2,
3a1f4268 12291 SEL_FMT = 0x2,
3c824109
NF
12292
12293 PLU_PS = 0x3,
12294 LDXC1 = 0x3,
12295
3a1f4268 12296 MOVN_FMT_04 = 0x4,
3c824109
NF
12297 PUL_PS = 0x4,
12298 SDXC1 = 0x4,
12299 RECIP2_FMT = 0x4,
12300
3a1f4268 12301 MOVZ_FMT_05 = 0x05,
3c824109
NF
12302 PUU_PS = 0x5,
12303 LUXC1 = 0x5,
12304
12305 CVT_PS_S = 0x6,
12306 SUXC1 = 0x6,
12307 ADDR_PS = 0x6,
12308 PREFX = 0x6,
3a1f4268 12309 MADDF_FMT = 0x6,
3c824109
NF
12310
12311 MULR_PS = 0x7,
3a1f4268 12312 MSUBF_FMT = 0x7,
3c824109
NF
12313
12314 MADD_S = 0x01,
12315 MADD_D = 0x09,
12316 MADD_PS = 0x11,
12317 ALNV_PS = 0x19,
12318 MSUB_S = 0x21,
12319 MSUB_D = 0x29,
12320 MSUB_PS = 0x31,
12321
12322 NMADD_S = 0x02,
12323 NMADD_D = 0x0a,
12324 NMADD_PS = 0x12,
12325 NMSUB_S = 0x22,
12326 NMSUB_D = 0x2a,
12327 NMSUB_PS = 0x32,
12328
3a1f4268
YK
12329 MIN_FMT = 0x3,
12330 MAX_FMT = 0xb,
12331 MINA_FMT = 0x23,
12332 MAXA_FMT = 0x2b,
3c824109
NF
12333 POOL32FXF = 0x3b,
12334
12335 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12336 C_COND_FMT = 0x3c,
12337
12338 CMP_CONDN_S = 0x5,
12339 CMP_CONDN_D = 0x15
3c824109
NF
12340};
12341
12342/* POOL32Fxf encoding of minor opcode extension field */
12343
12344enum {
12345 CVT_L = 0x04,
12346 RSQRT_FMT = 0x08,
12347 FLOOR_L = 0x0c,
12348 CVT_PW_PS = 0x1c,
12349 CVT_W = 0x24,
12350 SQRT_FMT = 0x28,
12351 FLOOR_W = 0x2c,
12352 CVT_PS_PW = 0x3c,
12353 CFC1 = 0x40,
12354 RECIP_FMT = 0x48,
12355 CEIL_L = 0x4c,
12356 CTC1 = 0x60,
12357 CEIL_W = 0x6c,
12358 MFC1 = 0x80,
12359 CVT_S_PL = 0x84,
12360 TRUNC_L = 0x8c,
12361 MTC1 = 0xa0,
12362 CVT_S_PU = 0xa4,
12363 TRUNC_W = 0xac,
12364 MFHC1 = 0xc0,
12365 ROUND_L = 0xcc,
12366 MTHC1 = 0xe0,
12367 ROUND_W = 0xec,
12368
12369 MOV_FMT = 0x01,
12370 MOVF = 0x05,
12371 ABS_FMT = 0x0d,
12372 RSQRT1_FMT = 0x1d,
12373 MOVT = 0x25,
12374 NEG_FMT = 0x2d,
12375 CVT_D = 0x4d,
12376 RECIP1_FMT = 0x5d,
12377 CVT_S = 0x6d
12378};
12379
12380/* POOL32I encoding of minor opcode field (bits 25..21) */
12381
12382enum {
12383 BLTZ = 0x00,
12384 BLTZAL = 0x01,
12385 BGEZ = 0x02,
12386 BGEZAL = 0x03,
12387 BLEZ = 0x04,
12388 BNEZC = 0x05,
12389 BGTZ = 0x06,
12390 BEQZC = 0x07,
12391 TLTI = 0x08,
3a1f4268 12392 BC1EQZC = 0x08,
3c824109 12393 TGEI = 0x09,
3a1f4268 12394 BC1NEZC = 0x09,
3c824109 12395 TLTIU = 0x0a,
3a1f4268 12396 BC2EQZC = 0x0a,
3c824109 12397 TGEIU = 0x0b,
3a1f4268 12398 BC2NEZC = 0x0a,
3c824109 12399 TNEI = 0x0c,
3a1f4268 12400 R6_SYNCI = 0x0c,
3c824109
NF
12401 LUI = 0x0d,
12402 TEQI = 0x0e,
12403 SYNCI = 0x10,
12404 BLTZALS = 0x11,
12405 BGEZALS = 0x13,
12406 BC2F = 0x14,
12407 BC2T = 0x15,
12408 BPOSGE64 = 0x1a,
12409 BPOSGE32 = 0x1b,
12410 /* These overlap and are distinguished by bit16 of the instruction */
12411 BC1F = 0x1c,
12412 BC1T = 0x1d,
12413 BC1ANY2F = 0x1c,
12414 BC1ANY2T = 0x1d,
12415 BC1ANY4F = 0x1e,
12416 BC1ANY4T = 0x1f
12417};
12418
12419/* POOL16A encoding of minor opcode field */
12420
12421enum {
12422 ADDU16 = 0x0,
12423 SUBU16 = 0x1
12424};
12425
12426/* POOL16B encoding of minor opcode field */
12427
12428enum {
12429 SLL16 = 0x0,
12430 SRL16 = 0x1
12431};
12432
12433/* POOL16C encoding of minor opcode field */
12434
12435enum {
12436 NOT16 = 0x00,
12437 XOR16 = 0x04,
12438 AND16 = 0x08,
12439 OR16 = 0x0c,
12440 LWM16 = 0x10,
12441 SWM16 = 0x14,
12442 JR16 = 0x18,
12443 JRC16 = 0x1a,
12444 JALR16 = 0x1c,
12445 JALR16S = 0x1e,
12446 MFHI16 = 0x20,
12447 MFLO16 = 0x24,
12448 BREAK16 = 0x28,
12449 SDBBP16 = 0x2c,
12450 JRADDIUSP = 0x30
12451};
12452
3a1f4268
YK
12453/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12454
12455enum {
12456 R6_NOT16 = 0x00,
12457 R6_AND16 = 0x01,
12458 R6_LWM16 = 0x02,
12459 R6_JRC16 = 0x03,
12460 MOVEP = 0x04,
12461 MOVEP_07 = 0x07,
12462 R6_XOR16 = 0x08,
12463 R6_OR16 = 0x09,
12464 R6_SWM16 = 0x0a,
12465 JALRC16 = 0x0b,
12466 MOVEP_0C = 0x0c,
12467 MOVEP_0F = 0x0f,
12468 JRCADDIUSP = 0x13,
12469 R6_BREAK16 = 0x1b,
12470 R6_SDBBP16 = 0x3b
12471};
12472
3c824109
NF
12473/* POOL16D encoding of minor opcode field */
12474
12475enum {
12476 ADDIUS5 = 0x0,
12477 ADDIUSP = 0x1
12478};
12479
12480/* POOL16E encoding of minor opcode field */
12481
12482enum {
12483 ADDIUR2 = 0x0,
12484 ADDIUR1SP = 0x1
12485};
12486
12487static int mmreg (int r)
12488{
12489 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12490
12491 return map[r];
12492}
12493
12494/* Used for 16-bit store instructions. */
12495static int mmreg2 (int r)
12496{
12497 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12498
12499 return map[r];
12500}
12501
12502#define uMIPS_RD(op) ((op >> 7) & 0x7)
12503#define uMIPS_RS(op) ((op >> 4) & 0x7)
12504#define uMIPS_RS2(op) uMIPS_RS(op)
12505#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12506#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12507#define uMIPS_RS5(op) (op & 0x1f)
12508
12509/* Signed immediate */
12510#define SIMM(op, start, width) \
12511 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12512 << (32-width)) \
12513 >> (32-width))
12514/* Zero-extended immediate */
12515#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12516
d75c135e 12517static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12518{
12519 int rd = mmreg(uMIPS_RD(ctx->opcode));
12520
d75c135e 12521 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12522}
12523
d75c135e 12524static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12525{
12526 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12527 int rd = mmreg(uMIPS_RD(ctx->opcode));
12528 int rs = mmreg(uMIPS_RS(ctx->opcode));
12529
d75c135e 12530 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12531}
12532
d75c135e 12533static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12534{
12535 int encoded = ZIMM(ctx->opcode, 1, 9);
12536 int decoded;
12537
12538 if (encoded <= 1) {
12539 decoded = 256 + encoded;
12540 } else if (encoded <= 255) {
12541 decoded = encoded;
12542 } else if (encoded <= 509) {
12543 decoded = encoded - 512;
12544 } else {
12545 decoded = encoded - 768;
12546 }
12547
d75c135e 12548 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12549}
12550
d75c135e 12551static void gen_addius5(DisasContext *ctx)
3c824109
NF
12552{
12553 int imm = SIMM(ctx->opcode, 1, 4);
12554 int rd = (ctx->opcode >> 5) & 0x1f;
12555
d75c135e 12556 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12557}
12558
d75c135e 12559static void gen_andi16(DisasContext *ctx)
3c824109
NF
12560{
12561 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12562 31, 32, 63, 64, 255, 32768, 65535 };
12563 int rd = mmreg(uMIPS_RD(ctx->opcode));
12564 int rs = mmreg(uMIPS_RS(ctx->opcode));
12565 int encoded = ZIMM(ctx->opcode, 0, 4);
12566
d75c135e 12567 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12568}
12569
12570static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12571 int base, int16_t offset)
12572{
12573 TCGv t0, t1;
12574 TCGv_i32 t2;
12575
12576 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12577 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12578 return;
12579 }
12580
12581 t0 = tcg_temp_new();
12582
12583 gen_base_offset_addr(ctx, t0, base, offset);
12584
12585 t1 = tcg_const_tl(reglist);
12586 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12587
3c824109
NF
12588 save_cpu_state(ctx, 1);
12589 switch (opc) {
12590 case LWM32:
895c2d04 12591 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12592 break;
12593 case SWM32:
895c2d04 12594 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12595 break;
12596#ifdef TARGET_MIPS64
12597 case LDM:
895c2d04 12598 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12599 break;
12600 case SDM:
895c2d04 12601 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12602 break;
6af0bf9c 12603#endif
3c824109 12604 }
3c824109 12605 tcg_temp_free(t0);
33087598 12606 tcg_temp_free(t1);
3c824109
NF
12607 tcg_temp_free_i32(t2);
12608}
6af0bf9c 12609
3c824109 12610
240ce26a 12611static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12612{
3c824109
NF
12613 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12614 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12615
3c824109
NF
12616 switch (((ctx->opcode) >> 4) & 0x3f) {
12617 case NOT16 + 0:
12618 case NOT16 + 1:
12619 case NOT16 + 2:
12620 case NOT16 + 3:
d75c135e 12621 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12622 break;
12623 case XOR16 + 0:
12624 case XOR16 + 1:
12625 case XOR16 + 2:
12626 case XOR16 + 3:
d75c135e 12627 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12628 break;
12629 case AND16 + 0:
12630 case AND16 + 1:
12631 case AND16 + 2:
12632 case AND16 + 3:
d75c135e 12633 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12634 break;
12635 case OR16 + 0:
12636 case OR16 + 1:
12637 case OR16 + 2:
12638 case OR16 + 3:
d75c135e 12639 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12640 break;
12641 case LWM16 + 0:
12642 case LWM16 + 1:
12643 case LWM16 + 2:
12644 case LWM16 + 3:
12645 {
12646 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12647 int offset = ZIMM(ctx->opcode, 0, 4);
12648
12649 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12650 29, offset << 2);
12651 }
12652 break;
12653 case SWM16 + 0:
12654 case SWM16 + 1:
12655 case SWM16 + 2:
12656 case SWM16 + 3:
12657 {
12658 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12659 int offset = ZIMM(ctx->opcode, 0, 4);
12660
12661 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12662 29, offset << 2);
12663 }
12664 break;
12665 case JR16 + 0:
12666 case JR16 + 1:
12667 {
12668 int reg = ctx->opcode & 0x1f;
12669
b231c103 12670 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12671 }
3c824109
NF
12672 break;
12673 case JRC16 + 0:
12674 case JRC16 + 1:
12675 {
12676 int reg = ctx->opcode & 0x1f;
b231c103 12677 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12678 /* Let normal delay slot handling in our caller take us
12679 to the branch target. */
12680 }
12681 break;
12682 case JALR16 + 0:
12683 case JALR16 + 1:
b231c103
YK
12684 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12685 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12686 break;
3c824109
NF
12687 case JALR16S + 0:
12688 case JALR16S + 1:
b231c103
YK
12689 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12690 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12691 break;
12692 case MFHI16 + 0:
12693 case MFHI16 + 1:
26135ead 12694 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12695 break;
12696 case MFLO16 + 0:
12697 case MFLO16 + 1:
26135ead 12698 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12699 break;
12700 case BREAK16:
9c708c7f 12701 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
12702 break;
12703 case SDBBP16:
3b3c1694
LA
12704 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12705 gen_helper_do_semihosting(cpu_env);
12706 } else {
12707 /* XXX: not clear which exception should be raised
12708 * when in debug mode...
12709 */
12710 check_insn(ctx, ISA_MIPS32);
9c708c7f 12711 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12712 }
3c824109
NF
12713 break;
12714 case JRADDIUSP + 0:
12715 case JRADDIUSP + 1:
12716 {
12717 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12718 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12719 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12720 /* Let normal delay slot handling in our caller take us
12721 to the branch target. */
12722 }
12723 break;
12724 default:
9c708c7f 12725 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12726 break;
12727 }
12728}
12729
ed7ce6c0
YK
12730static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12731 int enc_rs)
12732{
12733 int rd, rs, re, rt;
12734 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12735 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12736 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12737 rd = rd_enc[enc_dest];
12738 re = re_enc[enc_dest];
12739 rs = rs_rt_enc[enc_rs];
12740 rt = rs_rt_enc[enc_rt];
12741 if (rs) {
12742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12743 } else {
12744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12745 }
12746 if (rt) {
12747 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12748 } else {
12749 tcg_gen_movi_tl(cpu_gpr[re], 0);
12750 }
12751}
12752
12753static void gen_pool16c_r6_insn(DisasContext *ctx)
12754{
12755 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12756 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12757
12758 switch (ctx->opcode & 0xf) {
12759 case R6_NOT16:
12760 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12761 break;
12762 case R6_AND16:
12763 gen_logic(ctx, OPC_AND, rt, rt, rs);
12764 break;
12765 case R6_LWM16:
12766 {
12767 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12768 int offset = extract32(ctx->opcode, 4, 4);
12769 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12770 }
12771 break;
12772 case R6_JRC16: /* JRCADDIUSP */
12773 if ((ctx->opcode >> 4) & 1) {
12774 /* JRCADDIUSP */
12775 int imm = extract32(ctx->opcode, 5, 5);
12776 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12777 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12778 } else {
12779 /* JRC16 */
12780 int rs = extract32(ctx->opcode, 5, 5);
12781 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12782 }
12783 break;
12784 case MOVEP ... MOVEP_07:
12785 case MOVEP_0C ... MOVEP_0F:
12786 {
12787 int enc_dest = uMIPS_RD(ctx->opcode);
12788 int enc_rt = uMIPS_RS2(ctx->opcode);
12789 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12790 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12791 }
12792 break;
12793 case R6_XOR16:
12794 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12795 break;
12796 case R6_OR16:
12797 gen_logic(ctx, OPC_OR, rt, rt, rs);
12798 break;
12799 case R6_SWM16:
12800 {
12801 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12802 int offset = extract32(ctx->opcode, 4, 4);
12803 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12804 }
12805 break;
12806 case JALRC16: /* BREAK16, SDBBP16 */
12807 switch (ctx->opcode & 0x3f) {
12808 case JALRC16:
12809 case JALRC16 + 0x20:
12810 /* JALRC16 */
12811 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12812 31, 0, 0);
12813 break;
12814 case R6_BREAK16:
12815 /* BREAK16 */
12816 generate_exception(ctx, EXCP_BREAK);
12817 break;
12818 case R6_SDBBP16:
12819 /* SDBBP16 */
060ebfef
LA
12820 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12821 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 12822 } else {
060ebfef
LA
12823 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12824 generate_exception(ctx, EXCP_RI);
12825 } else {
12826 generate_exception(ctx, EXCP_DBp);
12827 }
ed7ce6c0
YK
12828 }
12829 break;
12830 }
12831 break;
12832 default:
12833 generate_exception(ctx, EXCP_RI);
12834 break;
12835 }
12836}
12837
3c824109
NF
12838static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12839{
12840 TCGv t0 = tcg_temp_new();
12841 TCGv t1 = tcg_temp_new();
12842
12843 gen_load_gpr(t0, base);
12844
12845 if (index != 0) {
12846 gen_load_gpr(t1, index);
12847 tcg_gen_shli_tl(t1, t1, 2);
12848 gen_op_addr_add(ctx, t0, t1, t0);
12849 }
12850
5f68f5ae 12851 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12852 gen_store_gpr(t1, rd);
12853
12854 tcg_temp_free(t0);
12855 tcg_temp_free(t1);
12856}
12857
12858static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12859 int base, int16_t offset)
12860{
3c824109
NF
12861 TCGv t0, t1;
12862
36c6711b 12863 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 12864 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
12865 return;
12866 }
12867
3c824109
NF
12868 t0 = tcg_temp_new();
12869 t1 = tcg_temp_new();
8e9ade68 12870
3c824109
NF
12871 gen_base_offset_addr(ctx, t0, base, offset);
12872
12873 switch (opc) {
12874 case LWP:
36c6711b 12875 if (rd == base) {
9c708c7f 12876 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
12877 return;
12878 }
5f68f5ae 12879 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12880 gen_store_gpr(t1, rd);
12881 tcg_gen_movi_tl(t1, 4);
12882 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12883 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 12884 gen_store_gpr(t1, rd+1);
3c824109
NF
12885 break;
12886 case SWP:
3c824109 12887 gen_load_gpr(t1, rd);
5f68f5ae 12888 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12889 tcg_gen_movi_tl(t1, 4);
12890 gen_op_addr_add(ctx, t0, t0, t1);
12891 gen_load_gpr(t1, rd+1);
5f68f5ae 12892 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12893 break;
12894#ifdef TARGET_MIPS64
12895 case LDP:
36c6711b 12896 if (rd == base) {
9c708c7f 12897 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
12898 return;
12899 }
5f68f5ae 12900 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12901 gen_store_gpr(t1, rd);
12902 tcg_gen_movi_tl(t1, 8);
12903 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12904 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 12905 gen_store_gpr(t1, rd+1);
3c824109
NF
12906 break;
12907 case SDP:
3c824109 12908 gen_load_gpr(t1, rd);
5f68f5ae 12909 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12910 tcg_gen_movi_tl(t1, 8);
12911 gen_op_addr_add(ctx, t0, t0, t1);
12912 gen_load_gpr(t1, rd+1);
5f68f5ae 12913 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12914 break;
12915#endif
6af0bf9c 12916 }
3c824109
NF
12917 tcg_temp_free(t0);
12918 tcg_temp_free(t1);
12919}
618b0fe9 12920
240ce26a 12921static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12922{
12923 int extension = (ctx->opcode >> 6) & 0x3f;
12924 int minor = (ctx->opcode >> 12) & 0xf;
12925 uint32_t mips32_op;
12926
12927 switch (extension) {
12928 case TEQ:
12929 mips32_op = OPC_TEQ;
12930 goto do_trap;
12931 case TGE:
12932 mips32_op = OPC_TGE;
12933 goto do_trap;
12934 case TGEU:
12935 mips32_op = OPC_TGEU;
12936 goto do_trap;
12937 case TLT:
12938 mips32_op = OPC_TLT;
12939 goto do_trap;
12940 case TLTU:
12941 mips32_op = OPC_TLTU;
12942 goto do_trap;
12943 case TNE:
12944 mips32_op = OPC_TNE;
12945 do_trap:
12946 gen_trap(ctx, mips32_op, rs, rt, -1);
12947 break;
12948#ifndef CONFIG_USER_ONLY
12949 case MFC0:
12950 case MFC0 + 32:
2e15497c 12951 check_cp0_enabled(ctx);
3c824109
NF
12952 if (rt == 0) {
12953 /* Treat as NOP. */
12954 break;
12955 }
d75c135e 12956 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12957 break;
12958 case MTC0:
12959 case MTC0 + 32:
2e15497c 12960 check_cp0_enabled(ctx);
3c824109
NF
12961 {
12962 TCGv t0 = tcg_temp_new();
618b0fe9 12963
3c824109 12964 gen_load_gpr(t0, rt);
d75c135e 12965 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12966 tcg_temp_free(t0);
12967 }
12968 break;
12969#endif
a1fc6246
LA
12970 case 0x2a:
12971 switch (minor & 3) {
12972 case MADD_ACC:
12973 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12974 break;
12975 case MADDU_ACC:
12976 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12977 break;
12978 case MSUB_ACC:
12979 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12980 break;
12981 case MSUBU_ACC:
12982 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12983 break;
12984 default:
12985 goto pool32axf_invalid;
12986 }
12987 break;
12988 case 0x32:
12989 switch (minor & 3) {
12990 case MULT_ACC:
12991 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12992 break;
12993 case MULTU_ACC:
12994 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12995 break;
12996 default:
12997 goto pool32axf_invalid;
12998 }
12999 break;
3c824109
NF
13000 case 0x2c:
13001 switch (minor) {
e0332095
YK
13002 case BITSWAP:
13003 check_insn(ctx, ISA_MIPS32R6);
13004 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13005 break;
3c824109
NF
13006 case SEB:
13007 gen_bshfl(ctx, OPC_SEB, rs, rt);
13008 break;
13009 case SEH:
13010 gen_bshfl(ctx, OPC_SEH, rs, rt);
13011 break;
13012 case CLO:
13013 mips32_op = OPC_CLO;
13014 goto do_cl;
13015 case CLZ:
13016 mips32_op = OPC_CLZ;
13017 do_cl:
d75c135e 13018 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13019 gen_cl(ctx, mips32_op, rt, rs);
13020 break;
13021 case RDHWR:
b00c7218
YK
13022 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13023 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13024 break;
13025 case WSBH:
13026 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13027 break;
13028 case MULT:
9e8f441a 13029 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13030 mips32_op = OPC_MULT;
26135ead 13031 goto do_mul;
3c824109 13032 case MULTU:
9e8f441a 13033 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13034 mips32_op = OPC_MULTU;
26135ead 13035 goto do_mul;
3c824109 13036 case DIV:
9e8f441a 13037 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13038 mips32_op = OPC_DIV;
26135ead 13039 goto do_div;
3c824109 13040 case DIVU:
9e8f441a 13041 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13042 mips32_op = OPC_DIVU;
26135ead
RS
13043 goto do_div;
13044 do_div:
13045 check_insn(ctx, ISA_MIPS32);
13046 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13047 break;
3c824109 13048 case MADD:
9e8f441a 13049 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13050 mips32_op = OPC_MADD;
26135ead 13051 goto do_mul;
3c824109 13052 case MADDU:
9e8f441a 13053 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13054 mips32_op = OPC_MADDU;
26135ead 13055 goto do_mul;
3c824109 13056 case MSUB:
9e8f441a 13057 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13058 mips32_op = OPC_MSUB;
26135ead 13059 goto do_mul;
3c824109 13060 case MSUBU:
9e8f441a 13061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13062 mips32_op = OPC_MSUBU;
26135ead 13063 do_mul:
d75c135e 13064 check_insn(ctx, ISA_MIPS32);
a1fc6246 13065 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13066 break;
13067 default:
13068 goto pool32axf_invalid;
13069 }
13070 break;
13071 case 0x34:
13072 switch (minor) {
13073 case MFC2:
13074 case MTC2:
13075 case MFHC2:
13076 case MTHC2:
13077 case CFC2:
13078 case CTC2:
13079 generate_exception_err(ctx, EXCP_CpU, 2);
13080 break;
13081 default:
13082 goto pool32axf_invalid;
13083 }
13084 break;
13085 case 0x3c:
13086 switch (minor) {
65935f07
YK
13087 case JALR: /* JALRC */
13088 case JALR_HB: /* JALRC_HB */
13089 if (ctx->insn_flags & ISA_MIPS32R6) {
13090 /* JALRC, JALRC_HB */
13091 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13092 } else {
13093 /* JALR, JALR_HB */
13094 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13095 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13096 }
3c824109
NF
13097 break;
13098 case JALRS:
13099 case JALRS_HB:
9e8f441a 13100 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13101 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13102 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13103 break;
13104 default:
13105 goto pool32axf_invalid;
13106 }
13107 break;
13108 case 0x05:
13109 switch (minor) {
13110 case RDPGPR:
2e15497c 13111 check_cp0_enabled(ctx);
d75c135e 13112 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13113 gen_load_srsgpr(rs, rt);
3c824109
NF
13114 break;
13115 case WRPGPR:
2e15497c 13116 check_cp0_enabled(ctx);
d75c135e 13117 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13118 gen_store_srsgpr(rs, rt);
3c824109
NF
13119 break;
13120 default:
13121 goto pool32axf_invalid;
13122 }
13123 break;
13124#ifndef CONFIG_USER_ONLY
13125 case 0x0d:
13126 switch (minor) {
13127 case TLBP:
13128 mips32_op = OPC_TLBP;
13129 goto do_cp0;
13130 case TLBR:
13131 mips32_op = OPC_TLBR;
13132 goto do_cp0;
13133 case TLBWI:
13134 mips32_op = OPC_TLBWI;
13135 goto do_cp0;
13136 case TLBWR:
13137 mips32_op = OPC_TLBWR;
13138 goto do_cp0;
e60ec063
YK
13139 case TLBINV:
13140 mips32_op = OPC_TLBINV;
13141 goto do_cp0;
13142 case TLBINVF:
13143 mips32_op = OPC_TLBINVF;
13144 goto do_cp0;
3c824109
NF
13145 case WAIT:
13146 mips32_op = OPC_WAIT;
13147 goto do_cp0;
13148 case DERET:
13149 mips32_op = OPC_DERET;
13150 goto do_cp0;
13151 case ERET:
13152 mips32_op = OPC_ERET;
13153 do_cp0:
13154 gen_cp0(env, ctx, mips32_op, rt, rs);
13155 break;
13156 default:
13157 goto pool32axf_invalid;
13158 }
13159 break;
13160 case 0x1d:
13161 switch (minor) {
13162 case DI:
2e15497c 13163 check_cp0_enabled(ctx);
3c824109
NF
13164 {
13165 TCGv t0 = tcg_temp_new();
13166
13167 save_cpu_state(ctx, 1);
895c2d04 13168 gen_helper_di(t0, cpu_env);
3c824109
NF
13169 gen_store_gpr(t0, rs);
13170 /* Stop translation as we may have switched the execution mode */
13171 ctx->bstate = BS_STOP;
13172 tcg_temp_free(t0);
13173 }
13174 break;
13175 case EI:
2e15497c 13176 check_cp0_enabled(ctx);
3c824109
NF
13177 {
13178 TCGv t0 = tcg_temp_new();
13179
13180 save_cpu_state(ctx, 1);
895c2d04 13181 gen_helper_ei(t0, cpu_env);
3c824109
NF
13182 gen_store_gpr(t0, rs);
13183 /* Stop translation as we may have switched the execution mode */
13184 ctx->bstate = BS_STOP;
13185 tcg_temp_free(t0);
13186 }
13187 break;
13188 default:
13189 goto pool32axf_invalid;
13190 }
13191 break;
13192#endif
13193 case 0x2d:
13194 switch (minor) {
13195 case SYNC:
13196 /* NOP */
13197 break;
13198 case SYSCALL:
9c708c7f 13199 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13200 break;
13201 case SDBBP:
3b3c1694
LA
13202 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13203 gen_helper_do_semihosting(cpu_env);
13204 } else {
13205 check_insn(ctx, ISA_MIPS32);
e0332095 13206 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13207 generate_exception_end(ctx, EXCP_RI);
e0332095 13208 } else {
9c708c7f 13209 generate_exception_end(ctx, EXCP_DBp);
e0332095 13210 }
3b3c1694 13211 }
3c824109
NF
13212 break;
13213 default:
13214 goto pool32axf_invalid;
13215 }
13216 break;
a1fc6246 13217 case 0x01:
26135ead 13218 switch (minor & 3) {
a1fc6246 13219 case MFHI_ACC:
26135ead 13220 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13221 break;
a1fc6246 13222 case MFLO_ACC:
26135ead 13223 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13224 break;
a1fc6246 13225 case MTHI_ACC:
26135ead 13226 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13227 break;
a1fc6246 13228 case MTLO_ACC:
26135ead 13229 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13230 break;
13231 default:
13232 goto pool32axf_invalid;
13233 }
13234 break;
a1fc6246 13235 case 0x35:
9e8f441a 13236 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13237 switch (minor) {
13238 case MFHI32:
13239 gen_HILO(ctx, OPC_MFHI, 0, rs);
13240 break;
13241 case MFLO32:
13242 gen_HILO(ctx, OPC_MFLO, 0, rs);
13243 break;
13244 case MTHI32:
13245 gen_HILO(ctx, OPC_MTHI, 0, rs);
13246 break;
13247 case MTLO32:
13248 gen_HILO(ctx, OPC_MTLO, 0, rs);
13249 break;
13250 default:
13251 goto pool32axf_invalid;
13252 }
13253 break;
3c824109
NF
13254 default:
13255 pool32axf_invalid:
13256 MIPS_INVAL("pool32axf");
9c708c7f 13257 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13258 break;
13259 }
13260}
13261
13262/* Values for microMIPS fmt field. Variable-width, depending on which
13263 formats the instruction supports. */
13264
13265enum {
13266 FMT_SD_S = 0,
13267 FMT_SD_D = 1,
13268
13269 FMT_SDPS_S = 0,
13270 FMT_SDPS_D = 1,
13271 FMT_SDPS_PS = 2,
13272
13273 FMT_SWL_S = 0,
13274 FMT_SWL_W = 1,
13275 FMT_SWL_L = 2,
13276
13277 FMT_DWL_D = 0,
13278 FMT_DWL_W = 1,
13279 FMT_DWL_L = 2
13280};
13281
d75c135e 13282static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13283{
13284 int extension = (ctx->opcode >> 6) & 0x3ff;
13285 uint32_t mips32_op;
13286
13287#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13288#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13289#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13290
13291 switch (extension) {
13292 case FLOAT_1BIT_FMT(CFC1, 0):
13293 mips32_op = OPC_CFC1;
13294 goto do_cp1;
13295 case FLOAT_1BIT_FMT(CTC1, 0):
13296 mips32_op = OPC_CTC1;
13297 goto do_cp1;
13298 case FLOAT_1BIT_FMT(MFC1, 0):
13299 mips32_op = OPC_MFC1;
13300 goto do_cp1;
13301 case FLOAT_1BIT_FMT(MTC1, 0):
13302 mips32_op = OPC_MTC1;
13303 goto do_cp1;
13304 case FLOAT_1BIT_FMT(MFHC1, 0):
13305 mips32_op = OPC_MFHC1;
13306 goto do_cp1;
13307 case FLOAT_1BIT_FMT(MTHC1, 0):
13308 mips32_op = OPC_MTHC1;
13309 do_cp1:
13310 gen_cp1(ctx, mips32_op, rt, rs);
13311 break;
13312
13313 /* Reciprocal square root */
13314 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13315 mips32_op = OPC_RSQRT_S;
13316 goto do_unaryfp;
13317 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13318 mips32_op = OPC_RSQRT_D;
13319 goto do_unaryfp;
13320
13321 /* Square root */
13322 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13323 mips32_op = OPC_SQRT_S;
13324 goto do_unaryfp;
13325 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13326 mips32_op = OPC_SQRT_D;
13327 goto do_unaryfp;
13328
13329 /* Reciprocal */
13330 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13331 mips32_op = OPC_RECIP_S;
13332 goto do_unaryfp;
13333 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13334 mips32_op = OPC_RECIP_D;
13335 goto do_unaryfp;
13336
13337 /* Floor */
13338 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13339 mips32_op = OPC_FLOOR_L_S;
13340 goto do_unaryfp;
13341 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13342 mips32_op = OPC_FLOOR_L_D;
13343 goto do_unaryfp;
13344 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13345 mips32_op = OPC_FLOOR_W_S;
13346 goto do_unaryfp;
13347 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13348 mips32_op = OPC_FLOOR_W_D;
13349 goto do_unaryfp;
13350
13351 /* Ceiling */
13352 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13353 mips32_op = OPC_CEIL_L_S;
13354 goto do_unaryfp;
13355 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13356 mips32_op = OPC_CEIL_L_D;
13357 goto do_unaryfp;
13358 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13359 mips32_op = OPC_CEIL_W_S;
13360 goto do_unaryfp;
13361 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13362 mips32_op = OPC_CEIL_W_D;
13363 goto do_unaryfp;
13364
13365 /* Truncation */
13366 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13367 mips32_op = OPC_TRUNC_L_S;
13368 goto do_unaryfp;
13369 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13370 mips32_op = OPC_TRUNC_L_D;
13371 goto do_unaryfp;
13372 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13373 mips32_op = OPC_TRUNC_W_S;
13374 goto do_unaryfp;
13375 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13376 mips32_op = OPC_TRUNC_W_D;
13377 goto do_unaryfp;
13378
13379 /* Round */
13380 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13381 mips32_op = OPC_ROUND_L_S;
13382 goto do_unaryfp;
13383 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13384 mips32_op = OPC_ROUND_L_D;
13385 goto do_unaryfp;
13386 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13387 mips32_op = OPC_ROUND_W_S;
13388 goto do_unaryfp;
13389 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13390 mips32_op = OPC_ROUND_W_D;
13391 goto do_unaryfp;
13392
13393 /* Integer to floating-point conversion */
13394 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13395 mips32_op = OPC_CVT_L_S;
13396 goto do_unaryfp;
13397 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13398 mips32_op = OPC_CVT_L_D;
13399 goto do_unaryfp;
13400 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13401 mips32_op = OPC_CVT_W_S;
13402 goto do_unaryfp;
13403 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13404 mips32_op = OPC_CVT_W_D;
13405 goto do_unaryfp;
13406
13407 /* Paired-foo conversions */
13408 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13409 mips32_op = OPC_CVT_S_PL;
13410 goto do_unaryfp;
13411 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13412 mips32_op = OPC_CVT_S_PU;
13413 goto do_unaryfp;
13414 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13415 mips32_op = OPC_CVT_PW_PS;
13416 goto do_unaryfp;
13417 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13418 mips32_op = OPC_CVT_PS_PW;
13419 goto do_unaryfp;
13420
13421 /* Floating-point moves */
13422 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13423 mips32_op = OPC_MOV_S;
13424 goto do_unaryfp;
13425 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13426 mips32_op = OPC_MOV_D;
13427 goto do_unaryfp;
13428 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13429 mips32_op = OPC_MOV_PS;
13430 goto do_unaryfp;
13431
13432 /* Absolute value */
13433 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13434 mips32_op = OPC_ABS_S;
13435 goto do_unaryfp;
13436 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13437 mips32_op = OPC_ABS_D;
13438 goto do_unaryfp;
13439 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13440 mips32_op = OPC_ABS_PS;
13441 goto do_unaryfp;
13442
13443 /* Negation */
13444 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13445 mips32_op = OPC_NEG_S;
13446 goto do_unaryfp;
13447 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13448 mips32_op = OPC_NEG_D;
13449 goto do_unaryfp;
13450 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13451 mips32_op = OPC_NEG_PS;
13452 goto do_unaryfp;
13453
13454 /* Reciprocal square root step */
13455 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13456 mips32_op = OPC_RSQRT1_S;
13457 goto do_unaryfp;
13458 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13459 mips32_op = OPC_RSQRT1_D;
13460 goto do_unaryfp;
13461 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13462 mips32_op = OPC_RSQRT1_PS;
13463 goto do_unaryfp;
13464
13465 /* Reciprocal step */
13466 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13467 mips32_op = OPC_RECIP1_S;
13468 goto do_unaryfp;
13469 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13470 mips32_op = OPC_RECIP1_S;
13471 goto do_unaryfp;
13472 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13473 mips32_op = OPC_RECIP1_PS;
13474 goto do_unaryfp;
13475
13476 /* Conversions from double */
13477 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13478 mips32_op = OPC_CVT_D_S;
13479 goto do_unaryfp;
13480 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13481 mips32_op = OPC_CVT_D_W;
13482 goto do_unaryfp;
13483 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13484 mips32_op = OPC_CVT_D_L;
13485 goto do_unaryfp;
13486
13487 /* Conversions from single */
13488 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13489 mips32_op = OPC_CVT_S_D;
13490 goto do_unaryfp;
13491 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13492 mips32_op = OPC_CVT_S_W;
13493 goto do_unaryfp;
13494 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13495 mips32_op = OPC_CVT_S_L;
13496 do_unaryfp:
13497 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13498 break;
13499
13500 /* Conditional moves on floating-point codes */
13501 case COND_FLOAT_MOV(MOVT, 0):
13502 case COND_FLOAT_MOV(MOVT, 1):
13503 case COND_FLOAT_MOV(MOVT, 2):
13504 case COND_FLOAT_MOV(MOVT, 3):
13505 case COND_FLOAT_MOV(MOVT, 4):
13506 case COND_FLOAT_MOV(MOVT, 5):
13507 case COND_FLOAT_MOV(MOVT, 6):
13508 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13509 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13510 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13511 break;
13512 case COND_FLOAT_MOV(MOVF, 0):
13513 case COND_FLOAT_MOV(MOVF, 1):
13514 case COND_FLOAT_MOV(MOVF, 2):
13515 case COND_FLOAT_MOV(MOVF, 3):
13516 case COND_FLOAT_MOV(MOVF, 4):
13517 case COND_FLOAT_MOV(MOVF, 5):
13518 case COND_FLOAT_MOV(MOVF, 6):
13519 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13521 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13522 break;
13523 default:
13524 MIPS_INVAL("pool32fxf");
9c708c7f 13525 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13526 break;
13527 }
13528}
13529
f60eeb0c 13530static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13531{
13532 int32_t offset;
13533 uint16_t insn;
13534 int rt, rs, rd, rr;
13535 int16_t imm;
13536 uint32_t op, minor, mips32_op;
13537 uint32_t cond, fmt, cc;
13538
895c2d04 13539 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13540 ctx->opcode = (ctx->opcode << 16) | insn;
13541
13542 rt = (ctx->opcode >> 21) & 0x1f;
13543 rs = (ctx->opcode >> 16) & 0x1f;
13544 rd = (ctx->opcode >> 11) & 0x1f;
13545 rr = (ctx->opcode >> 6) & 0x1f;
13546 imm = (int16_t) ctx->opcode;
13547
13548 op = (ctx->opcode >> 26) & 0x3f;
13549 switch (op) {
13550 case POOL32A:
13551 minor = ctx->opcode & 0x3f;
13552 switch (minor) {
13553 case 0x00:
13554 minor = (ctx->opcode >> 6) & 0xf;
13555 switch (minor) {
13556 case SLL32:
13557 mips32_op = OPC_SLL;
13558 goto do_shifti;
13559 case SRA:
13560 mips32_op = OPC_SRA;
13561 goto do_shifti;
13562 case SRL32:
13563 mips32_op = OPC_SRL;
13564 goto do_shifti;
13565 case ROTR:
13566 mips32_op = OPC_ROTR;
13567 do_shifti:
d75c135e 13568 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13569 break;
e0332095
YK
13570 case SELEQZ:
13571 check_insn(ctx, ISA_MIPS32R6);
13572 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13573 break;
13574 case SELNEZ:
13575 check_insn(ctx, ISA_MIPS32R6);
13576 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13577 break;
b00c7218
YK
13578 case R6_RDHWR:
13579 check_insn(ctx, ISA_MIPS32R6);
13580 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13581 break;
3c824109
NF
13582 default:
13583 goto pool32a_invalid;
13584 }
13585 break;
13586 case 0x10:
13587 minor = (ctx->opcode >> 6) & 0xf;
13588 switch (minor) {
13589 /* Arithmetic */
13590 case ADD:
13591 mips32_op = OPC_ADD;
13592 goto do_arith;
13593 case ADDU32:
13594 mips32_op = OPC_ADDU;
13595 goto do_arith;
13596 case SUB:
13597 mips32_op = OPC_SUB;
13598 goto do_arith;
13599 case SUBU32:
13600 mips32_op = OPC_SUBU;
13601 goto do_arith;
13602 case MUL:
9e8f441a 13603 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13604 mips32_op = OPC_MUL;
13605 do_arith:
d75c135e 13606 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13607 break;
13608 /* Shifts */
13609 case SLLV:
13610 mips32_op = OPC_SLLV;
13611 goto do_shift;
13612 case SRLV:
13613 mips32_op = OPC_SRLV;
13614 goto do_shift;
13615 case SRAV:
13616 mips32_op = OPC_SRAV;
13617 goto do_shift;
13618 case ROTRV:
13619 mips32_op = OPC_ROTRV;
13620 do_shift:
d75c135e 13621 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13622 break;
13623 /* Logical operations */
13624 case AND:
13625 mips32_op = OPC_AND;
13626 goto do_logic;
13627 case OR32:
13628 mips32_op = OPC_OR;
13629 goto do_logic;
13630 case NOR:
13631 mips32_op = OPC_NOR;
13632 goto do_logic;
13633 case XOR32:
13634 mips32_op = OPC_XOR;
13635 do_logic:
d75c135e 13636 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13637 break;
13638 /* Set less than */
13639 case SLT:
13640 mips32_op = OPC_SLT;
13641 goto do_slt;
13642 case SLTU:
13643 mips32_op = OPC_SLTU;
13644 do_slt:
d75c135e 13645 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13646 break;
13647 default:
13648 goto pool32a_invalid;
13649 }
13650 break;
13651 case 0x18:
13652 minor = (ctx->opcode >> 6) & 0xf;
13653 switch (minor) {
13654 /* Conditional moves */
e0332095
YK
13655 case MOVN: /* MUL */
13656 if (ctx->insn_flags & ISA_MIPS32R6) {
13657 /* MUL */
13658 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13659 } else {
13660 /* MOVN */
13661 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13662 }
13663 break;
13664 case MOVZ: /* MUH */
13665 if (ctx->insn_flags & ISA_MIPS32R6) {
13666 /* MUH */
13667 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13668 } else {
13669 /* MOVZ */
13670 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13671 }
13672 break;
13673 case MULU:
13674 check_insn(ctx, ISA_MIPS32R6);
13675 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13676 break;
13677 case MUHU:
13678 check_insn(ctx, ISA_MIPS32R6);
13679 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13680 break;
13681 case LWXS: /* DIV */
13682 if (ctx->insn_flags & ISA_MIPS32R6) {
13683 /* DIV */
13684 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13685 } else {
13686 /* LWXS */
13687 gen_ldxs(ctx, rs, rt, rd);
13688 }
13689 break;
13690 case MOD:
13691 check_insn(ctx, ISA_MIPS32R6);
13692 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13693 break;
13694 case R6_DIVU:
13695 check_insn(ctx, ISA_MIPS32R6);
13696 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 13697 break;
e0332095
YK
13698 case MODU:
13699 check_insn(ctx, ISA_MIPS32R6);
13700 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
13701 break;
13702 default:
13703 goto pool32a_invalid;
13704 }
13705 break;
13706 case INS:
13707 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13708 return;
e0332095
YK
13709 case LSA:
13710 check_insn(ctx, ISA_MIPS32R6);
13711 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13712 extract32(ctx->opcode, 9, 2));
13713 break;
13714 case ALIGN:
13715 check_insn(ctx, ISA_MIPS32R6);
13716 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13717 extract32(ctx->opcode, 9, 2));
13718 break;
3c824109
NF
13719 case EXT:
13720 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13721 return;
13722 case POOL32AXF:
240ce26a 13723 gen_pool32axf(env, ctx, rt, rs);
3c824109 13724 break;
dbd8af98 13725 case BREAK32:
9c708c7f 13726 generate_exception_end(ctx, EXCP_BREAK);
3c824109 13727 break;
bb238210
YK
13728 case SIGRIE:
13729 check_insn(ctx, ISA_MIPS32R6);
13730 generate_exception_end(ctx, EXCP_RI);
13731 break;
3c824109
NF
13732 default:
13733 pool32a_invalid:
13734 MIPS_INVAL("pool32a");
9c708c7f 13735 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13736 break;
13737 }
13738 break;
13739 case POOL32B:
13740 minor = (ctx->opcode >> 12) & 0xf;
13741 switch (minor) {
13742 case CACHE:
2e15497c 13743 check_cp0_enabled(ctx);
3c824109
NF
13744 /* Treat as no-op. */
13745 break;
13746 case LWC2:
13747 case SWC2:
13748 /* COP2: Not implemented. */
13749 generate_exception_err(ctx, EXCP_CpU, 2);
13750 break;
3c824109
NF
13751#ifdef TARGET_MIPS64
13752 case LDP:
13753 case SDP:
d9224450
MR
13754 check_insn(ctx, ISA_MIPS3);
13755 check_mips_64(ctx);
13756 /* Fallthrough */
3c824109 13757#endif
d9224450
MR
13758 case LWP:
13759 case SWP:
3c824109
NF
13760 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13761 break;
3c824109
NF
13762#ifdef TARGET_MIPS64
13763 case LDM:
13764 case SDM:
d9224450
MR
13765 check_insn(ctx, ISA_MIPS3);
13766 check_mips_64(ctx);
13767 /* Fallthrough */
3c824109 13768#endif
d9224450
MR
13769 case LWM32:
13770 case SWM32:
3c824109
NF
13771 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13772 break;
13773 default:
13774 MIPS_INVAL("pool32b");
9c708c7f 13775 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13776 break;
13777 }
13778 break;
13779 case POOL32F:
5ab5c041 13780 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13781 minor = ctx->opcode & 0x3f;
13782 check_cp1_enabled(ctx);
13783 switch (minor) {
13784 case ALNV_PS:
9e8f441a 13785 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13786 mips32_op = OPC_ALNV_PS;
13787 goto do_madd;
13788 case MADD_S:
9e8f441a 13789 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13790 mips32_op = OPC_MADD_S;
13791 goto do_madd;
13792 case MADD_D:
9e8f441a 13793 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13794 mips32_op = OPC_MADD_D;
13795 goto do_madd;
13796 case MADD_PS:
9e8f441a 13797 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13798 mips32_op = OPC_MADD_PS;
13799 goto do_madd;
13800 case MSUB_S:
9e8f441a 13801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13802 mips32_op = OPC_MSUB_S;
13803 goto do_madd;
13804 case MSUB_D:
9e8f441a 13805 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13806 mips32_op = OPC_MSUB_D;
13807 goto do_madd;
13808 case MSUB_PS:
9e8f441a 13809 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13810 mips32_op = OPC_MSUB_PS;
13811 goto do_madd;
13812 case NMADD_S:
9e8f441a 13813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13814 mips32_op = OPC_NMADD_S;
13815 goto do_madd;
13816 case NMADD_D:
9e8f441a 13817 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13818 mips32_op = OPC_NMADD_D;
13819 goto do_madd;
13820 case NMADD_PS:
9e8f441a 13821 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13822 mips32_op = OPC_NMADD_PS;
13823 goto do_madd;
13824 case NMSUB_S:
9e8f441a 13825 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13826 mips32_op = OPC_NMSUB_S;
13827 goto do_madd;
13828 case NMSUB_D:
9e8f441a 13829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13830 mips32_op = OPC_NMSUB_D;
13831 goto do_madd;
13832 case NMSUB_PS:
9e8f441a 13833 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13834 mips32_op = OPC_NMSUB_PS;
13835 do_madd:
13836 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13837 break;
13838 case CABS_COND_FMT:
9e8f441a 13839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13840 cond = (ctx->opcode >> 6) & 0xf;
13841 cc = (ctx->opcode >> 13) & 0x7;
13842 fmt = (ctx->opcode >> 10) & 0x3;
13843 switch (fmt) {
13844 case 0x0:
13845 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13846 break;
13847 case 0x1:
13848 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13849 break;
13850 case 0x2:
13851 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13852 break;
13853 default:
13854 goto pool32f_invalid;
13855 }
13856 break;
13857 case C_COND_FMT:
9e8f441a 13858 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13859 cond = (ctx->opcode >> 6) & 0xf;
13860 cc = (ctx->opcode >> 13) & 0x7;
13861 fmt = (ctx->opcode >> 10) & 0x3;
13862 switch (fmt) {
13863 case 0x0:
13864 gen_cmp_s(ctx, cond, rt, rs, cc);
13865 break;
13866 case 0x1:
13867 gen_cmp_d(ctx, cond, rt, rs, cc);
13868 break;
13869 case 0x2:
13870 gen_cmp_ps(ctx, cond, rt, rs, cc);
13871 break;
13872 default:
13873 goto pool32f_invalid;
13874 }
13875 break;
2a24a7ba
YK
13876 case CMP_CONDN_S:
13877 check_insn(ctx, ISA_MIPS32R6);
13878 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13879 break;
13880 case CMP_CONDN_D:
13881 check_insn(ctx, ISA_MIPS32R6);
13882 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13883 break;
3c824109 13884 case POOL32FXF:
d75c135e 13885 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13886 break;
13887 case 0x00:
13888 /* PLL foo */
13889 switch ((ctx->opcode >> 6) & 0x7) {
13890 case PLL_PS:
13891 mips32_op = OPC_PLL_PS;
13892 goto do_ps;
13893 case PLU_PS:
13894 mips32_op = OPC_PLU_PS;
13895 goto do_ps;
13896 case PUL_PS:
13897 mips32_op = OPC_PUL_PS;
13898 goto do_ps;
13899 case PUU_PS:
13900 mips32_op = OPC_PUU_PS;
13901 goto do_ps;
13902 case CVT_PS_S:
9e8f441a 13903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13904 mips32_op = OPC_CVT_PS_S;
13905 do_ps:
13906 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13907 break;
13908 default:
13909 goto pool32f_invalid;
13910 }
13911 break;
2a24a7ba
YK
13912 case MIN_FMT:
13913 check_insn(ctx, ISA_MIPS32R6);
13914 switch ((ctx->opcode >> 9) & 0x3) {
13915 case FMT_SDPS_S:
13916 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13917 break;
13918 case FMT_SDPS_D:
13919 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13920 break;
13921 default:
13922 goto pool32f_invalid;
13923 }
13924 break;
3c824109
NF
13925 case 0x08:
13926 /* [LS][WDU]XC1 */
13927 switch ((ctx->opcode >> 6) & 0x7) {
13928 case LWXC1:
9e8f441a 13929 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13930 mips32_op = OPC_LWXC1;
13931 goto do_ldst_cp1;
13932 case SWXC1:
9e8f441a 13933 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13934 mips32_op = OPC_SWXC1;
13935 goto do_ldst_cp1;
13936 case LDXC1:
9e8f441a 13937 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13938 mips32_op = OPC_LDXC1;
13939 goto do_ldst_cp1;
13940 case SDXC1:
9e8f441a 13941 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13942 mips32_op = OPC_SDXC1;
13943 goto do_ldst_cp1;
13944 case LUXC1:
9e8f441a 13945 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13946 mips32_op = OPC_LUXC1;
13947 goto do_ldst_cp1;
13948 case SUXC1:
9e8f441a 13949 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13950 mips32_op = OPC_SUXC1;
13951 do_ldst_cp1:
13952 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13953 break;
13954 default:
13955 goto pool32f_invalid;
13956 }
13957 break;
2a24a7ba
YK
13958 case MAX_FMT:
13959 check_insn(ctx, ISA_MIPS32R6);
13960 switch ((ctx->opcode >> 9) & 0x3) {
13961 case FMT_SDPS_S:
13962 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13963 break;
13964 case FMT_SDPS_D:
13965 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13966 break;
13967 default:
13968 goto pool32f_invalid;
13969 }
13970 break;
3c824109
NF
13971 case 0x18:
13972 /* 3D insns */
9e8f441a 13973 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13974 fmt = (ctx->opcode >> 9) & 0x3;
13975 switch ((ctx->opcode >> 6) & 0x7) {
13976 case RSQRT2_FMT:
13977 switch (fmt) {
13978 case FMT_SDPS_S:
13979 mips32_op = OPC_RSQRT2_S;
13980 goto do_3d;
13981 case FMT_SDPS_D:
13982 mips32_op = OPC_RSQRT2_D;
13983 goto do_3d;
13984 case FMT_SDPS_PS:
13985 mips32_op = OPC_RSQRT2_PS;
13986 goto do_3d;
13987 default:
13988 goto pool32f_invalid;
13989 }
13990 break;
13991 case RECIP2_FMT:
13992 switch (fmt) {
13993 case FMT_SDPS_S:
13994 mips32_op = OPC_RECIP2_S;
13995 goto do_3d;
13996 case FMT_SDPS_D:
13997 mips32_op = OPC_RECIP2_D;
13998 goto do_3d;
13999 case FMT_SDPS_PS:
14000 mips32_op = OPC_RECIP2_PS;
14001 goto do_3d;
14002 default:
14003 goto pool32f_invalid;
14004 }
14005 break;
14006 case ADDR_PS:
14007 mips32_op = OPC_ADDR_PS;
14008 goto do_3d;
14009 case MULR_PS:
14010 mips32_op = OPC_MULR_PS;
14011 do_3d:
14012 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14013 break;
14014 default:
14015 goto pool32f_invalid;
14016 }
14017 break;
14018 case 0x20:
2a24a7ba 14019 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14020 cc = (ctx->opcode >> 13) & 0x7;
14021 fmt = (ctx->opcode >> 9) & 0x3;
14022 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14023 case MOVF_FMT: /* RINT_FMT */
14024 if (ctx->insn_flags & ISA_MIPS32R6) {
14025 /* RINT_FMT */
14026 switch (fmt) {
14027 case FMT_SDPS_S:
14028 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14029 break;
14030 case FMT_SDPS_D:
14031 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14032 break;
14033 default:
14034 goto pool32f_invalid;
14035 }
14036 } else {
14037 /* MOVF_FMT */
14038 switch (fmt) {
14039 case FMT_SDPS_S:
14040 gen_movcf_s(ctx, rs, rt, cc, 0);
14041 break;
14042 case FMT_SDPS_D:
14043 gen_movcf_d(ctx, rs, rt, cc, 0);
14044 break;
14045 case FMT_SDPS_PS:
14046 check_ps(ctx);
14047 gen_movcf_ps(ctx, rs, rt, cc, 0);
14048 break;
14049 default:
14050 goto pool32f_invalid;
14051 }
3c824109
NF
14052 }
14053 break;
2a24a7ba
YK
14054 case MOVT_FMT: /* CLASS_FMT */
14055 if (ctx->insn_flags & ISA_MIPS32R6) {
14056 /* CLASS_FMT */
14057 switch (fmt) {
14058 case FMT_SDPS_S:
14059 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14060 break;
14061 case FMT_SDPS_D:
14062 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14063 break;
14064 default:
14065 goto pool32f_invalid;
14066 }
14067 } else {
14068 /* MOVT_FMT */
14069 switch (fmt) {
14070 case FMT_SDPS_S:
14071 gen_movcf_s(ctx, rs, rt, cc, 1);
14072 break;
14073 case FMT_SDPS_D:
14074 gen_movcf_d(ctx, rs, rt, cc, 1);
14075 break;
14076 case FMT_SDPS_PS:
14077 check_ps(ctx);
14078 gen_movcf_ps(ctx, rs, rt, cc, 1);
14079 break;
14080 default:
14081 goto pool32f_invalid;
14082 }
3c824109
NF
14083 }
14084 break;
14085 case PREFX:
9e8f441a 14086 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14087 break;
14088 default:
14089 goto pool32f_invalid;
14090 }
14091 break;
14092#define FINSN_3ARG_SDPS(prfx) \
14093 switch ((ctx->opcode >> 8) & 0x3) { \
14094 case FMT_SDPS_S: \
14095 mips32_op = OPC_##prfx##_S; \
14096 goto do_fpop; \
14097 case FMT_SDPS_D: \
14098 mips32_op = OPC_##prfx##_D; \
14099 goto do_fpop; \
14100 case FMT_SDPS_PS: \
e29c9628 14101 check_ps(ctx); \
3c824109
NF
14102 mips32_op = OPC_##prfx##_PS; \
14103 goto do_fpop; \
14104 default: \
14105 goto pool32f_invalid; \
14106 }
2a24a7ba
YK
14107 case MINA_FMT:
14108 check_insn(ctx, ISA_MIPS32R6);
14109 switch ((ctx->opcode >> 9) & 0x3) {
14110 case FMT_SDPS_S:
14111 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14112 break;
14113 case FMT_SDPS_D:
14114 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14115 break;
14116 default:
14117 goto pool32f_invalid;
14118 }
14119 break;
14120 case MAXA_FMT:
14121 check_insn(ctx, ISA_MIPS32R6);
14122 switch ((ctx->opcode >> 9) & 0x3) {
14123 case FMT_SDPS_S:
14124 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14125 break;
14126 case FMT_SDPS_D:
14127 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14128 break;
14129 default:
14130 goto pool32f_invalid;
14131 }
14132 break;
3c824109
NF
14133 case 0x30:
14134 /* regular FP ops */
14135 switch ((ctx->opcode >> 6) & 0x3) {
14136 case ADD_FMT:
14137 FINSN_3ARG_SDPS(ADD);
14138 break;
14139 case SUB_FMT:
14140 FINSN_3ARG_SDPS(SUB);
14141 break;
14142 case MUL_FMT:
14143 FINSN_3ARG_SDPS(MUL);
14144 break;
14145 case DIV_FMT:
14146 fmt = (ctx->opcode >> 8) & 0x3;
14147 if (fmt == 1) {
14148 mips32_op = OPC_DIV_D;
14149 } else if (fmt == 0) {
14150 mips32_op = OPC_DIV_S;
14151 } else {
14152 goto pool32f_invalid;
14153 }
14154 goto do_fpop;
14155 default:
14156 goto pool32f_invalid;
14157 }
14158 break;
14159 case 0x38:
14160 /* cmovs */
2a24a7ba
YK
14161 switch ((ctx->opcode >> 6) & 0x7) {
14162 case MOVN_FMT: /* SELNEZ_FMT */
14163 if (ctx->insn_flags & ISA_MIPS32R6) {
14164 /* SELNEZ_FMT */
14165 switch ((ctx->opcode >> 9) & 0x3) {
14166 case FMT_SDPS_S:
14167 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14168 break;
14169 case FMT_SDPS_D:
14170 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14171 break;
14172 default:
14173 goto pool32f_invalid;
14174 }
14175 } else {
14176 /* MOVN_FMT */
14177 FINSN_3ARG_SDPS(MOVN);
14178 }
14179 break;
14180 case MOVN_FMT_04:
14181 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14182 FINSN_3ARG_SDPS(MOVN);
14183 break;
2a24a7ba
YK
14184 case MOVZ_FMT: /* SELEQZ_FMT */
14185 if (ctx->insn_flags & ISA_MIPS32R6) {
14186 /* SELEQZ_FMT */
14187 switch ((ctx->opcode >> 9) & 0x3) {
14188 case FMT_SDPS_S:
14189 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14190 break;
14191 case FMT_SDPS_D:
14192 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14193 break;
14194 default:
14195 goto pool32f_invalid;
14196 }
14197 } else {
14198 /* MOVZ_FMT */
14199 FINSN_3ARG_SDPS(MOVZ);
14200 }
14201 break;
14202 case MOVZ_FMT_05:
14203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14204 FINSN_3ARG_SDPS(MOVZ);
14205 break;
2a24a7ba
YK
14206 case SEL_FMT:
14207 check_insn(ctx, ISA_MIPS32R6);
14208 switch ((ctx->opcode >> 9) & 0x3) {
14209 case FMT_SDPS_S:
14210 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14211 break;
14212 case FMT_SDPS_D:
14213 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14214 break;
14215 default:
14216 goto pool32f_invalid;
14217 }
14218 break;
14219 case MADDF_FMT:
14220 check_insn(ctx, ISA_MIPS32R6);
14221 switch ((ctx->opcode >> 9) & 0x3) {
14222 case FMT_SDPS_S:
14223 mips32_op = OPC_MADDF_S;
14224 goto do_fpop;
14225 case FMT_SDPS_D:
14226 mips32_op = OPC_MADDF_D;
14227 goto do_fpop;
14228 default:
14229 goto pool32f_invalid;
14230 }
14231 break;
14232 case MSUBF_FMT:
14233 check_insn(ctx, ISA_MIPS32R6);
14234 switch ((ctx->opcode >> 9) & 0x3) {
14235 case FMT_SDPS_S:
14236 mips32_op = OPC_MSUBF_S;
14237 goto do_fpop;
14238 case FMT_SDPS_D:
14239 mips32_op = OPC_MSUBF_D;
14240 goto do_fpop;
14241 default:
14242 goto pool32f_invalid;
14243 }
14244 break;
3c824109
NF
14245 default:
14246 goto pool32f_invalid;
14247 }
14248 break;
14249 do_fpop:
14250 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14251 break;
14252 default:
14253 pool32f_invalid:
14254 MIPS_INVAL("pool32f");
9c708c7f 14255 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14256 break;
14257 }
14258 } else {
14259 generate_exception_err(ctx, EXCP_CpU, 1);
14260 }
14261 break;
14262 case POOL32I:
14263 minor = (ctx->opcode >> 21) & 0x1f;
14264 switch (minor) {
14265 case BLTZ:
9e8f441a 14266 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14267 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14268 break;
3c824109 14269 case BLTZAL:
9e8f441a 14270 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14271 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14272 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14273 break;
3c824109 14274 case BLTZALS:
9e8f441a 14275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14276 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14277 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14278 break;
3c824109 14279 case BGEZ:
9e8f441a 14280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14281 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14282 break;
3c824109 14283 case BGEZAL:
9e8f441a 14284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14285 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14286 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14287 break;
3c824109 14288 case BGEZALS:
9e8f441a 14289 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14290 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14291 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14292 break;
3c824109 14293 case BLEZ:
9e8f441a 14294 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14295 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14296 break;
3c824109 14297 case BGTZ:
9e8f441a 14298 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14299 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14300 break;
14301
14302 /* Traps */
65935f07
YK
14303 case TLTI: /* BC1EQZC */
14304 if (ctx->insn_flags & ISA_MIPS32R6) {
14305 /* BC1EQZC */
14306 check_cp1_enabled(ctx);
14307 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14308 } else {
14309 /* TLTI */
14310 mips32_op = OPC_TLTI;
14311 goto do_trapi;
14312 }
14313 break;
14314 case TGEI: /* BC1NEZC */
14315 if (ctx->insn_flags & ISA_MIPS32R6) {
14316 /* BC1NEZC */
14317 check_cp1_enabled(ctx);
14318 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14319 } else {
14320 /* TGEI */
14321 mips32_op = OPC_TGEI;
14322 goto do_trapi;
14323 }
14324 break;
3c824109 14325 case TLTIU:
9e8f441a 14326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14327 mips32_op = OPC_TLTIU;
14328 goto do_trapi;
14329 case TGEIU:
9e8f441a 14330 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14331 mips32_op = OPC_TGEIU;
14332 goto do_trapi;
3b4a5489
YK
14333 case TNEI: /* SYNCI */
14334 if (ctx->insn_flags & ISA_MIPS32R6) {
14335 /* SYNCI */
14336 /* Break the TB to be able to sync copied instructions
14337 immediately */
14338 ctx->bstate = BS_STOP;
14339 } else {
14340 /* TNEI */
14341 mips32_op = OPC_TNEI;
14342 goto do_trapi;
14343 }
14344 break;
3c824109 14345 case TEQI:
9e8f441a 14346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14347 mips32_op = OPC_TEQI;
14348 do_trapi:
14349 gen_trap(ctx, mips32_op, rs, -1, imm);
14350 break;
14351
14352 case BNEZC:
14353 case BEQZC:
9e8f441a 14354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14355 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14356 4, rs, 0, imm << 1, 0);
3c824109
NF
14357 /* Compact branches don't have a delay slot, so just let
14358 the normal delay slot handling take us to the branch
14359 target. */
14360 break;
14361 case LUI:
9e8f441a 14362 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14363 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14364 break;
14365 case SYNCI:
9e8f441a 14366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14367 /* Break the TB to be able to sync copied instructions
14368 immediately */
14369 ctx->bstate = BS_STOP;
3c824109
NF
14370 break;
14371 case BC2F:
14372 case BC2T:
9e8f441a 14373 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14374 /* COP2: Not implemented. */
14375 generate_exception_err(ctx, EXCP_CpU, 2);
14376 break;
14377 case BC1F:
9e8f441a 14378 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14379 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14380 goto do_cp1branch;
14381 case BC1T:
9e8f441a 14382 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14383 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14384 goto do_cp1branch;
14385 case BC1ANY4F:
9e8f441a 14386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14387 mips32_op = OPC_BC1FANY4;
14388 goto do_cp1mips3d;
14389 case BC1ANY4T:
9e8f441a 14390 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14391 mips32_op = OPC_BC1TANY4;
14392 do_cp1mips3d:
14393 check_cop1x(ctx);
d75c135e 14394 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14395 /* Fall through */
14396 do_cp1branch:
272f458d
MR
14397 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14398 check_cp1_enabled(ctx);
14399 gen_compute_branch1(ctx, mips32_op,
14400 (ctx->opcode >> 18) & 0x7, imm << 1);
14401 } else {
14402 generate_exception_err(ctx, EXCP_CpU, 1);
14403 }
3c824109
NF
14404 break;
14405 case BPOSGE64:
14406 case BPOSGE32:
14407 /* MIPS DSP: not implemented */
14408 /* Fall through */
14409 default:
14410 MIPS_INVAL("pool32i");
9c708c7f 14411 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14412 break;
14413 }
14414 break;
14415 case POOL32C:
14416 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14417 offset = sextract32(ctx->opcode, 0,
14418 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14419 switch (minor) {
14420 case LWL:
9e8f441a 14421 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14422 mips32_op = OPC_LWL;
5c13fdfd 14423 goto do_ld_lr;
3c824109 14424 case SWL:
9e8f441a 14425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14426 mips32_op = OPC_SWL;
5c13fdfd 14427 goto do_st_lr;
3c824109 14428 case LWR:
9e8f441a 14429 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14430 mips32_op = OPC_LWR;
5c13fdfd 14431 goto do_ld_lr;
3c824109 14432 case SWR:
9e8f441a 14433 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14434 mips32_op = OPC_SWR;
5c13fdfd 14435 goto do_st_lr;
3c824109
NF
14436#if defined(TARGET_MIPS64)
14437 case LDL:
d9224450
MR
14438 check_insn(ctx, ISA_MIPS3);
14439 check_mips_64(ctx);
9e8f441a 14440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14441 mips32_op = OPC_LDL;
5c13fdfd 14442 goto do_ld_lr;
3c824109 14443 case SDL:
d9224450
MR
14444 check_insn(ctx, ISA_MIPS3);
14445 check_mips_64(ctx);
9e8f441a 14446 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14447 mips32_op = OPC_SDL;
5c13fdfd 14448 goto do_st_lr;
3c824109 14449 case LDR:
d9224450
MR
14450 check_insn(ctx, ISA_MIPS3);
14451 check_mips_64(ctx);
9e8f441a 14452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14453 mips32_op = OPC_LDR;
5c13fdfd 14454 goto do_ld_lr;
3c824109 14455 case SDR:
d9224450
MR
14456 check_insn(ctx, ISA_MIPS3);
14457 check_mips_64(ctx);
9e8f441a 14458 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14459 mips32_op = OPC_SDR;
5c13fdfd 14460 goto do_st_lr;
3c824109 14461 case LWU:
d9224450
MR
14462 check_insn(ctx, ISA_MIPS3);
14463 check_mips_64(ctx);
3c824109 14464 mips32_op = OPC_LWU;
5c13fdfd 14465 goto do_ld_lr;
3c824109 14466 case LLD:
d9224450
MR
14467 check_insn(ctx, ISA_MIPS3);
14468 check_mips_64(ctx);
3c824109 14469 mips32_op = OPC_LLD;
5c13fdfd 14470 goto do_ld_lr;
3c824109
NF
14471#endif
14472 case LL:
14473 mips32_op = OPC_LL;
5c13fdfd
AJ
14474 goto do_ld_lr;
14475 do_ld_lr:
3b4a5489 14476 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14477 break;
14478 do_st_lr:
14479 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14480 break;
14481 case SC:
3b4a5489 14482 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14483 break;
14484#if defined(TARGET_MIPS64)
14485 case SCD:
d9224450
MR
14486 check_insn(ctx, ISA_MIPS3);
14487 check_mips_64(ctx);
3b4a5489 14488 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14489 break;
14490#endif
14491 case PREF:
14492 /* Treat as no-op */
3b4a5489
YK
14493 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14494 /* hint codes 24-31 are reserved and signal RI */
14495 generate_exception(ctx, EXCP_RI);
14496 }
3c824109
NF
14497 break;
14498 default:
14499 MIPS_INVAL("pool32c");
9c708c7f 14500 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14501 break;
14502 }
14503 break;
ab39ee45
YK
14504 case ADDI32: /* AUI, LUI */
14505 if (ctx->insn_flags & ISA_MIPS32R6) {
14506 /* AUI, LUI */
14507 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14508 } else {
14509 /* ADDI32 */
14510 mips32_op = OPC_ADDI;
14511 goto do_addi;
14512 }
14513 break;
3c824109
NF
14514 case ADDIU32:
14515 mips32_op = OPC_ADDIU;
14516 do_addi:
d75c135e 14517 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14518 break;
14519
14520 /* Logical operations */
14521 case ORI32:
14522 mips32_op = OPC_ORI;
14523 goto do_logici;
14524 case XORI32:
14525 mips32_op = OPC_XORI;
14526 goto do_logici;
14527 case ANDI32:
14528 mips32_op = OPC_ANDI;
14529 do_logici:
d75c135e 14530 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14531 break;
14532
14533 /* Set less than immediate */
14534 case SLTI32:
14535 mips32_op = OPC_SLTI;
14536 goto do_slti;
14537 case SLTIU32:
14538 mips32_op = OPC_SLTIU;
14539 do_slti:
d75c135e 14540 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14541 break;
14542 case JALX32:
9e8f441a 14543 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14544 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14545 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14546 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14547 break;
65935f07
YK
14548 case JALS32: /* BOVC, BEQC, BEQZALC */
14549 if (ctx->insn_flags & ISA_MIPS32R6) {
14550 if (rs >= rt) {
14551 /* BOVC */
14552 mips32_op = OPC_BOVC;
14553 } else if (rs < rt && rs == 0) {
14554 /* BEQZALC */
14555 mips32_op = OPC_BEQZALC;
14556 } else {
14557 /* BEQC */
14558 mips32_op = OPC_BEQC;
14559 }
14560 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14561 } else {
14562 /* JALS32 */
14563 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14564 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14565 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14566 }
3c824109 14567 break;
65935f07
YK
14568 case BEQ32: /* BC */
14569 if (ctx->insn_flags & ISA_MIPS32R6) {
14570 /* BC */
14571 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14572 sextract32(ctx->opcode << 1, 0, 27));
14573 } else {
14574 /* BEQ32 */
14575 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14576 }
3c824109 14577 break;
65935f07
YK
14578 case BNE32: /* BALC */
14579 if (ctx->insn_flags & ISA_MIPS32R6) {
14580 /* BALC */
14581 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14582 sextract32(ctx->opcode << 1, 0, 27));
14583 } else {
14584 /* BNE32 */
14585 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14586 }
3c824109 14587 break;
65935f07
YK
14588 case J32: /* BGTZC, BLTZC, BLTC */
14589 if (ctx->insn_flags & ISA_MIPS32R6) {
14590 if (rs == 0 && rt != 0) {
14591 /* BGTZC */
14592 mips32_op = OPC_BGTZC;
14593 } else if (rs != 0 && rt != 0 && rs == rt) {
14594 /* BLTZC */
14595 mips32_op = OPC_BLTZC;
14596 } else {
14597 /* BLTC */
14598 mips32_op = OPC_BLTC;
14599 }
14600 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14601 } else {
14602 /* J32 */
14603 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14604 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14605 }
3c824109 14606 break;
65935f07
YK
14607 case JAL32: /* BLEZC, BGEZC, BGEC */
14608 if (ctx->insn_flags & ISA_MIPS32R6) {
14609 if (rs == 0 && rt != 0) {
14610 /* BLEZC */
14611 mips32_op = OPC_BLEZC;
14612 } else if (rs != 0 && rt != 0 && rs == rt) {
14613 /* BGEZC */
14614 mips32_op = OPC_BGEZC;
14615 } else {
14616 /* BGEC */
14617 mips32_op = OPC_BGEC;
14618 }
14619 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14620 } else {
14621 /* JAL32 */
14622 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14623 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14624 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14625 }
3c824109
NF
14626 break;
14627 /* Floating point (COP1) */
14628 case LWC132:
14629 mips32_op = OPC_LWC1;
14630 goto do_cop1;
14631 case LDC132:
14632 mips32_op = OPC_LDC1;
14633 goto do_cop1;
14634 case SWC132:
14635 mips32_op = OPC_SWC1;
14636 goto do_cop1;
14637 case SDC132:
14638 mips32_op = OPC_SDC1;
14639 do_cop1:
5ab5c041 14640 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 14641 break;
ab39ee45
YK
14642 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14643 if (ctx->insn_flags & ISA_MIPS32R6) {
14644 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14645 switch ((ctx->opcode >> 16) & 0x1f) {
14646 case ADDIUPC_00 ... ADDIUPC_07:
14647 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14648 break;
14649 case AUIPC:
14650 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14651 break;
14652 case ALUIPC:
14653 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14654 break;
14655 case LWPC_08 ... LWPC_0F:
14656 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14657 break;
14658 default:
14659 generate_exception(ctx, EXCP_RI);
14660 break;
14661 }
14662 } else {
14663 /* ADDIUPC */
3c824109
NF
14664 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14665 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14666
14667 gen_addiupc(ctx, reg, offset, 0, 0);
14668 }
14669 break;
65935f07
YK
14670 case BNVC: /* BNEC, BNEZALC */
14671 check_insn(ctx, ISA_MIPS32R6);
14672 if (rs >= rt) {
14673 /* BNVC */
14674 mips32_op = OPC_BNVC;
14675 } else if (rs < rt && rs == 0) {
14676 /* BNEZALC */
14677 mips32_op = OPC_BNEZALC;
14678 } else {
14679 /* BNEC */
14680 mips32_op = OPC_BNEC;
14681 }
14682 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14683 break;
14684 case R6_BNEZC: /* JIALC */
14685 check_insn(ctx, ISA_MIPS32R6);
14686 if (rt != 0) {
14687 /* BNEZC */
14688 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14689 sextract32(ctx->opcode << 1, 0, 22));
14690 } else {
14691 /* JIALC */
14692 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14693 }
14694 break;
14695 case R6_BEQZC: /* JIC */
14696 check_insn(ctx, ISA_MIPS32R6);
14697 if (rt != 0) {
14698 /* BEQZC */
14699 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14700 sextract32(ctx->opcode << 1, 0, 22));
14701 } else {
14702 /* JIC */
14703 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14704 }
14705 break;
14706 case BLEZALC: /* BGEZALC, BGEUC */
14707 check_insn(ctx, ISA_MIPS32R6);
14708 if (rs == 0 && rt != 0) {
14709 /* BLEZALC */
14710 mips32_op = OPC_BLEZALC;
14711 } else if (rs != 0 && rt != 0 && rs == rt) {
14712 /* BGEZALC */
14713 mips32_op = OPC_BGEZALC;
14714 } else {
14715 /* BGEUC */
14716 mips32_op = OPC_BGEUC;
14717 }
14718 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14719 break;
14720 case BGTZALC: /* BLTZALC, BLTUC */
14721 check_insn(ctx, ISA_MIPS32R6);
14722 if (rs == 0 && rt != 0) {
14723 /* BGTZALC */
14724 mips32_op = OPC_BGTZALC;
14725 } else if (rs != 0 && rt != 0 && rs == rt) {
14726 /* BLTZALC */
14727 mips32_op = OPC_BLTZALC;
14728 } else {
14729 /* BLTUC */
14730 mips32_op = OPC_BLTUC;
14731 }
14732 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14733 break;
3c824109
NF
14734 /* Loads and stores */
14735 case LB32:
14736 mips32_op = OPC_LB;
5c13fdfd 14737 goto do_ld;
3c824109
NF
14738 case LBU32:
14739 mips32_op = OPC_LBU;
5c13fdfd 14740 goto do_ld;
3c824109
NF
14741 case LH32:
14742 mips32_op = OPC_LH;
5c13fdfd 14743 goto do_ld;
3c824109
NF
14744 case LHU32:
14745 mips32_op = OPC_LHU;
5c13fdfd 14746 goto do_ld;
3c824109
NF
14747 case LW32:
14748 mips32_op = OPC_LW;
5c13fdfd 14749 goto do_ld;
3c824109
NF
14750#ifdef TARGET_MIPS64
14751 case LD32:
d9224450
MR
14752 check_insn(ctx, ISA_MIPS3);
14753 check_mips_64(ctx);
3c824109 14754 mips32_op = OPC_LD;
5c13fdfd 14755 goto do_ld;
3c824109 14756 case SD32:
d9224450
MR
14757 check_insn(ctx, ISA_MIPS3);
14758 check_mips_64(ctx);
3c824109 14759 mips32_op = OPC_SD;
5c13fdfd 14760 goto do_st;
3c824109
NF
14761#endif
14762 case SB32:
14763 mips32_op = OPC_SB;
5c13fdfd 14764 goto do_st;
3c824109
NF
14765 case SH32:
14766 mips32_op = OPC_SH;
5c13fdfd 14767 goto do_st;
3c824109
NF
14768 case SW32:
14769 mips32_op = OPC_SW;
5c13fdfd
AJ
14770 goto do_st;
14771 do_ld:
d75c135e 14772 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
14773 break;
14774 do_st:
14775 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14776 break;
14777 default:
9c708c7f 14778 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14779 break;
14780 }
14781}
14782
240ce26a 14783static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14784{
14785 uint32_t op;
14786
14787 /* make sure instructions are on a halfword boundary */
14788 if (ctx->pc & 0x1) {
14789 env->CP0_BadVAddr = ctx->pc;
9c708c7f 14790 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
14791 return 2;
14792 }
14793
14794 op = (ctx->opcode >> 10) & 0x3f;
14795 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
14796 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14797 switch (op & 0x7) { /* MSB-3..MSB-5 */
14798 case 0:
14799 /* POOL32A, POOL32B, POOL32I, POOL32C */
14800 case 4:
14801 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14802 case 5:
14803 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14804 case 6:
14805 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14806 case 7:
14807 /* LB32, LH32, LWC132, LDC132, LW32 */
14808 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 14809 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14810 return 2;
14811 }
14812 break;
b231c103
YK
14813 case 1:
14814 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14815 case 2:
14816 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14817 case 3:
14818 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14819 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 14820 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14821 return 2;
14822 }
14823 break;
3c824109
NF
14824 }
14825 }
b231c103 14826
3c824109
NF
14827 switch (op) {
14828 case POOL16A:
14829 {
14830 int rd = mmreg(uMIPS_RD(ctx->opcode));
14831 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14832 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14833 uint32_t opc = 0;
14834
14835 switch (ctx->opcode & 0x1) {
14836 case ADDU16:
14837 opc = OPC_ADDU;
14838 break;
14839 case SUBU16:
14840 opc = OPC_SUBU;
14841 break;
14842 }
ed7ce6c0
YK
14843 if (ctx->insn_flags & ISA_MIPS32R6) {
14844 /* In the Release 6 the register number location in
14845 * the instruction encoding has changed.
14846 */
14847 gen_arith(ctx, opc, rs1, rd, rs2);
14848 } else {
14849 gen_arith(ctx, opc, rd, rs1, rs2);
14850 }
3c824109
NF
14851 }
14852 break;
14853 case POOL16B:
14854 {
14855 int rd = mmreg(uMIPS_RD(ctx->opcode));
14856 int rs = mmreg(uMIPS_RS(ctx->opcode));
14857 int amount = (ctx->opcode >> 1) & 0x7;
14858 uint32_t opc = 0;
14859 amount = amount == 0 ? 8 : amount;
14860
14861 switch (ctx->opcode & 0x1) {
14862 case SLL16:
14863 opc = OPC_SLL;
14864 break;
14865 case SRL16:
14866 opc = OPC_SRL;
14867 break;
14868 }
14869
d75c135e 14870 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14871 }
14872 break;
14873 case POOL16C:
ed7ce6c0
YK
14874 if (ctx->insn_flags & ISA_MIPS32R6) {
14875 gen_pool16c_r6_insn(ctx);
14876 } else {
14877 gen_pool16c_insn(ctx);
14878 }
3c824109
NF
14879 break;
14880 case LWGP16:
14881 {
14882 int rd = mmreg(uMIPS_RD(ctx->opcode));
14883 int rb = 28; /* GP */
14884 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14885
d75c135e 14886 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14887 }
14888 break;
14889 case POOL16F:
9e8f441a 14890 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14891 if (ctx->opcode & 1) {
9c708c7f 14892 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14893 } else {
14894 /* MOVEP */
14895 int enc_dest = uMIPS_RD(ctx->opcode);
14896 int enc_rt = uMIPS_RS2(ctx->opcode);
14897 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 14898 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
14899 }
14900 break;
14901 case LBU16:
14902 {
14903 int rd = mmreg(uMIPS_RD(ctx->opcode));
14904 int rb = mmreg(uMIPS_RS(ctx->opcode));
14905 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14906 offset = (offset == 0xf ? -1 : offset);
14907
d75c135e 14908 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14909 }
14910 break;
14911 case LHU16:
14912 {
14913 int rd = mmreg(uMIPS_RD(ctx->opcode));
14914 int rb = mmreg(uMIPS_RS(ctx->opcode));
14915 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14916
d75c135e 14917 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14918 }
14919 break;
14920 case LWSP16:
14921 {
14922 int rd = (ctx->opcode >> 5) & 0x1f;
14923 int rb = 29; /* SP */
14924 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14925
d75c135e 14926 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14927 }
14928 break;
14929 case LW16:
14930 {
14931 int rd = mmreg(uMIPS_RD(ctx->opcode));
14932 int rb = mmreg(uMIPS_RS(ctx->opcode));
14933 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14934
d75c135e 14935 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14936 }
14937 break;
14938 case SB16:
14939 {
14940 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14941 int rb = mmreg(uMIPS_RS(ctx->opcode));
14942 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14943
5c13fdfd 14944 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14945 }
14946 break;
14947 case SH16:
14948 {
14949 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14950 int rb = mmreg(uMIPS_RS(ctx->opcode));
14951 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14952
5c13fdfd 14953 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14954 }
14955 break;
14956 case SWSP16:
14957 {
14958 int rd = (ctx->opcode >> 5) & 0x1f;
14959 int rb = 29; /* SP */
14960 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14961
5c13fdfd 14962 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14963 }
14964 break;
14965 case SW16:
14966 {
14967 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14968 int rb = mmreg(uMIPS_RS(ctx->opcode));
14969 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14970
5c13fdfd 14971 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14972 }
14973 break;
14974 case MOVE16:
14975 {
14976 int rd = uMIPS_RD5(ctx->opcode);
14977 int rs = uMIPS_RS5(ctx->opcode);
14978
7215d7e7 14979 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14980 }
14981 break;
14982 case ANDI16:
d75c135e 14983 gen_andi16(ctx);
3c824109
NF
14984 break;
14985 case POOL16D:
14986 switch (ctx->opcode & 0x1) {
14987 case ADDIUS5:
d75c135e 14988 gen_addius5(ctx);
3c824109
NF
14989 break;
14990 case ADDIUSP:
d75c135e 14991 gen_addiusp(ctx);
3c824109
NF
14992 break;
14993 }
14994 break;
14995 case POOL16E:
14996 switch (ctx->opcode & 0x1) {
14997 case ADDIUR2:
d75c135e 14998 gen_addiur2(ctx);
3c824109
NF
14999 break;
15000 case ADDIUR1SP:
d75c135e 15001 gen_addiur1sp(ctx);
3c824109
NF
15002 break;
15003 }
15004 break;
65935f07 15005 case B16: /* BC16 */
3c824109 15006 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15007 sextract32(ctx->opcode, 0, 10) << 1,
15008 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15009 break;
65935f07
YK
15010 case BNEZ16: /* BNEZC16 */
15011 case BEQZ16: /* BEQZC16 */
3c824109
NF
15012 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15013 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15014 0, sextract32(ctx->opcode, 0, 7) << 1,
15015 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15016
3c824109
NF
15017 break;
15018 case LI16:
15019 {
15020 int reg = mmreg(uMIPS_RD(ctx->opcode));
15021 int imm = ZIMM(ctx->opcode, 0, 7);
15022
15023 imm = (imm == 0x7f ? -1 : imm);
15024 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15025 }
15026 break;
3c824109 15027 case RES_29:
3c824109 15028 case RES_31:
3c824109 15029 case RES_39:
9c708c7f 15030 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15031 break;
15032 default:
f60eeb0c 15033 decode_micromips32_opc(env, ctx);
3c824109
NF
15034 return 4;
15035 }
15036
15037 return 2;
15038}
15039
15040/* SmartMIPS extension to MIPS32 */
15041
15042#if defined(TARGET_MIPS64)
15043
15044/* MDMX extension to MIPS64 */
15045
15046#endif
15047
9b1a1d68 15048/* MIPSDSP functions. */
d75c135e 15049static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15050 int rd, int base, int offset)
15051{
9b1a1d68
JL
15052 TCGv t0;
15053
9b1a1d68
JL
15054 check_dsp(ctx);
15055 t0 = tcg_temp_new();
15056
15057 if (base == 0) {
15058 gen_load_gpr(t0, offset);
15059 } else if (offset == 0) {
15060 gen_load_gpr(t0, base);
15061 } else {
15062 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15063 }
15064
9b1a1d68
JL
15065 switch (opc) {
15066 case OPC_LBUX:
5f68f5ae 15067 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15068 gen_store_gpr(t0, rd);
9b1a1d68
JL
15069 break;
15070 case OPC_LHX:
5f68f5ae 15071 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15072 gen_store_gpr(t0, rd);
9b1a1d68
JL
15073 break;
15074 case OPC_LWX:
5f68f5ae 15075 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15076 gen_store_gpr(t0, rd);
9b1a1d68
JL
15077 break;
15078#if defined(TARGET_MIPS64)
15079 case OPC_LDX:
5f68f5ae 15080 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15081 gen_store_gpr(t0, rd);
9b1a1d68
JL
15082 break;
15083#endif
15084 }
9b1a1d68
JL
15085 tcg_temp_free(t0);
15086}
15087
461c08df
JL
15088static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15089 int ret, int v1, int v2)
15090{
461c08df
JL
15091 TCGv v1_t;
15092 TCGv v2_t;
15093
15094 if (ret == 0) {
15095 /* Treat as NOP. */
461c08df
JL
15096 return;
15097 }
15098
15099 v1_t = tcg_temp_new();
15100 v2_t = tcg_temp_new();
15101
15102 gen_load_gpr(v1_t, v1);
15103 gen_load_gpr(v2_t, v2);
15104
15105 switch (op1) {
15106 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15107 case OPC_MULT_G_2E:
15108 check_dspr2(ctx);
15109 switch (op2) {
15110 case OPC_ADDUH_QB:
15111 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15112 break;
15113 case OPC_ADDUH_R_QB:
15114 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15115 break;
15116 case OPC_ADDQH_PH:
15117 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15118 break;
15119 case OPC_ADDQH_R_PH:
15120 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15121 break;
15122 case OPC_ADDQH_W:
15123 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15124 break;
15125 case OPC_ADDQH_R_W:
15126 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15127 break;
15128 case OPC_SUBUH_QB:
15129 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15130 break;
15131 case OPC_SUBUH_R_QB:
15132 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15133 break;
15134 case OPC_SUBQH_PH:
15135 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15136 break;
15137 case OPC_SUBQH_R_PH:
15138 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15139 break;
15140 case OPC_SUBQH_W:
15141 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15142 break;
15143 case OPC_SUBQH_R_W:
15144 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15145 break;
15146 }
15147 break;
15148 case OPC_ABSQ_S_PH_DSP:
15149 switch (op2) {
15150 case OPC_ABSQ_S_QB:
15151 check_dspr2(ctx);
15152 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15153 break;
15154 case OPC_ABSQ_S_PH:
15155 check_dsp(ctx);
15156 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15157 break;
15158 case OPC_ABSQ_S_W:
15159 check_dsp(ctx);
15160 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15161 break;
15162 case OPC_PRECEQ_W_PHL:
15163 check_dsp(ctx);
15164 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15165 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15166 break;
15167 case OPC_PRECEQ_W_PHR:
15168 check_dsp(ctx);
15169 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15170 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15171 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15172 break;
15173 case OPC_PRECEQU_PH_QBL:
15174 check_dsp(ctx);
15175 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15176 break;
15177 case OPC_PRECEQU_PH_QBR:
15178 check_dsp(ctx);
15179 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15180 break;
15181 case OPC_PRECEQU_PH_QBLA:
15182 check_dsp(ctx);
15183 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15184 break;
15185 case OPC_PRECEQU_PH_QBRA:
15186 check_dsp(ctx);
15187 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15188 break;
15189 case OPC_PRECEU_PH_QBL:
15190 check_dsp(ctx);
15191 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15192 break;
15193 case OPC_PRECEU_PH_QBR:
15194 check_dsp(ctx);
15195 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15196 break;
15197 case OPC_PRECEU_PH_QBLA:
15198 check_dsp(ctx);
15199 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15200 break;
15201 case OPC_PRECEU_PH_QBRA:
15202 check_dsp(ctx);
15203 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15204 break;
15205 }
15206 break;
15207 case OPC_ADDU_QB_DSP:
15208 switch (op2) {
15209 case OPC_ADDQ_PH:
15210 check_dsp(ctx);
15211 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15212 break;
15213 case OPC_ADDQ_S_PH:
15214 check_dsp(ctx);
15215 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15216 break;
15217 case OPC_ADDQ_S_W:
15218 check_dsp(ctx);
15219 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15220 break;
15221 case OPC_ADDU_QB:
15222 check_dsp(ctx);
15223 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15224 break;
15225 case OPC_ADDU_S_QB:
15226 check_dsp(ctx);
15227 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15228 break;
15229 case OPC_ADDU_PH:
15230 check_dspr2(ctx);
15231 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15232 break;
15233 case OPC_ADDU_S_PH:
15234 check_dspr2(ctx);
15235 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15236 break;
15237 case OPC_SUBQ_PH:
15238 check_dsp(ctx);
15239 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15240 break;
15241 case OPC_SUBQ_S_PH:
15242 check_dsp(ctx);
15243 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15244 break;
15245 case OPC_SUBQ_S_W:
15246 check_dsp(ctx);
15247 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15248 break;
15249 case OPC_SUBU_QB:
15250 check_dsp(ctx);
15251 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15252 break;
15253 case OPC_SUBU_S_QB:
15254 check_dsp(ctx);
15255 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15256 break;
15257 case OPC_SUBU_PH:
15258 check_dspr2(ctx);
15259 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15260 break;
15261 case OPC_SUBU_S_PH:
15262 check_dspr2(ctx);
15263 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15264 break;
15265 case OPC_ADDSC:
15266 check_dsp(ctx);
15267 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15268 break;
15269 case OPC_ADDWC:
15270 check_dsp(ctx);
15271 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15272 break;
15273 case OPC_MODSUB:
15274 check_dsp(ctx);
15275 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15276 break;
15277 case OPC_RADDU_W_QB:
15278 check_dsp(ctx);
15279 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15280 break;
15281 }
15282 break;
15283 case OPC_CMPU_EQ_QB_DSP:
15284 switch (op2) {
15285 case OPC_PRECR_QB_PH:
15286 check_dspr2(ctx);
15287 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15288 break;
15289 case OPC_PRECRQ_QB_PH:
15290 check_dsp(ctx);
15291 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15292 break;
15293 case OPC_PRECR_SRA_PH_W:
15294 check_dspr2(ctx);
15295 {
15296 TCGv_i32 sa_t = tcg_const_i32(v2);
15297 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15298 cpu_gpr[ret]);
15299 tcg_temp_free_i32(sa_t);
15300 break;
15301 }
15302 case OPC_PRECR_SRA_R_PH_W:
15303 check_dspr2(ctx);
15304 {
15305 TCGv_i32 sa_t = tcg_const_i32(v2);
15306 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15307 cpu_gpr[ret]);
15308 tcg_temp_free_i32(sa_t);
15309 break;
15310 }
15311 case OPC_PRECRQ_PH_W:
15312 check_dsp(ctx);
15313 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15314 break;
15315 case OPC_PRECRQ_RS_PH_W:
15316 check_dsp(ctx);
15317 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15318 break;
15319 case OPC_PRECRQU_S_QB_PH:
15320 check_dsp(ctx);
15321 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15322 break;
15323 }
15324 break;
15325#ifdef TARGET_MIPS64
15326 case OPC_ABSQ_S_QH_DSP:
15327 switch (op2) {
15328 case OPC_PRECEQ_L_PWL:
15329 check_dsp(ctx);
15330 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15331 break;
15332 case OPC_PRECEQ_L_PWR:
15333 check_dsp(ctx);
15334 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15335 break;
15336 case OPC_PRECEQ_PW_QHL:
15337 check_dsp(ctx);
15338 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15339 break;
15340 case OPC_PRECEQ_PW_QHR:
15341 check_dsp(ctx);
15342 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15343 break;
15344 case OPC_PRECEQ_PW_QHLA:
15345 check_dsp(ctx);
15346 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15347 break;
15348 case OPC_PRECEQ_PW_QHRA:
15349 check_dsp(ctx);
15350 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15351 break;
15352 case OPC_PRECEQU_QH_OBL:
15353 check_dsp(ctx);
15354 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15355 break;
15356 case OPC_PRECEQU_QH_OBR:
15357 check_dsp(ctx);
15358 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15359 break;
15360 case OPC_PRECEQU_QH_OBLA:
15361 check_dsp(ctx);
15362 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15363 break;
15364 case OPC_PRECEQU_QH_OBRA:
15365 check_dsp(ctx);
15366 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15367 break;
15368 case OPC_PRECEU_QH_OBL:
15369 check_dsp(ctx);
15370 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15371 break;
15372 case OPC_PRECEU_QH_OBR:
15373 check_dsp(ctx);
15374 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15375 break;
15376 case OPC_PRECEU_QH_OBLA:
15377 check_dsp(ctx);
15378 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15379 break;
15380 case OPC_PRECEU_QH_OBRA:
15381 check_dsp(ctx);
15382 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15383 break;
15384 case OPC_ABSQ_S_OB:
15385 check_dspr2(ctx);
15386 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15387 break;
15388 case OPC_ABSQ_S_PW:
15389 check_dsp(ctx);
15390 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15391 break;
15392 case OPC_ABSQ_S_QH:
15393 check_dsp(ctx);
15394 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15395 break;
15396 }
15397 break;
15398 case OPC_ADDU_OB_DSP:
15399 switch (op2) {
15400 case OPC_RADDU_L_OB:
15401 check_dsp(ctx);
15402 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15403 break;
15404 case OPC_SUBQ_PW:
15405 check_dsp(ctx);
15406 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15407 break;
15408 case OPC_SUBQ_S_PW:
15409 check_dsp(ctx);
15410 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15411 break;
15412 case OPC_SUBQ_QH:
15413 check_dsp(ctx);
15414 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15415 break;
15416 case OPC_SUBQ_S_QH:
15417 check_dsp(ctx);
15418 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15419 break;
15420 case OPC_SUBU_OB:
15421 check_dsp(ctx);
15422 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15423 break;
15424 case OPC_SUBU_S_OB:
15425 check_dsp(ctx);
15426 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15427 break;
15428 case OPC_SUBU_QH:
15429 check_dspr2(ctx);
15430 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15431 break;
15432 case OPC_SUBU_S_QH:
15433 check_dspr2(ctx);
15434 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15435 break;
15436 case OPC_SUBUH_OB:
15437 check_dspr2(ctx);
15438 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15439 break;
15440 case OPC_SUBUH_R_OB:
15441 check_dspr2(ctx);
15442 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15443 break;
15444 case OPC_ADDQ_PW:
15445 check_dsp(ctx);
15446 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15447 break;
15448 case OPC_ADDQ_S_PW:
15449 check_dsp(ctx);
15450 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15451 break;
15452 case OPC_ADDQ_QH:
15453 check_dsp(ctx);
15454 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15455 break;
15456 case OPC_ADDQ_S_QH:
15457 check_dsp(ctx);
15458 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15459 break;
15460 case OPC_ADDU_OB:
15461 check_dsp(ctx);
15462 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15463 break;
15464 case OPC_ADDU_S_OB:
15465 check_dsp(ctx);
15466 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15467 break;
15468 case OPC_ADDU_QH:
15469 check_dspr2(ctx);
15470 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15471 break;
15472 case OPC_ADDU_S_QH:
15473 check_dspr2(ctx);
15474 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15475 break;
15476 case OPC_ADDUH_OB:
15477 check_dspr2(ctx);
15478 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15479 break;
15480 case OPC_ADDUH_R_OB:
15481 check_dspr2(ctx);
15482 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15483 break;
15484 }
15485 break;
15486 case OPC_CMPU_EQ_OB_DSP:
15487 switch (op2) {
15488 case OPC_PRECR_OB_QH:
15489 check_dspr2(ctx);
15490 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15491 break;
15492 case OPC_PRECR_SRA_QH_PW:
15493 check_dspr2(ctx);
15494 {
15495 TCGv_i32 ret_t = tcg_const_i32(ret);
15496 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15497 tcg_temp_free_i32(ret_t);
15498 break;
15499 }
15500 case OPC_PRECR_SRA_R_QH_PW:
15501 check_dspr2(ctx);
15502 {
15503 TCGv_i32 sa_v = tcg_const_i32(ret);
15504 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15505 tcg_temp_free_i32(sa_v);
15506 break;
15507 }
15508 case OPC_PRECRQ_OB_QH:
15509 check_dsp(ctx);
15510 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15511 break;
15512 case OPC_PRECRQ_PW_L:
15513 check_dsp(ctx);
15514 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15515 break;
15516 case OPC_PRECRQ_QH_PW:
15517 check_dsp(ctx);
15518 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15519 break;
15520 case OPC_PRECRQ_RS_QH_PW:
15521 check_dsp(ctx);
15522 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15523 break;
15524 case OPC_PRECRQU_S_OB_QH:
15525 check_dsp(ctx);
15526 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15527 break;
15528 }
15529 break;
15530#endif
15531 }
15532
15533 tcg_temp_free(v1_t);
15534 tcg_temp_free(v2_t);
461c08df 15535}
9b1a1d68 15536
77c5fa8b
JL
15537static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15538 int ret, int v1, int v2)
15539{
15540 uint32_t op2;
77c5fa8b
JL
15541 TCGv t0;
15542 TCGv v1_t;
15543 TCGv v2_t;
15544
15545 if (ret == 0) {
15546 /* Treat as NOP. */
77c5fa8b
JL
15547 return;
15548 }
15549
15550 t0 = tcg_temp_new();
15551 v1_t = tcg_temp_new();
15552 v2_t = tcg_temp_new();
15553
15554 tcg_gen_movi_tl(t0, v1);
15555 gen_load_gpr(v1_t, v1);
15556 gen_load_gpr(v2_t, v2);
15557
15558 switch (opc) {
15559 case OPC_SHLL_QB_DSP:
15560 {
15561 op2 = MASK_SHLL_QB(ctx->opcode);
15562 switch (op2) {
15563 case OPC_SHLL_QB:
15564 check_dsp(ctx);
15565 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15566 break;
15567 case OPC_SHLLV_QB:
15568 check_dsp(ctx);
15569 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15570 break;
15571 case OPC_SHLL_PH:
15572 check_dsp(ctx);
15573 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15574 break;
15575 case OPC_SHLLV_PH:
15576 check_dsp(ctx);
15577 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15578 break;
15579 case OPC_SHLL_S_PH:
15580 check_dsp(ctx);
15581 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15582 break;
15583 case OPC_SHLLV_S_PH:
15584 check_dsp(ctx);
15585 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15586 break;
15587 case OPC_SHLL_S_W:
15588 check_dsp(ctx);
15589 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15590 break;
15591 case OPC_SHLLV_S_W:
15592 check_dsp(ctx);
15593 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15594 break;
15595 case OPC_SHRL_QB:
15596 check_dsp(ctx);
15597 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15598 break;
15599 case OPC_SHRLV_QB:
15600 check_dsp(ctx);
15601 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15602 break;
15603 case OPC_SHRL_PH:
15604 check_dspr2(ctx);
15605 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15606 break;
15607 case OPC_SHRLV_PH:
15608 check_dspr2(ctx);
15609 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15610 break;
15611 case OPC_SHRA_QB:
15612 check_dspr2(ctx);
15613 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15614 break;
15615 case OPC_SHRA_R_QB:
15616 check_dspr2(ctx);
15617 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15618 break;
15619 case OPC_SHRAV_QB:
15620 check_dspr2(ctx);
15621 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15622 break;
15623 case OPC_SHRAV_R_QB:
15624 check_dspr2(ctx);
15625 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15626 break;
15627 case OPC_SHRA_PH:
15628 check_dsp(ctx);
15629 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15630 break;
15631 case OPC_SHRA_R_PH:
15632 check_dsp(ctx);
15633 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15634 break;
15635 case OPC_SHRAV_PH:
15636 check_dsp(ctx);
15637 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15638 break;
15639 case OPC_SHRAV_R_PH:
15640 check_dsp(ctx);
15641 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15642 break;
15643 case OPC_SHRA_R_W:
15644 check_dsp(ctx);
15645 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15646 break;
15647 case OPC_SHRAV_R_W:
15648 check_dsp(ctx);
15649 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15650 break;
15651 default: /* Invalid */
15652 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 15653 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15654 break;
15655 }
15656 break;
15657 }
15658#ifdef TARGET_MIPS64
15659 case OPC_SHLL_OB_DSP:
15660 op2 = MASK_SHLL_OB(ctx->opcode);
15661 switch (op2) {
15662 case OPC_SHLL_PW:
15663 check_dsp(ctx);
15664 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15665 break;
15666 case OPC_SHLLV_PW:
15667 check_dsp(ctx);
15668 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15669 break;
15670 case OPC_SHLL_S_PW:
15671 check_dsp(ctx);
15672 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15673 break;
15674 case OPC_SHLLV_S_PW:
15675 check_dsp(ctx);
15676 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15677 break;
15678 case OPC_SHLL_OB:
15679 check_dsp(ctx);
15680 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15681 break;
15682 case OPC_SHLLV_OB:
15683 check_dsp(ctx);
15684 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15685 break;
15686 case OPC_SHLL_QH:
15687 check_dsp(ctx);
15688 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15689 break;
15690 case OPC_SHLLV_QH:
15691 check_dsp(ctx);
15692 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15693 break;
15694 case OPC_SHLL_S_QH:
15695 check_dsp(ctx);
15696 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15697 break;
15698 case OPC_SHLLV_S_QH:
15699 check_dsp(ctx);
15700 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15701 break;
15702 case OPC_SHRA_OB:
15703 check_dspr2(ctx);
15704 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15705 break;
15706 case OPC_SHRAV_OB:
15707 check_dspr2(ctx);
15708 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15709 break;
15710 case OPC_SHRA_R_OB:
15711 check_dspr2(ctx);
15712 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15713 break;
15714 case OPC_SHRAV_R_OB:
15715 check_dspr2(ctx);
15716 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15717 break;
15718 case OPC_SHRA_PW:
15719 check_dsp(ctx);
15720 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15721 break;
15722 case OPC_SHRAV_PW:
15723 check_dsp(ctx);
15724 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15725 break;
15726 case OPC_SHRA_R_PW:
15727 check_dsp(ctx);
15728 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15729 break;
15730 case OPC_SHRAV_R_PW:
15731 check_dsp(ctx);
15732 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15733 break;
15734 case OPC_SHRA_QH:
15735 check_dsp(ctx);
15736 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15737 break;
15738 case OPC_SHRAV_QH:
15739 check_dsp(ctx);
15740 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15741 break;
15742 case OPC_SHRA_R_QH:
15743 check_dsp(ctx);
15744 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15745 break;
15746 case OPC_SHRAV_R_QH:
15747 check_dsp(ctx);
15748 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15749 break;
15750 case OPC_SHRL_OB:
15751 check_dsp(ctx);
15752 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15753 break;
15754 case OPC_SHRLV_OB:
15755 check_dsp(ctx);
15756 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15757 break;
15758 case OPC_SHRL_QH:
15759 check_dspr2(ctx);
15760 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15761 break;
15762 case OPC_SHRLV_QH:
15763 check_dspr2(ctx);
15764 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15765 break;
15766 default: /* Invalid */
15767 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 15768 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15769 break;
15770 }
15771 break;
15772#endif
15773 }
15774
15775 tcg_temp_free(t0);
15776 tcg_temp_free(v1_t);
15777 tcg_temp_free(v2_t);
77c5fa8b
JL
15778}
15779
a22260ae
JL
15780static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15781 int ret, int v1, int v2, int check_ret)
15782{
a22260ae
JL
15783 TCGv_i32 t0;
15784 TCGv v1_t;
15785 TCGv v2_t;
15786
15787 if ((ret == 0) && (check_ret == 1)) {
15788 /* Treat as NOP. */
a22260ae
JL
15789 return;
15790 }
15791
15792 t0 = tcg_temp_new_i32();
15793 v1_t = tcg_temp_new();
15794 v2_t = tcg_temp_new();
15795
15796 tcg_gen_movi_i32(t0, ret);
15797 gen_load_gpr(v1_t, v1);
15798 gen_load_gpr(v2_t, v2);
15799
15800 switch (op1) {
15801 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15802 * the same mask and op1. */
15803 case OPC_MULT_G_2E:
639eadb9 15804 check_dspr2(ctx);
a22260ae
JL
15805 switch (op2) {
15806 case OPC_MUL_PH:
15807 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15808 break;
15809 case OPC_MUL_S_PH:
15810 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15811 break;
15812 case OPC_MULQ_S_W:
15813 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15814 break;
15815 case OPC_MULQ_RS_W:
15816 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15817 break;
15818 }
15819 break;
15820 case OPC_DPA_W_PH_DSP:
15821 switch (op2) {
15822 case OPC_DPAU_H_QBL:
15823 check_dsp(ctx);
15824 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15825 break;
15826 case OPC_DPAU_H_QBR:
15827 check_dsp(ctx);
15828 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15829 break;
15830 case OPC_DPSU_H_QBL:
15831 check_dsp(ctx);
15832 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15833 break;
15834 case OPC_DPSU_H_QBR:
15835 check_dsp(ctx);
15836 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15837 break;
15838 case OPC_DPA_W_PH:
15839 check_dspr2(ctx);
15840 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15841 break;
15842 case OPC_DPAX_W_PH:
15843 check_dspr2(ctx);
15844 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15845 break;
15846 case OPC_DPAQ_S_W_PH:
15847 check_dsp(ctx);
15848 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15849 break;
15850 case OPC_DPAQX_S_W_PH:
15851 check_dspr2(ctx);
15852 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15853 break;
15854 case OPC_DPAQX_SA_W_PH:
15855 check_dspr2(ctx);
15856 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15857 break;
15858 case OPC_DPS_W_PH:
15859 check_dspr2(ctx);
15860 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15861 break;
15862 case OPC_DPSX_W_PH:
15863 check_dspr2(ctx);
15864 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15865 break;
15866 case OPC_DPSQ_S_W_PH:
15867 check_dsp(ctx);
15868 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15869 break;
15870 case OPC_DPSQX_S_W_PH:
15871 check_dspr2(ctx);
15872 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15873 break;
15874 case OPC_DPSQX_SA_W_PH:
15875 check_dspr2(ctx);
15876 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15877 break;
15878 case OPC_MULSAQ_S_W_PH:
15879 check_dsp(ctx);
15880 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15881 break;
15882 case OPC_DPAQ_SA_L_W:
15883 check_dsp(ctx);
15884 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15885 break;
15886 case OPC_DPSQ_SA_L_W:
15887 check_dsp(ctx);
15888 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15889 break;
15890 case OPC_MAQ_S_W_PHL:
15891 check_dsp(ctx);
15892 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15893 break;
15894 case OPC_MAQ_S_W_PHR:
15895 check_dsp(ctx);
15896 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15897 break;
15898 case OPC_MAQ_SA_W_PHL:
15899 check_dsp(ctx);
15900 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15901 break;
15902 case OPC_MAQ_SA_W_PHR:
15903 check_dsp(ctx);
15904 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15905 break;
15906 case OPC_MULSA_W_PH:
15907 check_dspr2(ctx);
15908 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15909 break;
15910 }
15911 break;
15912#ifdef TARGET_MIPS64
15913 case OPC_DPAQ_W_QH_DSP:
15914 {
15915 int ac = ret & 0x03;
15916 tcg_gen_movi_i32(t0, ac);
15917
15918 switch (op2) {
15919 case OPC_DMADD:
15920 check_dsp(ctx);
15921 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15922 break;
15923 case OPC_DMADDU:
15924 check_dsp(ctx);
15925 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15926 break;
15927 case OPC_DMSUB:
15928 check_dsp(ctx);
15929 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15930 break;
15931 case OPC_DMSUBU:
15932 check_dsp(ctx);
15933 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15934 break;
15935 case OPC_DPA_W_QH:
15936 check_dspr2(ctx);
15937 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15938 break;
15939 case OPC_DPAQ_S_W_QH:
15940 check_dsp(ctx);
15941 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15942 break;
15943 case OPC_DPAQ_SA_L_PW:
15944 check_dsp(ctx);
15945 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15946 break;
15947 case OPC_DPAU_H_OBL:
15948 check_dsp(ctx);
15949 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15950 break;
15951 case OPC_DPAU_H_OBR:
15952 check_dsp(ctx);
15953 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15954 break;
15955 case OPC_DPS_W_QH:
15956 check_dspr2(ctx);
15957 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15958 break;
15959 case OPC_DPSQ_S_W_QH:
15960 check_dsp(ctx);
15961 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15962 break;
15963 case OPC_DPSQ_SA_L_PW:
15964 check_dsp(ctx);
15965 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15966 break;
15967 case OPC_DPSU_H_OBL:
15968 check_dsp(ctx);
15969 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15970 break;
15971 case OPC_DPSU_H_OBR:
15972 check_dsp(ctx);
15973 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15974 break;
15975 case OPC_MAQ_S_L_PWL:
15976 check_dsp(ctx);
15977 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15978 break;
15979 case OPC_MAQ_S_L_PWR:
15980 check_dsp(ctx);
15981 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15982 break;
15983 case OPC_MAQ_S_W_QHLL:
15984 check_dsp(ctx);
15985 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15986 break;
15987 case OPC_MAQ_SA_W_QHLL:
15988 check_dsp(ctx);
15989 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15990 break;
15991 case OPC_MAQ_S_W_QHLR:
15992 check_dsp(ctx);
15993 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15994 break;
15995 case OPC_MAQ_SA_W_QHLR:
15996 check_dsp(ctx);
15997 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15998 break;
15999 case OPC_MAQ_S_W_QHRL:
16000 check_dsp(ctx);
16001 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16002 break;
16003 case OPC_MAQ_SA_W_QHRL:
16004 check_dsp(ctx);
16005 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16006 break;
16007 case OPC_MAQ_S_W_QHRR:
16008 check_dsp(ctx);
16009 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16010 break;
16011 case OPC_MAQ_SA_W_QHRR:
16012 check_dsp(ctx);
16013 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16014 break;
16015 case OPC_MULSAQ_S_L_PW:
16016 check_dsp(ctx);
16017 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16018 break;
16019 case OPC_MULSAQ_S_W_QH:
16020 check_dsp(ctx);
16021 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16022 break;
16023 }
16024 }
16025 break;
16026#endif
16027 case OPC_ADDU_QB_DSP:
16028 switch (op2) {
16029 case OPC_MULEU_S_PH_QBL:
16030 check_dsp(ctx);
16031 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16032 break;
16033 case OPC_MULEU_S_PH_QBR:
16034 check_dsp(ctx);
16035 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16036 break;
16037 case OPC_MULQ_RS_PH:
16038 check_dsp(ctx);
16039 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16040 break;
16041 case OPC_MULEQ_S_W_PHL:
16042 check_dsp(ctx);
16043 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16044 break;
16045 case OPC_MULEQ_S_W_PHR:
16046 check_dsp(ctx);
16047 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16048 break;
16049 case OPC_MULQ_S_PH:
16050 check_dspr2(ctx);
16051 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16052 break;
16053 }
16054 break;
16055#ifdef TARGET_MIPS64
16056 case OPC_ADDU_OB_DSP:
16057 switch (op2) {
16058 case OPC_MULEQ_S_PW_QHL:
16059 check_dsp(ctx);
16060 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16061 break;
16062 case OPC_MULEQ_S_PW_QHR:
16063 check_dsp(ctx);
16064 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16065 break;
16066 case OPC_MULEU_S_QH_OBL:
16067 check_dsp(ctx);
16068 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16069 break;
16070 case OPC_MULEU_S_QH_OBR:
16071 check_dsp(ctx);
16072 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16073 break;
16074 case OPC_MULQ_RS_QH:
16075 check_dsp(ctx);
16076 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16077 break;
16078 }
16079 break;
16080#endif
16081 }
16082
16083 tcg_temp_free_i32(t0);
16084 tcg_temp_free(v1_t);
16085 tcg_temp_free(v2_t);
a22260ae
JL
16086}
16087
d75c135e 16088static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16089 int ret, int val)
16090{
1cb6686c
JL
16091 int16_t imm;
16092 TCGv t0;
16093 TCGv val_t;
16094
16095 if (ret == 0) {
16096 /* Treat as NOP. */
1cb6686c
JL
16097 return;
16098 }
16099
16100 t0 = tcg_temp_new();
16101 val_t = tcg_temp_new();
16102 gen_load_gpr(val_t, val);
16103
16104 switch (op1) {
16105 case OPC_ABSQ_S_PH_DSP:
16106 switch (op2) {
16107 case OPC_BITREV:
16108 check_dsp(ctx);
16109 gen_helper_bitrev(cpu_gpr[ret], val_t);
16110 break;
16111 case OPC_REPL_QB:
16112 check_dsp(ctx);
16113 {
16114 target_long result;
16115 imm = (ctx->opcode >> 16) & 0xFF;
16116 result = (uint32_t)imm << 24 |
16117 (uint32_t)imm << 16 |
16118 (uint32_t)imm << 8 |
16119 (uint32_t)imm;
16120 result = (int32_t)result;
16121 tcg_gen_movi_tl(cpu_gpr[ret], result);
16122 }
16123 break;
16124 case OPC_REPLV_QB:
16125 check_dsp(ctx);
16126 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16127 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16128 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16129 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16130 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16131 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16132 break;
16133 case OPC_REPL_PH:
16134 check_dsp(ctx);
16135 {
16136 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16137 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16138 tcg_gen_movi_tl(cpu_gpr[ret], \
16139 (target_long)((int32_t)imm << 16 | \
c4aaba92 16140 (uint16_t)imm));
1cb6686c
JL
16141 }
16142 break;
16143 case OPC_REPLV_PH:
16144 check_dsp(ctx);
16145 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16146 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16147 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16148 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16149 break;
16150 }
16151 break;
16152#ifdef TARGET_MIPS64
16153 case OPC_ABSQ_S_QH_DSP:
16154 switch (op2) {
16155 case OPC_REPL_OB:
16156 check_dsp(ctx);
16157 {
16158 target_long temp;
16159
16160 imm = (ctx->opcode >> 16) & 0xFF;
16161 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16162 temp = (temp << 16) | temp;
16163 temp = (temp << 32) | temp;
16164 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16165 break;
16166 }
16167 case OPC_REPL_PW:
16168 check_dsp(ctx);
16169 {
16170 target_long temp;
16171
16172 imm = (ctx->opcode >> 16) & 0x03FF;
16173 imm = (int16_t)(imm << 6) >> 6;
16174 temp = ((target_long)imm << 32) \
16175 | ((target_long)imm & 0xFFFFFFFF);
16176 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16177 break;
16178 }
16179 case OPC_REPL_QH:
16180 check_dsp(ctx);
16181 {
16182 target_long temp;
16183
16184 imm = (ctx->opcode >> 16) & 0x03FF;
16185 imm = (int16_t)(imm << 6) >> 6;
16186
16187 temp = ((uint64_t)(uint16_t)imm << 48) |
16188 ((uint64_t)(uint16_t)imm << 32) |
16189 ((uint64_t)(uint16_t)imm << 16) |
16190 (uint64_t)(uint16_t)imm;
16191 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16192 break;
16193 }
16194 case OPC_REPLV_OB:
16195 check_dsp(ctx);
16196 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16197 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16198 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16199 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16200 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16201 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16202 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16203 break;
16204 case OPC_REPLV_PW:
16205 check_dsp(ctx);
16206 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16207 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16208 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16209 break;
16210 case OPC_REPLV_QH:
16211 check_dsp(ctx);
16212 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16213 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16214 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16215 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16216 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16217 break;
16218 }
16219 break;
16220#endif
16221 }
16222 tcg_temp_free(t0);
16223 tcg_temp_free(val_t);
1cb6686c
JL
16224}
16225
26690560
JL
16226static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16227 uint32_t op1, uint32_t op2,
16228 int ret, int v1, int v2, int check_ret)
16229{
26690560
JL
16230 TCGv t1;
16231 TCGv v1_t;
16232 TCGv v2_t;
16233
16234 if ((ret == 0) && (check_ret == 1)) {
16235 /* Treat as NOP. */
26690560
JL
16236 return;
16237 }
16238
26690560
JL
16239 t1 = tcg_temp_new();
16240 v1_t = tcg_temp_new();
16241 v2_t = tcg_temp_new();
16242
16243 gen_load_gpr(v1_t, v1);
16244 gen_load_gpr(v2_t, v2);
16245
16246 switch (op1) {
26690560
JL
16247 case OPC_CMPU_EQ_QB_DSP:
16248 switch (op2) {
16249 case OPC_CMPU_EQ_QB:
16250 check_dsp(ctx);
16251 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16252 break;
16253 case OPC_CMPU_LT_QB:
16254 check_dsp(ctx);
16255 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16256 break;
16257 case OPC_CMPU_LE_QB:
16258 check_dsp(ctx);
16259 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16260 break;
16261 case OPC_CMPGU_EQ_QB:
16262 check_dsp(ctx);
16263 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16264 break;
16265 case OPC_CMPGU_LT_QB:
16266 check_dsp(ctx);
16267 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16268 break;
16269 case OPC_CMPGU_LE_QB:
16270 check_dsp(ctx);
16271 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16272 break;
16273 case OPC_CMPGDU_EQ_QB:
16274 check_dspr2(ctx);
16275 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16276 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16277 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16278 tcg_gen_shli_tl(t1, t1, 24);
16279 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16280 break;
16281 case OPC_CMPGDU_LT_QB:
16282 check_dspr2(ctx);
16283 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16284 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16285 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16286 tcg_gen_shli_tl(t1, t1, 24);
16287 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16288 break;
16289 case OPC_CMPGDU_LE_QB:
16290 check_dspr2(ctx);
16291 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16292 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16293 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16294 tcg_gen_shli_tl(t1, t1, 24);
16295 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16296 break;
16297 case OPC_CMP_EQ_PH:
16298 check_dsp(ctx);
16299 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16300 break;
16301 case OPC_CMP_LT_PH:
16302 check_dsp(ctx);
16303 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16304 break;
16305 case OPC_CMP_LE_PH:
16306 check_dsp(ctx);
16307 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16308 break;
16309 case OPC_PICK_QB:
16310 check_dsp(ctx);
16311 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16312 break;
16313 case OPC_PICK_PH:
16314 check_dsp(ctx);
16315 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16316 break;
16317 case OPC_PACKRL_PH:
16318 check_dsp(ctx);
16319 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16320 break;
16321 }
16322 break;
16323#ifdef TARGET_MIPS64
16324 case OPC_CMPU_EQ_OB_DSP:
16325 switch (op2) {
16326 case OPC_CMP_EQ_PW:
16327 check_dsp(ctx);
16328 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16329 break;
16330 case OPC_CMP_LT_PW:
16331 check_dsp(ctx);
16332 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16333 break;
16334 case OPC_CMP_LE_PW:
16335 check_dsp(ctx);
16336 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16337 break;
16338 case OPC_CMP_EQ_QH:
16339 check_dsp(ctx);
16340 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16341 break;
16342 case OPC_CMP_LT_QH:
16343 check_dsp(ctx);
16344 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16345 break;
16346 case OPC_CMP_LE_QH:
16347 check_dsp(ctx);
16348 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16349 break;
16350 case OPC_CMPGDU_EQ_OB:
16351 check_dspr2(ctx);
16352 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16353 break;
16354 case OPC_CMPGDU_LT_OB:
16355 check_dspr2(ctx);
16356 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16357 break;
16358 case OPC_CMPGDU_LE_OB:
16359 check_dspr2(ctx);
16360 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16361 break;
16362 case OPC_CMPGU_EQ_OB:
16363 check_dsp(ctx);
16364 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16365 break;
16366 case OPC_CMPGU_LT_OB:
16367 check_dsp(ctx);
16368 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16369 break;
16370 case OPC_CMPGU_LE_OB:
16371 check_dsp(ctx);
16372 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16373 break;
16374 case OPC_CMPU_EQ_OB:
16375 check_dsp(ctx);
16376 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16377 break;
16378 case OPC_CMPU_LT_OB:
16379 check_dsp(ctx);
16380 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16381 break;
16382 case OPC_CMPU_LE_OB:
16383 check_dsp(ctx);
16384 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16385 break;
16386 case OPC_PACKRL_PW:
16387 check_dsp(ctx);
16388 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16389 break;
16390 case OPC_PICK_OB:
16391 check_dsp(ctx);
16392 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16393 break;
16394 case OPC_PICK_PW:
16395 check_dsp(ctx);
16396 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16397 break;
16398 case OPC_PICK_QH:
16399 check_dsp(ctx);
16400 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16401 break;
16402 }
16403 break;
df6126a7
AJ
16404#endif
16405 }
16406
16407 tcg_temp_free(t1);
16408 tcg_temp_free(v1_t);
16409 tcg_temp_free(v2_t);
df6126a7
AJ
16410}
16411
16412static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16413 uint32_t op1, int rt, int rs, int sa)
16414{
df6126a7
AJ
16415 TCGv t0;
16416
16417 check_dspr2(ctx);
16418
16419 if (rt == 0) {
16420 /* Treat as NOP. */
df6126a7
AJ
16421 return;
16422 }
16423
16424 t0 = tcg_temp_new();
16425 gen_load_gpr(t0, rs);
16426
16427 switch (op1) {
16428 case OPC_APPEND_DSP:
16429 switch (MASK_APPEND(ctx->opcode)) {
16430 case OPC_APPEND:
16431 if (sa != 0) {
16432 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16433 }
16434 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16435 break;
16436 case OPC_PREPEND:
16437 if (sa != 0) {
16438 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16439 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16440 tcg_gen_shli_tl(t0, t0, 32 - sa);
16441 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16442 }
16443 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16444 break;
16445 case OPC_BALIGN:
16446 sa &= 3;
16447 if (sa != 0 && sa != 2) {
16448 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16449 tcg_gen_ext32u_tl(t0, t0);
16450 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16451 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16452 }
16453 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16454 break;
16455 default: /* Invalid */
16456 MIPS_INVAL("MASK APPEND");
9c708c7f 16457 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16458 break;
16459 }
16460 break;
16461#ifdef TARGET_MIPS64
26690560 16462 case OPC_DAPPEND_DSP:
df6126a7 16463 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16464 case OPC_DAPPEND:
df6126a7
AJ
16465 if (sa != 0) {
16466 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16467 }
26690560
JL
16468 break;
16469 case OPC_PREPENDD:
df6126a7
AJ
16470 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16471 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16472 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16473 break;
16474 case OPC_PREPENDW:
df6126a7
AJ
16475 if (sa != 0) {
16476 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16477 tcg_gen_shli_tl(t0, t0, 64 - sa);
16478 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16479 }
26690560
JL
16480 break;
16481 case OPC_DBALIGN:
df6126a7
AJ
16482 sa &= 7;
16483 if (sa != 0 && sa != 2 && sa != 4) {
16484 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16485 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16486 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16487 }
26690560
JL
16488 break;
16489 default: /* Invalid */
16490 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16491 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16492 break;
16493 }
16494 break;
16495#endif
16496 }
df6126a7 16497 tcg_temp_free(t0);
26690560
JL
16498}
16499
b53371ed
JL
16500static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16501 int ret, int v1, int v2, int check_ret)
16502
16503{
b53371ed
JL
16504 TCGv t0;
16505 TCGv t1;
16506 TCGv v1_t;
16507 TCGv v2_t;
16508 int16_t imm;
16509
16510 if ((ret == 0) && (check_ret == 1)) {
16511 /* Treat as NOP. */
b53371ed
JL
16512 return;
16513 }
16514
16515 t0 = tcg_temp_new();
16516 t1 = tcg_temp_new();
16517 v1_t = tcg_temp_new();
16518 v2_t = tcg_temp_new();
16519
16520 gen_load_gpr(v1_t, v1);
16521 gen_load_gpr(v2_t, v2);
16522
16523 switch (op1) {
16524 case OPC_EXTR_W_DSP:
16525 check_dsp(ctx);
16526 switch (op2) {
16527 case OPC_EXTR_W:
16528 tcg_gen_movi_tl(t0, v2);
16529 tcg_gen_movi_tl(t1, v1);
16530 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16531 break;
16532 case OPC_EXTR_R_W:
16533 tcg_gen_movi_tl(t0, v2);
16534 tcg_gen_movi_tl(t1, v1);
16535 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16536 break;
16537 case OPC_EXTR_RS_W:
16538 tcg_gen_movi_tl(t0, v2);
16539 tcg_gen_movi_tl(t1, v1);
16540 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16541 break;
16542 case OPC_EXTR_S_H:
16543 tcg_gen_movi_tl(t0, v2);
16544 tcg_gen_movi_tl(t1, v1);
16545 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16546 break;
16547 case OPC_EXTRV_S_H:
16548 tcg_gen_movi_tl(t0, v2);
16549 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16550 break;
16551 case OPC_EXTRV_W:
16552 tcg_gen_movi_tl(t0, v2);
16553 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16554 break;
16555 case OPC_EXTRV_R_W:
16556 tcg_gen_movi_tl(t0, v2);
16557 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16558 break;
16559 case OPC_EXTRV_RS_W:
16560 tcg_gen_movi_tl(t0, v2);
16561 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16562 break;
16563 case OPC_EXTP:
16564 tcg_gen_movi_tl(t0, v2);
16565 tcg_gen_movi_tl(t1, v1);
16566 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16567 break;
16568 case OPC_EXTPV:
16569 tcg_gen_movi_tl(t0, v2);
16570 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16571 break;
16572 case OPC_EXTPDP:
16573 tcg_gen_movi_tl(t0, v2);
16574 tcg_gen_movi_tl(t1, v1);
16575 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16576 break;
16577 case OPC_EXTPDPV:
16578 tcg_gen_movi_tl(t0, v2);
16579 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16580 break;
16581 case OPC_SHILO:
16582 imm = (ctx->opcode >> 20) & 0x3F;
16583 tcg_gen_movi_tl(t0, ret);
16584 tcg_gen_movi_tl(t1, imm);
16585 gen_helper_shilo(t0, t1, cpu_env);
16586 break;
16587 case OPC_SHILOV:
16588 tcg_gen_movi_tl(t0, ret);
16589 gen_helper_shilo(t0, v1_t, cpu_env);
16590 break;
16591 case OPC_MTHLIP:
16592 tcg_gen_movi_tl(t0, ret);
16593 gen_helper_mthlip(t0, v1_t, cpu_env);
16594 break;
16595 case OPC_WRDSP:
16596 imm = (ctx->opcode >> 11) & 0x3FF;
16597 tcg_gen_movi_tl(t0, imm);
16598 gen_helper_wrdsp(v1_t, t0, cpu_env);
16599 break;
16600 case OPC_RDDSP:
16601 imm = (ctx->opcode >> 16) & 0x03FF;
16602 tcg_gen_movi_tl(t0, imm);
16603 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16604 break;
16605 }
16606 break;
16607#ifdef TARGET_MIPS64
16608 case OPC_DEXTR_W_DSP:
16609 check_dsp(ctx);
16610 switch (op2) {
16611 case OPC_DMTHLIP:
16612 tcg_gen_movi_tl(t0, ret);
16613 gen_helper_dmthlip(v1_t, t0, cpu_env);
16614 break;
16615 case OPC_DSHILO:
16616 {
16617 int shift = (ctx->opcode >> 19) & 0x7F;
16618 int ac = (ctx->opcode >> 11) & 0x03;
16619 tcg_gen_movi_tl(t0, shift);
16620 tcg_gen_movi_tl(t1, ac);
16621 gen_helper_dshilo(t0, t1, cpu_env);
16622 break;
16623 }
16624 case OPC_DSHILOV:
16625 {
16626 int ac = (ctx->opcode >> 11) & 0x03;
16627 tcg_gen_movi_tl(t0, ac);
16628 gen_helper_dshilo(v1_t, t0, cpu_env);
16629 break;
16630 }
16631 case OPC_DEXTP:
16632 tcg_gen_movi_tl(t0, v2);
16633 tcg_gen_movi_tl(t1, v1);
16634
16635 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16636 break;
16637 case OPC_DEXTPV:
16638 tcg_gen_movi_tl(t0, v2);
16639 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16640 break;
16641 case OPC_DEXTPDP:
16642 tcg_gen_movi_tl(t0, v2);
16643 tcg_gen_movi_tl(t1, v1);
16644 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16645 break;
16646 case OPC_DEXTPDPV:
16647 tcg_gen_movi_tl(t0, v2);
16648 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16649 break;
16650 case OPC_DEXTR_L:
16651 tcg_gen_movi_tl(t0, v2);
16652 tcg_gen_movi_tl(t1, v1);
16653 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16654 break;
16655 case OPC_DEXTR_R_L:
16656 tcg_gen_movi_tl(t0, v2);
16657 tcg_gen_movi_tl(t1, v1);
16658 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16659 break;
16660 case OPC_DEXTR_RS_L:
16661 tcg_gen_movi_tl(t0, v2);
16662 tcg_gen_movi_tl(t1, v1);
16663 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16664 break;
16665 case OPC_DEXTR_W:
16666 tcg_gen_movi_tl(t0, v2);
16667 tcg_gen_movi_tl(t1, v1);
16668 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16669 break;
16670 case OPC_DEXTR_R_W:
16671 tcg_gen_movi_tl(t0, v2);
16672 tcg_gen_movi_tl(t1, v1);
16673 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16674 break;
16675 case OPC_DEXTR_RS_W:
16676 tcg_gen_movi_tl(t0, v2);
16677 tcg_gen_movi_tl(t1, v1);
16678 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16679 break;
16680 case OPC_DEXTR_S_H:
16681 tcg_gen_movi_tl(t0, v2);
16682 tcg_gen_movi_tl(t1, v1);
16683 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16684 break;
16685 case OPC_DEXTRV_S_H:
16686 tcg_gen_movi_tl(t0, v2);
16687 tcg_gen_movi_tl(t1, v1);
16688 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16689 break;
16690 case OPC_DEXTRV_L:
16691 tcg_gen_movi_tl(t0, v2);
16692 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16693 break;
16694 case OPC_DEXTRV_R_L:
16695 tcg_gen_movi_tl(t0, v2);
16696 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16697 break;
16698 case OPC_DEXTRV_RS_L:
16699 tcg_gen_movi_tl(t0, v2);
16700 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16701 break;
16702 case OPC_DEXTRV_W:
16703 tcg_gen_movi_tl(t0, v2);
16704 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16705 break;
16706 case OPC_DEXTRV_R_W:
16707 tcg_gen_movi_tl(t0, v2);
16708 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16709 break;
16710 case OPC_DEXTRV_RS_W:
16711 tcg_gen_movi_tl(t0, v2);
16712 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16713 break;
16714 }
16715 break;
16716#endif
16717 }
16718
16719 tcg_temp_free(t0);
16720 tcg_temp_free(t1);
16721 tcg_temp_free(v1_t);
16722 tcg_temp_free(v2_t);
b53371ed
JL
16723}
16724
9b1a1d68
JL
16725/* End MIPSDSP functions. */
16726
10dc65db
LA
16727static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16728{
4267d3e6 16729 int rs, rt, rd, sa;
b42ee5e1 16730 uint32_t op1, op2;
10dc65db
LA
16731
16732 rs = (ctx->opcode >> 21) & 0x1f;
16733 rt = (ctx->opcode >> 16) & 0x1f;
16734 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16735 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16736
16737 op1 = MASK_SPECIAL(ctx->opcode);
16738 switch (op1) {
d4ea6acd 16739 case OPC_LSA:
1f1b4c00 16740 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16741 break;
b42ee5e1
LA
16742 case OPC_MULT ... OPC_DIVU:
16743 op2 = MASK_R6_MULDIV(ctx->opcode);
16744 switch (op2) {
16745 case R6_OPC_MUL:
16746 case R6_OPC_MUH:
16747 case R6_OPC_MULU:
16748 case R6_OPC_MUHU:
16749 case R6_OPC_DIV:
16750 case R6_OPC_MOD:
16751 case R6_OPC_DIVU:
16752 case R6_OPC_MODU:
16753 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16754 break;
16755 default:
16756 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16757 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16758 break;
16759 }
16760 break;
10dc65db
LA
16761 case OPC_SELEQZ:
16762 case OPC_SELNEZ:
16763 gen_cond_move(ctx, op1, rd, rs, rt);
16764 break;
4267d3e6
LA
16765 case R6_OPC_CLO:
16766 case R6_OPC_CLZ:
16767 if (rt == 0 && sa == 1) {
16768 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16769 We need additionally to check other fields */
16770 gen_cl(ctx, op1, rd, rs);
16771 } else {
9c708c7f 16772 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16773 }
16774 break;
16775 case R6_OPC_SDBBP:
3b3c1694
LA
16776 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16777 gen_helper_do_semihosting(cpu_env);
faf1f68b 16778 } else {
3b3c1694 16779 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 16780 generate_exception_end(ctx, EXCP_RI);
3b3c1694 16781 } else {
9c708c7f 16782 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 16783 }
faf1f68b 16784 }
4267d3e6 16785 break;
b42ee5e1 16786#if defined(TARGET_MIPS64)
d4ea6acd
LA
16787 case OPC_DLSA:
16788 check_mips_64(ctx);
1f1b4c00 16789 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16790 break;
4267d3e6
LA
16791 case R6_OPC_DCLO:
16792 case R6_OPC_DCLZ:
16793 if (rt == 0 && sa == 1) {
16794 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16795 We need additionally to check other fields */
16796 check_mips_64(ctx);
16797 gen_cl(ctx, op1, rd, rs);
16798 } else {
9c708c7f 16799 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16800 }
16801 break;
b42ee5e1
LA
16802 case OPC_DMULT ... OPC_DDIVU:
16803 op2 = MASK_R6_MULDIV(ctx->opcode);
16804 switch (op2) {
16805 case R6_OPC_DMUL:
16806 case R6_OPC_DMUH:
16807 case R6_OPC_DMULU:
16808 case R6_OPC_DMUHU:
16809 case R6_OPC_DDIV:
16810 case R6_OPC_DMOD:
16811 case R6_OPC_DDIVU:
16812 case R6_OPC_DMODU:
16813 check_mips_64(ctx);
16814 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16815 break;
16816 default:
16817 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16818 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16819 break;
16820 }
16821 break;
16822#endif
10dc65db
LA
16823 default: /* Invalid */
16824 MIPS_INVAL("special_r6");
9c708c7f 16825 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
16826 break;
16827 }
16828}
16829
16830static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16831{
b42ee5e1 16832 int rs, rt, rd, sa;
10dc65db
LA
16833 uint32_t op1;
16834
16835 rs = (ctx->opcode >> 21) & 0x1f;
16836 rt = (ctx->opcode >> 16) & 0x1f;
16837 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16838 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16839
16840 op1 = MASK_SPECIAL(ctx->opcode);
16841 switch (op1) {
16842 case OPC_MOVN: /* Conditional move */
16843 case OPC_MOVZ:
16844 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16845 INSN_LOONGSON2E | INSN_LOONGSON2F);
16846 gen_cond_move(ctx, op1, rd, rs, rt);
16847 break;
16848 case OPC_MFHI: /* Move from HI/LO */
16849 case OPC_MFLO:
16850 gen_HILO(ctx, op1, rs & 3, rd);
16851 break;
16852 case OPC_MTHI:
16853 case OPC_MTLO: /* Move to HI/LO */
16854 gen_HILO(ctx, op1, rd & 3, rs);
16855 break;
16856 case OPC_MOVCI:
16857 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16858 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16859 check_cp1_enabled(ctx);
16860 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16861 (ctx->opcode >> 16) & 1);
16862 } else {
16863 generate_exception_err(ctx, EXCP_CpU, 1);
16864 }
16865 break;
b42ee5e1
LA
16866 case OPC_MULT:
16867 case OPC_MULTU:
16868 if (sa) {
16869 check_insn(ctx, INSN_VR54XX);
16870 op1 = MASK_MUL_VR54XX(ctx->opcode);
16871 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16872 } else {
16873 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16874 }
16875 break;
16876 case OPC_DIV:
16877 case OPC_DIVU:
16878 gen_muldiv(ctx, op1, 0, rs, rt);
16879 break;
16880#if defined(TARGET_MIPS64)
16881 case OPC_DMULT ... OPC_DDIVU:
16882 check_insn(ctx, ISA_MIPS3);
16883 check_mips_64(ctx);
16884 gen_muldiv(ctx, op1, 0, rs, rt);
16885 break;
16886#endif
0aefa333 16887 case OPC_JR:
b231c103 16888 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16889 break;
4267d3e6
LA
16890 case OPC_SPIM:
16891#ifdef MIPS_STRICT_STANDARD
16892 MIPS_INVAL("SPIM");
9c708c7f 16893 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16894#else
16895 /* Implemented as RI exception for now. */
16896 MIPS_INVAL("spim (unofficial)");
9c708c7f 16897 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16898#endif
16899 break;
10dc65db
LA
16900 default: /* Invalid */
16901 MIPS_INVAL("special_legacy");
9c708c7f 16902 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
16903 break;
16904 }
16905}
16906
099e5b4d 16907static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16908{
3c824109 16909 int rs, rt, rd, sa;
099e5b4d 16910 uint32_t op1;
3c824109 16911
3c824109
NF
16912 rs = (ctx->opcode >> 21) & 0x1f;
16913 rt = (ctx->opcode >> 16) & 0x1f;
16914 rd = (ctx->opcode >> 11) & 0x1f;
16915 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16916
16917 op1 = MASK_SPECIAL(ctx->opcode);
16918 switch (op1) {
16919 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16920 if (sa == 5 && rd == 0 &&
16921 rs == 0 && rt == 0) { /* PAUSE */
16922 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16923 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 16924 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
16925 break;
16926 }
16927 }
16928 /* Fallthrough */
099e5b4d
LA
16929 case OPC_SRA:
16930 gen_shift_imm(ctx, op1, rd, rt, sa);
16931 break;
16932 case OPC_SRL:
16933 switch ((ctx->opcode >> 21) & 0x1f) {
16934 case 1:
16935 /* rotr is decoded as srl on non-R2 CPUs */
16936 if (ctx->insn_flags & ISA_MIPS32R2) {
16937 op1 = OPC_ROTR;
ea63e2c3 16938 }
099e5b4d
LA
16939 /* Fallthrough */
16940 case 0:
16941 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16942 break;
099e5b4d 16943 default:
9c708c7f 16944 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 16945 break;
099e5b4d
LA
16946 }
16947 break;
099e5b4d
LA
16948 case OPC_ADD ... OPC_SUBU:
16949 gen_arith(ctx, op1, rd, rs, rt);
16950 break;
16951 case OPC_SLLV: /* Shifts */
16952 case OPC_SRAV:
16953 gen_shift(ctx, op1, rd, rs, rt);
16954 break;
16955 case OPC_SRLV:
16956 switch ((ctx->opcode >> 6) & 0x1f) {
16957 case 1:
16958 /* rotrv is decoded as srlv on non-R2 CPUs */
16959 if (ctx->insn_flags & ISA_MIPS32R2) {
16960 op1 = OPC_ROTRV;
26135ead 16961 }
099e5b4d
LA
16962 /* Fallthrough */
16963 case 0:
16964 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16965 break;
099e5b4d 16966 default:
9c708c7f 16967 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 16968 break;
099e5b4d
LA
16969 }
16970 break;
16971 case OPC_SLT: /* Set on less than */
16972 case OPC_SLTU:
16973 gen_slt(ctx, op1, rd, rs, rt);
16974 break;
16975 case OPC_AND: /* Logic*/
16976 case OPC_OR:
16977 case OPC_NOR:
16978 case OPC_XOR:
16979 gen_logic(ctx, op1, rd, rs, rt);
16980 break;
0aefa333 16981 case OPC_JALR:
b231c103 16982 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16983 break;
16984 case OPC_TGE ... OPC_TEQ: /* Traps */
16985 case OPC_TNE:
d9224450 16986 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16987 gen_trap(ctx, op1, rs, rt, -1);
16988 break;
d4ea6acd 16989 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16990 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16991 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16992 decode_opc_special_r6(env, ctx);
16993 } else {
16994 /* Pmon entry point, also R4010 selsl */
b48cfdff 16995#ifdef MIPS_STRICT_STANDARD
d4ea6acd 16996 MIPS_INVAL("PMON / selsl");
9c708c7f 16997 generate_exception_end(ctx, EXCP_RI);
b48cfdff 16998#else
d4ea6acd 16999 gen_helper_0e0i(pmon, sa);
b48cfdff 17000#endif
d4ea6acd 17001 }
099e5b4d
LA
17002 break;
17003 case OPC_SYSCALL:
9c708c7f 17004 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17005 break;
17006 case OPC_BREAK:
9c708c7f 17007 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17008 break;
099e5b4d 17009 case OPC_SYNC:
d9224450 17010 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17011 /* Treat as NOP. */
17012 break;
4ad40f36 17013
d26bc211 17014#if defined(TARGET_MIPS64)
099e5b4d
LA
17015 /* MIPS64 specific opcodes */
17016 case OPC_DSLL:
17017 case OPC_DSRA:
17018 case OPC_DSLL32:
17019 case OPC_DSRA32:
17020 check_insn(ctx, ISA_MIPS3);
17021 check_mips_64(ctx);
17022 gen_shift_imm(ctx, op1, rd, rt, sa);
17023 break;
17024 case OPC_DSRL:
17025 switch ((ctx->opcode >> 21) & 0x1f) {
17026 case 1:
17027 /* drotr is decoded as dsrl on non-R2 CPUs */
17028 if (ctx->insn_flags & ISA_MIPS32R2) {
17029 op1 = OPC_DROTR;
ea63e2c3 17030 }
099e5b4d
LA
17031 /* Fallthrough */
17032 case 0:
d75c135e 17033 check_insn(ctx, ISA_MIPS3);
e189e748 17034 check_mips_64(ctx);
099e5b4d 17035 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17036 break;
099e5b4d 17037 default:
9c708c7f 17038 generate_exception_end(ctx, EXCP_RI);
460f00c4 17039 break;
099e5b4d
LA
17040 }
17041 break;
17042 case OPC_DSRL32:
17043 switch ((ctx->opcode >> 21) & 0x1f) {
17044 case 1:
17045 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17046 if (ctx->insn_flags & ISA_MIPS32R2) {
17047 op1 = OPC_DROTR32;
ea63e2c3 17048 }
099e5b4d
LA
17049 /* Fallthrough */
17050 case 0:
d75c135e 17051 check_insn(ctx, ISA_MIPS3);
e189e748 17052 check_mips_64(ctx);
099e5b4d 17053 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17054 break;
099e5b4d 17055 default:
9c708c7f 17056 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17057 break;
17058 }
17059 break;
099e5b4d
LA
17060 case OPC_DADD ... OPC_DSUBU:
17061 check_insn(ctx, ISA_MIPS3);
17062 check_mips_64(ctx);
17063 gen_arith(ctx, op1, rd, rs, rt);
17064 break;
17065 case OPC_DSLLV:
17066 case OPC_DSRAV:
17067 check_insn(ctx, ISA_MIPS3);
17068 check_mips_64(ctx);
17069 gen_shift(ctx, op1, rd, rs, rt);
17070 break;
17071 case OPC_DSRLV:
17072 switch ((ctx->opcode >> 6) & 0x1f) {
17073 case 1:
17074 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17075 if (ctx->insn_flags & ISA_MIPS32R2) {
17076 op1 = OPC_DROTRV;
6af0bf9c 17077 }
099e5b4d
LA
17078 /* Fallthrough */
17079 case 0:
17080 check_insn(ctx, ISA_MIPS3);
e189e748 17081 check_mips_64(ctx);
099e5b4d 17082 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17083 break;
099e5b4d 17084 default:
9c708c7f 17085 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17086 break;
17087 }
17088 break;
f7685877
YK
17089 case OPC_DLSA:
17090 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17091 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17092 decode_opc_special_r6(env, ctx);
17093 }
17094 break;
099e5b4d 17095#endif
10dc65db
LA
17096 default:
17097 if (ctx->insn_flags & ISA_MIPS32R6) {
17098 decode_opc_special_r6(env, ctx);
17099 } else {
17100 decode_opc_special_legacy(env, ctx);
17101 }
17102 }
17103}
17104
10dc65db 17105static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17106{
17107 int rs, rt, rd;
17108 uint32_t op1;
6c5c1e20 17109
4267d3e6
LA
17110 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17111
099e5b4d
LA
17112 rs = (ctx->opcode >> 21) & 0x1f;
17113 rt = (ctx->opcode >> 16) & 0x1f;
17114 rd = (ctx->opcode >> 11) & 0x1f;
17115
17116 op1 = MASK_SPECIAL2(ctx->opcode);
17117 switch (op1) {
17118 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17119 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17120 check_insn(ctx, ISA_MIPS32);
17121 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17122 break;
17123 case OPC_MUL:
099e5b4d
LA
17124 gen_arith(ctx, op1, rd, rs, rt);
17125 break;
fac5a073
LA
17126 case OPC_DIV_G_2F:
17127 case OPC_DIVU_G_2F:
17128 case OPC_MULT_G_2F:
17129 case OPC_MULTU_G_2F:
17130 case OPC_MOD_G_2F:
17131 case OPC_MODU_G_2F:
17132 check_insn(ctx, INSN_LOONGSON2F);
17133 gen_loongson_integer(ctx, op1, rd, rs, rt);
17134 break;
099e5b4d
LA
17135 case OPC_CLO:
17136 case OPC_CLZ:
17137 check_insn(ctx, ISA_MIPS32);
17138 gen_cl(ctx, op1, rd, rs);
17139 break;
17140 case OPC_SDBBP:
3b3c1694
LA
17141 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17142 gen_helper_do_semihosting(cpu_env);
17143 } else {
17144 /* XXX: not clear which exception should be raised
17145 * when in debug mode...
17146 */
17147 check_insn(ctx, ISA_MIPS32);
9c708c7f 17148 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17149 }
099e5b4d 17150 break;
9b1a1d68 17151#if defined(TARGET_MIPS64)
099e5b4d
LA
17152 case OPC_DCLO:
17153 case OPC_DCLZ:
17154 check_insn(ctx, ISA_MIPS64);
17155 check_mips_64(ctx);
17156 gen_cl(ctx, op1, rd, rs);
17157 break;
4267d3e6
LA
17158 case OPC_DMULT_G_2F:
17159 case OPC_DMULTU_G_2F:
17160 case OPC_DDIV_G_2F:
17161 case OPC_DDIVU_G_2F:
17162 case OPC_DMOD_G_2F:
17163 case OPC_DMODU_G_2F:
17164 check_insn(ctx, INSN_LOONGSON2F);
17165 gen_loongson_integer(ctx, op1, rd, rs, rt);
17166 break;
10dc65db 17167#endif
4267d3e6
LA
17168 default: /* Invalid */
17169 MIPS_INVAL("special2_legacy");
9c708c7f 17170 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17171 break;
10dc65db
LA
17172 }
17173}
17174
17175static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17176{
15eacb9b
YK
17177 int rs, rt, rd, sa;
17178 uint32_t op1, op2;
10dc65db
LA
17179 int16_t imm;
17180
17181 rs = (ctx->opcode >> 21) & 0x1f;
17182 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17183 rd = (ctx->opcode >> 11) & 0x1f;
17184 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17185 imm = (int16_t)ctx->opcode >> 7;
17186
17187 op1 = MASK_SPECIAL3(ctx->opcode);
17188 switch (op1) {
bf7910c6
LA
17189 case R6_OPC_PREF:
17190 if (rt >= 24) {
17191 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17192 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17193 }
17194 /* Treat as NOP. */
17195 break;
17196 case R6_OPC_CACHE:
40d48212 17197 check_cp0_enabled(ctx);
bf7910c6
LA
17198 /* Treat as NOP. */
17199 break;
10dc65db
LA
17200 case R6_OPC_SC:
17201 gen_st_cond(ctx, op1, rt, rs, imm);
17202 break;
17203 case R6_OPC_LL:
17204 gen_ld(ctx, op1, rt, rs, imm);
17205 break;
15eacb9b
YK
17206 case OPC_BSHFL:
17207 {
17208 if (rd == 0) {
17209 /* Treat as NOP. */
17210 break;
17211 }
15eacb9b
YK
17212 op2 = MASK_BSHFL(ctx->opcode);
17213 switch (op2) {
17214 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17215 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17216 break;
17217 case OPC_BITSWAP:
1f1b4c00 17218 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17219 break;
17220 }
15eacb9b
YK
17221 }
17222 break;
bf7910c6
LA
17223#if defined(TARGET_MIPS64)
17224 case R6_OPC_SCD:
17225 gen_st_cond(ctx, op1, rt, rs, imm);
17226 break;
17227 case R6_OPC_LLD:
17228 gen_ld(ctx, op1, rt, rs, imm);
17229 break;
15eacb9b
YK
17230 case OPC_DBSHFL:
17231 check_mips_64(ctx);
17232 {
17233 if (rd == 0) {
17234 /* Treat as NOP. */
17235 break;
17236 }
15eacb9b
YK
17237 op2 = MASK_DBSHFL(ctx->opcode);
17238 switch (op2) {
17239 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17240 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17241 break;
17242 case OPC_DBITSWAP:
1f1b4c00 17243 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17244 break;
17245 }
1f1b4c00 17246
15eacb9b
YK
17247 }
17248 break;
bf7910c6 17249#endif
10dc65db
LA
17250 default: /* Invalid */
17251 MIPS_INVAL("special3_r6");
9c708c7f 17252 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17253 break;
17254 }
17255}
17256
17257static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17258{
fac5a073 17259 int rs, rt, rd;
099e5b4d 17260 uint32_t op1, op2;
099e5b4d
LA
17261
17262 rs = (ctx->opcode >> 21) & 0x1f;
17263 rt = (ctx->opcode >> 16) & 0x1f;
17264 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17265
17266 op1 = MASK_SPECIAL3(ctx->opcode);
17267 switch (op1) {
099e5b4d
LA
17268 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17269 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17270 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17271 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17272 * the same mask and op1. */
17273 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17274 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17275 switch (op2) {
099e5b4d
LA
17276 case OPC_ADDUH_QB:
17277 case OPC_ADDUH_R_QB:
17278 case OPC_ADDQH_PH:
17279 case OPC_ADDQH_R_PH:
17280 case OPC_ADDQH_W:
17281 case OPC_ADDQH_R_W:
17282 case OPC_SUBUH_QB:
17283 case OPC_SUBUH_R_QB:
17284 case OPC_SUBQH_PH:
17285 case OPC_SUBQH_R_PH:
17286 case OPC_SUBQH_W:
17287 case OPC_SUBQH_R_W:
461c08df
JL
17288 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17289 break;
099e5b4d
LA
17290 case OPC_MUL_PH:
17291 case OPC_MUL_S_PH:
17292 case OPC_MULQ_S_W:
17293 case OPC_MULQ_RS_W:
17294 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17295 break;
461c08df 17296 default:
099e5b4d 17297 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17298 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17299 break;
17300 }
099e5b4d
LA
17301 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17302 gen_loongson_integer(ctx, op1, rd, rs, rt);
17303 } else {
9c708c7f 17304 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17305 }
17306 break;
17307 case OPC_LX_DSP:
17308 op2 = MASK_LX(ctx->opcode);
17309 switch (op2) {
17310#if defined(TARGET_MIPS64)
17311 case OPC_LDX:
17312#endif
17313 case OPC_LBUX:
17314 case OPC_LHX:
17315 case OPC_LWX:
17316 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17317 break;
17318 default: /* Invalid */
17319 MIPS_INVAL("MASK LX");
9c708c7f 17320 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17321 break;
17322 }
17323 break;
17324 case OPC_ABSQ_S_PH_DSP:
17325 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17326 switch (op2) {
17327 case OPC_ABSQ_S_QB:
17328 case OPC_ABSQ_S_PH:
17329 case OPC_ABSQ_S_W:
17330 case OPC_PRECEQ_W_PHL:
17331 case OPC_PRECEQ_W_PHR:
17332 case OPC_PRECEQU_PH_QBL:
17333 case OPC_PRECEQU_PH_QBR:
17334 case OPC_PRECEQU_PH_QBLA:
17335 case OPC_PRECEQU_PH_QBRA:
17336 case OPC_PRECEU_PH_QBL:
17337 case OPC_PRECEU_PH_QBR:
17338 case OPC_PRECEU_PH_QBLA:
17339 case OPC_PRECEU_PH_QBRA:
17340 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17341 break;
17342 case OPC_BITREV:
17343 case OPC_REPL_QB:
17344 case OPC_REPLV_QB:
17345 case OPC_REPL_PH:
17346 case OPC_REPLV_PH:
17347 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17348 break;
17349 default:
17350 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17351 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17352 break;
17353 }
17354 break;
17355 case OPC_ADDU_QB_DSP:
17356 op2 = MASK_ADDU_QB(ctx->opcode);
17357 switch (op2) {
17358 case OPC_ADDQ_PH:
17359 case OPC_ADDQ_S_PH:
17360 case OPC_ADDQ_S_W:
17361 case OPC_ADDU_QB:
17362 case OPC_ADDU_S_QB:
17363 case OPC_ADDU_PH:
17364 case OPC_ADDU_S_PH:
17365 case OPC_SUBQ_PH:
17366 case OPC_SUBQ_S_PH:
17367 case OPC_SUBQ_S_W:
17368 case OPC_SUBU_QB:
17369 case OPC_SUBU_S_QB:
17370 case OPC_SUBU_PH:
17371 case OPC_SUBU_S_PH:
17372 case OPC_ADDSC:
17373 case OPC_ADDWC:
17374 case OPC_MODSUB:
17375 case OPC_RADDU_W_QB:
17376 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17377 break;
17378 case OPC_MULEU_S_PH_QBL:
17379 case OPC_MULEU_S_PH_QBR:
17380 case OPC_MULQ_RS_PH:
17381 case OPC_MULEQ_S_W_PHL:
17382 case OPC_MULEQ_S_W_PHR:
17383 case OPC_MULQ_S_PH:
17384 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17385 break;
17386 default: /* Invalid */
17387 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17388 generate_exception_end(ctx, EXCP_RI);
461c08df 17389 break;
461c08df 17390
099e5b4d
LA
17391 }
17392 break;
17393 case OPC_CMPU_EQ_QB_DSP:
17394 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17395 switch (op2) {
17396 case OPC_PRECR_SRA_PH_W:
17397 case OPC_PRECR_SRA_R_PH_W:
17398 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17399 break;
099e5b4d
LA
17400 case OPC_PRECR_QB_PH:
17401 case OPC_PRECRQ_QB_PH:
17402 case OPC_PRECRQ_PH_W:
17403 case OPC_PRECRQ_RS_PH_W:
17404 case OPC_PRECRQU_S_QB_PH:
17405 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17406 break;
099e5b4d
LA
17407 case OPC_CMPU_EQ_QB:
17408 case OPC_CMPU_LT_QB:
17409 case OPC_CMPU_LE_QB:
17410 case OPC_CMP_EQ_PH:
17411 case OPC_CMP_LT_PH:
17412 case OPC_CMP_LE_PH:
17413 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17414 break;
099e5b4d
LA
17415 case OPC_CMPGU_EQ_QB:
17416 case OPC_CMPGU_LT_QB:
17417 case OPC_CMPGU_LE_QB:
17418 case OPC_CMPGDU_EQ_QB:
17419 case OPC_CMPGDU_LT_QB:
17420 case OPC_CMPGDU_LE_QB:
17421 case OPC_PICK_QB:
17422 case OPC_PICK_PH:
17423 case OPC_PACKRL_PH:
17424 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17425 break;
17426 default: /* Invalid */
17427 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17428 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17429 break;
17430 }
17431 break;
17432 case OPC_SHLL_QB_DSP:
17433 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17434 break;
17435 case OPC_DPA_W_PH_DSP:
17436 op2 = MASK_DPA_W_PH(ctx->opcode);
17437 switch (op2) {
17438 case OPC_DPAU_H_QBL:
17439 case OPC_DPAU_H_QBR:
17440 case OPC_DPSU_H_QBL:
17441 case OPC_DPSU_H_QBR:
17442 case OPC_DPA_W_PH:
17443 case OPC_DPAX_W_PH:
17444 case OPC_DPAQ_S_W_PH:
17445 case OPC_DPAQX_S_W_PH:
17446 case OPC_DPAQX_SA_W_PH:
17447 case OPC_DPS_W_PH:
17448 case OPC_DPSX_W_PH:
17449 case OPC_DPSQ_S_W_PH:
17450 case OPC_DPSQX_S_W_PH:
17451 case OPC_DPSQX_SA_W_PH:
17452 case OPC_MULSAQ_S_W_PH:
17453 case OPC_DPAQ_SA_L_W:
17454 case OPC_DPSQ_SA_L_W:
17455 case OPC_MAQ_S_W_PHL:
17456 case OPC_MAQ_S_W_PHR:
17457 case OPC_MAQ_SA_W_PHL:
17458 case OPC_MAQ_SA_W_PHR:
17459 case OPC_MULSA_W_PH:
17460 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17461 break;
17462 default: /* Invalid */
17463 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17464 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17465 break;
17466 }
17467 break;
17468 case OPC_INSV_DSP:
17469 op2 = MASK_INSV(ctx->opcode);
17470 switch (op2) {
17471 case OPC_INSV:
17472 check_dsp(ctx);
17473 {
17474 TCGv t0, t1;
17475
17476 if (rt == 0) {
099e5b4d
LA
17477 break;
17478 }
17479
17480 t0 = tcg_temp_new();
17481 t1 = tcg_temp_new();
17482
17483 gen_load_gpr(t0, rt);
17484 gen_load_gpr(t1, rs);
17485
17486 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17487
17488 tcg_temp_free(t0);
17489 tcg_temp_free(t1);
a22260ae
JL
17490 break;
17491 }
099e5b4d
LA
17492 default: /* Invalid */
17493 MIPS_INVAL("MASK INSV");
9c708c7f 17494 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17495 break;
17496 }
17497 break;
17498 case OPC_APPEND_DSP:
17499 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17500 break;
17501 case OPC_EXTR_W_DSP:
17502 op2 = MASK_EXTR_W(ctx->opcode);
17503 switch (op2) {
17504 case OPC_EXTR_W:
17505 case OPC_EXTR_R_W:
17506 case OPC_EXTR_RS_W:
17507 case OPC_EXTR_S_H:
17508 case OPC_EXTRV_S_H:
17509 case OPC_EXTRV_W:
17510 case OPC_EXTRV_R_W:
17511 case OPC_EXTRV_RS_W:
17512 case OPC_EXTP:
17513 case OPC_EXTPV:
17514 case OPC_EXTPDP:
17515 case OPC_EXTPDPV:
17516 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17517 break;
17518 case OPC_RDDSP:
17519 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17520 break;
17521 case OPC_SHILO:
17522 case OPC_SHILOV:
17523 case OPC_MTHLIP:
17524 case OPC_WRDSP:
17525 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17526 break;
17527 default: /* Invalid */
17528 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17529 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17530 break;
17531 }
17532 break;
099e5b4d 17533#if defined(TARGET_MIPS64)
fac5a073
LA
17534 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17535 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17536 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17537 check_insn(ctx, INSN_LOONGSON2E);
17538 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17539 break;
099e5b4d
LA
17540 case OPC_ABSQ_S_QH_DSP:
17541 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17542 switch (op2) {
17543 case OPC_PRECEQ_L_PWL:
17544 case OPC_PRECEQ_L_PWR:
17545 case OPC_PRECEQ_PW_QHL:
17546 case OPC_PRECEQ_PW_QHR:
17547 case OPC_PRECEQ_PW_QHLA:
17548 case OPC_PRECEQ_PW_QHRA:
17549 case OPC_PRECEQU_QH_OBL:
17550 case OPC_PRECEQU_QH_OBR:
17551 case OPC_PRECEQU_QH_OBLA:
17552 case OPC_PRECEQU_QH_OBRA:
17553 case OPC_PRECEU_QH_OBL:
17554 case OPC_PRECEU_QH_OBR:
17555 case OPC_PRECEU_QH_OBLA:
17556 case OPC_PRECEU_QH_OBRA:
17557 case OPC_ABSQ_S_OB:
17558 case OPC_ABSQ_S_PW:
17559 case OPC_ABSQ_S_QH:
17560 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17561 break;
17562 case OPC_REPL_OB:
17563 case OPC_REPL_PW:
17564 case OPC_REPL_QH:
17565 case OPC_REPLV_OB:
17566 case OPC_REPLV_PW:
17567 case OPC_REPLV_QH:
17568 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17569 break;
17570 default: /* Invalid */
17571 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 17572 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17573 break;
17574 }
17575 break;
17576 case OPC_ADDU_OB_DSP:
17577 op2 = MASK_ADDU_OB(ctx->opcode);
17578 switch (op2) {
17579 case OPC_RADDU_L_OB:
17580 case OPC_SUBQ_PW:
17581 case OPC_SUBQ_S_PW:
17582 case OPC_SUBQ_QH:
17583 case OPC_SUBQ_S_QH:
17584 case OPC_SUBU_OB:
17585 case OPC_SUBU_S_OB:
17586 case OPC_SUBU_QH:
17587 case OPC_SUBU_S_QH:
17588 case OPC_SUBUH_OB:
17589 case OPC_SUBUH_R_OB:
17590 case OPC_ADDQ_PW:
17591 case OPC_ADDQ_S_PW:
17592 case OPC_ADDQ_QH:
17593 case OPC_ADDQ_S_QH:
17594 case OPC_ADDU_OB:
17595 case OPC_ADDU_S_OB:
17596 case OPC_ADDU_QH:
17597 case OPC_ADDU_S_QH:
17598 case OPC_ADDUH_OB:
17599 case OPC_ADDUH_R_OB:
17600 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17601 break;
099e5b4d
LA
17602 case OPC_MULEQ_S_PW_QHL:
17603 case OPC_MULEQ_S_PW_QHR:
17604 case OPC_MULEU_S_QH_OBL:
17605 case OPC_MULEU_S_QH_OBR:
17606 case OPC_MULQ_RS_QH:
17607 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17608 break;
099e5b4d
LA
17609 default: /* Invalid */
17610 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 17611 generate_exception_end(ctx, EXCP_RI);
26690560 17612 break;
099e5b4d
LA
17613 }
17614 break;
17615 case OPC_CMPU_EQ_OB_DSP:
17616 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17617 switch (op2) {
17618 case OPC_PRECR_SRA_QH_PW:
17619 case OPC_PRECR_SRA_R_QH_PW:
17620 /* Return value is rt. */
17621 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17622 break;
099e5b4d
LA
17623 case OPC_PRECR_OB_QH:
17624 case OPC_PRECRQ_OB_QH:
17625 case OPC_PRECRQ_PW_L:
17626 case OPC_PRECRQ_QH_PW:
17627 case OPC_PRECRQ_RS_QH_PW:
17628 case OPC_PRECRQU_S_OB_QH:
17629 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17630 break;
099e5b4d
LA
17631 case OPC_CMPU_EQ_OB:
17632 case OPC_CMPU_LT_OB:
17633 case OPC_CMPU_LE_OB:
17634 case OPC_CMP_EQ_QH:
17635 case OPC_CMP_LT_QH:
17636 case OPC_CMP_LE_QH:
17637 case OPC_CMP_EQ_PW:
17638 case OPC_CMP_LT_PW:
17639 case OPC_CMP_LE_PW:
17640 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17641 break;
099e5b4d
LA
17642 case OPC_CMPGDU_EQ_OB:
17643 case OPC_CMPGDU_LT_OB:
17644 case OPC_CMPGDU_LE_OB:
17645 case OPC_CMPGU_EQ_OB:
17646 case OPC_CMPGU_LT_OB:
17647 case OPC_CMPGU_LE_OB:
17648 case OPC_PACKRL_PW:
17649 case OPC_PICK_OB:
17650 case OPC_PICK_PW:
17651 case OPC_PICK_QH:
17652 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17653 break;
099e5b4d
LA
17654 default: /* Invalid */
17655 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 17656 generate_exception_end(ctx, EXCP_RI);
161f85e6 17657 break;
099e5b4d
LA
17658 }
17659 break;
17660 case OPC_DAPPEND_DSP:
17661 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17662 break;
17663 case OPC_DEXTR_W_DSP:
17664 op2 = MASK_DEXTR_W(ctx->opcode);
17665 switch (op2) {
17666 case OPC_DEXTP:
17667 case OPC_DEXTPDP:
17668 case OPC_DEXTPDPV:
17669 case OPC_DEXTPV:
17670 case OPC_DEXTR_L:
17671 case OPC_DEXTR_R_L:
17672 case OPC_DEXTR_RS_L:
17673 case OPC_DEXTR_W:
17674 case OPC_DEXTR_R_W:
17675 case OPC_DEXTR_RS_W:
17676 case OPC_DEXTR_S_H:
17677 case OPC_DEXTRV_L:
17678 case OPC_DEXTRV_R_L:
17679 case OPC_DEXTRV_RS_L:
17680 case OPC_DEXTRV_S_H:
17681 case OPC_DEXTRV_W:
17682 case OPC_DEXTRV_R_W:
17683 case OPC_DEXTRV_RS_W:
17684 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17685 break;
099e5b4d
LA
17686 case OPC_DMTHLIP:
17687 case OPC_DSHILO:
17688 case OPC_DSHILOV:
17689 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17690 break;
099e5b4d
LA
17691 default: /* Invalid */
17692 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17693 generate_exception_end(ctx, EXCP_RI);
461c08df 17694 break;
099e5b4d
LA
17695 }
17696 break;
17697 case OPC_DPAQ_W_QH_DSP:
17698 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17699 switch (op2) {
17700 case OPC_DPAU_H_OBL:
17701 case OPC_DPAU_H_OBR:
17702 case OPC_DPSU_H_OBL:
17703 case OPC_DPSU_H_OBR:
17704 case OPC_DPA_W_QH:
17705 case OPC_DPAQ_S_W_QH:
17706 case OPC_DPS_W_QH:
17707 case OPC_DPSQ_S_W_QH:
17708 case OPC_MULSAQ_S_W_QH:
17709 case OPC_DPAQ_SA_L_PW:
17710 case OPC_DPSQ_SA_L_PW:
17711 case OPC_MULSAQ_S_L_PW:
17712 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17713 break;
17714 case OPC_MAQ_S_W_QHLL:
17715 case OPC_MAQ_S_W_QHLR:
17716 case OPC_MAQ_S_W_QHRL:
17717 case OPC_MAQ_S_W_QHRR:
17718 case OPC_MAQ_SA_W_QHLL:
17719 case OPC_MAQ_SA_W_QHLR:
17720 case OPC_MAQ_SA_W_QHRL:
17721 case OPC_MAQ_SA_W_QHRR:
17722 case OPC_MAQ_S_L_PWL:
17723 case OPC_MAQ_S_L_PWR:
17724 case OPC_DMADD:
17725 case OPC_DMADDU:
17726 case OPC_DMSUB:
17727 case OPC_DMSUBU:
17728 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17729 break;
099e5b4d
LA
17730 default: /* Invalid */
17731 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 17732 generate_exception_end(ctx, EXCP_RI);
b53371ed 17733 break;
099e5b4d
LA
17734 }
17735 break;
17736 case OPC_DINSV_DSP:
17737 op2 = MASK_INSV(ctx->opcode);
17738 switch (op2) {
17739 case OPC_DINSV:
17740 {
17741 TCGv t0, t1;
17742
17743 if (rt == 0) {
a22260ae
JL
17744 break;
17745 }
099e5b4d 17746 check_dsp(ctx);
1cb6686c 17747
099e5b4d
LA
17748 t0 = tcg_temp_new();
17749 t1 = tcg_temp_new();
1cb6686c 17750
099e5b4d
LA
17751 gen_load_gpr(t0, rt);
17752 gen_load_gpr(t1, rs);
1cb6686c 17753
099e5b4d 17754 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17755
099e5b4d
LA
17756 tcg_temp_free(t0);
17757 tcg_temp_free(t1);
77c5fa8b 17758 break;
099e5b4d 17759 }
7a387fff 17760 default: /* Invalid */
099e5b4d 17761 MIPS_INVAL("MASK DINSV");
9c708c7f 17762 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
17763 break;
17764 }
17765 break;
099e5b4d
LA
17766 case OPC_SHLL_OB_DSP:
17767 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17768 break;
17769#endif
fac5a073
LA
17770 default: /* Invalid */
17771 MIPS_INVAL("special3_legacy");
9c708c7f 17772 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
17773 break;
17774 }
17775}
17776
17777static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17778{
17779 int rs, rt, rd, sa;
17780 uint32_t op1, op2;
17781
17782 rs = (ctx->opcode >> 21) & 0x1f;
17783 rt = (ctx->opcode >> 16) & 0x1f;
17784 rd = (ctx->opcode >> 11) & 0x1f;
17785 sa = (ctx->opcode >> 6) & 0x1f;
17786
17787 op1 = MASK_SPECIAL3(ctx->opcode);
17788 switch (op1) {
17789 case OPC_EXT:
17790 case OPC_INS:
17791 check_insn(ctx, ISA_MIPS32R2);
17792 gen_bitops(ctx, op1, rt, rs, sa, rd);
17793 break;
17794 case OPC_BSHFL:
fac5a073 17795 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17796 switch (op2) {
17797 case OPC_ALIGN ... OPC_ALIGN_END:
17798 case OPC_BITSWAP:
17799 check_insn(ctx, ISA_MIPS32R6);
17800 decode_opc_special3_r6(env, ctx);
17801 break;
17802 default:
17803 check_insn(ctx, ISA_MIPS32R2);
17804 gen_bshfl(ctx, op2, rt, rd);
17805 break;
17806 }
fac5a073
LA
17807 break;
17808#if defined(TARGET_MIPS64)
17809 case OPC_DEXTM ... OPC_DEXT:
17810 case OPC_DINSM ... OPC_DINS:
17811 check_insn(ctx, ISA_MIPS64R2);
17812 check_mips_64(ctx);
17813 gen_bitops(ctx, op1, rt, rs, sa, rd);
17814 break;
17815 case OPC_DBSHFL:
fac5a073 17816 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17817 switch (op2) {
17818 case OPC_DALIGN ... OPC_DALIGN_END:
17819 case OPC_DBITSWAP:
17820 check_insn(ctx, ISA_MIPS32R6);
17821 decode_opc_special3_r6(env, ctx);
17822 break;
17823 default:
17824 check_insn(ctx, ISA_MIPS64R2);
17825 check_mips_64(ctx);
17826 op2 = MASK_DBSHFL(ctx->opcode);
17827 gen_bshfl(ctx, op2, rt, rd);
17828 break;
17829 }
fac5a073
LA
17830 break;
17831#endif
17832 case OPC_RDHWR:
b00c7218 17833 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
17834 break;
17835 case OPC_FORK:
17836 check_insn(ctx, ASE_MT);
17837 {
17838 TCGv t0 = tcg_temp_new();
17839 TCGv t1 = tcg_temp_new();
17840
17841 gen_load_gpr(t0, rt);
17842 gen_load_gpr(t1, rs);
17843 gen_helper_fork(t0, t1);
17844 tcg_temp_free(t0);
17845 tcg_temp_free(t1);
17846 }
17847 break;
17848 case OPC_YIELD:
17849 check_insn(ctx, ASE_MT);
17850 {
17851 TCGv t0 = tcg_temp_new();
17852
fac5a073
LA
17853 gen_load_gpr(t0, rs);
17854 gen_helper_yield(t0, cpu_env, t0);
17855 gen_store_gpr(t0, rd);
17856 tcg_temp_free(t0);
17857 }
17858 break;
10dc65db
LA
17859 default:
17860 if (ctx->insn_flags & ISA_MIPS32R6) {
17861 decode_opc_special3_r6(env, ctx);
17862 } else {
17863 decode_opc_special3_legacy(env, ctx);
17864 }
099e5b4d
LA
17865 }
17866}
17867
863f264d
YK
17868/* MIPS SIMD Architecture (MSA) */
17869static inline int check_msa_access(DisasContext *ctx)
17870{
17871 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17872 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 17873 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
17874 return 0;
17875 }
17876
17877 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17878 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 17879 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
17880 return 0;
17881 } else {
9c708c7f 17882 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
17883 return 0;
17884 }
17885 }
17886 return 1;
17887}
17888
5692c6e1
YK
17889static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17890{
17891 /* generates tcg ops to check if any element is 0 */
17892 /* Note this function only works with MSA_WRLEN = 128 */
17893 uint64_t eval_zero_or_big = 0;
17894 uint64_t eval_big = 0;
17895 TCGv_i64 t0 = tcg_temp_new_i64();
17896 TCGv_i64 t1 = tcg_temp_new_i64();
17897 switch (df) {
17898 case DF_BYTE:
17899 eval_zero_or_big = 0x0101010101010101ULL;
17900 eval_big = 0x8080808080808080ULL;
17901 break;
17902 case DF_HALF:
17903 eval_zero_or_big = 0x0001000100010001ULL;
17904 eval_big = 0x8000800080008000ULL;
17905 break;
17906 case DF_WORD:
17907 eval_zero_or_big = 0x0000000100000001ULL;
17908 eval_big = 0x8000000080000000ULL;
17909 break;
17910 case DF_DOUBLE:
17911 eval_zero_or_big = 0x0000000000000001ULL;
17912 eval_big = 0x8000000000000000ULL;
17913 break;
17914 }
17915 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17916 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17917 tcg_gen_andi_i64(t0, t0, eval_big);
17918 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17919 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17920 tcg_gen_andi_i64(t1, t1, eval_big);
17921 tcg_gen_or_i64(t0, t0, t1);
17922 /* if all bits are zero then all elements are not zero */
17923 /* if some bit is non-zero then some element is zero */
17924 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17925 tcg_gen_trunc_i64_tl(tresult, t0);
17926 tcg_temp_free_i64(t0);
17927 tcg_temp_free_i64(t1);
17928}
17929
17930static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17931{
17932 uint8_t df = (ctx->opcode >> 21) & 0x3;
17933 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17934 int64_t s16 = (int16_t)ctx->opcode;
17935
17936 check_msa_access(ctx);
17937
17938 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 17939 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
17940 return;
17941 }
17942 switch (op1) {
17943 case OPC_BZ_V:
17944 case OPC_BNZ_V:
17945 {
17946 TCGv_i64 t0 = tcg_temp_new_i64();
17947 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17948 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17949 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17950 tcg_gen_trunc_i64_tl(bcond, t0);
17951 tcg_temp_free_i64(t0);
17952 }
17953 break;
17954 case OPC_BZ_B:
17955 case OPC_BZ_H:
17956 case OPC_BZ_W:
17957 case OPC_BZ_D:
17958 gen_check_zero_element(bcond, df, wt);
17959 break;
17960 case OPC_BNZ_B:
17961 case OPC_BNZ_H:
17962 case OPC_BNZ_W:
17963 case OPC_BNZ_D:
17964 gen_check_zero_element(bcond, df, wt);
17965 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17966 break;
17967 }
17968
17969 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17970
17971 ctx->hflags |= MIPS_HFLAG_BC;
17972 ctx->hflags |= MIPS_HFLAG_BDS32;
17973}
17974
4c789546
YK
17975static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17976{
17977#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17978 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17979 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17980 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17981
17982 TCGv_i32 twd = tcg_const_i32(wd);
17983 TCGv_i32 tws = tcg_const_i32(ws);
17984 TCGv_i32 ti8 = tcg_const_i32(i8);
17985
17986 switch (MASK_MSA_I8(ctx->opcode)) {
17987 case OPC_ANDI_B:
17988 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17989 break;
17990 case OPC_ORI_B:
17991 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17992 break;
17993 case OPC_NORI_B:
17994 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17995 break;
17996 case OPC_XORI_B:
17997 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17998 break;
17999 case OPC_BMNZI_B:
18000 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18001 break;
18002 case OPC_BMZI_B:
18003 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18004 break;
18005 case OPC_BSELI_B:
18006 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18007 break;
18008 case OPC_SHF_B:
18009 case OPC_SHF_H:
18010 case OPC_SHF_W:
18011 {
18012 uint8_t df = (ctx->opcode >> 24) & 0x3;
18013 if (df == DF_DOUBLE) {
9c708c7f 18014 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18015 } else {
18016 TCGv_i32 tdf = tcg_const_i32(df);
18017 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18018 tcg_temp_free_i32(tdf);
18019 }
18020 }
18021 break;
18022 default:
18023 MIPS_INVAL("MSA instruction");
9c708c7f 18024 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18025 break;
18026 }
18027
18028 tcg_temp_free_i32(twd);
18029 tcg_temp_free_i32(tws);
18030 tcg_temp_free_i32(ti8);
18031}
18032
80e71591
YK
18033static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18034{
18035#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18036 uint8_t df = (ctx->opcode >> 21) & 0x3;
18037 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18038 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18039 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18040 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18041
18042 TCGv_i32 tdf = tcg_const_i32(df);
18043 TCGv_i32 twd = tcg_const_i32(wd);
18044 TCGv_i32 tws = tcg_const_i32(ws);
18045 TCGv_i32 timm = tcg_temp_new_i32();
18046 tcg_gen_movi_i32(timm, u5);
18047
18048 switch (MASK_MSA_I5(ctx->opcode)) {
18049 case OPC_ADDVI_df:
18050 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18051 break;
18052 case OPC_SUBVI_df:
18053 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18054 break;
18055 case OPC_MAXI_S_df:
18056 tcg_gen_movi_i32(timm, s5);
18057 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18058 break;
18059 case OPC_MAXI_U_df:
18060 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18061 break;
18062 case OPC_MINI_S_df:
18063 tcg_gen_movi_i32(timm, s5);
18064 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18065 break;
18066 case OPC_MINI_U_df:
18067 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18068 break;
18069 case OPC_CEQI_df:
18070 tcg_gen_movi_i32(timm, s5);
18071 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18072 break;
18073 case OPC_CLTI_S_df:
18074 tcg_gen_movi_i32(timm, s5);
18075 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18076 break;
18077 case OPC_CLTI_U_df:
18078 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18079 break;
18080 case OPC_CLEI_S_df:
18081 tcg_gen_movi_i32(timm, s5);
18082 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18083 break;
18084 case OPC_CLEI_U_df:
18085 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18086 break;
18087 case OPC_LDI_df:
18088 {
18089 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18090 tcg_gen_movi_i32(timm, s10);
18091 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18092 }
18093 break;
18094 default:
18095 MIPS_INVAL("MSA instruction");
9c708c7f 18096 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18097 break;
18098 }
18099
18100 tcg_temp_free_i32(tdf);
18101 tcg_temp_free_i32(twd);
18102 tcg_temp_free_i32(tws);
18103 tcg_temp_free_i32(timm);
18104}
18105
d4cf28de
YK
18106static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18107{
18108#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18109 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18110 uint32_t df = 0, m = 0;
18111 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18112 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18113
18114 TCGv_i32 tdf;
18115 TCGv_i32 tm;
18116 TCGv_i32 twd;
18117 TCGv_i32 tws;
18118
18119 if ((dfm & 0x40) == 0x00) {
18120 m = dfm & 0x3f;
18121 df = DF_DOUBLE;
18122 } else if ((dfm & 0x60) == 0x40) {
18123 m = dfm & 0x1f;
18124 df = DF_WORD;
18125 } else if ((dfm & 0x70) == 0x60) {
18126 m = dfm & 0x0f;
18127 df = DF_HALF;
18128 } else if ((dfm & 0x78) == 0x70) {
18129 m = dfm & 0x7;
18130 df = DF_BYTE;
18131 } else {
9c708c7f 18132 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18133 return;
18134 }
18135
18136 tdf = tcg_const_i32(df);
18137 tm = tcg_const_i32(m);
18138 twd = tcg_const_i32(wd);
18139 tws = tcg_const_i32(ws);
18140
18141 switch (MASK_MSA_BIT(ctx->opcode)) {
18142 case OPC_SLLI_df:
18143 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18144 break;
18145 case OPC_SRAI_df:
18146 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18147 break;
18148 case OPC_SRLI_df:
18149 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18150 break;
18151 case OPC_BCLRI_df:
18152 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18153 break;
18154 case OPC_BSETI_df:
18155 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18156 break;
18157 case OPC_BNEGI_df:
18158 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18159 break;
18160 case OPC_BINSLI_df:
18161 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18162 break;
18163 case OPC_BINSRI_df:
18164 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18165 break;
18166 case OPC_SAT_S_df:
18167 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18168 break;
18169 case OPC_SAT_U_df:
18170 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18171 break;
18172 case OPC_SRARI_df:
18173 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18174 break;
18175 case OPC_SRLRI_df:
18176 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18177 break;
18178 default:
18179 MIPS_INVAL("MSA instruction");
9c708c7f 18180 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18181 break;
18182 }
18183
18184 tcg_temp_free_i32(tdf);
18185 tcg_temp_free_i32(tm);
18186 tcg_temp_free_i32(twd);
18187 tcg_temp_free_i32(tws);
18188}
18189
28f99f08
YK
18190static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18191{
18192#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18193 uint8_t df = (ctx->opcode >> 21) & 0x3;
18194 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18195 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18196 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18197
18198 TCGv_i32 tdf = tcg_const_i32(df);
18199 TCGv_i32 twd = tcg_const_i32(wd);
18200 TCGv_i32 tws = tcg_const_i32(ws);
18201 TCGv_i32 twt = tcg_const_i32(wt);
18202
18203 switch (MASK_MSA_3R(ctx->opcode)) {
18204 case OPC_SLL_df:
18205 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18206 break;
18207 case OPC_ADDV_df:
18208 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18209 break;
18210 case OPC_CEQ_df:
18211 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18212 break;
18213 case OPC_ADD_A_df:
18214 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18215 break;
18216 case OPC_SUBS_S_df:
18217 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18218 break;
18219 case OPC_MULV_df:
18220 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18221 break;
18222 case OPC_SLD_df:
18223 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18224 break;
18225 case OPC_VSHF_df:
18226 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18227 break;
18228 case OPC_SRA_df:
18229 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18230 break;
18231 case OPC_SUBV_df:
18232 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18233 break;
18234 case OPC_ADDS_A_df:
18235 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18236 break;
18237 case OPC_SUBS_U_df:
18238 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18239 break;
18240 case OPC_MADDV_df:
18241 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18242 break;
18243 case OPC_SPLAT_df:
18244 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18245 break;
18246 case OPC_SRAR_df:
18247 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18248 break;
18249 case OPC_SRL_df:
18250 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18251 break;
18252 case OPC_MAX_S_df:
18253 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18254 break;
18255 case OPC_CLT_S_df:
18256 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18257 break;
18258 case OPC_ADDS_S_df:
18259 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18260 break;
18261 case OPC_SUBSUS_U_df:
18262 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18263 break;
18264 case OPC_MSUBV_df:
18265 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18266 break;
18267 case OPC_PCKEV_df:
18268 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18269 break;
18270 case OPC_SRLR_df:
18271 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18272 break;
18273 case OPC_BCLR_df:
18274 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18275 break;
18276 case OPC_MAX_U_df:
18277 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18278 break;
18279 case OPC_CLT_U_df:
18280 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18281 break;
18282 case OPC_ADDS_U_df:
18283 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18284 break;
18285 case OPC_SUBSUU_S_df:
18286 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18287 break;
18288 case OPC_PCKOD_df:
18289 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18290 break;
18291 case OPC_BSET_df:
18292 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18293 break;
18294 case OPC_MIN_S_df:
18295 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18296 break;
18297 case OPC_CLE_S_df:
18298 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18299 break;
18300 case OPC_AVE_S_df:
18301 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18302 break;
18303 case OPC_ASUB_S_df:
18304 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18305 break;
18306 case OPC_DIV_S_df:
18307 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18308 break;
18309 case OPC_ILVL_df:
18310 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18311 break;
18312 case OPC_BNEG_df:
18313 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18314 break;
18315 case OPC_MIN_U_df:
18316 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18317 break;
18318 case OPC_CLE_U_df:
18319 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18320 break;
18321 case OPC_AVE_U_df:
18322 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18323 break;
18324 case OPC_ASUB_U_df:
18325 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18326 break;
18327 case OPC_DIV_U_df:
18328 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18329 break;
18330 case OPC_ILVR_df:
18331 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18332 break;
18333 case OPC_BINSL_df:
18334 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18335 break;
18336 case OPC_MAX_A_df:
18337 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18338 break;
18339 case OPC_AVER_S_df:
18340 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18341 break;
18342 case OPC_MOD_S_df:
18343 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18344 break;
18345 case OPC_ILVEV_df:
18346 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18347 break;
18348 case OPC_BINSR_df:
18349 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18350 break;
18351 case OPC_MIN_A_df:
18352 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18353 break;
18354 case OPC_AVER_U_df:
18355 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18356 break;
18357 case OPC_MOD_U_df:
18358 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18359 break;
18360 case OPC_ILVOD_df:
18361 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18362 break;
18363
18364 case OPC_DOTP_S_df:
18365 case OPC_DOTP_U_df:
18366 case OPC_DPADD_S_df:
18367 case OPC_DPADD_U_df:
18368 case OPC_DPSUB_S_df:
18369 case OPC_HADD_S_df:
18370 case OPC_DPSUB_U_df:
18371 case OPC_HADD_U_df:
18372 case OPC_HSUB_S_df:
18373 case OPC_HSUB_U_df:
18374 if (df == DF_BYTE) {
9c708c7f
PD
18375 generate_exception_end(ctx, EXCP_RI);
18376 break;
28f99f08
YK
18377 }
18378 switch (MASK_MSA_3R(ctx->opcode)) {
18379 case OPC_DOTP_S_df:
18380 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18381 break;
18382 case OPC_DOTP_U_df:
18383 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18384 break;
18385 case OPC_DPADD_S_df:
18386 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18387 break;
18388 case OPC_DPADD_U_df:
18389 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18390 break;
18391 case OPC_DPSUB_S_df:
18392 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18393 break;
18394 case OPC_HADD_S_df:
18395 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18396 break;
18397 case OPC_DPSUB_U_df:
18398 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18399 break;
18400 case OPC_HADD_U_df:
18401 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18402 break;
18403 case OPC_HSUB_S_df:
18404 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18405 break;
18406 case OPC_HSUB_U_df:
18407 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18408 break;
18409 }
18410 break;
18411 default:
18412 MIPS_INVAL("MSA instruction");
9c708c7f 18413 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18414 break;
18415 }
18416 tcg_temp_free_i32(twd);
18417 tcg_temp_free_i32(tws);
18418 tcg_temp_free_i32(twt);
18419 tcg_temp_free_i32(tdf);
18420}
18421
1e608ec1
YK
18422static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18423{
18424#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18425 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18426 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18427 TCGv telm = tcg_temp_new();
18428 TCGv_i32 tsr = tcg_const_i32(source);
18429 TCGv_i32 tdt = tcg_const_i32(dest);
18430
18431 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18432 case OPC_CTCMSA:
18433 gen_load_gpr(telm, source);
18434 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18435 break;
18436 case OPC_CFCMSA:
18437 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18438 gen_store_gpr(telm, dest);
18439 break;
18440 case OPC_MOVE_V:
18441 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18442 break;
18443 default:
18444 MIPS_INVAL("MSA instruction");
9c708c7f 18445 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18446 break;
18447 }
18448
18449 tcg_temp_free(telm);
18450 tcg_temp_free_i32(tdt);
18451 tcg_temp_free_i32(tsr);
18452}
18453
18454static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18455 uint32_t n)
18456{
18457#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18458 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18459 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18460
18461 TCGv_i32 tws = tcg_const_i32(ws);
18462 TCGv_i32 twd = tcg_const_i32(wd);
18463 TCGv_i32 tn = tcg_const_i32(n);
18464 TCGv_i32 tdf = tcg_const_i32(df);
18465
18466 switch (MASK_MSA_ELM(ctx->opcode)) {
18467 case OPC_SLDI_df:
18468 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18469 break;
18470 case OPC_SPLATI_df:
18471 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18472 break;
18473 case OPC_INSVE_df:
18474 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18475 break;
18476 case OPC_COPY_S_df:
18477 case OPC_COPY_U_df:
18478 case OPC_INSERT_df:
18479#if !defined(TARGET_MIPS64)
18480 /* Double format valid only for MIPS64 */
18481 if (df == DF_DOUBLE) {
9c708c7f 18482 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18483 break;
18484 }
18485#endif
18486 switch (MASK_MSA_ELM(ctx->opcode)) {
18487 case OPC_COPY_S_df:
18488 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18489 break;
18490 case OPC_COPY_U_df:
18491 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18492 break;
18493 case OPC_INSERT_df:
18494 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18495 break;
18496 }
18497 break;
18498 default:
18499 MIPS_INVAL("MSA instruction");
9c708c7f 18500 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18501 }
18502 tcg_temp_free_i32(twd);
18503 tcg_temp_free_i32(tws);
18504 tcg_temp_free_i32(tn);
18505 tcg_temp_free_i32(tdf);
18506}
18507
18508static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18509{
18510 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18511 uint32_t df = 0, n = 0;
18512
18513 if ((dfn & 0x30) == 0x00) {
18514 n = dfn & 0x0f;
18515 df = DF_BYTE;
18516 } else if ((dfn & 0x38) == 0x20) {
18517 n = dfn & 0x07;
18518 df = DF_HALF;
18519 } else if ((dfn & 0x3c) == 0x30) {
18520 n = dfn & 0x03;
18521 df = DF_WORD;
18522 } else if ((dfn & 0x3e) == 0x38) {
18523 n = dfn & 0x01;
18524 df = DF_DOUBLE;
18525 } else if (dfn == 0x3E) {
18526 /* CTCMSA, CFCMSA, MOVE.V */
18527 gen_msa_elm_3e(env, ctx);
18528 return;
18529 } else {
9c708c7f 18530 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18531 return;
18532 }
18533
18534 gen_msa_elm_df(env, ctx, df, n);
18535}
18536
7d05b9c8
YK
18537static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18538{
18539#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18540 uint8_t df = (ctx->opcode >> 21) & 0x1;
18541 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18542 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18543 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18544
18545 TCGv_i32 twd = tcg_const_i32(wd);
18546 TCGv_i32 tws = tcg_const_i32(ws);
18547 TCGv_i32 twt = tcg_const_i32(wt);
18548 TCGv_i32 tdf = tcg_temp_new_i32();
18549
18550 /* adjust df value for floating-point instruction */
18551 tcg_gen_movi_i32(tdf, df + 2);
18552
18553 switch (MASK_MSA_3RF(ctx->opcode)) {
18554 case OPC_FCAF_df:
18555 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18556 break;
18557 case OPC_FADD_df:
18558 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18559 break;
18560 case OPC_FCUN_df:
18561 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18562 break;
18563 case OPC_FSUB_df:
18564 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18565 break;
18566 case OPC_FCOR_df:
18567 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18568 break;
18569 case OPC_FCEQ_df:
18570 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_FMUL_df:
18573 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_FCUNE_df:
18576 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_FCUEQ_df:
18579 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18580 break;
18581 case OPC_FDIV_df:
18582 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18583 break;
18584 case OPC_FCNE_df:
18585 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18586 break;
18587 case OPC_FCLT_df:
18588 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18589 break;
18590 case OPC_FMADD_df:
18591 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18592 break;
18593 case OPC_MUL_Q_df:
18594 tcg_gen_movi_i32(tdf, df + 1);
18595 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18596 break;
18597 case OPC_FCULT_df:
18598 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18599 break;
18600 case OPC_FMSUB_df:
18601 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18602 break;
18603 case OPC_MADD_Q_df:
18604 tcg_gen_movi_i32(tdf, df + 1);
18605 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18606 break;
18607 case OPC_FCLE_df:
18608 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18609 break;
18610 case OPC_MSUB_Q_df:
18611 tcg_gen_movi_i32(tdf, df + 1);
18612 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18613 break;
18614 case OPC_FCULE_df:
18615 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18616 break;
18617 case OPC_FEXP2_df:
18618 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18619 break;
18620 case OPC_FSAF_df:
18621 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18622 break;
18623 case OPC_FEXDO_df:
18624 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18625 break;
18626 case OPC_FSUN_df:
18627 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18628 break;
18629 case OPC_FSOR_df:
18630 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18631 break;
18632 case OPC_FSEQ_df:
18633 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18634 break;
18635 case OPC_FTQ_df:
18636 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18637 break;
18638 case OPC_FSUNE_df:
18639 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18640 break;
18641 case OPC_FSUEQ_df:
18642 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18643 break;
18644 case OPC_FSNE_df:
18645 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18646 break;
18647 case OPC_FSLT_df:
18648 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18649 break;
18650 case OPC_FMIN_df:
18651 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18652 break;
18653 case OPC_MULR_Q_df:
18654 tcg_gen_movi_i32(tdf, df + 1);
18655 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18656 break;
18657 case OPC_FSULT_df:
18658 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18659 break;
18660 case OPC_FMIN_A_df:
18661 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18662 break;
18663 case OPC_MADDR_Q_df:
18664 tcg_gen_movi_i32(tdf, df + 1);
18665 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18666 break;
18667 case OPC_FSLE_df:
18668 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18669 break;
18670 case OPC_FMAX_df:
18671 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18672 break;
18673 case OPC_MSUBR_Q_df:
18674 tcg_gen_movi_i32(tdf, df + 1);
18675 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18676 break;
18677 case OPC_FSULE_df:
18678 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18679 break;
18680 case OPC_FMAX_A_df:
18681 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18682 break;
18683 default:
18684 MIPS_INVAL("MSA instruction");
9c708c7f 18685 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
18686 break;
18687 }
18688
18689 tcg_temp_free_i32(twd);
18690 tcg_temp_free_i32(tws);
18691 tcg_temp_free_i32(twt);
18692 tcg_temp_free_i32(tdf);
18693}
18694
cbe50b9a
YK
18695static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18696{
18697#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18698 (op & (0x7 << 18)))
18699 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18700 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18701 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18702 uint8_t df = (ctx->opcode >> 16) & 0x3;
18703 TCGv_i32 twd = tcg_const_i32(wd);
18704 TCGv_i32 tws = tcg_const_i32(ws);
18705 TCGv_i32 twt = tcg_const_i32(wt);
18706 TCGv_i32 tdf = tcg_const_i32(df);
18707
18708 switch (MASK_MSA_2R(ctx->opcode)) {
18709 case OPC_FILL_df:
18710#if !defined(TARGET_MIPS64)
18711 /* Double format valid only for MIPS64 */
18712 if (df == DF_DOUBLE) {
9c708c7f 18713 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18714 break;
18715 }
18716#endif
18717 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18718 break;
18719 case OPC_PCNT_df:
18720 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18721 break;
18722 case OPC_NLOC_df:
18723 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18724 break;
18725 case OPC_NLZC_df:
18726 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18727 break;
18728 default:
18729 MIPS_INVAL("MSA instruction");
9c708c7f 18730 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18731 break;
18732 }
18733
18734 tcg_temp_free_i32(twd);
18735 tcg_temp_free_i32(tws);
18736 tcg_temp_free_i32(twt);
18737 tcg_temp_free_i32(tdf);
18738}
18739
3bdeb688
YK
18740static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18741{
18742#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18743 (op & (0xf << 17)))
18744 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18745 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18746 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18747 uint8_t df = (ctx->opcode >> 16) & 0x1;
18748 TCGv_i32 twd = tcg_const_i32(wd);
18749 TCGv_i32 tws = tcg_const_i32(ws);
18750 TCGv_i32 twt = tcg_const_i32(wt);
18751 /* adjust df value for floating-point instruction */
18752 TCGv_i32 tdf = tcg_const_i32(df + 2);
18753
18754 switch (MASK_MSA_2RF(ctx->opcode)) {
18755 case OPC_FCLASS_df:
18756 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18757 break;
18758 case OPC_FTRUNC_S_df:
18759 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18760 break;
18761 case OPC_FTRUNC_U_df:
18762 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18763 break;
18764 case OPC_FSQRT_df:
18765 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18766 break;
18767 case OPC_FRSQRT_df:
18768 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18769 break;
18770 case OPC_FRCP_df:
18771 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18772 break;
18773 case OPC_FRINT_df:
18774 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18775 break;
18776 case OPC_FLOG2_df:
18777 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18778 break;
18779 case OPC_FEXUPL_df:
18780 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18781 break;
18782 case OPC_FEXUPR_df:
18783 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18784 break;
18785 case OPC_FFQL_df:
18786 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18787 break;
18788 case OPC_FFQR_df:
18789 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18790 break;
18791 case OPC_FTINT_S_df:
18792 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18793 break;
18794 case OPC_FTINT_U_df:
18795 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18796 break;
18797 case OPC_FFINT_S_df:
18798 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18799 break;
18800 case OPC_FFINT_U_df:
18801 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18802 break;
18803 }
18804
18805 tcg_temp_free_i32(twd);
18806 tcg_temp_free_i32(tws);
18807 tcg_temp_free_i32(twt);
18808 tcg_temp_free_i32(tdf);
18809}
18810
cbe50b9a
YK
18811static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18812{
18813#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18814 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18815 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18816 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18817 TCGv_i32 twd = tcg_const_i32(wd);
18818 TCGv_i32 tws = tcg_const_i32(ws);
18819 TCGv_i32 twt = tcg_const_i32(wt);
18820
18821 switch (MASK_MSA_VEC(ctx->opcode)) {
18822 case OPC_AND_V:
18823 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18824 break;
18825 case OPC_OR_V:
18826 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18827 break;
18828 case OPC_NOR_V:
18829 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18830 break;
18831 case OPC_XOR_V:
18832 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18833 break;
18834 case OPC_BMNZ_V:
18835 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18836 break;
18837 case OPC_BMZ_V:
18838 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18839 break;
18840 case OPC_BSEL_V:
18841 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18842 break;
18843 default:
18844 MIPS_INVAL("MSA instruction");
9c708c7f 18845 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18846 break;
18847 }
18848
18849 tcg_temp_free_i32(twd);
18850 tcg_temp_free_i32(tws);
18851 tcg_temp_free_i32(twt);
18852}
18853
18854static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18855{
18856 switch (MASK_MSA_VEC(ctx->opcode)) {
18857 case OPC_AND_V:
18858 case OPC_OR_V:
18859 case OPC_NOR_V:
18860 case OPC_XOR_V:
18861 case OPC_BMNZ_V:
18862 case OPC_BMZ_V:
18863 case OPC_BSEL_V:
18864 gen_msa_vec_v(env, ctx);
18865 break;
18866 case OPC_MSA_2R:
18867 gen_msa_2r(env, ctx);
18868 break;
3bdeb688
YK
18869 case OPC_MSA_2RF:
18870 gen_msa_2rf(env, ctx);
18871 break;
cbe50b9a
YK
18872 default:
18873 MIPS_INVAL("MSA instruction");
9c708c7f 18874 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18875 break;
18876 }
18877}
18878
4c789546
YK
18879static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18880{
18881 uint32_t opcode = ctx->opcode;
18882 check_insn(ctx, ASE_MSA);
18883 check_msa_access(ctx);
18884
18885 switch (MASK_MSA_MINOR(opcode)) {
18886 case OPC_MSA_I8_00:
18887 case OPC_MSA_I8_01:
18888 case OPC_MSA_I8_02:
18889 gen_msa_i8(env, ctx);
18890 break;
80e71591
YK
18891 case OPC_MSA_I5_06:
18892 case OPC_MSA_I5_07:
18893 gen_msa_i5(env, ctx);
18894 break;
d4cf28de
YK
18895 case OPC_MSA_BIT_09:
18896 case OPC_MSA_BIT_0A:
18897 gen_msa_bit(env, ctx);
18898 break;
28f99f08
YK
18899 case OPC_MSA_3R_0D:
18900 case OPC_MSA_3R_0E:
18901 case OPC_MSA_3R_0F:
18902 case OPC_MSA_3R_10:
18903 case OPC_MSA_3R_11:
18904 case OPC_MSA_3R_12:
18905 case OPC_MSA_3R_13:
18906 case OPC_MSA_3R_14:
18907 case OPC_MSA_3R_15:
18908 gen_msa_3r(env, ctx);
18909 break;
1e608ec1
YK
18910 case OPC_MSA_ELM:
18911 gen_msa_elm(env, ctx);
18912 break;
7d05b9c8
YK
18913 case OPC_MSA_3RF_1A:
18914 case OPC_MSA_3RF_1B:
18915 case OPC_MSA_3RF_1C:
18916 gen_msa_3rf(env, ctx);
18917 break;
cbe50b9a
YK
18918 case OPC_MSA_VEC:
18919 gen_msa_vec(env, ctx);
18920 break;
f7685877
YK
18921 case OPC_LD_B:
18922 case OPC_LD_H:
18923 case OPC_LD_W:
18924 case OPC_LD_D:
18925 case OPC_ST_B:
18926 case OPC_ST_H:
18927 case OPC_ST_W:
18928 case OPC_ST_D:
18929 {
18930 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18931 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18932 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18933 uint8_t df = (ctx->opcode >> 0) & 0x3;
18934
f7685877 18935 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
18936 TCGv taddr = tcg_temp_new();
18937 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
18938
18939 switch (MASK_MSA_MINOR(opcode)) {
18940 case OPC_LD_B:
adc370a4
YK
18941 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18942 break;
f7685877 18943 case OPC_LD_H:
adc370a4
YK
18944 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18945 break;
f7685877 18946 case OPC_LD_W:
adc370a4
YK
18947 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18948 break;
f7685877 18949 case OPC_LD_D:
adc370a4 18950 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
18951 break;
18952 case OPC_ST_B:
adc370a4
YK
18953 gen_helper_msa_st_b(cpu_env, twd, taddr);
18954 break;
f7685877 18955 case OPC_ST_H:
adc370a4
YK
18956 gen_helper_msa_st_h(cpu_env, twd, taddr);
18957 break;
f7685877 18958 case OPC_ST_W:
adc370a4
YK
18959 gen_helper_msa_st_w(cpu_env, twd, taddr);
18960 break;
f7685877 18961 case OPC_ST_D:
adc370a4 18962 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
18963 break;
18964 }
18965
18966 tcg_temp_free_i32(twd);
adc370a4 18967 tcg_temp_free(taddr);
f7685877
YK
18968 }
18969 break;
4c789546
YK
18970 default:
18971 MIPS_INVAL("MSA instruction");
9c708c7f 18972 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18973 break;
18974 }
18975
18976}
18977
d2bfa6e6 18978static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18979{
18980 int32_t offset;
18981 int rs, rt, rd, sa;
18982 uint32_t op, op1;
18983 int16_t imm;
18984
18985 /* make sure instructions are on a word boundary */
18986 if (ctx->pc & 0x3) {
18987 env->CP0_BadVAddr = ctx->pc;
aea14095 18988 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
18989 return;
18990 }
18991
18992 /* Handle blikely not taken case */
18993 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18994 TCGLabel *l1 = gen_new_label();
099e5b4d 18995
099e5b4d
LA
18996 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18997 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18998 gen_goto_tb(ctx, 1, ctx->pc + 4);
18999 gen_set_label(l1);
19000 }
19001
099e5b4d
LA
19002 op = MASK_OP_MAJOR(ctx->opcode);
19003 rs = (ctx->opcode >> 21) & 0x1f;
19004 rt = (ctx->opcode >> 16) & 0x1f;
19005 rd = (ctx->opcode >> 11) & 0x1f;
19006 sa = (ctx->opcode >> 6) & 0x1f;
19007 imm = (int16_t)ctx->opcode;
19008 switch (op) {
19009 case OPC_SPECIAL:
19010 decode_opc_special(env, ctx);
19011 break;
19012 case OPC_SPECIAL2:
4267d3e6 19013 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19014 break;
19015 case OPC_SPECIAL3:
19016 decode_opc_special3(env, ctx);
19017 break;
7a387fff
TS
19018 case OPC_REGIMM:
19019 op1 = MASK_REGIMM(ctx->opcode);
19020 switch (op1) {
fecd2646
LA
19021 case OPC_BLTZL: /* REGIMM branches */
19022 case OPC_BGEZL:
19023 case OPC_BLTZALL:
19024 case OPC_BGEZALL:
d9224450 19025 check_insn(ctx, ISA_MIPS2);
fecd2646 19026 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19027 /* Fallthrough */
fecd2646
LA
19028 case OPC_BLTZ:
19029 case OPC_BGEZ:
b231c103 19030 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19031 break;
fecd2646
LA
19032 case OPC_BLTZAL:
19033 case OPC_BGEZAL:
0aefa333
YK
19034 if (ctx->insn_flags & ISA_MIPS32R6) {
19035 if (rs == 0) {
19036 /* OPC_NAL, OPC_BAL */
b231c103 19037 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19038 } else {
9c708c7f 19039 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19040 }
19041 } else {
b231c103 19042 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19043 }
c9602061 19044 break;
7a387fff
TS
19045 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19046 case OPC_TNEI:
d9224450 19047 check_insn(ctx, ISA_MIPS2);
fecd2646 19048 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19049 gen_trap(ctx, op1, rs, -1, imm);
19050 break;
bb238210
YK
19051 case OPC_SIGRIE:
19052 check_insn(ctx, ISA_MIPS32R6);
19053 generate_exception_end(ctx, EXCP_RI);
19054 break;
7a387fff 19055 case OPC_SYNCI:
d75c135e 19056 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19057 /* Break the TB to be able to sync copied instructions
19058 immediately */
19059 ctx->bstate = BS_STOP;
6af0bf9c 19060 break;
e45a93e2
JL
19061 case OPC_BPOSGE32: /* MIPS DSP branch */
19062#if defined(TARGET_MIPS64)
19063 case OPC_BPOSGE64:
19064#endif
19065 check_dsp(ctx);
b231c103 19066 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19067 break;
d4ea6acd
LA
19068#if defined(TARGET_MIPS64)
19069 case OPC_DAHI:
19070 check_insn(ctx, ISA_MIPS32R6);
19071 check_mips_64(ctx);
19072 if (rs != 0) {
19073 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19074 }
d4ea6acd
LA
19075 break;
19076 case OPC_DATI:
19077 check_insn(ctx, ISA_MIPS32R6);
19078 check_mips_64(ctx);
19079 if (rs != 0) {
19080 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19081 }
d4ea6acd
LA
19082 break;
19083#endif
6af0bf9c 19084 default: /* Invalid */
923617a3 19085 MIPS_INVAL("regimm");
9c708c7f 19086 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19087 break;
19088 }
19089 break;
7a387fff 19090 case OPC_CP0:
387a8fe5 19091 check_cp0_enabled(ctx);
7a387fff 19092 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19093 switch (op1) {
7a387fff
TS
19094 case OPC_MFC0:
19095 case OPC_MTC0:
ead9360e
TS
19096 case OPC_MFTR:
19097 case OPC_MTTR:
5204ea79
LA
19098 case OPC_MFHC0:
19099 case OPC_MTHC0:
d26bc211 19100#if defined(TARGET_MIPS64)
7a387fff
TS
19101 case OPC_DMFC0:
19102 case OPC_DMTC0:
19103#endif
f1aa6320 19104#ifndef CONFIG_USER_ONLY
932e71cd 19105 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19106#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19107 break;
19108 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19109#ifndef CONFIG_USER_ONLY
932e71cd 19110 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19111#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19112 break;
19113 case OPC_MFMC0:
8706c382 19114#ifndef CONFIG_USER_ONLY
932e71cd 19115 {
099e5b4d 19116 uint32_t op2;
35fbce2c 19117 TCGv t0 = tcg_temp_new();
6c5c1e20 19118
0eaef5aa 19119 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19120 switch (op2) {
19121 case OPC_DMT:
d75c135e 19122 check_insn(ctx, ASE_MT);
9ed5726c 19123 gen_helper_dmt(t0);
35fbce2c 19124 gen_store_gpr(t0, rt);
6c5c1e20
TS
19125 break;
19126 case OPC_EMT:
d75c135e 19127 check_insn(ctx, ASE_MT);
9ed5726c 19128 gen_helper_emt(t0);
35fbce2c 19129 gen_store_gpr(t0, rt);
da80682b 19130 break;
6c5c1e20 19131 case OPC_DVPE:
d75c135e 19132 check_insn(ctx, ASE_MT);
895c2d04 19133 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19134 gen_store_gpr(t0, rt);
6c5c1e20
TS
19135 break;
19136 case OPC_EVPE:
d75c135e 19137 check_insn(ctx, ASE_MT);
895c2d04 19138 gen_helper_evpe(t0, cpu_env);
35fbce2c 19139 gen_store_gpr(t0, rt);
6c5c1e20 19140 break;
01bc435b
YK
19141 case OPC_DVP:
19142 check_insn(ctx, ISA_MIPS32R6);
19143 if (ctx->vp) {
19144 gen_helper_dvp(t0, cpu_env);
19145 gen_store_gpr(t0, rt);
19146 }
19147 break;
19148 case OPC_EVP:
19149 check_insn(ctx, ISA_MIPS32R6);
19150 if (ctx->vp) {
19151 gen_helper_evp(t0, cpu_env);
19152 gen_store_gpr(t0, rt);
19153 }
19154 break;
6c5c1e20 19155 case OPC_DI:
d75c135e 19156 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19157 save_cpu_state(ctx, 1);
895c2d04 19158 gen_helper_di(t0, cpu_env);
35fbce2c 19159 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19160 /* Stop translation as we may have switched
19161 the execution mode. */
6c5c1e20
TS
19162 ctx->bstate = BS_STOP;
19163 break;
19164 case OPC_EI:
d75c135e 19165 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19166 save_cpu_state(ctx, 1);
895c2d04 19167 gen_helper_ei(t0, cpu_env);
35fbce2c 19168 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19169 /* Stop translation as we may have switched
19170 the execution mode. */
6c5c1e20
TS
19171 ctx->bstate = BS_STOP;
19172 break;
19173 default: /* Invalid */
19174 MIPS_INVAL("mfmc0");
9c708c7f 19175 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19176 break;
19177 }
6c5c1e20 19178 tcg_temp_free(t0);
7a387fff 19179 }
0eaef5aa 19180#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19181 break;
7a387fff 19182 case OPC_RDPGPR:
d75c135e 19183 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19184 gen_load_srsgpr(rt, rd);
ead9360e 19185 break;
7a387fff 19186 case OPC_WRPGPR:
d75c135e 19187 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19188 gen_store_srsgpr(rt, rd);
38121543 19189 break;
6af0bf9c 19190 default:
923617a3 19191 MIPS_INVAL("cp0");
9c708c7f 19192 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19193 break;
19194 }
19195 break;
31837be3
YK
19196 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19197 if (ctx->insn_flags & ISA_MIPS32R6) {
19198 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19199 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19200 } else {
19201 /* OPC_ADDI */
19202 /* Arithmetic with immediate opcode */
19203 gen_arith_imm(ctx, op, rt, rs, imm);
19204 }
19205 break;
324d9e32 19206 case OPC_ADDIU:
d75c135e 19207 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19208 break;
324d9e32
AJ
19209 case OPC_SLTI: /* Set on less than with immediate opcode */
19210 case OPC_SLTIU:
d75c135e 19211 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19212 break;
19213 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19214 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19215 case OPC_ORI:
19216 case OPC_XORI:
d75c135e 19217 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19218 break;
7a387fff
TS
19219 case OPC_J ... OPC_JAL: /* Jump */
19220 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19221 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19222 break;
31837be3
YK
19223 /* Branch */
19224 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19225 if (ctx->insn_flags & ISA_MIPS32R6) {
19226 if (rt == 0) {
9c708c7f 19227 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19228 break;
19229 }
19230 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19231 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19232 } else {
19233 /* OPC_BLEZL */
b231c103 19234 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19235 }
19236 break;
19237 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19238 if (ctx->insn_flags & ISA_MIPS32R6) {
19239 if (rt == 0) {
9c708c7f 19240 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19241 break;
19242 }
19243 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19244 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19245 } else {
19246 /* OPC_BGTZL */
b231c103 19247 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19248 }
19249 break;
19250 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19251 if (rt == 0) {
19252 /* OPC_BLEZ */
b231c103 19253 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19254 } else {
19255 check_insn(ctx, ISA_MIPS32R6);
19256 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19257 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19258 }
19259 break;
19260 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19261 if (rt == 0) {
19262 /* OPC_BGTZ */
b231c103 19263 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19264 } else {
19265 check_insn(ctx, ISA_MIPS32R6);
19266 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19267 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19268 }
19269 break;
19270 case OPC_BEQL:
19271 case OPC_BNEL:
d9224450 19272 check_insn(ctx, ISA_MIPS2);
fecd2646 19273 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19274 /* Fallthrough */
31837be3
YK
19275 case OPC_BEQ:
19276 case OPC_BNE:
b231c103 19277 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19278 break;
d9224450
MR
19279 case OPC_LL: /* Load and stores */
19280 check_insn(ctx, ISA_MIPS2);
19281 /* Fallthrough */
19282 case OPC_LWL:
fecd2646
LA
19283 case OPC_LWR:
19284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19285 /* Fallthrough */
fecd2646
LA
19286 case OPC_LB ... OPC_LH:
19287 case OPC_LW ... OPC_LHU:
d75c135e 19288 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19289 break;
fecd2646 19290 case OPC_SWL:
7a387fff 19291 case OPC_SWR:
fecd2646 19292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19293 /* fall through */
fecd2646
LA
19294 case OPC_SB ... OPC_SH:
19295 case OPC_SW:
5c13fdfd 19296 gen_st(ctx, op, rt, rs, imm);
7a387fff 19297 break;
d66c7132 19298 case OPC_SC:
d9224450 19299 check_insn(ctx, ISA_MIPS2);
4368b29a 19300 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19301 gen_st_cond(ctx, op, rt, rs, imm);
19302 break;
7a387fff 19303 case OPC_CACHE:
bf7910c6 19304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19305 check_cp0_enabled(ctx);
d75c135e 19306 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 19307 /* Treat as NOP. */
34ae7b51 19308 break;
7a387fff 19309 case OPC_PREF:
bf7910c6 19310 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19311 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19312 /* Treat as NOP. */
6af0bf9c 19313 break;
4ad40f36 19314
923617a3 19315 /* Floating point (COP1). */
7a387fff
TS
19316 case OPC_LWC1:
19317 case OPC_LDC1:
19318 case OPC_SWC1:
19319 case OPC_SDC1:
5ab5c041 19320 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19321 break;
19322
7a387fff 19323 case OPC_CP1:
5692c6e1
YK
19324 op1 = MASK_CP1(ctx->opcode);
19325
19326 switch (op1) {
19327 case OPC_MFHC1:
19328 case OPC_MTHC1:
5e755519 19329 check_cp1_enabled(ctx);
5692c6e1
YK
19330 check_insn(ctx, ISA_MIPS32R2);
19331 case OPC_MFC1:
19332 case OPC_CFC1:
19333 case OPC_MTC1:
19334 case OPC_CTC1:
19335 check_cp1_enabled(ctx);
19336 gen_cp1(ctx, op1, rt, rd);
19337 break;
d26bc211 19338#if defined(TARGET_MIPS64)
5692c6e1
YK
19339 case OPC_DMFC1:
19340 case OPC_DMTC1:
19341 check_cp1_enabled(ctx);
19342 check_insn(ctx, ISA_MIPS3);
d9224450 19343 check_mips_64(ctx);
5692c6e1
YK
19344 gen_cp1(ctx, op1, rt, rd);
19345 break;
e189e748 19346#endif
5692c6e1
YK
19347 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19348 check_cp1_enabled(ctx);
19349 if (ctx->insn_flags & ISA_MIPS32R6) {
19350 /* OPC_BC1EQZ */
31837be3 19351 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19352 rt, imm << 2, 4);
5692c6e1
YK
19353 } else {
19354 /* OPC_BC1ANY2 */
b8aa4598 19355 check_cop1x(ctx);
d75c135e 19356 check_insn(ctx, ASE_MIPS3D);
d75c135e 19357 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19358 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19359 }
19360 break;
19361 case OPC_BC1NEZ:
19362 check_cp1_enabled(ctx);
19363 check_insn(ctx, ISA_MIPS32R6);
19364 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19365 rt, imm << 2, 4);
5692c6e1
YK
19366 break;
19367 case OPC_BC1ANY4:
19368 check_cp1_enabled(ctx);
19369 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19370 check_cop1x(ctx);
19371 check_insn(ctx, ASE_MIPS3D);
19372 /* fall through */
19373 case OPC_BC1:
19374 check_cp1_enabled(ctx);
19375 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19376 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19377 (rt >> 2) & 0x7, imm << 2);
19378 break;
19379 case OPC_PS_FMT:
e29c9628 19380 check_ps(ctx);
b6f3b233 19381 /* fall through */
5692c6e1
YK
19382 case OPC_S_FMT:
19383 case OPC_D_FMT:
19384 check_cp1_enabled(ctx);
19385 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19386 (imm >> 8) & 0x7);
19387 break;
19388 case OPC_W_FMT:
19389 case OPC_L_FMT:
19390 {
19391 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19392 check_cp1_enabled(ctx);
19393 if (ctx->insn_flags & ISA_MIPS32R6) {
19394 switch (r6_op) {
19395 case R6_OPC_CMP_AF_S:
19396 case R6_OPC_CMP_UN_S:
19397 case R6_OPC_CMP_EQ_S:
19398 case R6_OPC_CMP_UEQ_S:
19399 case R6_OPC_CMP_LT_S:
19400 case R6_OPC_CMP_ULT_S:
19401 case R6_OPC_CMP_LE_S:
19402 case R6_OPC_CMP_ULE_S:
19403 case R6_OPC_CMP_SAF_S:
19404 case R6_OPC_CMP_SUN_S:
19405 case R6_OPC_CMP_SEQ_S:
19406 case R6_OPC_CMP_SEUQ_S:
19407 case R6_OPC_CMP_SLT_S:
19408 case R6_OPC_CMP_SULT_S:
19409 case R6_OPC_CMP_SLE_S:
19410 case R6_OPC_CMP_SULE_S:
19411 case R6_OPC_CMP_OR_S:
19412 case R6_OPC_CMP_UNE_S:
19413 case R6_OPC_CMP_NE_S:
19414 case R6_OPC_CMP_SOR_S:
19415 case R6_OPC_CMP_SUNE_S:
19416 case R6_OPC_CMP_SNE_S:
19417 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19418 break;
19419 case R6_OPC_CMP_AF_D:
19420 case R6_OPC_CMP_UN_D:
19421 case R6_OPC_CMP_EQ_D:
19422 case R6_OPC_CMP_UEQ_D:
19423 case R6_OPC_CMP_LT_D:
19424 case R6_OPC_CMP_ULT_D:
19425 case R6_OPC_CMP_LE_D:
19426 case R6_OPC_CMP_ULE_D:
19427 case R6_OPC_CMP_SAF_D:
19428 case R6_OPC_CMP_SUN_D:
19429 case R6_OPC_CMP_SEQ_D:
19430 case R6_OPC_CMP_SEUQ_D:
19431 case R6_OPC_CMP_SLT_D:
19432 case R6_OPC_CMP_SULT_D:
19433 case R6_OPC_CMP_SLE_D:
19434 case R6_OPC_CMP_SULE_D:
19435 case R6_OPC_CMP_OR_D:
19436 case R6_OPC_CMP_UNE_D:
19437 case R6_OPC_CMP_NE_D:
19438 case R6_OPC_CMP_SOR_D:
19439 case R6_OPC_CMP_SUNE_D:
19440 case R6_OPC_CMP_SNE_D:
19441 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19442 break;
19443 default:
d2bfa6e6
MR
19444 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19445 rt, rd, sa, (imm >> 8) & 0x7);
19446
5692c6e1 19447 break;
3f493883 19448 }
5692c6e1
YK
19449 } else {
19450 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19451 (imm >> 8) & 0x7);
36d23958 19452 }
5692c6e1
YK
19453 break;
19454 }
19455 case OPC_BZ_V:
19456 case OPC_BNZ_V:
19457 case OPC_BZ_B:
19458 case OPC_BZ_H:
19459 case OPC_BZ_W:
19460 case OPC_BZ_D:
19461 case OPC_BNZ_B:
19462 case OPC_BNZ_H:
19463 case OPC_BNZ_W:
19464 case OPC_BNZ_D:
19465 check_insn(ctx, ASE_MSA);
19466 gen_msa_branch(env, ctx, op1);
19467 break;
19468 default:
19469 MIPS_INVAL("cp1");
9c708c7f 19470 generate_exception_end(ctx, EXCP_RI);
5692c6e1 19471 break;
6ea83fed 19472 }
4ad40f36
FB
19473 break;
19474
31837be3
YK
19475 /* Compact branches [R6] and COP2 [non-R6] */
19476 case OPC_BC: /* OPC_LWC2 */
19477 case OPC_BALC: /* OPC_SWC2 */
19478 if (ctx->insn_flags & ISA_MIPS32R6) {
19479 /* OPC_BC, OPC_BALC */
19480 gen_compute_compact_branch(ctx, op, 0, 0,
19481 sextract32(ctx->opcode << 2, 0, 28));
19482 } else {
19483 /* OPC_LWC2, OPC_SWC2 */
19484 /* COP2: Not implemented. */
19485 generate_exception_err(ctx, EXCP_CpU, 2);
19486 }
19487 break;
19488 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19489 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19490 if (ctx->insn_flags & ISA_MIPS32R6) {
19491 if (rs != 0) {
19492 /* OPC_BEQZC, OPC_BNEZC */
19493 gen_compute_compact_branch(ctx, op, rs, 0,
19494 sextract32(ctx->opcode << 2, 0, 23));
19495 } else {
19496 /* OPC_JIC, OPC_JIALC */
19497 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19498 }
19499 } else {
19500 /* OPC_LWC2, OPC_SWC2 */
19501 /* COP2: Not implemented. */
19502 generate_exception_err(ctx, EXCP_CpU, 2);
19503 }
4ad40f36 19504 break;
bd277fa1 19505 case OPC_CP2:
d75c135e 19506 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19507 /* Note that these instructions use different fields. */
19508 gen_loongson_multimedia(ctx, sa, rd, rt);
19509 break;
4ad40f36 19510
7a387fff 19511 case OPC_CP3:
fecd2646 19512 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19513 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19514 check_cp1_enabled(ctx);
36d23958
TS
19515 op1 = MASK_CP3(ctx->opcode);
19516 switch (op1) {
d9224450
MR
19517 case OPC_LUXC1:
19518 case OPC_SUXC1:
19519 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19520 /* Fallthrough */
5a5012ec
TS
19521 case OPC_LWXC1:
19522 case OPC_LDXC1:
5a5012ec
TS
19523 case OPC_SWXC1:
19524 case OPC_SDXC1:
d9224450 19525 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19526 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19527 break;
e0c84da7 19528 case OPC_PREFX:
d9224450 19529 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19530 /* Treat as NOP. */
e0c84da7 19531 break;
5a5012ec 19532 case OPC_ALNV_PS:
d9224450
MR
19533 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19534 /* Fallthrough */
5a5012ec
TS
19535 case OPC_MADD_S:
19536 case OPC_MADD_D:
19537 case OPC_MADD_PS:
19538 case OPC_MSUB_S:
19539 case OPC_MSUB_D:
19540 case OPC_MSUB_PS:
19541 case OPC_NMADD_S:
19542 case OPC_NMADD_D:
19543 case OPC_NMADD_PS:
19544 case OPC_NMSUB_S:
19545 case OPC_NMSUB_D:
19546 case OPC_NMSUB_PS:
d9224450 19547 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19548 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19549 break;
36d23958 19550 default:
923617a3 19551 MIPS_INVAL("cp3");
9c708c7f 19552 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
19553 break;
19554 }
19555 } else {
e397ee33 19556 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19557 }
4ad40f36
FB
19558 break;
19559
d26bc211 19560#if defined(TARGET_MIPS64)
7a387fff 19561 /* MIPS64 opcodes */
7a387fff 19562 case OPC_LDL ... OPC_LDR:
bf7910c6 19563 case OPC_LLD:
fecd2646 19564 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19565 /* fall through */
fecd2646 19566 case OPC_LWU:
7a387fff 19567 case OPC_LD:
d75c135e 19568 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19569 check_mips_64(ctx);
d75c135e 19570 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19571 break;
19572 case OPC_SDL ... OPC_SDR:
fecd2646 19573 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19574 /* fall through */
7a387fff 19575 case OPC_SD:
d75c135e 19576 check_insn(ctx, ISA_MIPS3);
e189e748 19577 check_mips_64(ctx);
5c13fdfd 19578 gen_st(ctx, op, rt, rs, imm);
7a387fff 19579 break;
d66c7132 19580 case OPC_SCD:
bf7910c6 19581 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19582 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19583 check_mips_64(ctx);
19584 gen_st_cond(ctx, op, rt, rs, imm);
19585 break;
31837be3
YK
19586 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19587 if (ctx->insn_flags & ISA_MIPS32R6) {
19588 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19589 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19590 } else {
19591 /* OPC_DADDI */
19592 check_insn(ctx, ISA_MIPS3);
19593 check_mips_64(ctx);
19594 gen_arith_imm(ctx, op, rt, rs, imm);
19595 }
19596 break;
324d9e32 19597 case OPC_DADDIU:
d75c135e 19598 check_insn(ctx, ISA_MIPS3);
e189e748 19599 check_mips_64(ctx);
d75c135e 19600 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19601 break;
31837be3
YK
19602#else
19603 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19604 if (ctx->insn_flags & ISA_MIPS32R6) {
19605 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19606 } else {
19607 MIPS_INVAL("major opcode");
9c708c7f 19608 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19609 }
19610 break;
6af0bf9c 19611#endif
d4ea6acd
LA
19612 case OPC_DAUI: /* OPC_JALX */
19613 if (ctx->insn_flags & ISA_MIPS32R6) {
19614#if defined(TARGET_MIPS64)
19615 /* OPC_DAUI */
19616 check_mips_64(ctx);
db77d852
LA
19617 if (rs == 0) {
19618 generate_exception(ctx, EXCP_RI);
19619 } else if (rt != 0) {
d4ea6acd
LA
19620 TCGv t0 = tcg_temp_new();
19621 gen_load_gpr(t0, rs);
19622 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19623 tcg_temp_free(t0);
19624 }
d4ea6acd 19625#else
9c708c7f 19626 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
19627 MIPS_INVAL("major opcode");
19628#endif
19629 } else {
19630 /* OPC_JALX */
19631 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19632 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19633 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19634 }
364d4831 19635 break;
4c789546 19636 case OPC_MSA: /* OPC_MDMX */
7a387fff 19637 /* MDMX: Not implemented. */
4c789546 19638 gen_msa(env, ctx);
d4ea6acd
LA
19639 break;
19640 case OPC_PCREL:
19641 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 19642 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 19643 break;
6af0bf9c 19644 default: /* Invalid */
923617a3 19645 MIPS_INVAL("major opcode");
9c708c7f 19646 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19647 break;
19648 }
6af0bf9c
FB
19649}
19650
4e5e1215 19651void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19652{
4e5e1215 19653 MIPSCPU *cpu = mips_env_get_cpu(env);
ed2803da 19654 CPUState *cs = CPU(cpu);
278d0702 19655 DisasContext ctx;
6af0bf9c 19656 target_ulong pc_start;
fe237291 19657 target_ulong next_page_start;
2e70f6ef
PB
19658 int num_insns;
19659 int max_insns;
c9602061 19660 int insn_bytes;
339cd2a8 19661 int is_slot;
6af0bf9c
FB
19662
19663 pc_start = tb->pc;
fe237291 19664 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19665 ctx.pc = pc_start;
4ad40f36 19666 ctx.saved_pc = -1;
ed2803da 19667 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19668 ctx.insn_flags = env->insn_flags;
5ab5c041 19669 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19670 ctx.tb = tb;
19671 ctx.bstate = BS_NONE;
c20d594e 19672 ctx.btarget = 0;
e98c0d17 19673 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19674 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19675 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19676 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19677 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
19678 ctx.PAMask = env->PAMask;
19679 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19680 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
c870e3f5 19681 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 19682 /* Restore delay slot state from the tb context. */
c068688b 19683 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19684 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
19685 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19686 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
01bc435b 19687 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
fd4a04eb 19688 restore_cpu_state(env, &ctx);
932e71cd 19689#ifdef CONFIG_USER_ONLY
0eaef5aa 19690 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19691#else
0eaef5aa 19692 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19693#endif
be3a8c53
YK
19694 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19695 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19696 num_insns = 0;
19697 max_insns = tb->cflags & CF_COUNT_MASK;
190ce7fb 19698 if (max_insns == 0) {
2e70f6ef 19699 max_insns = CF_COUNT_MASK;
190ce7fb
RH
19700 }
19701 if (max_insns > TCG_MAX_INSNS) {
19702 max_insns = TCG_MAX_INSNS;
19703 }
19704
d12d51d5 19705 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19706 gen_tb_start(tb);
faf7aaa9 19707 while (ctx.bstate == BS_NONE) {
c20d594e 19708 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
959082fc 19709 num_insns++;
667b8e29 19710
b933066a
RH
19711 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19712 save_cpu_state(&ctx, 1);
19713 ctx.bstate = BS_BRANCH;
19714 gen_helper_raise_exception_debug(cpu_env);
522a0d4e
RH
19715 /* The address covered by the breakpoint must be included in
19716 [tb->pc, tb->pc + tb->size) in order to for it to be
19717 properly cleared -- thus we increment the PC here so that
19718 the logic setting tb->size below does the right thing. */
b933066a
RH
19719 ctx.pc += 4;
19720 goto done_generating;
19721 }
19722
959082fc 19723 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 19724 gen_io_start();
667b8e29 19725 }
c9602061 19726
339cd2a8 19727 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19728 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19729 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19730 insn_bytes = 4;
240ce26a 19731 decode_opc(env, &ctx);
d75c135e 19732 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19733 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19734 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19735 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19736 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19737 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 19738 } else {
9c708c7f 19739 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
19740 break;
19741 }
31837be3 19742
b231c103 19743 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19744 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19745 MIPS_HFLAG_FBNSLOT))) {
19746 /* force to generate branch as there is neither delay nor
19747 forbidden slot */
19748 is_slot = 1;
b231c103 19749 }
65935f07
YK
19750 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19751 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19752 /* Force to generate branch as microMIPS R6 doesn't restrict
19753 branches in the forbidden slot. */
19754 is_slot = 1;
19755 }
b231c103 19756 }
339cd2a8 19757 if (is_slot) {
31837be3 19758 gen_branch(&ctx, insn_bytes);
c9602061
NF
19759 }
19760 ctx.pc += insn_bytes;
19761
7b270ef2
NF
19762 /* Execute a branch and its delay slot as a single instruction.
19763 This is what GDB expects and is consistent with what the
19764 hardware does (e.g. if a delay slot instruction faults, the
19765 reported PC is the PC of the branch). */
ed2803da 19766 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19767 break;
ed2803da 19768 }
4ad40f36 19769
fe237291 19770 if (ctx.pc >= next_page_start) {
6af0bf9c 19771 break;
fe237291 19772 }
4ad40f36 19773
fe700adb 19774 if (tcg_op_buf_full()) {
faf7aaa9 19775 break;
efd7f486 19776 }
faf7aaa9 19777
2e70f6ef
PB
19778 if (num_insns >= max_insns)
19779 break;
1b530a6d
AJ
19780
19781 if (singlestep)
19782 break;
6af0bf9c 19783 }
ed2803da 19784 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19785 gen_io_end();
ed2803da
AF
19786 }
19787 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19788 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
9c708c7f 19789 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 19790 } else {
6958549d 19791 switch (ctx.bstate) {
16c00cb2 19792 case BS_STOP:
df1561e2
TS
19793 gen_goto_tb(&ctx, 0, ctx.pc);
19794 break;
16c00cb2 19795 case BS_NONE:
278d0702 19796 save_cpu_state(&ctx, 0);
16c00cb2
TS
19797 gen_goto_tb(&ctx, 0, ctx.pc);
19798 break;
5a5012ec 19799 case BS_EXCP:
57fec1fe 19800 tcg_gen_exit_tb(0);
16c00cb2 19801 break;
5a5012ec
TS
19802 case BS_BRANCH:
19803 default:
19804 break;
6958549d 19805 }
6af0bf9c 19806 }
4ad40f36 19807done_generating:
806f352d 19808 gen_tb_end(tb, num_insns);
0a7df5da 19809
4e5e1215
RH
19810 tb->size = ctx.pc - pc_start;
19811 tb->icount = num_insns;
19812
6af0bf9c 19813#ifdef DEBUG_DISAS
d12d51d5 19814 LOG_DISAS("\n");
8fec2b8c 19815 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19816 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 19817 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19818 qemu_log("\n");
6af0bf9c
FB
19819 }
19820#endif
6af0bf9c
FB
19821}
19822
7db13fae 19823static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19824 int flags)
6ea83fed
FB
19825{
19826 int i;
5e755519 19827 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19828
2a5612e6
SW
19829#define printfpr(fp) \
19830 do { \
19831 if (is_fpu64) \
19832 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19833 " fd:%13g fs:%13g psu: %13g\n", \
19834 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19835 (double)(fp)->fd, \
19836 (double)(fp)->fs[FP_ENDIAN_IDX], \
19837 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19838 else { \
19839 fpr_t tmp; \
19840 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19841 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19842 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19843 " fd:%13g fs:%13g psu:%13g\n", \
19844 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19845 (double)tmp.fd, \
19846 (double)tmp.fs[FP_ENDIAN_IDX], \
19847 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19848 } \
6ea83fed
FB
19849 } while(0)
19850
5a5012ec 19851
9a78eead
SW
19852 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19853 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19854 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19855 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19856 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19857 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19858 }
19859
19860#undef printfpr
19861}
19862
878096ee
AF
19863void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19864 int flags)
6af0bf9c 19865{
878096ee
AF
19866 MIPSCPU *cpu = MIPS_CPU(cs);
19867 CPUMIPSState *env = &cpu->env;
6af0bf9c 19868 int i;
3b46e624 19869
a7200c9f
SW
19870 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19871 " LO=0x" TARGET_FMT_lx " ds %04x "
19872 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19873 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19874 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19875 for (i = 0; i < 32; i++) {
19876 if ((i & 3) == 0)
19877 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19878 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19879 if ((i & 3) == 3)
19880 cpu_fprintf(f, "\n");
19881 }
568b600d 19882
3594c774 19883 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19884 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
19885 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19886 PRIx64 "\n",
5499b6ff 19887 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19888 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19889 env->CP0_Config2, env->CP0_Config3);
19890 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19891 env->CP0_Config4, env->CP0_Config5);
5e755519 19892 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19893 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
19894}
19895
78ce64f4 19896void mips_tcg_init(void)
39454628 19897{
f01be154 19898 int i;
39454628
TS
19899 static int inited;
19900
19901 /* Initialize various static tables. */
19902 if (inited)
6958549d 19903 return;
39454628 19904
a7812ae4 19905 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
e1ccc054 19906
f2c94b92 19907 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19908 for (i = 1; i < 32; i++)
e1ccc054 19909 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 19910 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19911 regnames[i]);
d73ee8a2 19912
863f264d
YK
19913 for (i = 0; i < 32; i++) {
19914 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19915 msa_wr_d[i * 2] =
e1ccc054 19916 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
19917 /* The scalar floating-point unit (FPU) registers are mapped on
19918 * the MSA vector registers. */
19919 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19920 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19921 msa_wr_d[i * 2 + 1] =
e1ccc054 19922 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
19923 }
19924
e1ccc054 19925 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 19926 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19927 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 19928 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 19929 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19930 regnames_HI[i]);
e1ccc054 19931 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 19932 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19933 regnames_LO[i]);
4b2eb8d2 19934 }
e1ccc054 19935 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 19936 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19937 "DSPControl");
e1ccc054 19938 bcond = tcg_global_mem_new(cpu_env,
7db13fae 19939 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 19940 btarget = tcg_global_mem_new(cpu_env,
7db13fae 19941 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 19942 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 19943 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19944
e1ccc054 19945 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 19946 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 19947 "fcr0");
e1ccc054 19948 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 19949 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19950 "fcr31");
39454628
TS
19951
19952 inited = 1;
19953}
19954
aaed909a
FB
19955#include "translate_init.c"
19956
30bf942d 19957MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19958{
0f71a709 19959 MIPSCPU *cpu;
6af0bf9c 19960 CPUMIPSState *env;
c227f099 19961 const mips_def_t *def;
6af0bf9c 19962
aaed909a
FB
19963 def = cpu_mips_find_by_name(cpu_model);
19964 if (!def)
19965 return NULL;
0f71a709
AF
19966 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19967 env = &cpu->env;
aaed909a
FB
19968 env->cpu_model = def;
19969
51cc2e78
BS
19970#ifndef CONFIG_USER_ONLY
19971 mmu_init(env, def);
19972#endif
19973 fpu_init(env, def);
19974 mvp_init(env, def);
c1caf1d9
AF
19975
19976 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19977
30bf942d 19978 return cpu;
6ae81775
TS
19979}
19980
bff384a4
LA
19981bool cpu_supports_cps_smp(const char *cpu_model)
19982{
19983 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
19984 if (!def) {
19985 return false;
19986 }
19987
19988 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
19989}
19990
1bba0dc9 19991void cpu_state_reset(CPUMIPSState *env)
6ae81775 19992{
55e5c285
AF
19993 MIPSCPU *cpu = mips_env_get_cpu(env);
19994 CPUState *cs = CPU(cpu);
6ae81775 19995
51cc2e78
BS
19996 /* Reset registers to their default values */
19997 env->CP0_PRid = env->cpu_model->CP0_PRid;
19998 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19999#ifdef TARGET_WORDS_BIGENDIAN
20000 env->CP0_Config0 |= (1 << CP0C0_BE);
20001#endif
20002 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20003 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20004 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20005 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20006 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20007 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20008 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20009 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20010 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20011 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20012 << env->cpu_model->CP0_LLAddr_shift;
20013 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20014 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20015 env->CCRes = env->cpu_model->CCRes;
20016 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20017 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20018 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20019 env->current_tc = 0;
20020 env->SEGBITS = env->cpu_model->SEGBITS;
20021 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20022#if defined(TARGET_MIPS64)
20023 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20024 env->SEGMask |= 3ULL << 62;
20025 }
20026#endif
20027 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20028 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20029 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20030 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20031 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20032 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20033 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20034 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20035 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20036 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20037 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20038 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20039 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 20040 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
ba5c79f2 20041 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20042 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20043 env->insn_flags = env->cpu_model->insn_flags;
20044
0eaef5aa 20045#if defined(CONFIG_USER_ONLY)
03e6e501 20046 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20047# ifdef TARGET_MIPS64
20048 /* Enable 64-bit register mode. */
20049 env->CP0_Status |= (1 << CP0St_PX);
20050# endif
20051# ifdef TARGET_ABI_MIPSN64
20052 /* Enable 64-bit address mode. */
20053 env->CP0_Status |= (1 << CP0St_UX);
20054# endif
94159135
MI
20055 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20056 hardware registers. */
20057 env->CP0_HWREna |= 0x0000000F;
91a75935 20058 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20059 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20060 }
6f0af304
PJ
20061 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20062 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20063 }
4d66261f
PJ
20064# if defined(TARGET_MIPS64)
20065 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20066 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20067 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20068 env->CP0_Status |= (1 << CP0St_FR);
20069 }
4d66261f 20070# endif
932e71cd
AJ
20071#else
20072 if (env->hflags & MIPS_HFLAG_BMASK) {
20073 /* If the exception was raised from a delay slot,
20074 come back to the jump. */
c3577479
MR
20075 env->CP0_ErrorEPC = (env->active_tc.PC
20076 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20077 } else {
932e71cd
AJ
20078 env->CP0_ErrorEPC = env->active_tc.PC;
20079 }
20080 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
20081 env->CP0_Random = env->tlb->nb_tlb - 1;
20082 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20083 env->CP0_Wired = 0;
01bc435b 20084 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7
JH
20085 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20086 if (kvm_enabled()) {
20087 env->CP0_EBase |= 0x40000000;
20088 } else {
20089 env->CP0_EBase |= 0x80000000;
20090 }
c870e3f5
YK
20091 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20092 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20093 }
932e71cd
AJ
20094 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20095 /* vectored interrupts not implemented, timer on int 7,
20096 no performance counters. */
20097 env->CP0_IntCtl = 0xe0000000;
20098 {
20099 int i;
20100
20101 for (i = 0; i < 7; i++) {
20102 env->CP0_WatchLo[i] = 0;
20103 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20104 }
932e71cd
AJ
20105 env->CP0_WatchLo[7] = 0;
20106 env->CP0_WatchHi[7] = 0;
fd88b6ab 20107 }
932e71cd
AJ
20108 /* Count register increments in debug mode, EJTAG version 1 */
20109 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20110
4b69c7e2
JH
20111 cpu_mips_store_count(env, 1);
20112
9e56e756
EI
20113 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20114 int i;
20115
20116 /* Only TC0 on VPE 0 starts as active. */
20117 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20118 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20119 env->tcs[i].CP0_TCHalt = 1;
20120 }
20121 env->active_tc.CP0_TCHalt = 1;
259186a7 20122 cs->halted = 1;
9e56e756 20123
55e5c285 20124 if (cs->cpu_index == 0) {
9e56e756
EI
20125 /* VPE0 starts up enabled. */
20126 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20127 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20128
20129 /* TC0 starts up unhalted. */
259186a7 20130 cs->halted = 0;
9e56e756
EI
20131 env->active_tc.CP0_TCHalt = 0;
20132 env->tcs[0].CP0_TCHalt = 0;
20133 /* With thread 0 active. */
20134 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20135 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20136 }
20137 }
51cc2e78 20138#endif
ddc584bd
LA
20139 if ((env->insn_flags & ISA_MIPS32R6) &&
20140 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20141 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20142 env->CP0_Status |= (1 << CP0St_FR);
20143 }
20144
863f264d
YK
20145 /* MSA */
20146 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20147 msa_reset(env);
20148 }
20149
03e6e501 20150 compute_hflags(env);
bb962386
MR
20151 restore_rounding_mode(env);
20152 restore_flush_mode(env);
e117f526 20153 restore_pamask(env);
27103424 20154 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20155
20156 if (semihosting_get_argc()) {
20157 /* UHI interface can be used to obtain argc and argv */
20158 env->active_tc.gpr[4] = -1;
20159 }
6af0bf9c 20160}
d2856f1a 20161
bad729e2
RH
20162void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20163 target_ulong *data)
d2856f1a 20164{
bad729e2 20165 env->active_tc.PC = data[0];
d2856f1a 20166 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20167 env->hflags |= data[1];
4636401d
AJ
20168 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20169 case MIPS_HFLAG_BR:
20170 break;
20171 case MIPS_HFLAG_BC:
20172 case MIPS_HFLAG_BL:
20173 case MIPS_HFLAG_B:
bad729e2 20174 env->btarget = data[2];
4636401d
AJ
20175 break;
20176 }
d2856f1a 20177}