]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
hw/mips: implement generic MIPS Coherent Processing System container
[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;
8e9ade68
TS
1435} DisasContext;
1436
1437enum {
1438 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1439 * exception condition */
8e9ade68
TS
1440 BS_STOP = 1, /* We want to stop translation for any reason */
1441 BS_BRANCH = 2, /* We reached a branch condition */
1442 BS_EXCP = 3, /* We reached an exception condition */
1443};
1444
d73ee8a2
RH
1445static const char * const regnames[] = {
1446 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1447 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1448 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1449 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1450};
6af0bf9c 1451
d73ee8a2
RH
1452static const char * const regnames_HI[] = {
1453 "HI0", "HI1", "HI2", "HI3",
1454};
4b2eb8d2 1455
d73ee8a2
RH
1456static const char * const regnames_LO[] = {
1457 "LO0", "LO1", "LO2", "LO3",
1458};
4b2eb8d2 1459
d73ee8a2
RH
1460static const char * const fregnames[] = {
1461 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1462 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1463 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1464 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1465};
958fb4a9 1466
863f264d
YK
1467static const char * const msaregnames[] = {
1468 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1469 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1470 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1471 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1472 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1473 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1474 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1475 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1476 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1477 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1478 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1479 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1480 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1481 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1482 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1483 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1484};
1485
9d68ac14 1486#define LOG_DISAS(...) \
fb7729e2
RH
1487 do { \
1488 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1489 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1490 } \
1491 } while (0)
1492
9d68ac14 1493#define MIPS_INVAL(op) \
fb7729e2
RH
1494 do { \
1495 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1496 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1497 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1498 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1499 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1500 } \
1501 } while (0)
958fb4a9 1502
8e9ade68
TS
1503/* General purpose registers moves. */
1504static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1505{
8e9ade68
TS
1506 if (reg == 0)
1507 tcg_gen_movi_tl(t, 0);
1508 else
4b2eb8d2 1509 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1510}
1511
8e9ade68 1512static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1513{
8e9ade68 1514 if (reg != 0)
4b2eb8d2 1515 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1516}
1517
8e9ade68 1518/* Moves to/from shadow registers. */
be24bb4f 1519static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1520{
d9bea114 1521 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1522
1523 if (from == 0)
d9bea114 1524 tcg_gen_movi_tl(t0, 0);
8e9ade68 1525 else {
d9bea114 1526 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1527 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1528
7db13fae 1529 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1530 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1531 tcg_gen_andi_i32(t2, t2, 0xf);
1532 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1533 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1534 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1535
d9bea114 1536 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1537 tcg_temp_free_ptr(addr);
d9bea114 1538 tcg_temp_free_i32(t2);
8e9ade68 1539 }
d9bea114
AJ
1540 gen_store_gpr(t0, to);
1541 tcg_temp_free(t0);
aaa9128a
TS
1542}
1543
be24bb4f 1544static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1545{
be24bb4f 1546 if (to != 0) {
d9bea114
AJ
1547 TCGv t0 = tcg_temp_new();
1548 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1549 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1550
d9bea114 1551 gen_load_gpr(t0, from);
7db13fae 1552 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1553 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1554 tcg_gen_andi_i32(t2, t2, 0xf);
1555 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1556 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1557 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1558
d9bea114 1559 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1560 tcg_temp_free_ptr(addr);
d9bea114
AJ
1561 tcg_temp_free_i32(t2);
1562 tcg_temp_free(t0);
8e9ade68 1563 }
aaa9128a
TS
1564}
1565
eab9944c
LA
1566/* Tests */
1567static inline void gen_save_pc(target_ulong pc)
1568{
1569 tcg_gen_movi_tl(cpu_PC, pc);
1570}
1571
1572static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1573{
1574 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1575 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1576 gen_save_pc(ctx->pc);
1577 ctx->saved_pc = ctx->pc;
1578 }
1579 if (ctx->hflags != ctx->saved_hflags) {
1580 tcg_gen_movi_i32(hflags, ctx->hflags);
1581 ctx->saved_hflags = ctx->hflags;
1582 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1583 case MIPS_HFLAG_BR:
1584 break;
1585 case MIPS_HFLAG_BC:
1586 case MIPS_HFLAG_BL:
1587 case MIPS_HFLAG_B:
1588 tcg_gen_movi_tl(btarget, ctx->btarget);
1589 break;
1590 }
1591 }
1592}
1593
1594static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1595{
1596 ctx->saved_hflags = ctx->hflags;
1597 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1598 case MIPS_HFLAG_BR:
1599 break;
1600 case MIPS_HFLAG_BC:
1601 case MIPS_HFLAG_BL:
1602 case MIPS_HFLAG_B:
1603 ctx->btarget = env->btarget;
1604 break;
1605 }
1606}
1607
1608static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1609{
1610 TCGv_i32 texcp = tcg_const_i32(excp);
1611 TCGv_i32 terr = tcg_const_i32(err);
1612 save_cpu_state(ctx, 1);
1613 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1614 tcg_temp_free_i32(terr);
1615 tcg_temp_free_i32(texcp);
9c708c7f 1616 ctx->bstate = BS_EXCP;
eab9944c
LA
1617}
1618
1619static inline void generate_exception(DisasContext *ctx, int excp)
1620{
eab9944c
LA
1621 gen_helper_0e0i(raise_exception, excp);
1622}
1623
9c708c7f
PD
1624static inline void generate_exception_end(DisasContext *ctx, int excp)
1625{
1626 generate_exception_err(ctx, excp, 0);
1627}
1628
aaa9128a 1629/* Floating point register moves. */
7c979afd 1630static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1631{
7c979afd
LA
1632 if (ctx->hflags & MIPS_HFLAG_FRE) {
1633 generate_exception(ctx, EXCP_RI);
1634 }
ecc7b3aa 1635 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1636}
1637
7c979afd 1638static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1639{
7c979afd
LA
1640 TCGv_i64 t64;
1641 if (ctx->hflags & MIPS_HFLAG_FRE) {
1642 generate_exception(ctx, EXCP_RI);
1643 }
1644 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1645 tcg_gen_extu_i32_i64(t64, t);
1646 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1647 tcg_temp_free_i64(t64);
6d066274
AJ
1648}
1649
7f6613ce 1650static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1651{
7f6613ce 1652 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1653 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1654 } else {
7c979afd 1655 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1656 }
6d066274
AJ
1657}
1658
7f6613ce 1659static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1660{
7f6613ce
PJ
1661 if (ctx->hflags & MIPS_HFLAG_F64) {
1662 TCGv_i64 t64 = tcg_temp_new_i64();
1663 tcg_gen_extu_i32_i64(t64, t);
1664 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1665 tcg_temp_free_i64(t64);
1666 } else {
7c979afd 1667 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1668 }
aa0bf00b 1669}
6ea83fed 1670
d73ee8a2 1671static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1672{
f364515c 1673 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1674 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1675 } else {
d73ee8a2 1676 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1677 }
1678}
6ea83fed 1679
d73ee8a2 1680static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1681{
f364515c 1682 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1683 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1684 } else {
d73ee8a2
RH
1685 TCGv_i64 t0;
1686 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1687 t0 = tcg_temp_new_i64();
6d066274 1688 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1689 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1690 tcg_temp_free_i64(t0);
aa0bf00b
TS
1691 }
1692}
6ea83fed 1693
d94536f4 1694static inline int get_fp_bit (int cc)
a16336e4 1695{
d94536f4
AJ
1696 if (cc)
1697 return 24 + cc;
1698 else
1699 return 23;
a16336e4
TS
1700}
1701
48d38ca5 1702/* Addresses computation */
941694d0 1703static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1704{
941694d0 1705 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1706
1707#if defined(TARGET_MIPS64)
01f72885 1708 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1709 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1710 }
1711#endif
4ad40f36
FB
1712}
1713
31837be3
YK
1714/* Addresses computation (translation time) */
1715static target_long addr_add(DisasContext *ctx, target_long base,
1716 target_long offset)
1717{
1718 target_long sum = base + offset;
1719
1720#if defined(TARGET_MIPS64)
1721 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1722 sum = (int32_t)sum;
1723 }
1724#endif
1725 return sum;
1726}
1727
71f303cd 1728/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1729static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1730{
1731#if defined(TARGET_MIPS64)
71f303cd
RH
1732 tcg_gen_ext32s_i64(ret, arg);
1733#else
1734 tcg_gen_extrl_i64_i32(ret, arg);
1735#endif
1736}
1737
1738/* Sign-extract the high 32-bits to a target_long. */
1739static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1740{
1741#if defined(TARGET_MIPS64)
1742 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1743#else
71f303cd 1744 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1745#endif
1746}
1747
356265ae 1748static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1749{
fe253235 1750 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1751 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1752}
1753
356265ae 1754static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1755{
fe253235 1756 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1757 generate_exception_err(ctx, EXCP_CpU, 1);
1758}
1759
b8aa4598
TS
1760/* Verify that the processor is running with COP1X instructions enabled.
1761 This is associated with the nabla symbol in the MIPS32 and MIPS64
1762 opcode tables. */
1763
356265ae 1764static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1765{
1766 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1767 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1768}
1769
1770/* Verify that the processor is running with 64-bit floating-point
1771 operations enabled. */
1772
356265ae 1773static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1774{
b8aa4598 1775 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1776 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1777}
1778
1779/*
1780 * Verify if floating point register is valid; an operation is not defined
1781 * if bit 0 of any register specification is set and the FR bit in the
1782 * Status register equals zero, since the register numbers specify an
1783 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1784 * in the Status register equals one, both even and odd register numbers
1785 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1786 *
1787 * Multiple 64 bit wide registers can be checked by calling
1788 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1789 */
356265ae 1790static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1791{
fe253235 1792 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1793 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1794}
1795
853c3240
JL
1796/* Verify that the processor is running with DSP instructions enabled.
1797 This is enabled by CP0 Status register MX(24) bit.
1798 */
1799
1800static inline void check_dsp(DisasContext *ctx)
1801{
1802 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1803 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1804 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1805 } else {
9c708c7f 1806 generate_exception_end(ctx, EXCP_RI);
ad153f15 1807 }
853c3240
JL
1808 }
1809}
1810
1811static inline void check_dspr2(DisasContext *ctx)
1812{
1813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1814 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1815 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1816 } else {
9c708c7f 1817 generate_exception_end(ctx, EXCP_RI);
ad153f15 1818 }
853c3240
JL
1819 }
1820}
1821
3a95e3a7 1822/* This code generates a "reserved instruction" exception if the
e189e748 1823 CPU does not support the instruction set corresponding to flags. */
d75c135e 1824static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1825{
d75c135e 1826 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1827 generate_exception_end(ctx, EXCP_RI);
d75c135e 1828 }
3a95e3a7
TS
1829}
1830
fecd2646
LA
1831/* This code generates a "reserved instruction" exception if the
1832 CPU has corresponding flag set which indicates that the instruction
1833 has been removed. */
1834static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1835{
1836 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1837 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1838 }
1839}
1840
e29c9628
YK
1841/* This code generates a "reserved instruction" exception if the
1842 CPU does not support 64-bit paired-single (PS) floating point data type */
1843static inline void check_ps(DisasContext *ctx)
1844{
1845 if (unlikely(!ctx->ps)) {
1846 generate_exception(ctx, EXCP_RI);
1847 }
1848 check_cp1_64bitmode(ctx);
1849}
1850
c7986fd6 1851#ifdef TARGET_MIPS64
e189e748
TS
1852/* This code generates a "reserved instruction" exception if 64-bit
1853 instructions are not enabled. */
356265ae 1854static inline void check_mips_64(DisasContext *ctx)
e189e748 1855{
fe253235 1856 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1857 generate_exception_end(ctx, EXCP_RI);
e189e748 1858}
c7986fd6 1859#endif
e189e748 1860
5204ea79
LA
1861#ifndef CONFIG_USER_ONLY
1862static inline void check_mvh(DisasContext *ctx)
1863{
1864 if (unlikely(!ctx->mvh)) {
1865 generate_exception(ctx, EXCP_RI);
1866 }
1867}
1868#endif
1869
8153667c
NF
1870/* Define small wrappers for gen_load_fpr* so that we have a uniform
1871 calling interface for 32 and 64-bit FPRs. No sense in changing
1872 all callers for gen_load_fpr32 when we need the CTX parameter for
1873 this one use. */
7c979afd 1874#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1875#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1876#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1877static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1878 int ft, int fs, int cc) \
1879{ \
1880 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1881 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1882 switch (ifmt) { \
1883 case FMT_PS: \
e29c9628 1884 check_ps(ctx); \
8153667c
NF
1885 break; \
1886 case FMT_D: \
1887 if (abs) { \
1888 check_cop1x(ctx); \
1889 } \
1890 check_cp1_registers(ctx, fs | ft); \
1891 break; \
1892 case FMT_S: \
1893 if (abs) { \
1894 check_cop1x(ctx); \
1895 } \
1896 break; \
1897 } \
1898 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1899 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1900 switch (n) { \
895c2d04
BS
1901 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1902 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1903 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1904 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1905 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1906 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1907 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1908 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1909 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1910 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1911 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1912 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1913 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1914 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1915 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1916 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1917 default: abort(); \
1918 } \
1919 tcg_temp_free_i##bits (fp0); \
1920 tcg_temp_free_i##bits (fp1); \
1921}
1922
1923FOP_CONDS(, 0, d, FMT_D, 64)
1924FOP_CONDS(abs, 1, d, FMT_D, 64)
1925FOP_CONDS(, 0, s, FMT_S, 32)
1926FOP_CONDS(abs, 1, s, FMT_S, 32)
1927FOP_CONDS(, 0, ps, FMT_PS, 64)
1928FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1929#undef FOP_CONDS
3f493883
YK
1930
1931#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1932static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1933 int ft, int fs, int fd) \
1934{ \
1935 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1936 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1937 if (ifmt == FMT_D) { \
3f493883 1938 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1939 } \
1940 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1941 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1942 switch (n) { \
1943 case 0: \
1944 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1945 break; \
1946 case 1: \
1947 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1948 break; \
1949 case 2: \
1950 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1951 break; \
1952 case 3: \
1953 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1954 break; \
1955 case 4: \
1956 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1957 break; \
1958 case 5: \
1959 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1960 break; \
1961 case 6: \
1962 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1963 break; \
1964 case 7: \
1965 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1966 break; \
1967 case 8: \
1968 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1969 break; \
1970 case 9: \
1971 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1972 break; \
1973 case 10: \
1974 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1975 break; \
1976 case 11: \
1977 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1978 break; \
1979 case 12: \
1980 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1981 break; \
1982 case 13: \
1983 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1984 break; \
1985 case 14: \
1986 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1987 break; \
1988 case 15: \
1989 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1990 break; \
1991 case 17: \
1992 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1993 break; \
1994 case 18: \
1995 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1996 break; \
1997 case 19: \
1998 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1999 break; \
2000 case 25: \
2001 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2002 break; \
2003 case 26: \
2004 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2005 break; \
2006 case 27: \
2007 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2008 break; \
2009 default: \
2010 abort(); \
2011 } \
2012 STORE; \
2013 tcg_temp_free_i ## bits (fp0); \
2014 tcg_temp_free_i ## bits (fp1); \
2015}
2016
2017FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2018FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2019#undef FOP_CONDNS
8153667c
NF
2020#undef gen_ldcmp_fpr32
2021#undef gen_ldcmp_fpr64
2022
958fb4a9 2023/* load/store instructions. */
e7139c44 2024#ifdef CONFIG_USER_ONLY
d9bea114 2025#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2026static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
2027{ \
2028 TCGv t0 = tcg_temp_new(); \
2029 tcg_gen_mov_tl(t0, arg1); \
2030 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2031 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2032 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2033 tcg_temp_free(t0); \
aaa9128a 2034}
e7139c44
AJ
2035#else
2036#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2037static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 2038{ \
895c2d04 2039 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
2040}
2041#endif
aaa9128a
TS
2042OP_LD_ATOMIC(ll,ld32s);
2043#if defined(TARGET_MIPS64)
2044OP_LD_ATOMIC(lld,ld64);
2045#endif
2046#undef OP_LD_ATOMIC
2047
590bc601
PB
2048#ifdef CONFIG_USER_ONLY
2049#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2050static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2051{ \
2052 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2053 TCGLabel *l1 = gen_new_label(); \
2054 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2055 \
2056 tcg_gen_andi_tl(t0, arg2, almask); \
2057 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2058 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2059 generate_exception(ctx, EXCP_AdES); \
2060 gen_set_label(l1); \
7db13fae 2061 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2062 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2063 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2064 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2065 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2066 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2067 gen_set_label(l2); \
2068 tcg_gen_movi_tl(t0, 0); \
2069 gen_store_gpr(t0, rt); \
2070 tcg_temp_free(t0); \
2071}
2072#else
2073#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2074static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2075{ \
2076 TCGv t0 = tcg_temp_new(); \
895c2d04 2077 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2078 gen_store_gpr(t0, rt); \
590bc601
PB
2079 tcg_temp_free(t0); \
2080}
2081#endif
590bc601 2082OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2083#if defined(TARGET_MIPS64)
590bc601 2084OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2085#endif
2086#undef OP_ST_ATOMIC
2087
662d7485
NF
2088static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2089 int base, int16_t offset)
2090{
2091 if (base == 0) {
2092 tcg_gen_movi_tl(addr, offset);
2093 } else if (offset == 0) {
2094 gen_load_gpr(addr, base);
2095 } else {
2096 tcg_gen_movi_tl(addr, offset);
2097 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2098 }
2099}
2100
364d4831
NF
2101static target_ulong pc_relative_pc (DisasContext *ctx)
2102{
2103 target_ulong pc = ctx->pc;
2104
2105 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2106 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2107
2108 pc -= branch_bytes;
2109 }
2110
2111 pc &= ~(target_ulong)3;
2112 return pc;
2113}
2114
5c13fdfd 2115/* Load */
d75c135e
AJ
2116static void gen_ld(DisasContext *ctx, uint32_t opc,
2117 int rt, int base, int16_t offset)
6af0bf9c 2118{
fc40787a 2119 TCGv t0, t1, t2;
afa88c3a 2120
d75c135e 2121 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2122 /* Loongson CPU uses a load to zero register for prefetch.
2123 We emulate it as a NOP. On other CPU we must perform the
2124 actual memory access. */
afa88c3a
AJ
2125 return;
2126 }
6af0bf9c 2127
afa88c3a 2128 t0 = tcg_temp_new();
662d7485 2129 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2130
6af0bf9c 2131 switch (opc) {
d26bc211 2132#if defined(TARGET_MIPS64)
6e473128 2133 case OPC_LWU:
be3a8c53
YK
2134 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2135 ctx->default_tcg_memop_mask);
78723684 2136 gen_store_gpr(t0, rt);
6e473128 2137 break;
6af0bf9c 2138 case OPC_LD:
be3a8c53
YK
2139 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2140 ctx->default_tcg_memop_mask);
78723684 2141 gen_store_gpr(t0, rt);
6af0bf9c 2142 break;
7a387fff 2143 case OPC_LLD:
bf7910c6 2144 case R6_OPC_LLD:
5c13fdfd 2145 op_ld_lld(t0, t0, ctx);
78723684 2146 gen_store_gpr(t0, rt);
7a387fff 2147 break;
6af0bf9c 2148 case OPC_LDL:
3cee3050 2149 t1 = tcg_temp_new();
908680c6
AJ
2150 /* Do a byte access to possibly trigger a page
2151 fault with the unaligned address. */
2152 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2153 tcg_gen_andi_tl(t1, t0, 7);
2154#ifndef TARGET_WORDS_BIGENDIAN
2155 tcg_gen_xori_tl(t1, t1, 7);
2156#endif
2157 tcg_gen_shli_tl(t1, t1, 3);
2158 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2159 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a 2160 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2161 t2 = tcg_const_tl(-1);
2162 tcg_gen_shl_tl(t2, t2, t1);
78723684 2163 gen_load_gpr(t1, rt);
eb02cc3f 2164 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2165 tcg_temp_free(t2);
2166 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2167 tcg_temp_free(t1);
fc40787a 2168 gen_store_gpr(t0, rt);
6af0bf9c 2169 break;
6af0bf9c 2170 case OPC_LDR:
3cee3050 2171 t1 = tcg_temp_new();
908680c6
AJ
2172 /* Do a byte access to possibly trigger a page
2173 fault with the unaligned address. */
2174 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2175 tcg_gen_andi_tl(t1, t0, 7);
2176#ifdef TARGET_WORDS_BIGENDIAN
2177 tcg_gen_xori_tl(t1, t1, 7);
2178#endif
2179 tcg_gen_shli_tl(t1, t1, 3);
2180 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2181 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2182 tcg_gen_shr_tl(t0, t0, t1);
2183 tcg_gen_xori_tl(t1, t1, 63);
2184 t2 = tcg_const_tl(0xfffffffffffffffeull);
2185 tcg_gen_shl_tl(t2, t2, t1);
78723684 2186 gen_load_gpr(t1, rt);
fc40787a
AJ
2187 tcg_gen_and_tl(t1, t1, t2);
2188 tcg_temp_free(t2);
2189 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2190 tcg_temp_free(t1);
fc40787a 2191 gen_store_gpr(t0, rt);
6af0bf9c 2192 break;
364d4831 2193 case OPC_LDPC:
3cee3050 2194 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2195 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2196 tcg_temp_free(t1);
5f68f5ae 2197 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831
NF
2198 gen_store_gpr(t0, rt);
2199 break;
6af0bf9c 2200#endif
364d4831 2201 case OPC_LWPC:
3cee3050 2202 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2203 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2204 tcg_temp_free(t1);
5f68f5ae 2205 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831
NF
2206 gen_store_gpr(t0, rt);
2207 break;
6af0bf9c 2208 case OPC_LW:
be3a8c53
YK
2209 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2210 ctx->default_tcg_memop_mask);
78723684 2211 gen_store_gpr(t0, rt);
6af0bf9c 2212 break;
6af0bf9c 2213 case OPC_LH:
be3a8c53
YK
2214 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2215 ctx->default_tcg_memop_mask);
78723684 2216 gen_store_gpr(t0, rt);
6af0bf9c 2217 break;
6af0bf9c 2218 case OPC_LHU:
be3a8c53
YK
2219 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2220 ctx->default_tcg_memop_mask);
78723684 2221 gen_store_gpr(t0, rt);
6af0bf9c
FB
2222 break;
2223 case OPC_LB:
5f68f5ae 2224 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2225 gen_store_gpr(t0, rt);
6af0bf9c 2226 break;
6af0bf9c 2227 case OPC_LBU:
5f68f5ae 2228 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2229 gen_store_gpr(t0, rt);
6af0bf9c
FB
2230 break;
2231 case OPC_LWL:
3cee3050 2232 t1 = tcg_temp_new();
908680c6
AJ
2233 /* Do a byte access to possibly trigger a page
2234 fault with the unaligned address. */
2235 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2236 tcg_gen_andi_tl(t1, t0, 3);
2237#ifndef TARGET_WORDS_BIGENDIAN
2238 tcg_gen_xori_tl(t1, t1, 3);
2239#endif
2240 tcg_gen_shli_tl(t1, t1, 3);
2241 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2242 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a 2243 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2244 t2 = tcg_const_tl(-1);
2245 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2246 gen_load_gpr(t1, rt);
eb02cc3f 2247 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2248 tcg_temp_free(t2);
2249 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2250 tcg_temp_free(t1);
fc40787a
AJ
2251 tcg_gen_ext32s_tl(t0, t0);
2252 gen_store_gpr(t0, rt);
6af0bf9c 2253 break;
6af0bf9c 2254 case OPC_LWR:
3cee3050 2255 t1 = tcg_temp_new();
908680c6
AJ
2256 /* Do a byte access to possibly trigger a page
2257 fault with the unaligned address. */
2258 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
fc40787a
AJ
2259 tcg_gen_andi_tl(t1, t0, 3);
2260#ifdef TARGET_WORDS_BIGENDIAN
2261 tcg_gen_xori_tl(t1, t1, 3);
2262#endif
2263 tcg_gen_shli_tl(t1, t1, 3);
2264 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2265 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2266 tcg_gen_shr_tl(t0, t0, t1);
2267 tcg_gen_xori_tl(t1, t1, 31);
2268 t2 = tcg_const_tl(0xfffffffeull);
2269 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2270 gen_load_gpr(t1, rt);
fc40787a
AJ
2271 tcg_gen_and_tl(t1, t1, t2);
2272 tcg_temp_free(t2);
2273 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2274 tcg_temp_free(t1);
c728154b 2275 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2276 gen_store_gpr(t0, rt);
6af0bf9c 2277 break;
6af0bf9c 2278 case OPC_LL:
4368b29a 2279 case R6_OPC_LL:
5c13fdfd 2280 op_ld_ll(t0, t0, ctx);
78723684 2281 gen_store_gpr(t0, rt);
6af0bf9c 2282 break;
d66c7132 2283 }
d66c7132 2284 tcg_temp_free(t0);
d66c7132
AJ
2285}
2286
5c13fdfd
AJ
2287/* Store */
2288static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2289 int base, int16_t offset)
2290{
5c13fdfd
AJ
2291 TCGv t0 = tcg_temp_new();
2292 TCGv t1 = tcg_temp_new();
2293
2294 gen_base_offset_addr(ctx, t0, base, offset);
2295 gen_load_gpr(t1, rt);
2296 switch (opc) {
2297#if defined(TARGET_MIPS64)
2298 case OPC_SD:
be3a8c53
YK
2299 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2300 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2301 break;
2302 case OPC_SDL:
895c2d04 2303 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2304 break;
2305 case OPC_SDR:
895c2d04 2306 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2307 break;
2308#endif
2309 case OPC_SW:
be3a8c53
YK
2310 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2311 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2312 break;
2313 case OPC_SH:
be3a8c53
YK
2314 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2315 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2316 break;
2317 case OPC_SB:
5f68f5ae 2318 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2319 break;
2320 case OPC_SWL:
895c2d04 2321 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2322 break;
2323 case OPC_SWR:
895c2d04 2324 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2325 break;
2326 }
5c13fdfd
AJ
2327 tcg_temp_free(t0);
2328 tcg_temp_free(t1);
2329}
2330
2331
d66c7132
AJ
2332/* Store conditional */
2333static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2334 int base, int16_t offset)
2335{
d66c7132
AJ
2336 TCGv t0, t1;
2337
2d2826b9 2338#ifdef CONFIG_USER_ONLY
d66c7132 2339 t0 = tcg_temp_local_new();
d66c7132 2340 t1 = tcg_temp_local_new();
2d2826b9
AJ
2341#else
2342 t0 = tcg_temp_new();
2343 t1 = tcg_temp_new();
2344#endif
2345 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2346 gen_load_gpr(t1, rt);
2347 switch (opc) {
2348#if defined(TARGET_MIPS64)
2349 case OPC_SCD:
bf7910c6 2350 case R6_OPC_SCD:
5c13fdfd 2351 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2352 break;
2353#endif
6af0bf9c 2354 case OPC_SC:
4368b29a 2355 case R6_OPC_SC:
5c13fdfd 2356 op_st_sc(t1, t0, rt, ctx);
6af0bf9c 2357 break;
6af0bf9c 2358 }
78723684 2359 tcg_temp_free(t1);
d66c7132 2360 tcg_temp_free(t0);
6af0bf9c
FB
2361}
2362
6ea83fed 2363/* Load and store */
7a387fff 2364static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2365 int base, int16_t offset)
6ea83fed 2366{
4e2474d6 2367 TCGv t0 = tcg_temp_new();
6ea83fed 2368
662d7485 2369 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2370 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2371 memory access. */
6ea83fed
FB
2372 switch (opc) {
2373 case OPC_LWC1:
b6d96bed 2374 {
a7812ae4 2375 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2376 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2377 ctx->default_tcg_memop_mask);
7c979afd 2378 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2379 tcg_temp_free_i32(fp0);
b6d96bed 2380 }
6ea83fed
FB
2381 break;
2382 case OPC_SWC1:
b6d96bed 2383 {
a7812ae4 2384 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2385 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2386 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2387 ctx->default_tcg_memop_mask);
a7812ae4 2388 tcg_temp_free_i32(fp0);
b6d96bed 2389 }
6ea83fed
FB
2390 break;
2391 case OPC_LDC1:
b6d96bed 2392 {
a7812ae4 2393 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2394 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2395 ctx->default_tcg_memop_mask);
b6d96bed 2396 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2397 tcg_temp_free_i64(fp0);
b6d96bed 2398 }
6ea83fed
FB
2399 break;
2400 case OPC_SDC1:
b6d96bed 2401 {
a7812ae4 2402 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2403 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2404 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2405 ctx->default_tcg_memop_mask);
a7812ae4 2406 tcg_temp_free_i64(fp0);
b6d96bed 2407 }
6ea83fed
FB
2408 break;
2409 default:
9d68ac14 2410 MIPS_INVAL("flt_ldst");
9c708c7f 2411 generate_exception_end(ctx, EXCP_RI);
78723684 2412 goto out;
6ea83fed 2413 }
78723684
TS
2414 out:
2415 tcg_temp_free(t0);
6ea83fed 2416}
6ea83fed 2417
5ab5c041
AJ
2418static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2419 int rs, int16_t imm)
26ebe468 2420{
5ab5c041 2421 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2422 check_cp1_enabled(ctx);
d9224450
MR
2423 switch (op) {
2424 case OPC_LDC1:
2425 case OPC_SDC1:
2426 check_insn(ctx, ISA_MIPS2);
2427 /* Fallthrough */
2428 default:
2429 gen_flt_ldst(ctx, op, rt, rs, imm);
2430 }
26ebe468
NF
2431 } else {
2432 generate_exception_err(ctx, EXCP_CpU, 1);
2433 }
2434}
2435
6af0bf9c 2436/* Arithmetic with immediate operand */
d75c135e
AJ
2437static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2438 int rt, int rs, int16_t imm)
6af0bf9c 2439{
324d9e32 2440 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2441
7a387fff 2442 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2443 /* If no destination, treat it as a NOP.
2444 For addi, we must generate the overflow exception when needed. */
324d9e32 2445 return;
6af0bf9c
FB
2446 }
2447 switch (opc) {
2448 case OPC_ADDI:
48d38ca5 2449 {
324d9e32
AJ
2450 TCGv t0 = tcg_temp_local_new();
2451 TCGv t1 = tcg_temp_new();
2452 TCGv t2 = tcg_temp_new();
42a268c2 2453 TCGLabel *l1 = gen_new_label();
48d38ca5 2454
324d9e32
AJ
2455 gen_load_gpr(t1, rs);
2456 tcg_gen_addi_tl(t0, t1, uimm);
2457 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2458
324d9e32
AJ
2459 tcg_gen_xori_tl(t1, t1, ~uimm);
2460 tcg_gen_xori_tl(t2, t0, uimm);
2461 tcg_gen_and_tl(t1, t1, t2);
2462 tcg_temp_free(t2);
2463 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2464 tcg_temp_free(t1);
48d38ca5
TS
2465 /* operands of same sign, result different sign */
2466 generate_exception(ctx, EXCP_OVERFLOW);
2467 gen_set_label(l1);
78723684 2468 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2469 gen_store_gpr(t0, rt);
2470 tcg_temp_free(t0);
48d38ca5 2471 }
6af0bf9c
FB
2472 break;
2473 case OPC_ADDIU:
324d9e32
AJ
2474 if (rs != 0) {
2475 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2476 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2477 } else {
2478 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2479 }
6af0bf9c 2480 break;
d26bc211 2481#if defined(TARGET_MIPS64)
7a387fff 2482 case OPC_DADDI:
48d38ca5 2483 {
324d9e32
AJ
2484 TCGv t0 = tcg_temp_local_new();
2485 TCGv t1 = tcg_temp_new();
2486 TCGv t2 = tcg_temp_new();
42a268c2 2487 TCGLabel *l1 = gen_new_label();
48d38ca5 2488
324d9e32
AJ
2489 gen_load_gpr(t1, rs);
2490 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2491
324d9e32
AJ
2492 tcg_gen_xori_tl(t1, t1, ~uimm);
2493 tcg_gen_xori_tl(t2, t0, uimm);
2494 tcg_gen_and_tl(t1, t1, t2);
2495 tcg_temp_free(t2);
2496 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2497 tcg_temp_free(t1);
48d38ca5
TS
2498 /* operands of same sign, result different sign */
2499 generate_exception(ctx, EXCP_OVERFLOW);
2500 gen_set_label(l1);
324d9e32
AJ
2501 gen_store_gpr(t0, rt);
2502 tcg_temp_free(t0);
48d38ca5 2503 }
7a387fff
TS
2504 break;
2505 case OPC_DADDIU:
324d9e32
AJ
2506 if (rs != 0) {
2507 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2508 } else {
2509 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2510 }
7a387fff
TS
2511 break;
2512#endif
324d9e32 2513 }
324d9e32
AJ
2514}
2515
2516/* Logic with immediate operand */
d75c135e 2517static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2518 int rt, int rs, int16_t imm)
324d9e32
AJ
2519{
2520 target_ulong uimm;
324d9e32
AJ
2521
2522 if (rt == 0) {
2523 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2524 return;
2525 }
2526 uimm = (uint16_t)imm;
2527 switch (opc) {
6af0bf9c 2528 case OPC_ANDI:
324d9e32
AJ
2529 if (likely(rs != 0))
2530 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2531 else
2532 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2533 break;
2534 case OPC_ORI:
324d9e32
AJ
2535 if (rs != 0)
2536 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2537 else
2538 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2539 break;
2540 case OPC_XORI:
324d9e32
AJ
2541 if (likely(rs != 0))
2542 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2543 else
2544 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2545 break;
2546 case OPC_LUI:
d4ea6acd
LA
2547 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2548 /* OPC_AUI */
2549 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2550 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2551 } else {
2552 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2553 }
7c2c3ea3
EJ
2554 break;
2555
2556 default:
6af0bf9c 2557 break;
324d9e32 2558 }
324d9e32
AJ
2559}
2560
2561/* Set on less than with immediate operand */
d75c135e 2562static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2563 int rt, int rs, int16_t imm)
324d9e32
AJ
2564{
2565 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2566 TCGv t0;
2567
2568 if (rt == 0) {
2569 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2570 return;
2571 }
2572 t0 = tcg_temp_new();
2573 gen_load_gpr(t0, rs);
2574 switch (opc) {
2575 case OPC_SLTI:
e68dd28f 2576 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2577 break;
2578 case OPC_SLTIU:
e68dd28f 2579 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2580 break;
2581 }
324d9e32
AJ
2582 tcg_temp_free(t0);
2583}
2584
2585/* Shifts with immediate operand */
d75c135e 2586static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2587 int rt, int rs, int16_t imm)
2588{
2589 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2590 TCGv t0;
2591
2592 if (rt == 0) {
2593 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2594 return;
2595 }
2596
2597 t0 = tcg_temp_new();
2598 gen_load_gpr(t0, rs);
2599 switch (opc) {
6af0bf9c 2600 case OPC_SLL:
78723684 2601 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2602 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2603 break;
2604 case OPC_SRA:
324d9e32 2605 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2606 break;
2607 case OPC_SRL:
ea63e2c3
NF
2608 if (uimm != 0) {
2609 tcg_gen_ext32u_tl(t0, t0);
2610 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2611 } else {
2612 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2613 }
ea63e2c3
NF
2614 break;
2615 case OPC_ROTR:
2616 if (uimm != 0) {
2617 TCGv_i32 t1 = tcg_temp_new_i32();
2618
2619 tcg_gen_trunc_tl_i32(t1, t0);
2620 tcg_gen_rotri_i32(t1, t1, uimm);
2621 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2622 tcg_temp_free_i32(t1);
3399e30f
NF
2623 } else {
2624 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2625 }
7a387fff 2626 break;
d26bc211 2627#if defined(TARGET_MIPS64)
7a387fff 2628 case OPC_DSLL:
324d9e32 2629 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2630 break;
2631 case OPC_DSRA:
324d9e32 2632 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2633 break;
2634 case OPC_DSRL:
ea63e2c3 2635 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2636 break;
2637 case OPC_DROTR:
2638 if (uimm != 0) {
2639 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2640 } else {
2641 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2642 }
7a387fff
TS
2643 break;
2644 case OPC_DSLL32:
324d9e32 2645 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2646 break;
2647 case OPC_DSRA32:
324d9e32 2648 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2649 break;
2650 case OPC_DSRL32:
ea63e2c3 2651 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2652 break;
2653 case OPC_DROTR32:
2654 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2655 break;
7a387fff 2656#endif
6af0bf9c 2657 }
78723684 2658 tcg_temp_free(t0);
6af0bf9c
FB
2659}
2660
2661/* Arithmetic */
d75c135e
AJ
2662static void gen_arith(DisasContext *ctx, uint32_t opc,
2663 int rd, int rs, int rt)
6af0bf9c 2664{
7a387fff
TS
2665 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2666 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2667 /* If no destination, treat it as a NOP.
2668 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2669 return;
185f0762 2670 }
460f00c4 2671
6af0bf9c
FB
2672 switch (opc) {
2673 case OPC_ADD:
48d38ca5 2674 {
460f00c4
AJ
2675 TCGv t0 = tcg_temp_local_new();
2676 TCGv t1 = tcg_temp_new();
2677 TCGv t2 = tcg_temp_new();
42a268c2 2678 TCGLabel *l1 = gen_new_label();
48d38ca5 2679
460f00c4
AJ
2680 gen_load_gpr(t1, rs);
2681 gen_load_gpr(t2, rt);
2682 tcg_gen_add_tl(t0, t1, t2);
2683 tcg_gen_ext32s_tl(t0, t0);
2684 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2685 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2686 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2687 tcg_temp_free(t2);
2688 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2689 tcg_temp_free(t1);
48d38ca5
TS
2690 /* operands of same sign, result different sign */
2691 generate_exception(ctx, EXCP_OVERFLOW);
2692 gen_set_label(l1);
460f00c4
AJ
2693 gen_store_gpr(t0, rd);
2694 tcg_temp_free(t0);
48d38ca5 2695 }
6af0bf9c
FB
2696 break;
2697 case OPC_ADDU:
460f00c4
AJ
2698 if (rs != 0 && rt != 0) {
2699 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2700 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2701 } else if (rs == 0 && rt != 0) {
2702 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2703 } else if (rs != 0 && rt == 0) {
2704 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2705 } else {
2706 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2707 }
6af0bf9c
FB
2708 break;
2709 case OPC_SUB:
48d38ca5 2710 {
460f00c4
AJ
2711 TCGv t0 = tcg_temp_local_new();
2712 TCGv t1 = tcg_temp_new();
2713 TCGv t2 = tcg_temp_new();
42a268c2 2714 TCGLabel *l1 = gen_new_label();
48d38ca5 2715
460f00c4
AJ
2716 gen_load_gpr(t1, rs);
2717 gen_load_gpr(t2, rt);
2718 tcg_gen_sub_tl(t0, t1, t2);
2719 tcg_gen_ext32s_tl(t0, t0);
2720 tcg_gen_xor_tl(t2, t1, t2);
2721 tcg_gen_xor_tl(t1, t0, t1);
2722 tcg_gen_and_tl(t1, t1, t2);
2723 tcg_temp_free(t2);
2724 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2725 tcg_temp_free(t1);
31e3104f 2726 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2727 generate_exception(ctx, EXCP_OVERFLOW);
2728 gen_set_label(l1);
460f00c4
AJ
2729 gen_store_gpr(t0, rd);
2730 tcg_temp_free(t0);
48d38ca5 2731 }
6af0bf9c
FB
2732 break;
2733 case OPC_SUBU:
460f00c4
AJ
2734 if (rs != 0 && rt != 0) {
2735 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2736 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2737 } else if (rs == 0 && rt != 0) {
2738 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2739 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2740 } else if (rs != 0 && rt == 0) {
2741 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2742 } else {
2743 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2744 }
6af0bf9c 2745 break;
d26bc211 2746#if defined(TARGET_MIPS64)
7a387fff 2747 case OPC_DADD:
48d38ca5 2748 {
460f00c4
AJ
2749 TCGv t0 = tcg_temp_local_new();
2750 TCGv t1 = tcg_temp_new();
2751 TCGv t2 = tcg_temp_new();
42a268c2 2752 TCGLabel *l1 = gen_new_label();
48d38ca5 2753
460f00c4
AJ
2754 gen_load_gpr(t1, rs);
2755 gen_load_gpr(t2, rt);
2756 tcg_gen_add_tl(t0, t1, t2);
2757 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2758 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2759 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2760 tcg_temp_free(t2);
2761 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2762 tcg_temp_free(t1);
48d38ca5
TS
2763 /* operands of same sign, result different sign */
2764 generate_exception(ctx, EXCP_OVERFLOW);
2765 gen_set_label(l1);
460f00c4
AJ
2766 gen_store_gpr(t0, rd);
2767 tcg_temp_free(t0);
48d38ca5 2768 }
7a387fff
TS
2769 break;
2770 case OPC_DADDU:
460f00c4
AJ
2771 if (rs != 0 && rt != 0) {
2772 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2773 } else if (rs == 0 && rt != 0) {
2774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2775 } else if (rs != 0 && rt == 0) {
2776 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2777 } else {
2778 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2779 }
7a387fff
TS
2780 break;
2781 case OPC_DSUB:
48d38ca5 2782 {
460f00c4
AJ
2783 TCGv t0 = tcg_temp_local_new();
2784 TCGv t1 = tcg_temp_new();
2785 TCGv t2 = tcg_temp_new();
42a268c2 2786 TCGLabel *l1 = gen_new_label();
48d38ca5 2787
460f00c4
AJ
2788 gen_load_gpr(t1, rs);
2789 gen_load_gpr(t2, rt);
2790 tcg_gen_sub_tl(t0, t1, t2);
2791 tcg_gen_xor_tl(t2, t1, t2);
2792 tcg_gen_xor_tl(t1, t0, t1);
2793 tcg_gen_and_tl(t1, t1, t2);
2794 tcg_temp_free(t2);
2795 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2796 tcg_temp_free(t1);
31e3104f 2797 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2798 generate_exception(ctx, EXCP_OVERFLOW);
2799 gen_set_label(l1);
460f00c4
AJ
2800 gen_store_gpr(t0, rd);
2801 tcg_temp_free(t0);
48d38ca5 2802 }
7a387fff
TS
2803 break;
2804 case OPC_DSUBU:
460f00c4
AJ
2805 if (rs != 0 && rt != 0) {
2806 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2807 } else if (rs == 0 && rt != 0) {
2808 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2809 } else if (rs != 0 && rt == 0) {
2810 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2811 } else {
2812 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2813 }
7a387fff
TS
2814 break;
2815#endif
460f00c4
AJ
2816 case OPC_MUL:
2817 if (likely(rs != 0 && rt != 0)) {
2818 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2819 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2820 } else {
2821 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2822 }
6af0bf9c 2823 break;
460f00c4 2824 }
460f00c4
AJ
2825}
2826
2827/* Conditional move */
d75c135e 2828static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2829 int rd, int rs, int rt)
460f00c4 2830{
acf12465 2831 TCGv t0, t1, t2;
460f00c4
AJ
2832
2833 if (rd == 0) {
acf12465 2834 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2835 return;
2836 }
2837
acf12465
AJ
2838 t0 = tcg_temp_new();
2839 gen_load_gpr(t0, rt);
2840 t1 = tcg_const_tl(0);
2841 t2 = tcg_temp_new();
2842 gen_load_gpr(t2, rs);
460f00c4
AJ
2843 switch (opc) {
2844 case OPC_MOVN:
acf12465 2845 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2846 break;
460f00c4 2847 case OPC_MOVZ:
acf12465 2848 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2849 break;
b691d9d2
LA
2850 case OPC_SELNEZ:
2851 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2852 break;
2853 case OPC_SELEQZ:
2854 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2855 break;
460f00c4 2856 }
acf12465
AJ
2857 tcg_temp_free(t2);
2858 tcg_temp_free(t1);
2859 tcg_temp_free(t0);
460f00c4
AJ
2860}
2861
2862/* Logic */
d75c135e 2863static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2864 int rd, int rs, int rt)
460f00c4 2865{
460f00c4
AJ
2866 if (rd == 0) {
2867 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2868 return;
2869 }
2870
2871 switch (opc) {
6af0bf9c 2872 case OPC_AND:
460f00c4
AJ
2873 if (likely(rs != 0 && rt != 0)) {
2874 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2875 } else {
2876 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2877 }
6af0bf9c
FB
2878 break;
2879 case OPC_NOR:
460f00c4
AJ
2880 if (rs != 0 && rt != 0) {
2881 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2882 } else if (rs == 0 && rt != 0) {
2883 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2884 } else if (rs != 0 && rt == 0) {
2885 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2886 } else {
2887 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2888 }
6af0bf9c
FB
2889 break;
2890 case OPC_OR:
460f00c4
AJ
2891 if (likely(rs != 0 && rt != 0)) {
2892 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2893 } else if (rs == 0 && rt != 0) {
2894 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2895 } else if (rs != 0 && rt == 0) {
2896 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2897 } else {
2898 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2899 }
6af0bf9c
FB
2900 break;
2901 case OPC_XOR:
460f00c4
AJ
2902 if (likely(rs != 0 && rt != 0)) {
2903 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2904 } else if (rs == 0 && rt != 0) {
2905 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2906 } else if (rs != 0 && rt == 0) {
2907 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2908 } else {
2909 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2910 }
6af0bf9c 2911 break;
460f00c4 2912 }
460f00c4
AJ
2913}
2914
2915/* Set on lower than */
d75c135e 2916static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2917 int rd, int rs, int rt)
460f00c4 2918{
460f00c4
AJ
2919 TCGv t0, t1;
2920
2921 if (rd == 0) {
2922 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2923 return;
2924 }
2925
2926 t0 = tcg_temp_new();
2927 t1 = tcg_temp_new();
2928 gen_load_gpr(t0, rs);
2929 gen_load_gpr(t1, rt);
2930 switch (opc) {
2931 case OPC_SLT:
e68dd28f 2932 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2933 break;
460f00c4 2934 case OPC_SLTU:
e68dd28f 2935 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2936 break;
2937 }
460f00c4
AJ
2938 tcg_temp_free(t0);
2939 tcg_temp_free(t1);
2940}
20c4c97c 2941
460f00c4 2942/* Shifts */
d75c135e
AJ
2943static void gen_shift(DisasContext *ctx, uint32_t opc,
2944 int rd, int rs, int rt)
460f00c4 2945{
460f00c4 2946 TCGv t0, t1;
20c4c97c 2947
460f00c4
AJ
2948 if (rd == 0) {
2949 /* If no destination, treat it as a NOP.
2950 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
2951 return;
2952 }
2953
2954 t0 = tcg_temp_new();
2955 t1 = tcg_temp_new();
2956 gen_load_gpr(t0, rs);
2957 gen_load_gpr(t1, rt);
2958 switch (opc) {
6af0bf9c 2959 case OPC_SLLV:
78723684
TS
2960 tcg_gen_andi_tl(t0, t0, 0x1f);
2961 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2962 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2963 break;
2964 case OPC_SRAV:
78723684 2965 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2966 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2967 break;
2968 case OPC_SRLV:
ea63e2c3
NF
2969 tcg_gen_ext32u_tl(t1, t1);
2970 tcg_gen_andi_tl(t0, t0, 0x1f);
2971 tcg_gen_shr_tl(t0, t1, t0);
2972 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2973 break;
2974 case OPC_ROTRV:
2975 {
2976 TCGv_i32 t2 = tcg_temp_new_i32();
2977 TCGv_i32 t3 = tcg_temp_new_i32();
2978
2979 tcg_gen_trunc_tl_i32(t2, t0);
2980 tcg_gen_trunc_tl_i32(t3, t1);
2981 tcg_gen_andi_i32(t2, t2, 0x1f);
2982 tcg_gen_rotr_i32(t2, t3, t2);
2983 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2984 tcg_temp_free_i32(t2);
2985 tcg_temp_free_i32(t3);
5a63bcb2 2986 }
7a387fff 2987 break;
d26bc211 2988#if defined(TARGET_MIPS64)
7a387fff 2989 case OPC_DSLLV:
78723684 2990 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2991 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2992 break;
2993 case OPC_DSRAV:
78723684 2994 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2995 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2996 break;
2997 case OPC_DSRLV:
ea63e2c3
NF
2998 tcg_gen_andi_tl(t0, t0, 0x3f);
2999 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3000 break;
3001 case OPC_DROTRV:
3002 tcg_gen_andi_tl(t0, t0, 0x3f);
3003 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3004 break;
7a387fff 3005#endif
6af0bf9c 3006 }
78723684
TS
3007 tcg_temp_free(t0);
3008 tcg_temp_free(t1);
6af0bf9c
FB
3009}
3010
3011/* Arithmetic on HI/LO registers */
26135ead 3012static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3013{
6af0bf9c 3014 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3015 /* Treat as NOP. */
a1f6684d 3016 return;
6af0bf9c 3017 }
4133498f 3018
4133498f
JL
3019 if (acc != 0) {
3020 check_dsp(ctx);
3021 }
3022
6af0bf9c
FB
3023 switch (opc) {
3024 case OPC_MFHI:
4133498f
JL
3025#if defined(TARGET_MIPS64)
3026 if (acc != 0) {
3027 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3028 } else
3029#endif
3030 {
3031 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3032 }
6af0bf9c
FB
3033 break;
3034 case OPC_MFLO:
4133498f
JL
3035#if defined(TARGET_MIPS64)
3036 if (acc != 0) {
3037 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3038 } else
3039#endif
3040 {
3041 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3042 }
6af0bf9c
FB
3043 break;
3044 case OPC_MTHI:
4133498f
JL
3045 if (reg != 0) {
3046#if defined(TARGET_MIPS64)
3047 if (acc != 0) {
3048 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3049 } else
3050#endif
3051 {
3052 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3053 }
3054 } else {
3055 tcg_gen_movi_tl(cpu_HI[acc], 0);
3056 }
6af0bf9c
FB
3057 break;
3058 case OPC_MTLO:
4133498f
JL
3059 if (reg != 0) {
3060#if defined(TARGET_MIPS64)
3061 if (acc != 0) {
3062 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3063 } else
3064#endif
3065 {
3066 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3067 }
3068 } else {
3069 tcg_gen_movi_tl(cpu_LO[acc], 0);
3070 }
6af0bf9c 3071 break;
6af0bf9c 3072 }
6af0bf9c
FB
3073}
3074
d4ea6acd
LA
3075static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3076 TCGMemOp memop)
3077{
3078 TCGv t0 = tcg_const_tl(addr);
3079 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3080 gen_store_gpr(t0, reg);
3081 tcg_temp_free(t0);
3082}
3083
ab39ee45
YK
3084static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3085 int rs)
d4ea6acd
LA
3086{
3087 target_long offset;
3088 target_long addr;
3089
ab39ee45 3090 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3091 case OPC_ADDIUPC:
3092 if (rs != 0) {
3093 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3094 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3095 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3096 }
3097 break;
3098 case R6_OPC_LWPC:
3099 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3100 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3101 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3102 break;
3103#if defined(TARGET_MIPS64)
3104 case OPC_LWUPC:
3105 check_mips_64(ctx);
3106 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3107 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3108 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3109 break;
3110#endif
3111 default:
ab39ee45 3112 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3113 case OPC_AUIPC:
3114 if (rs != 0) {
ab39ee45
YK
3115 offset = sextract32(ctx->opcode, 0, 16) << 16;
3116 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3117 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3118 }
3119 break;
3120 case OPC_ALUIPC:
3121 if (rs != 0) {
ab39ee45
YK
3122 offset = sextract32(ctx->opcode, 0, 16) << 16;
3123 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3124 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3125 }
3126 break;
3127#if defined(TARGET_MIPS64)
3128 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3129 case R6_OPC_LDPC + (1 << 16):
3130 case R6_OPC_LDPC + (2 << 16):
3131 case R6_OPC_LDPC + (3 << 16):
3132 check_mips_64(ctx);
3133 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3134 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3135 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3136 break;
3137#endif
3138 default:
3139 MIPS_INVAL("OPC_PCREL");
9c708c7f 3140 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3141 break;
3142 }
3143 break;
3144 }
3145}
3146
b42ee5e1
LA
3147static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3148{
b42ee5e1
LA
3149 TCGv t0, t1;
3150
3151 if (rd == 0) {
3152 /* Treat as NOP. */
b42ee5e1
LA
3153 return;
3154 }
3155
3156 t0 = tcg_temp_new();
3157 t1 = tcg_temp_new();
3158
3159 gen_load_gpr(t0, rs);
3160 gen_load_gpr(t1, rt);
3161
3162 switch (opc) {
3163 case R6_OPC_DIV:
3164 {
3165 TCGv t2 = tcg_temp_new();
3166 TCGv t3 = tcg_temp_new();
3167 tcg_gen_ext32s_tl(t0, t0);
3168 tcg_gen_ext32s_tl(t1, t1);
3169 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3170 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3171 tcg_gen_and_tl(t2, t2, t3);
3172 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3173 tcg_gen_or_tl(t2, t2, t3);
3174 tcg_gen_movi_tl(t3, 0);
3175 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3176 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3177 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3178 tcg_temp_free(t3);
3179 tcg_temp_free(t2);
3180 }
b42ee5e1
LA
3181 break;
3182 case R6_OPC_MOD:
3183 {
3184 TCGv t2 = tcg_temp_new();
3185 TCGv t3 = tcg_temp_new();
3186 tcg_gen_ext32s_tl(t0, t0);
3187 tcg_gen_ext32s_tl(t1, t1);
3188 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3189 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3190 tcg_gen_and_tl(t2, t2, t3);
3191 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3192 tcg_gen_or_tl(t2, t2, t3);
3193 tcg_gen_movi_tl(t3, 0);
3194 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3195 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3196 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3197 tcg_temp_free(t3);
3198 tcg_temp_free(t2);
3199 }
b42ee5e1
LA
3200 break;
3201 case R6_OPC_DIVU:
3202 {
3203 TCGv t2 = tcg_const_tl(0);
3204 TCGv t3 = tcg_const_tl(1);
3205 tcg_gen_ext32u_tl(t0, t0);
3206 tcg_gen_ext32u_tl(t1, t1);
3207 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3208 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3209 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3210 tcg_temp_free(t3);
3211 tcg_temp_free(t2);
3212 }
b42ee5e1
LA
3213 break;
3214 case R6_OPC_MODU:
3215 {
3216 TCGv t2 = tcg_const_tl(0);
3217 TCGv t3 = tcg_const_tl(1);
3218 tcg_gen_ext32u_tl(t0, t0);
3219 tcg_gen_ext32u_tl(t1, t1);
3220 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3221 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3222 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3223 tcg_temp_free(t3);
3224 tcg_temp_free(t2);
3225 }
b42ee5e1
LA
3226 break;
3227 case R6_OPC_MUL:
3228 {
3229 TCGv_i32 t2 = tcg_temp_new_i32();
3230 TCGv_i32 t3 = tcg_temp_new_i32();
3231 tcg_gen_trunc_tl_i32(t2, t0);
3232 tcg_gen_trunc_tl_i32(t3, t1);
3233 tcg_gen_mul_i32(t2, t2, t3);
3234 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3235 tcg_temp_free_i32(t2);
3236 tcg_temp_free_i32(t3);
3237 }
b42ee5e1
LA
3238 break;
3239 case R6_OPC_MUH:
3240 {
3241 TCGv_i32 t2 = tcg_temp_new_i32();
3242 TCGv_i32 t3 = tcg_temp_new_i32();
3243 tcg_gen_trunc_tl_i32(t2, t0);
3244 tcg_gen_trunc_tl_i32(t3, t1);
3245 tcg_gen_muls2_i32(t2, t3, t2, t3);
3246 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3247 tcg_temp_free_i32(t2);
3248 tcg_temp_free_i32(t3);
3249 }
b42ee5e1
LA
3250 break;
3251 case R6_OPC_MULU:
3252 {
3253 TCGv_i32 t2 = tcg_temp_new_i32();
3254 TCGv_i32 t3 = tcg_temp_new_i32();
3255 tcg_gen_trunc_tl_i32(t2, t0);
3256 tcg_gen_trunc_tl_i32(t3, t1);
3257 tcg_gen_mul_i32(t2, t2, t3);
3258 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3259 tcg_temp_free_i32(t2);
3260 tcg_temp_free_i32(t3);
3261 }
b42ee5e1
LA
3262 break;
3263 case R6_OPC_MUHU:
3264 {
3265 TCGv_i32 t2 = tcg_temp_new_i32();
3266 TCGv_i32 t3 = tcg_temp_new_i32();
3267 tcg_gen_trunc_tl_i32(t2, t0);
3268 tcg_gen_trunc_tl_i32(t3, t1);
3269 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3270 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3271 tcg_temp_free_i32(t2);
3272 tcg_temp_free_i32(t3);
3273 }
b42ee5e1
LA
3274 break;
3275#if defined(TARGET_MIPS64)
3276 case R6_OPC_DDIV:
3277 {
3278 TCGv t2 = tcg_temp_new();
3279 TCGv t3 = tcg_temp_new();
3280 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3282 tcg_gen_and_tl(t2, t2, t3);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3284 tcg_gen_or_tl(t2, t2, t3);
3285 tcg_gen_movi_tl(t3, 0);
3286 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3287 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3288 tcg_temp_free(t3);
3289 tcg_temp_free(t2);
3290 }
b42ee5e1
LA
3291 break;
3292 case R6_OPC_DMOD:
3293 {
3294 TCGv t2 = tcg_temp_new();
3295 TCGv t3 = tcg_temp_new();
3296 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3297 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3298 tcg_gen_and_tl(t2, t2, t3);
3299 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3300 tcg_gen_or_tl(t2, t2, t3);
3301 tcg_gen_movi_tl(t3, 0);
3302 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3303 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3304 tcg_temp_free(t3);
3305 tcg_temp_free(t2);
3306 }
b42ee5e1
LA
3307 break;
3308 case R6_OPC_DDIVU:
3309 {
3310 TCGv t2 = tcg_const_tl(0);
3311 TCGv t3 = tcg_const_tl(1);
3312 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3313 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3314 tcg_temp_free(t3);
3315 tcg_temp_free(t2);
3316 }
b42ee5e1
LA
3317 break;
3318 case R6_OPC_DMODU:
3319 {
3320 TCGv t2 = tcg_const_tl(0);
3321 TCGv t3 = tcg_const_tl(1);
3322 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3323 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3324 tcg_temp_free(t3);
3325 tcg_temp_free(t2);
3326 }
b42ee5e1
LA
3327 break;
3328 case R6_OPC_DMUL:
3329 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3330 break;
3331 case R6_OPC_DMUH:
3332 {
3333 TCGv t2 = tcg_temp_new();
3334 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3335 tcg_temp_free(t2);
3336 }
b42ee5e1
LA
3337 break;
3338 case R6_OPC_DMULU:
3339 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3340 break;
3341 case R6_OPC_DMUHU:
3342 {
3343 TCGv t2 = tcg_temp_new();
3344 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3345 tcg_temp_free(t2);
3346 }
b42ee5e1
LA
3347 break;
3348#endif
3349 default:
9d68ac14 3350 MIPS_INVAL("r6 mul/div");
9c708c7f 3351 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3352 goto out;
3353 }
b42ee5e1
LA
3354 out:
3355 tcg_temp_free(t0);
3356 tcg_temp_free(t1);
3357}
3358
26135ead
RS
3359static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3360 int acc, int rs, int rt)
6af0bf9c 3361{
d45f89f4
AJ
3362 TCGv t0, t1;
3363
51127181
AJ
3364 t0 = tcg_temp_new();
3365 t1 = tcg_temp_new();
6af0bf9c 3366
78723684
TS
3367 gen_load_gpr(t0, rs);
3368 gen_load_gpr(t1, rt);
51127181 3369
26135ead
RS
3370 if (acc != 0) {
3371 check_dsp(ctx);
3372 }
3373
6af0bf9c
FB
3374 switch (opc) {
3375 case OPC_DIV:
48d38ca5 3376 {
51127181
AJ
3377 TCGv t2 = tcg_temp_new();
3378 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3379 tcg_gen_ext32s_tl(t0, t0);
3380 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3381 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3383 tcg_gen_and_tl(t2, t2, t3);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3385 tcg_gen_or_tl(t2, t2, t3);
3386 tcg_gen_movi_tl(t3, 0);
3387 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3388 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3389 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3390 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3391 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3392 tcg_temp_free(t3);
3393 tcg_temp_free(t2);
48d38ca5 3394 }
6af0bf9c
FB
3395 break;
3396 case OPC_DIVU:
48d38ca5 3397 {
51127181
AJ
3398 TCGv t2 = tcg_const_tl(0);
3399 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3400 tcg_gen_ext32u_tl(t0, t0);
3401 tcg_gen_ext32u_tl(t1, t1);
51127181 3402 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3403 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3404 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3405 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3406 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3407 tcg_temp_free(t3);
3408 tcg_temp_free(t2);
48d38ca5 3409 }
6af0bf9c
FB
3410 break;
3411 case OPC_MULT:
214c465f 3412 {
ce1dd5d1
RH
3413 TCGv_i32 t2 = tcg_temp_new_i32();
3414 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3415 tcg_gen_trunc_tl_i32(t2, t0);
3416 tcg_gen_trunc_tl_i32(t3, t1);
3417 tcg_gen_muls2_i32(t2, t3, t2, t3);
3418 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3419 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3420 tcg_temp_free_i32(t2);
3421 tcg_temp_free_i32(t3);
214c465f 3422 }
6af0bf9c
FB
3423 break;
3424 case OPC_MULTU:
214c465f 3425 {
ce1dd5d1
RH
3426 TCGv_i32 t2 = tcg_temp_new_i32();
3427 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3428 tcg_gen_trunc_tl_i32(t2, t0);
3429 tcg_gen_trunc_tl_i32(t3, t1);
3430 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3431 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3432 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3433 tcg_temp_free_i32(t2);
3434 tcg_temp_free_i32(t3);
214c465f 3435 }
6af0bf9c 3436 break;
d26bc211 3437#if defined(TARGET_MIPS64)
7a387fff 3438 case OPC_DDIV:
48d38ca5 3439 {
51127181
AJ
3440 TCGv t2 = tcg_temp_new();
3441 TCGv t3 = tcg_temp_new();
3442 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3443 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3444 tcg_gen_and_tl(t2, t2, t3);
3445 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3446 tcg_gen_or_tl(t2, t2, t3);
3447 tcg_gen_movi_tl(t3, 0);
3448 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3449 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3450 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3451 tcg_temp_free(t3);
3452 tcg_temp_free(t2);
48d38ca5 3453 }
7a387fff
TS
3454 break;
3455 case OPC_DDIVU:
48d38ca5 3456 {
51127181
AJ
3457 TCGv t2 = tcg_const_tl(0);
3458 TCGv t3 = tcg_const_tl(1);
3459 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3460 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3461 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3462 tcg_temp_free(t3);
3463 tcg_temp_free(t2);
48d38ca5 3464 }
7a387fff
TS
3465 break;
3466 case OPC_DMULT:
26135ead 3467 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3468 break;
3469 case OPC_DMULTU:
26135ead 3470 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3471 break;
3472#endif
6af0bf9c 3473 case OPC_MADD:
214c465f 3474 {
d45f89f4
AJ
3475 TCGv_i64 t2 = tcg_temp_new_i64();
3476 TCGv_i64 t3 = tcg_temp_new_i64();
3477
3478 tcg_gen_ext_tl_i64(t2, t0);
3479 tcg_gen_ext_tl_i64(t3, t1);
3480 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3481 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3482 tcg_gen_add_i64(t2, t2, t3);
3483 tcg_temp_free_i64(t3);
71f303cd
RH
3484 gen_move_low32(cpu_LO[acc], t2);
3485 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3486 tcg_temp_free_i64(t2);
214c465f 3487 }
6af0bf9c
FB
3488 break;
3489 case OPC_MADDU:
4133498f 3490 {
d45f89f4
AJ
3491 TCGv_i64 t2 = tcg_temp_new_i64();
3492 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3493
78723684
TS
3494 tcg_gen_ext32u_tl(t0, t0);
3495 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3496 tcg_gen_extu_tl_i64(t2, t0);
3497 tcg_gen_extu_tl_i64(t3, t1);
3498 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3499 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3500 tcg_gen_add_i64(t2, t2, t3);
3501 tcg_temp_free_i64(t3);
71f303cd
RH
3502 gen_move_low32(cpu_LO[acc], t2);
3503 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3504 tcg_temp_free_i64(t2);
214c465f 3505 }
6af0bf9c
FB
3506 break;
3507 case OPC_MSUB:
214c465f 3508 {
d45f89f4
AJ
3509 TCGv_i64 t2 = tcg_temp_new_i64();
3510 TCGv_i64 t3 = tcg_temp_new_i64();
3511
3512 tcg_gen_ext_tl_i64(t2, t0);
3513 tcg_gen_ext_tl_i64(t3, t1);
3514 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3515 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3516 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3517 tcg_temp_free_i64(t3);
71f303cd
RH
3518 gen_move_low32(cpu_LO[acc], t2);
3519 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3520 tcg_temp_free_i64(t2);
214c465f 3521 }
6af0bf9c
FB
3522 break;
3523 case OPC_MSUBU:
214c465f 3524 {
d45f89f4
AJ
3525 TCGv_i64 t2 = tcg_temp_new_i64();
3526 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3527
78723684
TS
3528 tcg_gen_ext32u_tl(t0, t0);
3529 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3530 tcg_gen_extu_tl_i64(t2, t0);
3531 tcg_gen_extu_tl_i64(t3, t1);
3532 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3533 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3534 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3535 tcg_temp_free_i64(t3);
71f303cd
RH
3536 gen_move_low32(cpu_LO[acc], t2);
3537 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3538 tcg_temp_free_i64(t2);
214c465f 3539 }
6af0bf9c
FB
3540 break;
3541 default:
9d68ac14 3542 MIPS_INVAL("mul/div");
9c708c7f 3543 generate_exception_end(ctx, EXCP_RI);
78723684 3544 goto out;
6af0bf9c 3545 }
78723684
TS
3546 out:
3547 tcg_temp_free(t0);
3548 tcg_temp_free(t1);
6af0bf9c
FB
3549}
3550
e9c71dd1
TS
3551static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3552 int rd, int rs, int rt)
3553{
f157bfe1
AJ
3554 TCGv t0 = tcg_temp_new();
3555 TCGv t1 = tcg_temp_new();
e9c71dd1 3556
6c5c1e20
TS
3557 gen_load_gpr(t0, rs);
3558 gen_load_gpr(t1, rt);
e9c71dd1
TS
3559
3560 switch (opc) {
3561 case OPC_VR54XX_MULS:
895c2d04 3562 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3563 break;
e9c71dd1 3564 case OPC_VR54XX_MULSU:
895c2d04 3565 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3566 break;
e9c71dd1 3567 case OPC_VR54XX_MACC:
895c2d04 3568 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3569 break;
e9c71dd1 3570 case OPC_VR54XX_MACCU:
895c2d04 3571 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3572 break;
e9c71dd1 3573 case OPC_VR54XX_MSAC:
895c2d04 3574 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3575 break;
e9c71dd1 3576 case OPC_VR54XX_MSACU:
895c2d04 3577 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3578 break;
e9c71dd1 3579 case OPC_VR54XX_MULHI:
895c2d04 3580 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3581 break;
e9c71dd1 3582 case OPC_VR54XX_MULHIU:
895c2d04 3583 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3584 break;
e9c71dd1 3585 case OPC_VR54XX_MULSHI:
895c2d04 3586 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3587 break;
e9c71dd1 3588 case OPC_VR54XX_MULSHIU:
895c2d04 3589 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3590 break;
e9c71dd1 3591 case OPC_VR54XX_MACCHI:
895c2d04 3592 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3593 break;
e9c71dd1 3594 case OPC_VR54XX_MACCHIU:
895c2d04 3595 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3596 break;
e9c71dd1 3597 case OPC_VR54XX_MSACHI:
895c2d04 3598 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3599 break;
e9c71dd1 3600 case OPC_VR54XX_MSACHIU:
895c2d04 3601 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3602 break;
e9c71dd1
TS
3603 default:
3604 MIPS_INVAL("mul vr54xx");
9c708c7f 3605 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3606 goto out;
e9c71dd1 3607 }
6c5c1e20 3608 gen_store_gpr(t0, rd);
6c5c1e20
TS
3609
3610 out:
3611 tcg_temp_free(t0);
3612 tcg_temp_free(t1);
e9c71dd1
TS
3613}
3614
7a387fff 3615static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3616 int rd, int rs)
3617{
20e1fb52 3618 TCGv t0;
6c5c1e20 3619
6af0bf9c 3620 if (rd == 0) {
ead9360e 3621 /* Treat as NOP. */
20e1fb52 3622 return;
6af0bf9c 3623 }
20e1fb52 3624 t0 = tcg_temp_new();
6c5c1e20 3625 gen_load_gpr(t0, rs);
6af0bf9c
FB
3626 switch (opc) {
3627 case OPC_CLO:
4267d3e6 3628 case R6_OPC_CLO:
20e1fb52 3629 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3630 break;
3631 case OPC_CLZ:
4267d3e6 3632 case R6_OPC_CLZ:
20e1fb52 3633 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c 3634 break;
d26bc211 3635#if defined(TARGET_MIPS64)
7a387fff 3636 case OPC_DCLO:
4267d3e6 3637 case R6_OPC_DCLO:
20e1fb52 3638 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3639 break;
3640 case OPC_DCLZ:
4267d3e6 3641 case R6_OPC_DCLZ:
20e1fb52 3642 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3643 break;
3644#endif
6af0bf9c 3645 }
6c5c1e20 3646 tcg_temp_free(t0);
6af0bf9c
FB
3647}
3648
161f85e6 3649/* Godson integer instructions */
bd277fa1
RH
3650static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3651 int rd, int rs, int rt)
161f85e6 3652{
161f85e6
AJ
3653 TCGv t0, t1;
3654
3655 if (rd == 0) {
3656 /* Treat as NOP. */
161f85e6
AJ
3657 return;
3658 }
3659
3660 switch (opc) {
3661 case OPC_MULT_G_2E:
3662 case OPC_MULT_G_2F:
3663 case OPC_MULTU_G_2E:
3664 case OPC_MULTU_G_2F:
3665#if defined(TARGET_MIPS64)
3666 case OPC_DMULT_G_2E:
3667 case OPC_DMULT_G_2F:
3668 case OPC_DMULTU_G_2E:
3669 case OPC_DMULTU_G_2F:
3670#endif
3671 t0 = tcg_temp_new();
3672 t1 = tcg_temp_new();
3673 break;
3674 default:
3675 t0 = tcg_temp_local_new();
3676 t1 = tcg_temp_local_new();
3677 break;
3678 }
3679
3680 gen_load_gpr(t0, rs);
3681 gen_load_gpr(t1, rt);
3682
3683 switch (opc) {
3684 case OPC_MULT_G_2E:
3685 case OPC_MULT_G_2F:
3686 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3687 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3688 break;
3689 case OPC_MULTU_G_2E:
3690 case OPC_MULTU_G_2F:
3691 tcg_gen_ext32u_tl(t0, t0);
3692 tcg_gen_ext32u_tl(t1, t1);
3693 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3694 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3695 break;
3696 case OPC_DIV_G_2E:
3697 case OPC_DIV_G_2F:
3698 {
42a268c2
RH
3699 TCGLabel *l1 = gen_new_label();
3700 TCGLabel *l2 = gen_new_label();
3701 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3702 tcg_gen_ext32s_tl(t0, t0);
3703 tcg_gen_ext32s_tl(t1, t1);
3704 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3705 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3706 tcg_gen_br(l3);
3707 gen_set_label(l1);
3708 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3709 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3710 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3711 tcg_gen_br(l3);
3712 gen_set_label(l2);
3713 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3714 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3715 gen_set_label(l3);
3716 }
161f85e6
AJ
3717 break;
3718 case OPC_DIVU_G_2E:
3719 case OPC_DIVU_G_2F:
3720 {
42a268c2
RH
3721 TCGLabel *l1 = gen_new_label();
3722 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3723 tcg_gen_ext32u_tl(t0, t0);
3724 tcg_gen_ext32u_tl(t1, t1);
3725 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3726 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3727 tcg_gen_br(l2);
3728 gen_set_label(l1);
3729 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3730 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3731 gen_set_label(l2);
3732 }
161f85e6
AJ
3733 break;
3734 case OPC_MOD_G_2E:
3735 case OPC_MOD_G_2F:
3736 {
42a268c2
RH
3737 TCGLabel *l1 = gen_new_label();
3738 TCGLabel *l2 = gen_new_label();
3739 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3740 tcg_gen_ext32u_tl(t0, t0);
3741 tcg_gen_ext32u_tl(t1, t1);
3742 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3743 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3744 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3745 gen_set_label(l1);
3746 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3747 tcg_gen_br(l3);
3748 gen_set_label(l2);
3749 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3750 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3751 gen_set_label(l3);
3752 }
161f85e6
AJ
3753 break;
3754 case OPC_MODU_G_2E:
3755 case OPC_MODU_G_2F:
3756 {
42a268c2
RH
3757 TCGLabel *l1 = gen_new_label();
3758 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3759 tcg_gen_ext32u_tl(t0, t0);
3760 tcg_gen_ext32u_tl(t1, t1);
3761 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3762 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3763 tcg_gen_br(l2);
3764 gen_set_label(l1);
3765 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3766 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3767 gen_set_label(l2);
3768 }
161f85e6
AJ
3769 break;
3770#if defined(TARGET_MIPS64)
3771 case OPC_DMULT_G_2E:
3772 case OPC_DMULT_G_2F:
3773 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3774 break;
3775 case OPC_DMULTU_G_2E:
3776 case OPC_DMULTU_G_2F:
3777 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3778 break;
3779 case OPC_DDIV_G_2E:
3780 case OPC_DDIV_G_2F:
3781 {
42a268c2
RH
3782 TCGLabel *l1 = gen_new_label();
3783 TCGLabel *l2 = gen_new_label();
3784 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3785 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3786 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3787 tcg_gen_br(l3);
3788 gen_set_label(l1);
3789 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3790 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3791 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3792 tcg_gen_br(l3);
3793 gen_set_label(l2);
3794 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3795 gen_set_label(l3);
3796 }
161f85e6
AJ
3797 break;
3798 case OPC_DDIVU_G_2E:
3799 case OPC_DDIVU_G_2F:
3800 {
42a268c2
RH
3801 TCGLabel *l1 = gen_new_label();
3802 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3803 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3804 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3805 tcg_gen_br(l2);
3806 gen_set_label(l1);
3807 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3808 gen_set_label(l2);
3809 }
161f85e6
AJ
3810 break;
3811 case OPC_DMOD_G_2E:
3812 case OPC_DMOD_G_2F:
3813 {
42a268c2
RH
3814 TCGLabel *l1 = gen_new_label();
3815 TCGLabel *l2 = gen_new_label();
3816 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3817 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3818 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3819 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3820 gen_set_label(l1);
3821 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3822 tcg_gen_br(l3);
3823 gen_set_label(l2);
3824 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3825 gen_set_label(l3);
3826 }
161f85e6
AJ
3827 break;
3828 case OPC_DMODU_G_2E:
3829 case OPC_DMODU_G_2F:
3830 {
42a268c2
RH
3831 TCGLabel *l1 = gen_new_label();
3832 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3833 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3834 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3835 tcg_gen_br(l2);
3836 gen_set_label(l1);
3837 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3838 gen_set_label(l2);
3839 }
161f85e6
AJ
3840 break;
3841#endif
3842 }
3843
161f85e6
AJ
3844 tcg_temp_free(t0);
3845 tcg_temp_free(t1);
3846}
3847
bd277fa1
RH
3848/* Loongson multimedia instructions */
3849static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3850{
bd277fa1
RH
3851 uint32_t opc, shift_max;
3852 TCGv_i64 t0, t1;
3853
3854 opc = MASK_LMI(ctx->opcode);
3855 switch (opc) {
3856 case OPC_ADD_CP2:
3857 case OPC_SUB_CP2:
3858 case OPC_DADD_CP2:
3859 case OPC_DSUB_CP2:
3860 t0 = tcg_temp_local_new_i64();
3861 t1 = tcg_temp_local_new_i64();
3862 break;
3863 default:
3864 t0 = tcg_temp_new_i64();
3865 t1 = tcg_temp_new_i64();
3866 break;
3867 }
3868
3869 gen_load_fpr64(ctx, t0, rs);
3870 gen_load_fpr64(ctx, t1, rt);
3871
3872#define LMI_HELPER(UP, LO) \
9d68ac14 3873 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3874#define LMI_HELPER_1(UP, LO) \
9d68ac14 3875 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3876#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3877 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3878
3879 switch (opc) {
3880 LMI_HELPER(PADDSH, paddsh);
3881 LMI_HELPER(PADDUSH, paddush);
3882 LMI_HELPER(PADDH, paddh);
3883 LMI_HELPER(PADDW, paddw);
3884 LMI_HELPER(PADDSB, paddsb);
3885 LMI_HELPER(PADDUSB, paddusb);
3886 LMI_HELPER(PADDB, paddb);
3887
3888 LMI_HELPER(PSUBSH, psubsh);
3889 LMI_HELPER(PSUBUSH, psubush);
3890 LMI_HELPER(PSUBH, psubh);
3891 LMI_HELPER(PSUBW, psubw);
3892 LMI_HELPER(PSUBSB, psubsb);
3893 LMI_HELPER(PSUBUSB, psubusb);
3894 LMI_HELPER(PSUBB, psubb);
3895
3896 LMI_HELPER(PSHUFH, pshufh);
3897 LMI_HELPER(PACKSSWH, packsswh);
3898 LMI_HELPER(PACKSSHB, packsshb);
3899 LMI_HELPER(PACKUSHB, packushb);
3900
3901 LMI_HELPER(PUNPCKLHW, punpcklhw);
3902 LMI_HELPER(PUNPCKHHW, punpckhhw);
3903 LMI_HELPER(PUNPCKLBH, punpcklbh);
3904 LMI_HELPER(PUNPCKHBH, punpckhbh);
3905 LMI_HELPER(PUNPCKLWD, punpcklwd);
3906 LMI_HELPER(PUNPCKHWD, punpckhwd);
3907
3908 LMI_HELPER(PAVGH, pavgh);
3909 LMI_HELPER(PAVGB, pavgb);
3910 LMI_HELPER(PMAXSH, pmaxsh);
3911 LMI_HELPER(PMINSH, pminsh);
3912 LMI_HELPER(PMAXUB, pmaxub);
3913 LMI_HELPER(PMINUB, pminub);
3914
3915 LMI_HELPER(PCMPEQW, pcmpeqw);
3916 LMI_HELPER(PCMPGTW, pcmpgtw);
3917 LMI_HELPER(PCMPEQH, pcmpeqh);
3918 LMI_HELPER(PCMPGTH, pcmpgth);
3919 LMI_HELPER(PCMPEQB, pcmpeqb);
3920 LMI_HELPER(PCMPGTB, pcmpgtb);
3921
3922 LMI_HELPER(PSLLW, psllw);
3923 LMI_HELPER(PSLLH, psllh);
3924 LMI_HELPER(PSRLW, psrlw);
3925 LMI_HELPER(PSRLH, psrlh);
3926 LMI_HELPER(PSRAW, psraw);
3927 LMI_HELPER(PSRAH, psrah);
3928
3929 LMI_HELPER(PMULLH, pmullh);
3930 LMI_HELPER(PMULHH, pmulhh);
3931 LMI_HELPER(PMULHUH, pmulhuh);
3932 LMI_HELPER(PMADDHW, pmaddhw);
3933
3934 LMI_HELPER(PASUBUB, pasubub);
3935 LMI_HELPER_1(BIADD, biadd);
3936 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3937
3938 LMI_DIRECT(PADDD, paddd, add);
3939 LMI_DIRECT(PSUBD, psubd, sub);
3940 LMI_DIRECT(XOR_CP2, xor, xor);
3941 LMI_DIRECT(NOR_CP2, nor, nor);
3942 LMI_DIRECT(AND_CP2, and, and);
3943 LMI_DIRECT(PANDN, pandn, andc);
3944 LMI_DIRECT(OR, or, or);
3945
3946 case OPC_PINSRH_0:
3947 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
3948 break;
3949 case OPC_PINSRH_1:
3950 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
3951 break;
3952 case OPC_PINSRH_2:
3953 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
3954 break;
3955 case OPC_PINSRH_3:
3956 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
3957 break;
3958
3959 case OPC_PEXTRH:
3960 tcg_gen_andi_i64(t1, t1, 3);
3961 tcg_gen_shli_i64(t1, t1, 4);
3962 tcg_gen_shr_i64(t0, t0, t1);
3963 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
3964 break;
3965
3966 case OPC_ADDU_CP2:
3967 tcg_gen_add_i64(t0, t0, t1);
3968 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3969 break;
3970 case OPC_SUBU_CP2:
3971 tcg_gen_sub_i64(t0, t0, t1);
3972 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
3973 break;
3974
3975 case OPC_SLL_CP2:
bd277fa1
RH
3976 shift_max = 32;
3977 goto do_shift;
3978 case OPC_SRL_CP2:
bd277fa1
RH
3979 shift_max = 32;
3980 goto do_shift;
3981 case OPC_SRA_CP2:
bd277fa1
RH
3982 shift_max = 32;
3983 goto do_shift;
3984 case OPC_DSLL_CP2:
bd277fa1
RH
3985 shift_max = 64;
3986 goto do_shift;
3987 case OPC_DSRL_CP2:
bd277fa1
RH
3988 shift_max = 64;
3989 goto do_shift;
3990 case OPC_DSRA_CP2:
bd277fa1
RH
3991 shift_max = 64;
3992 goto do_shift;
3993 do_shift:
3994 /* Make sure shift count isn't TCG undefined behaviour. */
3995 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3996
3997 switch (opc) {
3998 case OPC_SLL_CP2:
3999 case OPC_DSLL_CP2:
4000 tcg_gen_shl_i64(t0, t0, t1);
4001 break;
4002 case OPC_SRA_CP2:
4003 case OPC_DSRA_CP2:
4004 /* Since SRA is UndefinedResult without sign-extended inputs,
4005 we can treat SRA and DSRA the same. */
4006 tcg_gen_sar_i64(t0, t0, t1);
4007 break;
4008 case OPC_SRL_CP2:
4009 /* We want to shift in zeros for SRL; zero-extend first. */
4010 tcg_gen_ext32u_i64(t0, t0);
4011 /* FALLTHRU */
4012 case OPC_DSRL_CP2:
4013 tcg_gen_shr_i64(t0, t0, t1);
4014 break;
4015 }
4016
4017 if (shift_max == 32) {
4018 tcg_gen_ext32s_i64(t0, t0);
4019 }
4020
4021 /* Shifts larger than MAX produce zero. */
4022 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4023 tcg_gen_neg_i64(t1, t1);
4024 tcg_gen_and_i64(t0, t0, t1);
4025 break;
4026
4027 case OPC_ADD_CP2:
4028 case OPC_DADD_CP2:
4029 {
4030 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4031 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4032
4033 tcg_gen_mov_i64(t2, t0);
4034 tcg_gen_add_i64(t0, t1, t2);
4035 if (opc == OPC_ADD_CP2) {
4036 tcg_gen_ext32s_i64(t0, t0);
4037 }
4038 tcg_gen_xor_i64(t1, t1, t2);
4039 tcg_gen_xor_i64(t2, t2, t0);
4040 tcg_gen_andc_i64(t1, t2, t1);
4041 tcg_temp_free_i64(t2);
4042 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4043 generate_exception(ctx, EXCP_OVERFLOW);
4044 gen_set_label(lab);
bd277fa1
RH
4045 break;
4046 }
4047
4048 case OPC_SUB_CP2:
4049 case OPC_DSUB_CP2:
4050 {
4051 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4052 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4053
4054 tcg_gen_mov_i64(t2, t0);
4055 tcg_gen_sub_i64(t0, t1, t2);
4056 if (opc == OPC_SUB_CP2) {
4057 tcg_gen_ext32s_i64(t0, t0);
4058 }
4059 tcg_gen_xor_i64(t1, t1, t2);
4060 tcg_gen_xor_i64(t2, t2, t0);
4061 tcg_gen_and_i64(t1, t1, t2);
4062 tcg_temp_free_i64(t2);
4063 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4064 generate_exception(ctx, EXCP_OVERFLOW);
4065 gen_set_label(lab);
bd277fa1
RH
4066 break;
4067 }
4068
4069 case OPC_PMULUW:
4070 tcg_gen_ext32u_i64(t0, t0);
4071 tcg_gen_ext32u_i64(t1, t1);
4072 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4073 break;
4074
4075 case OPC_SEQU_CP2:
4076 case OPC_SEQ_CP2:
4077 case OPC_SLTU_CP2:
4078 case OPC_SLT_CP2:
4079 case OPC_SLEU_CP2:
4080 case OPC_SLE_CP2:
4081 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4082 FD field is the CC field? */
4083 default:
9d68ac14 4084 MIPS_INVAL("loongson_cp2");
9c708c7f 4085 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4086 return;
4087 }
4088
4089#undef LMI_HELPER
4090#undef LMI_DIRECT
4091
4092 gen_store_fpr64(ctx, t0, rd);
4093
bd277fa1
RH
4094 tcg_temp_free_i64(t0);
4095 tcg_temp_free_i64(t1);
4096}
4097
6af0bf9c 4098/* Traps */
7a387fff 4099static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4100 int rs, int rt, int16_t imm)
4101{
4102 int cond;
cdc0faa6 4103 TCGv t0 = tcg_temp_new();
1ba74fb8 4104 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4105
4106 cond = 0;
4107 /* Load needed operands */
4108 switch (opc) {
4109 case OPC_TEQ:
4110 case OPC_TGE:
4111 case OPC_TGEU:
4112 case OPC_TLT:
4113 case OPC_TLTU:
4114 case OPC_TNE:
4115 /* Compare two registers */
4116 if (rs != rt) {
be24bb4f
TS
4117 gen_load_gpr(t0, rs);
4118 gen_load_gpr(t1, rt);
6af0bf9c
FB
4119 cond = 1;
4120 }
179e32bb 4121 break;
6af0bf9c
FB
4122 case OPC_TEQI:
4123 case OPC_TGEI:
4124 case OPC_TGEIU:
4125 case OPC_TLTI:
4126 case OPC_TLTIU:
4127 case OPC_TNEI:
4128 /* Compare register to immediate */
4129 if (rs != 0 || imm != 0) {
be24bb4f
TS
4130 gen_load_gpr(t0, rs);
4131 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4132 cond = 1;
4133 }
4134 break;
4135 }
4136 if (cond == 0) {
4137 switch (opc) {
4138 case OPC_TEQ: /* rs == rs */
4139 case OPC_TEQI: /* r0 == 0 */
4140 case OPC_TGE: /* rs >= rs */
4141 case OPC_TGEI: /* r0 >= 0 */
4142 case OPC_TGEU: /* rs >= rs unsigned */
4143 case OPC_TGEIU: /* r0 >= 0 unsigned */
4144 /* Always trap */
9c708c7f 4145 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4146 break;
4147 case OPC_TLT: /* rs < rs */
4148 case OPC_TLTI: /* r0 < 0 */
4149 case OPC_TLTU: /* rs < rs unsigned */
4150 case OPC_TLTIU: /* r0 < 0 unsigned */
4151 case OPC_TNE: /* rs != rs */
4152 case OPC_TNEI: /* r0 != 0 */
ead9360e 4153 /* Never trap: treat as NOP. */
cdc0faa6 4154 break;
6af0bf9c
FB
4155 }
4156 } else {
42a268c2 4157 TCGLabel *l1 = gen_new_label();
cdc0faa6 4158
6af0bf9c
FB
4159 switch (opc) {
4160 case OPC_TEQ:
4161 case OPC_TEQI:
cdc0faa6 4162 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4163 break;
4164 case OPC_TGE:
4165 case OPC_TGEI:
cdc0faa6 4166 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4167 break;
4168 case OPC_TGEU:
4169 case OPC_TGEIU:
cdc0faa6 4170 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4171 break;
4172 case OPC_TLT:
4173 case OPC_TLTI:
cdc0faa6 4174 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4175 break;
4176 case OPC_TLTU:
4177 case OPC_TLTIU:
cdc0faa6 4178 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4179 break;
4180 case OPC_TNE:
4181 case OPC_TNEI:
cdc0faa6 4182 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4183 break;
6af0bf9c 4184 }
cdc0faa6 4185 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4186 gen_set_label(l1);
4187 }
be24bb4f
TS
4188 tcg_temp_free(t0);
4189 tcg_temp_free(t1);
6af0bf9c
FB
4190}
4191
356265ae 4192static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4193{
6e256c93
FB
4194 TranslationBlock *tb;
4195 tb = ctx->tb;
7b270ef2
NF
4196 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4197 likely(!ctx->singlestep_enabled)) {
57fec1fe 4198 tcg_gen_goto_tb(n);
9b9e4393 4199 gen_save_pc(dest);
8cfd0495 4200 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4201 } else {
9b9e4393 4202 gen_save_pc(dest);
7b270ef2
NF
4203 if (ctx->singlestep_enabled) {
4204 save_cpu_state(ctx, 0);
9c708c7f 4205 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4206 }
57fec1fe 4207 tcg_gen_exit_tb(0);
6e256c93 4208 }
c53be334
FB
4209}
4210
6af0bf9c 4211/* Branches (before delay slot) */
7a387fff 4212static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4213 int insn_bytes,
b231c103
YK
4214 int rs, int rt, int32_t offset,
4215 int delayslot_size)
6af0bf9c 4216{
d077b6f7 4217 target_ulong btgt = -1;
3ad4bb2d 4218 int blink = 0;
2fdbad25 4219 int bcond_compute = 0;
1ba74fb8
AJ
4220 TCGv t0 = tcg_temp_new();
4221 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4222
4223 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4224#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4225 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4226 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4227#endif
9c708c7f 4228 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4229 goto out;
3ad4bb2d 4230 }
6af0bf9c 4231
6af0bf9c
FB
4232 /* Load needed operands */
4233 switch (opc) {
4234 case OPC_BEQ:
4235 case OPC_BEQL:
4236 case OPC_BNE:
4237 case OPC_BNEL:
4238 /* Compare two registers */
4239 if (rs != rt) {
6c5c1e20
TS
4240 gen_load_gpr(t0, rs);
4241 gen_load_gpr(t1, rt);
2fdbad25 4242 bcond_compute = 1;
6af0bf9c 4243 }
7dca4ad0 4244 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4245 break;
4246 case OPC_BGEZ:
4247 case OPC_BGEZAL:
4248 case OPC_BGEZALL:
4249 case OPC_BGEZL:
4250 case OPC_BGTZ:
4251 case OPC_BGTZL:
4252 case OPC_BLEZ:
4253 case OPC_BLEZL:
4254 case OPC_BLTZ:
4255 case OPC_BLTZAL:
4256 case OPC_BLTZALL:
4257 case OPC_BLTZL:
4258 /* Compare to zero */
4259 if (rs != 0) {
6c5c1e20 4260 gen_load_gpr(t0, rs);
2fdbad25 4261 bcond_compute = 1;
6af0bf9c 4262 }
7dca4ad0 4263 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4264 break;
e45a93e2
JL
4265 case OPC_BPOSGE32:
4266#if defined(TARGET_MIPS64)
4267 case OPC_BPOSGE64:
4268 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4269#else
4270 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4271#endif
4272 bcond_compute = 1;
4273 btgt = ctx->pc + insn_bytes + offset;
4274 break;
6af0bf9c
FB
4275 case OPC_J:
4276 case OPC_JAL:
364d4831 4277 case OPC_JALX:
6af0bf9c 4278 /* Jump to immediate */
7dca4ad0 4279 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4280 break;
4281 case OPC_JR:
4282 case OPC_JALR:
4283 /* Jump to register */
7a387fff
TS
4284 if (offset != 0 && offset != 16) {
4285 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4286 others are reserved. */
923617a3 4287 MIPS_INVAL("jump hint");
9c708c7f 4288 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4289 goto out;
6af0bf9c 4290 }
d077b6f7 4291 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4292 break;
4293 default:
4294 MIPS_INVAL("branch/jump");
9c708c7f 4295 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4296 goto out;
6af0bf9c 4297 }
2fdbad25 4298 if (bcond_compute == 0) {
6af0bf9c
FB
4299 /* No condition to be computed */
4300 switch (opc) {
4301 case OPC_BEQ: /* rx == rx */
4302 case OPC_BEQL: /* rx == rx likely */
4303 case OPC_BGEZ: /* 0 >= 0 */
4304 case OPC_BGEZL: /* 0 >= 0 likely */
4305 case OPC_BLEZ: /* 0 <= 0 */
4306 case OPC_BLEZL: /* 0 <= 0 likely */
4307 /* Always take */
4ad40f36 4308 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4309 break;
4310 case OPC_BGEZAL: /* 0 >= 0 */
4311 case OPC_BGEZALL: /* 0 >= 0 likely */
4312 /* Always take and link */
4313 blink = 31;
4ad40f36 4314 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4315 break;
4316 case OPC_BNE: /* rx != rx */
4317 case OPC_BGTZ: /* 0 > 0 */
4318 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4319 /* Treat as NOP. */
6c5c1e20 4320 goto out;
eeef26cd 4321 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4322 /* Handle as an unconditional branch to get correct delay
4323 slot checking. */
4324 blink = 31;
b231c103 4325 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4326 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4327 break;
eeef26cd 4328 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4329 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f 4330 /* Skip the instruction in the delay slot */
9898128f 4331 ctx->pc += 4;
6c5c1e20 4332 goto out;
6af0bf9c
FB
4333 case OPC_BNEL: /* rx != rx likely */
4334 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4335 case OPC_BLTZL: /* 0 < 0 likely */
4336 /* Skip the instruction in the delay slot */
9898128f 4337 ctx->pc += 4;
6c5c1e20 4338 goto out;
6af0bf9c 4339 case OPC_J:
4ad40f36 4340 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4341 break;
364d4831
NF
4342 case OPC_JALX:
4343 ctx->hflags |= MIPS_HFLAG_BX;
4344 /* Fallthrough */
6af0bf9c
FB
4345 case OPC_JAL:
4346 blink = 31;
4ad40f36 4347 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4348 break;
4349 case OPC_JR:
4ad40f36 4350 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4351 break;
4352 case OPC_JALR:
4353 blink = rt;
4ad40f36 4354 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4355 break;
4356 default:
4357 MIPS_INVAL("branch/jump");
9c708c7f 4358 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4359 goto out;
6af0bf9c
FB
4360 }
4361 } else {
4362 switch (opc) {
4363 case OPC_BEQ:
e68dd28f 4364 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4365 goto not_likely;
4366 case OPC_BEQL:
e68dd28f 4367 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4368 goto likely;
4369 case OPC_BNE:
e68dd28f 4370 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4371 goto not_likely;
4372 case OPC_BNEL:
e68dd28f 4373 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4374 goto likely;
4375 case OPC_BGEZ:
e68dd28f 4376 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4377 goto not_likely;
4378 case OPC_BGEZL:
e68dd28f 4379 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4380 goto likely;
4381 case OPC_BGEZAL:
e68dd28f 4382 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4383 blink = 31;
4384 goto not_likely;
4385 case OPC_BGEZALL:
e68dd28f 4386 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4387 blink = 31;
6af0bf9c
FB
4388 goto likely;
4389 case OPC_BGTZ:
e68dd28f 4390 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4391 goto not_likely;
4392 case OPC_BGTZL:
e68dd28f 4393 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4394 goto likely;
4395 case OPC_BLEZ:
e68dd28f 4396 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4397 goto not_likely;
4398 case OPC_BLEZL:
e68dd28f 4399 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4400 goto likely;
4401 case OPC_BLTZ:
e68dd28f 4402 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4403 goto not_likely;
4404 case OPC_BLTZL:
e68dd28f 4405 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4406 goto likely;
e45a93e2
JL
4407 case OPC_BPOSGE32:
4408 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4409 goto not_likely;
4410#if defined(TARGET_MIPS64)
4411 case OPC_BPOSGE64:
4412 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4413 goto not_likely;
4414#endif
6af0bf9c 4415 case OPC_BLTZAL:
e68dd28f 4416 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4417 blink = 31;
6af0bf9c 4418 not_likely:
4ad40f36 4419 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4420 break;
4421 case OPC_BLTZALL:
e68dd28f 4422 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4423 blink = 31;
6af0bf9c 4424 likely:
4ad40f36 4425 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4426 break;
c53f4a62
TS
4427 default:
4428 MIPS_INVAL("conditional branch/jump");
9c708c7f 4429 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4430 goto out;
6af0bf9c 4431 }
6af0bf9c 4432 }
9b9e4393 4433
d077b6f7 4434 ctx->btarget = btgt;
b231c103
YK
4435
4436 switch (delayslot_size) {
4437 case 2:
4438 ctx->hflags |= MIPS_HFLAG_BDS16;
4439 break;
4440 case 4:
4441 ctx->hflags |= MIPS_HFLAG_BDS32;
4442 break;
4443 }
4444
6af0bf9c 4445 if (blink > 0) {
b231c103 4446 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4447 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4448
364d4831 4449 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4450 }
6c5c1e20
TS
4451
4452 out:
364d4831
NF
4453 if (insn_bytes == 2)
4454 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4455 tcg_temp_free(t0);
4456 tcg_temp_free(t1);
6af0bf9c
FB
4457}
4458
7a387fff
TS
4459/* special3 bitfield operations */
4460static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4461 int rs, int lsb, int msb)
7a387fff 4462{
a7812ae4
PB
4463 TCGv t0 = tcg_temp_new();
4464 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4465
4466 gen_load_gpr(t1, rs);
7a387fff
TS
4467 switch (opc) {
4468 case OPC_EXT:
b7f26e52 4469 if (lsb + msb > 31) {
7a387fff 4470 goto fail;
b7f26e52 4471 }
505ad7c2
AJ
4472 tcg_gen_shri_tl(t0, t1, lsb);
4473 if (msb != 31) {
b7f26e52 4474 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
505ad7c2
AJ
4475 } else {
4476 tcg_gen_ext32s_tl(t0, t0);
4477 }
7a387fff 4478 break;
c6d6dd7c 4479#if defined(TARGET_MIPS64)
7a387fff 4480 case OPC_DEXTU:
b7f26e52
RH
4481 lsb += 32;
4482 goto do_dext;
4483 case OPC_DEXTM:
4484 msb += 32;
4485 goto do_dext;
7a387fff 4486 case OPC_DEXT:
b7f26e52
RH
4487 do_dext:
4488 if (lsb + msb > 63) {
4489 goto fail;
4490 }
505ad7c2 4491 tcg_gen_shri_tl(t0, t1, lsb);
b7f26e52
RH
4492 if (msb != 63) {
4493 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4494 }
7a387fff 4495 break;
c6d6dd7c 4496#endif
7a387fff 4497 case OPC_INS:
b7f26e52 4498 if (lsb > msb) {
7a387fff 4499 goto fail;
b7f26e52 4500 }
6c5c1e20 4501 gen_load_gpr(t0, rt);
e0d002f1 4502 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4503 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4504 break;
c6d6dd7c 4505#if defined(TARGET_MIPS64)
7a387fff 4506 case OPC_DINSU:
b7f26e52
RH
4507 lsb += 32;
4508 /* FALLTHRU */
4509 case OPC_DINSM:
4510 msb += 32;
4511 /* FALLTHRU */
7a387fff 4512 case OPC_DINS:
b7f26e52
RH
4513 if (lsb > msb) {
4514 goto fail;
4515 }
6c5c1e20 4516 gen_load_gpr(t0, rt);
e0d002f1 4517 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4518 break;
c6d6dd7c 4519#endif
7a387fff
TS
4520 default:
4521fail:
4522 MIPS_INVAL("bitops");
9c708c7f 4523 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4524 tcg_temp_free(t0);
4525 tcg_temp_free(t1);
7a387fff
TS
4526 return;
4527 }
6c5c1e20
TS
4528 gen_store_gpr(t0, rt);
4529 tcg_temp_free(t0);
4530 tcg_temp_free(t1);
7a387fff
TS
4531}
4532
49bcf33c
AJ
4533static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4534{
3a55fa47 4535 TCGv t0;
49bcf33c 4536
3a55fa47
AJ
4537 if (rd == 0) {
4538 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4539 return;
4540 }
4541
4542 t0 = tcg_temp_new();
4543 gen_load_gpr(t0, rt);
49bcf33c
AJ
4544 switch (op2) {
4545 case OPC_WSBH:
3a55fa47
AJ
4546 {
4547 TCGv t1 = tcg_temp_new();
4548
4549 tcg_gen_shri_tl(t1, t0, 8);
4550 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4551 tcg_gen_shli_tl(t0, t0, 8);
4552 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4553 tcg_gen_or_tl(t0, t0, t1);
4554 tcg_temp_free(t1);
4555 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4556 }
49bcf33c
AJ
4557 break;
4558 case OPC_SEB:
3a55fa47 4559 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4560 break;
4561 case OPC_SEH:
3a55fa47 4562 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4563 break;
4564#if defined(TARGET_MIPS64)
4565 case OPC_DSBH:
3a55fa47
AJ
4566 {
4567 TCGv t1 = tcg_temp_new();
4568
4569 tcg_gen_shri_tl(t1, t0, 8);
4570 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4571 tcg_gen_shli_tl(t0, t0, 8);
4572 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4573 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4574 tcg_temp_free(t1);
4575 }
49bcf33c
AJ
4576 break;
4577 case OPC_DSHD:
3a55fa47
AJ
4578 {
4579 TCGv t1 = tcg_temp_new();
4580
4581 tcg_gen_shri_tl(t1, t0, 16);
4582 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4583 tcg_gen_shli_tl(t0, t0, 16);
4584 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4585 tcg_gen_or_tl(t0, t0, t1);
4586 tcg_gen_shri_tl(t1, t0, 32);
4587 tcg_gen_shli_tl(t0, t0, 32);
4588 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4589 tcg_temp_free(t1);
4590 }
49bcf33c
AJ
4591 break;
4592#endif
4593 default:
4594 MIPS_INVAL("bsfhl");
9c708c7f 4595 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4596 tcg_temp_free(t0);
49bcf33c
AJ
4597 return;
4598 }
49bcf33c 4599 tcg_temp_free(t0);
49bcf33c
AJ
4600}
4601
1f1b4c00
YK
4602static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4603 int imm2)
4604{
4605 TCGv t0;
4606 TCGv t1;
4607 if (rd == 0) {
4608 /* Treat as NOP. */
4609 return;
4610 }
4611 t0 = tcg_temp_new();
4612 t1 = tcg_temp_new();
4613 gen_load_gpr(t0, rs);
4614 gen_load_gpr(t1, rt);
4615 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4616 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4617 if (opc == OPC_LSA) {
4618 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4619 }
4620
4621 tcg_temp_free(t1);
4622 tcg_temp_free(t0);
4623
4624 return;
4625}
4626
4627static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4628 int bp)
284b731a 4629{
1f1b4c00
YK
4630 TCGv t0;
4631 if (rd == 0) {
4632 /* Treat as NOP. */
4633 return;
4634 }
4635 t0 = tcg_temp_new();
4636 gen_load_gpr(t0, rt);
4637 if (bp == 0) {
51243852
MD
4638 switch (opc) {
4639 case OPC_ALIGN:
4640 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4641 break;
4642#if defined(TARGET_MIPS64)
4643 case OPC_DALIGN:
4644 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4645 break;
4646#endif
4647 }
1f1b4c00
YK
4648 } else {
4649 TCGv t1 = tcg_temp_new();
4650 gen_load_gpr(t1, rs);
4651 switch (opc) {
4652 case OPC_ALIGN:
4653 {
4654 TCGv_i64 t2 = tcg_temp_new_i64();
4655 tcg_gen_concat_tl_i64(t2, t1, t0);
4656 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4657 gen_move_low32(cpu_gpr[rd], t2);
4658 tcg_temp_free_i64(t2);
4659 }
4660 break;
284b731a 4661#if defined(TARGET_MIPS64)
1f1b4c00
YK
4662 case OPC_DALIGN:
4663 tcg_gen_shli_tl(t0, t0, 8 * bp);
4664 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4665 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4666 break;
284b731a 4667#endif
1f1b4c00
YK
4668 }
4669 tcg_temp_free(t1);
4670 }
4671
4672 tcg_temp_free(t0);
4673}
4674
4675static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4676{
4677 TCGv t0;
4678 if (rd == 0) {
4679 /* Treat as NOP. */
4680 return;
4681 }
4682 t0 = tcg_temp_new();
4683 gen_load_gpr(t0, rt);
4684 switch (opc) {
4685 case OPC_BITSWAP:
4686 gen_helper_bitswap(cpu_gpr[rd], t0);
4687 break;
4688#if defined(TARGET_MIPS64)
4689 case OPC_DBITSWAP:
4690 gen_helper_dbitswap(cpu_gpr[rd], t0);
4691 break;
4692#endif
4693 }
4694 tcg_temp_free(t0);
284b731a
LA
4695}
4696
1f1b4c00
YK
4697#ifndef CONFIG_USER_ONLY
4698/* CP0 (MMU and control) */
5204ea79
LA
4699static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4700{
4701 TCGv_i64 t0 = tcg_temp_new_i64();
4702 TCGv_i64 t1 = tcg_temp_new_i64();
4703
4704 tcg_gen_ext_tl_i64(t0, arg);
4705 tcg_gen_ld_i64(t1, cpu_env, off);
4706#if defined(TARGET_MIPS64)
4707 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4708#else
4709 tcg_gen_concat32_i64(t1, t1, t0);
4710#endif
4711 tcg_gen_st_i64(t1, cpu_env, off);
4712 tcg_temp_free_i64(t1);
4713 tcg_temp_free_i64(t0);
4714}
4715
4716static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4717{
4718 TCGv_i64 t0 = tcg_temp_new_i64();
4719 TCGv_i64 t1 = tcg_temp_new_i64();
4720
4721 tcg_gen_ext_tl_i64(t0, arg);
4722 tcg_gen_ld_i64(t1, cpu_env, off);
4723 tcg_gen_concat32_i64(t1, t1, t0);
4724 tcg_gen_st_i64(t1, cpu_env, off);
4725 tcg_temp_free_i64(t1);
4726 tcg_temp_free_i64(t0);
4727}
4728
4729static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4730{
4731 TCGv_i64 t0 = tcg_temp_new_i64();
4732
4733 tcg_gen_ld_i64(t0, cpu_env, off);
4734#if defined(TARGET_MIPS64)
4735 tcg_gen_shri_i64(t0, t0, 30);
4736#else
4737 tcg_gen_shri_i64(t0, t0, 32);
4738#endif
4739 gen_move_low32(arg, t0);
4740 tcg_temp_free_i64(t0);
4741}
4742
4743static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4744{
4745 TCGv_i64 t0 = tcg_temp_new_i64();
4746
4747 tcg_gen_ld_i64(t0, cpu_env, off);
4748 tcg_gen_shri_i64(t0, t0, 32 + shift);
4749 gen_move_low32(arg, t0);
4750 tcg_temp_free_i64(t0);
4751}
4752
d9bea114 4753static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4754{
d9bea114 4755 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4756
d9bea114
AJ
4757 tcg_gen_ld_i32(t0, cpu_env, off);
4758 tcg_gen_ext_i32_tl(arg, t0);
4759 tcg_temp_free_i32(t0);
4f57689a
TS
4760}
4761
d9bea114 4762static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4763{
d9bea114
AJ
4764 tcg_gen_ld_tl(arg, cpu_env, off);
4765 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4766}
4767
d9bea114 4768static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4769{
d9bea114 4770 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4771
d9bea114
AJ
4772 tcg_gen_trunc_tl_i32(t0, arg);
4773 tcg_gen_st_i32(t0, cpu_env, off);
4774 tcg_temp_free_i32(t0);
f1aa6320
TS
4775}
4776
5204ea79
LA
4777static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4778{
4779 const char *rn = "invalid";
4780
4781 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4782 goto mfhc0_read_zero;
4783 }
4784
4785 switch (reg) {
4786 case 2:
4787 switch (sel) {
4788 case 0:
4789 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4790 rn = "EntryLo0";
4791 break;
4792 default:
4793 goto mfhc0_read_zero;
4794 }
4795 break;
4796 case 3:
4797 switch (sel) {
4798 case 0:
4799 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4800 rn = "EntryLo1";
4801 break;
4802 default:
4803 goto mfhc0_read_zero;
4804 }
4805 break;
4806 case 17:
4807 switch (sel) {
4808 case 0:
4809 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4810 ctx->CP0_LLAddr_shift);
4811 rn = "LLAddr";
4812 break;
4813 default:
4814 goto mfhc0_read_zero;
4815 }
4816 break;
4817 case 28:
4818 switch (sel) {
4819 case 0:
4820 case 2:
4821 case 4:
4822 case 6:
4823 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4824 rn = "TagLo";
4825 break;
4826 default:
4827 goto mfhc0_read_zero;
4828 }
4829 break;
4830 default:
4831 goto mfhc0_read_zero;
4832 }
4833
4834 (void)rn; /* avoid a compiler warning */
4835 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4836 return;
4837
4838mfhc0_read_zero:
4839 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4840 tcg_gen_movi_tl(arg, 0);
4841}
4842
4843static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4844{
4845 const char *rn = "invalid";
4846 uint64_t mask = ctx->PAMask >> 36;
4847
4848 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4849 goto mthc0_nop;
4850 }
4851
4852 switch (reg) {
4853 case 2:
4854 switch (sel) {
4855 case 0:
4856 tcg_gen_andi_tl(arg, arg, mask);
4857 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4858 rn = "EntryLo0";
4859 break;
4860 default:
4861 goto mthc0_nop;
4862 }
4863 break;
4864 case 3:
4865 switch (sel) {
4866 case 0:
4867 tcg_gen_andi_tl(arg, arg, mask);
4868 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4869 rn = "EntryLo1";
4870 break;
4871 default:
4872 goto mthc0_nop;
4873 }
4874 break;
4875 case 17:
4876 switch (sel) {
4877 case 0:
4878 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4879 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4880 relevant for modern MIPS cores supporting MTHC0, therefore
4881 treating MTHC0 to LLAddr as NOP. */
4882 rn = "LLAddr";
4883 break;
4884 default:
4885 goto mthc0_nop;
4886 }
4887 break;
4888 case 28:
4889 switch (sel) {
4890 case 0:
4891 case 2:
4892 case 4:
4893 case 6:
4894 tcg_gen_andi_tl(arg, arg, mask);
4895 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4896 rn = "TagLo";
4897 break;
4898 default:
4899 goto mthc0_nop;
4900 }
4901 break;
4902 default:
4903 goto mthc0_nop;
4904 }
4905
4906 (void)rn; /* avoid a compiler warning */
4907mthc0_nop:
4908 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4909}
4910
e98c0d17
LA
4911static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4912{
4913 if (ctx->insn_flags & ISA_MIPS32R6) {
4914 tcg_gen_movi_tl(arg, 0);
4915 } else {
4916 tcg_gen_movi_tl(arg, ~0);
4917 }
4918}
4919
f31b035a
LA
4920#define CP0_CHECK(c) \
4921 do { \
4922 if (!(c)) { \
4923 goto cp0_unimplemented; \
4924 } \
4925 } while (0)
4926
d75c135e 4927static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4928{
7a387fff 4929 const char *rn = "invalid";
873eb012 4930
e189e748 4931 if (sel != 0)
d75c135e 4932 check_insn(ctx, ISA_MIPS32);
e189e748 4933
873eb012
TS
4934 switch (reg) {
4935 case 0:
7a387fff
TS
4936 switch (sel) {
4937 case 0:
7db13fae 4938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4939 rn = "Index";
4940 break;
4941 case 1:
f31b035a 4942 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4943 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4944 rn = "MVPControl";
ead9360e 4945 break;
7a387fff 4946 case 2:
f31b035a 4947 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4948 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4949 rn = "MVPConf0";
ead9360e 4950 break;
7a387fff 4951 case 3:
f31b035a 4952 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4953 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4954 rn = "MVPConf1";
ead9360e 4955 break;
01bc435b
YK
4956 case 4:
4957 CP0_CHECK(ctx->vp);
4958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4959 rn = "VPControl";
4960 break;
7a387fff 4961 default:
f31b035a 4962 goto cp0_unimplemented;
7a387fff 4963 }
873eb012
TS
4964 break;
4965 case 1:
7a387fff
TS
4966 switch (sel) {
4967 case 0:
f31b035a 4968 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4969 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4970 rn = "Random";
2423f660 4971 break;
7a387fff 4972 case 1:
f31b035a 4973 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4975 rn = "VPEControl";
ead9360e 4976 break;
7a387fff 4977 case 2:
f31b035a 4978 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4980 rn = "VPEConf0";
ead9360e 4981 break;
7a387fff 4982 case 3:
f31b035a 4983 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4984 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4985 rn = "VPEConf1";
ead9360e 4986 break;
7a387fff 4987 case 4:
f31b035a 4988 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4989 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4990 rn = "YQMask";
ead9360e 4991 break;
7a387fff 4992 case 5:
f31b035a 4993 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4994 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4995 rn = "VPESchedule";
ead9360e 4996 break;
7a387fff 4997 case 6:
f31b035a 4998 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4999 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5000 rn = "VPEScheFBack";
ead9360e 5001 break;
7a387fff 5002 case 7:
f31b035a 5003 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5005 rn = "VPEOpt";
ead9360e 5006 break;
7a387fff 5007 default:
f31b035a 5008 goto cp0_unimplemented;
7a387fff 5009 }
873eb012
TS
5010 break;
5011 case 2:
7a387fff
TS
5012 switch (sel) {
5013 case 0:
284b731a
LA
5014 {
5015 TCGv_i64 tmp = tcg_temp_new_i64();
5016 tcg_gen_ld_i64(tmp, cpu_env,
5017 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5018#if defined(TARGET_MIPS64)
284b731a
LA
5019 if (ctx->rxi) {
5020 /* Move RI/XI fields to bits 31:30 */
5021 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5022 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5023 }
7207c7f9 5024#endif
284b731a
LA
5025 gen_move_low32(arg, tmp);
5026 tcg_temp_free_i64(tmp);
5027 }
2423f660
TS
5028 rn = "EntryLo0";
5029 break;
7a387fff 5030 case 1:
f31b035a 5031 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5032 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5033 rn = "TCStatus";
ead9360e 5034 break;
7a387fff 5035 case 2:
f31b035a 5036 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5037 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5038 rn = "TCBind";
ead9360e 5039 break;
7a387fff 5040 case 3:
f31b035a 5041 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5042 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5043 rn = "TCRestart";
ead9360e 5044 break;
7a387fff 5045 case 4:
f31b035a 5046 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5047 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5048 rn = "TCHalt";
ead9360e 5049 break;
7a387fff 5050 case 5:
f31b035a 5051 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5052 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5053 rn = "TCContext";
ead9360e 5054 break;
7a387fff 5055 case 6:
f31b035a 5056 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5057 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5058 rn = "TCSchedule";
ead9360e 5059 break;
7a387fff 5060 case 7:
f31b035a 5061 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5062 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5063 rn = "TCScheFBack";
ead9360e 5064 break;
7a387fff 5065 default:
f31b035a 5066 goto cp0_unimplemented;
7a387fff 5067 }
873eb012
TS
5068 break;
5069 case 3:
7a387fff
TS
5070 switch (sel) {
5071 case 0:
284b731a
LA
5072 {
5073 TCGv_i64 tmp = tcg_temp_new_i64();
5074 tcg_gen_ld_i64(tmp, cpu_env,
5075 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5076#if defined(TARGET_MIPS64)
284b731a
LA
5077 if (ctx->rxi) {
5078 /* Move RI/XI fields to bits 31:30 */
5079 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5080 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5081 }
7207c7f9 5082#endif
284b731a
LA
5083 gen_move_low32(arg, tmp);
5084 tcg_temp_free_i64(tmp);
5085 }
2423f660
TS
5086 rn = "EntryLo1";
5087 break;
01bc435b
YK
5088 case 1:
5089 CP0_CHECK(ctx->vp);
5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5091 rn = "GlobalNumber";
5092 break;
7a387fff 5093 default:
f31b035a 5094 goto cp0_unimplemented;
1579a72e 5095 }
873eb012
TS
5096 break;
5097 case 4:
7a387fff
TS
5098 switch (sel) {
5099 case 0:
7db13fae 5100 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5101 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5102 rn = "Context";
5103 break;
7a387fff 5104 case 1:
d9bea114 5105// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5106 rn = "ContextConfig";
f31b035a 5107 goto cp0_unimplemented;
2423f660 5108// break;
d279279e 5109 case 2:
f31b035a
LA
5110 CP0_CHECK(ctx->ulri);
5111 tcg_gen_ld32s_tl(arg, cpu_env,
5112 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5113 rn = "UserLocal";
d279279e 5114 break;
7a387fff 5115 default:
f31b035a 5116 goto cp0_unimplemented;
1579a72e 5117 }
873eb012
TS
5118 break;
5119 case 5:
7a387fff
TS
5120 switch (sel) {
5121 case 0:
7db13fae 5122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5123 rn = "PageMask";
5124 break;
7a387fff 5125 case 1:
d75c135e 5126 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5128 rn = "PageGrain";
5129 break;
7a387fff 5130 default:
f31b035a 5131 goto cp0_unimplemented;
1579a72e 5132 }
873eb012
TS
5133 break;
5134 case 6:
7a387fff
TS
5135 switch (sel) {
5136 case 0:
7db13fae 5137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5138 rn = "Wired";
5139 break;
7a387fff 5140 case 1:
d75c135e 5141 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5143 rn = "SRSConf0";
ead9360e 5144 break;
7a387fff 5145 case 2:
d75c135e 5146 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5148 rn = "SRSConf1";
ead9360e 5149 break;
7a387fff 5150 case 3:
d75c135e 5151 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5153 rn = "SRSConf2";
ead9360e 5154 break;
7a387fff 5155 case 4:
d75c135e 5156 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5158 rn = "SRSConf3";
ead9360e 5159 break;
7a387fff 5160 case 5:
d75c135e 5161 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5163 rn = "SRSConf4";
ead9360e 5164 break;
7a387fff 5165 default:
f31b035a 5166 goto cp0_unimplemented;
1579a72e 5167 }
873eb012 5168 break;
8c0fdd85 5169 case 7:
7a387fff
TS
5170 switch (sel) {
5171 case 0:
d75c135e 5172 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5174 rn = "HWREna";
5175 break;
7a387fff 5176 default:
f31b035a 5177 goto cp0_unimplemented;
1579a72e 5178 }
8c0fdd85 5179 break;
873eb012 5180 case 8:
7a387fff
TS
5181 switch (sel) {
5182 case 0:
7db13fae 5183 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5184 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5185 rn = "BadVAddr";
2423f660 5186 break;
aea14095 5187 case 1:
f31b035a
LA
5188 CP0_CHECK(ctx->bi);
5189 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5190 rn = "BadInstr";
aea14095
LA
5191 break;
5192 case 2:
f31b035a
LA
5193 CP0_CHECK(ctx->bp);
5194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5195 rn = "BadInstrP";
aea14095 5196 break;
7a387fff 5197 default:
f31b035a 5198 goto cp0_unimplemented;
aea14095 5199 }
873eb012
TS
5200 break;
5201 case 9:
7a387fff
TS
5202 switch (sel) {
5203 case 0:
2e70f6ef 5204 /* Mark as an IO operation because we read the time. */
bd79255d 5205 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5206 gen_io_start();
bd79255d 5207 }
895c2d04 5208 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5209 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5210 gen_io_end();
2e70f6ef 5211 }
55807224
EI
5212 /* Break the TB to be able to take timer interrupts immediately
5213 after reading count. */
5214 ctx->bstate = BS_STOP;
2423f660
TS
5215 rn = "Count";
5216 break;
5217 /* 6,7 are implementation dependent */
7a387fff 5218 default:
f31b035a 5219 goto cp0_unimplemented;
2423f660 5220 }
873eb012
TS
5221 break;
5222 case 10:
7a387fff
TS
5223 switch (sel) {
5224 case 0:
7db13fae 5225 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5226 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5227 rn = "EntryHi";
5228 break;
7a387fff 5229 default:
f31b035a 5230 goto cp0_unimplemented;
1579a72e 5231 }
873eb012
TS
5232 break;
5233 case 11:
7a387fff
TS
5234 switch (sel) {
5235 case 0:
7db13fae 5236 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5237 rn = "Compare";
5238 break;
5239 /* 6,7 are implementation dependent */
7a387fff 5240 default:
f31b035a 5241 goto cp0_unimplemented;
2423f660 5242 }
873eb012
TS
5243 break;
5244 case 12:
7a387fff
TS
5245 switch (sel) {
5246 case 0:
7db13fae 5247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5248 rn = "Status";
5249 break;
7a387fff 5250 case 1:
d75c135e 5251 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5252 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5253 rn = "IntCtl";
5254 break;
7a387fff 5255 case 2:
d75c135e 5256 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5257 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5258 rn = "SRSCtl";
5259 break;
7a387fff 5260 case 3:
d75c135e 5261 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5263 rn = "SRSMap";
fd88b6ab 5264 break;
7a387fff 5265 default:
f31b035a 5266 goto cp0_unimplemented;
7a387fff 5267 }
873eb012
TS
5268 break;
5269 case 13:
7a387fff
TS
5270 switch (sel) {
5271 case 0:
7db13fae 5272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5273 rn = "Cause";
5274 break;
7a387fff 5275 default:
f31b035a 5276 goto cp0_unimplemented;
7a387fff 5277 }
873eb012
TS
5278 break;
5279 case 14:
7a387fff
TS
5280 switch (sel) {
5281 case 0:
7db13fae 5282 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5283 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5284 rn = "EPC";
5285 break;
7a387fff 5286 default:
f31b035a 5287 goto cp0_unimplemented;
1579a72e 5288 }
873eb012
TS
5289 break;
5290 case 15:
7a387fff
TS
5291 switch (sel) {
5292 case 0:
7db13fae 5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5294 rn = "PRid";
5295 break;
7a387fff 5296 case 1:
d75c135e 5297 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5299 rn = "EBase";
5300 break;
7a387fff 5301 default:
f31b035a 5302 goto cp0_unimplemented;
7a387fff 5303 }
873eb012
TS
5304 break;
5305 case 16:
5306 switch (sel) {
5307 case 0:
7db13fae 5308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5309 rn = "Config";
5310 break;
5311 case 1:
7db13fae 5312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5313 rn = "Config1";
5314 break;
7a387fff 5315 case 2:
7db13fae 5316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5317 rn = "Config2";
5318 break;
5319 case 3:
7db13fae 5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5321 rn = "Config3";
5322 break;
b4160af1
PJ
5323 case 4:
5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5325 rn = "Config4";
5326 break;
b4dd99a3
PJ
5327 case 5:
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5329 rn = "Config5";
5330 break;
e397ee33
TS
5331 /* 6,7 are implementation dependent */
5332 case 6:
7db13fae 5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5334 rn = "Config6";
5335 break;
5336 case 7:
7db13fae 5337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5338 rn = "Config7";
5339 break;
873eb012 5340 default:
f31b035a 5341 goto cp0_unimplemented;
873eb012
TS
5342 }
5343 break;
5344 case 17:
7a387fff
TS
5345 switch (sel) {
5346 case 0:
895c2d04 5347 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5348 rn = "LLAddr";
5349 break;
7a387fff 5350 default:
f31b035a 5351 goto cp0_unimplemented;
7a387fff 5352 }
873eb012
TS
5353 break;
5354 case 18:
7a387fff 5355 switch (sel) {
fd88b6ab 5356 case 0 ... 7:
895c2d04 5357 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5358 rn = "WatchLo";
5359 break;
7a387fff 5360 default:
f31b035a 5361 goto cp0_unimplemented;
7a387fff 5362 }
873eb012
TS
5363 break;
5364 case 19:
7a387fff 5365 switch (sel) {
fd88b6ab 5366 case 0 ...7:
895c2d04 5367 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5368 rn = "WatchHi";
5369 break;
7a387fff 5370 default:
f31b035a 5371 goto cp0_unimplemented;
7a387fff 5372 }
873eb012 5373 break;
8c0fdd85 5374 case 20:
7a387fff
TS
5375 switch (sel) {
5376 case 0:
d26bc211 5377#if defined(TARGET_MIPS64)
d75c135e 5378 check_insn(ctx, ISA_MIPS3);
7db13fae 5379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5380 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5381 rn = "XContext";
5382 break;
703eaf37 5383#endif
7a387fff 5384 default:
f31b035a 5385 goto cp0_unimplemented;
7a387fff 5386 }
8c0fdd85
TS
5387 break;
5388 case 21:
7a387fff 5389 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5390 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5391 switch (sel) {
5392 case 0:
7db13fae 5393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5394 rn = "Framemask";
5395 break;
7a387fff 5396 default:
f31b035a 5397 goto cp0_unimplemented;
7a387fff 5398 }
8c0fdd85
TS
5399 break;
5400 case 22:
d9bea114 5401 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5402 rn = "'Diagnostic"; /* implementation dependent */
5403 break;
873eb012 5404 case 23:
7a387fff
TS
5405 switch (sel) {
5406 case 0:
895c2d04 5407 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5408 rn = "Debug";
5409 break;
7a387fff 5410 case 1:
d9bea114 5411// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5412 rn = "TraceControl";
5413// break;
7a387fff 5414 case 2:
d9bea114 5415// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5416 rn = "TraceControl2";
5417// break;
7a387fff 5418 case 3:
d9bea114 5419// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5420 rn = "UserTraceData";
5421// break;
7a387fff 5422 case 4:
d9bea114 5423// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5424 rn = "TraceBPC";
5425// break;
7a387fff 5426 default:
f31b035a 5427 goto cp0_unimplemented;
7a387fff 5428 }
873eb012
TS
5429 break;
5430 case 24:
7a387fff
TS
5431 switch (sel) {
5432 case 0:
f0b3f3ae 5433 /* EJTAG support */
7db13fae 5434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5435 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5436 rn = "DEPC";
5437 break;
7a387fff 5438 default:
f31b035a 5439 goto cp0_unimplemented;
7a387fff 5440 }
873eb012 5441 break;
8c0fdd85 5442 case 25:
7a387fff
TS
5443 switch (sel) {
5444 case 0:
7db13fae 5445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5446 rn = "Performance0";
7a387fff
TS
5447 break;
5448 case 1:
d9bea114 5449// gen_helper_mfc0_performance1(arg);
2423f660
TS
5450 rn = "Performance1";
5451// break;
7a387fff 5452 case 2:
d9bea114 5453// gen_helper_mfc0_performance2(arg);
2423f660
TS
5454 rn = "Performance2";
5455// break;
7a387fff 5456 case 3:
d9bea114 5457// gen_helper_mfc0_performance3(arg);
2423f660
TS
5458 rn = "Performance3";
5459// break;
7a387fff 5460 case 4:
d9bea114 5461// gen_helper_mfc0_performance4(arg);
2423f660
TS
5462 rn = "Performance4";
5463// break;
7a387fff 5464 case 5:
d9bea114 5465// gen_helper_mfc0_performance5(arg);
2423f660
TS
5466 rn = "Performance5";
5467// break;
7a387fff 5468 case 6:
d9bea114 5469// gen_helper_mfc0_performance6(arg);
2423f660
TS
5470 rn = "Performance6";
5471// break;
7a387fff 5472 case 7:
d9bea114 5473// gen_helper_mfc0_performance7(arg);
2423f660
TS
5474 rn = "Performance7";
5475// break;
7a387fff 5476 default:
f31b035a 5477 goto cp0_unimplemented;
7a387fff 5478 }
8c0fdd85
TS
5479 break;
5480 case 26:
d9bea114 5481 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5482 rn = "ECC";
5483 break;
8c0fdd85 5484 case 27:
7a387fff 5485 switch (sel) {
7a387fff 5486 case 0 ... 3:
d9bea114 5487 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5488 rn = "CacheErr";
5489 break;
7a387fff 5490 default:
f31b035a 5491 goto cp0_unimplemented;
7a387fff 5492 }
8c0fdd85 5493 break;
873eb012
TS
5494 case 28:
5495 switch (sel) {
5496 case 0:
7a387fff
TS
5497 case 2:
5498 case 4:
5499 case 6:
284b731a
LA
5500 {
5501 TCGv_i64 tmp = tcg_temp_new_i64();
5502 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5503 gen_move_low32(arg, tmp);
5504 tcg_temp_free_i64(tmp);
5505 }
873eb012
TS
5506 rn = "TagLo";
5507 break;
5508 case 1:
7a387fff
TS
5509 case 3:
5510 case 5:
5511 case 7:
7db13fae 5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5513 rn = "DataLo";
5514 break;
5515 default:
f31b035a 5516 goto cp0_unimplemented;
873eb012
TS
5517 }
5518 break;
8c0fdd85 5519 case 29:
7a387fff
TS
5520 switch (sel) {
5521 case 0:
5522 case 2:
5523 case 4:
5524 case 6:
7db13fae 5525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5526 rn = "TagHi";
5527 break;
5528 case 1:
5529 case 3:
5530 case 5:
5531 case 7:
7db13fae 5532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5533 rn = "DataHi";
5534 break;
5535 default:
f31b035a 5536 goto cp0_unimplemented;
7a387fff 5537 }
8c0fdd85 5538 break;
873eb012 5539 case 30:
7a387fff
TS
5540 switch (sel) {
5541 case 0:
7db13fae 5542 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5543 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5544 rn = "ErrorEPC";
5545 break;
7a387fff 5546 default:
f31b035a 5547 goto cp0_unimplemented;
7a387fff 5548 }
873eb012
TS
5549 break;
5550 case 31:
7a387fff
TS
5551 switch (sel) {
5552 case 0:
f0b3f3ae 5553 /* EJTAG support */
7db13fae 5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5555 rn = "DESAVE";
5556 break;
e98c0d17 5557 case 2 ... 7:
f31b035a
LA
5558 CP0_CHECK(ctx->kscrexist & (1 << sel));
5559 tcg_gen_ld_tl(arg, cpu_env,
5560 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5561 tcg_gen_ext32s_tl(arg, arg);
5562 rn = "KScratch";
e98c0d17 5563 break;
7a387fff 5564 default:
f31b035a 5565 goto cp0_unimplemented;
7a387fff 5566 }
873eb012
TS
5567 break;
5568 default:
f31b035a 5569 goto cp0_unimplemented;
873eb012 5570 }
2abf314d 5571 (void)rn; /* avoid a compiler warning */
d12d51d5 5572 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5573 return;
5574
f31b035a 5575cp0_unimplemented:
d12d51d5 5576 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5577 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5578}
5579
d75c135e 5580static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5581{
7a387fff
TS
5582 const char *rn = "invalid";
5583
e189e748 5584 if (sel != 0)
d75c135e 5585 check_insn(ctx, ISA_MIPS32);
e189e748 5586
bd79255d 5587 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5588 gen_io_start();
bd79255d 5589 }
2e70f6ef 5590
8c0fdd85
TS
5591 switch (reg) {
5592 case 0:
7a387fff
TS
5593 switch (sel) {
5594 case 0:
895c2d04 5595 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5596 rn = "Index";
5597 break;
5598 case 1:
f31b035a 5599 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5600 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5601 rn = "MVPControl";
ead9360e 5602 break;
7a387fff 5603 case 2:
f31b035a 5604 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5605 /* ignored */
7a387fff 5606 rn = "MVPConf0";
ead9360e 5607 break;
7a387fff 5608 case 3:
f31b035a 5609 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5610 /* ignored */
7a387fff 5611 rn = "MVPConf1";
ead9360e 5612 break;
01bc435b
YK
5613 case 4:
5614 CP0_CHECK(ctx->vp);
5615 /* ignored */
5616 rn = "VPControl";
5617 break;
7a387fff 5618 default:
f31b035a 5619 goto cp0_unimplemented;
7a387fff 5620 }
8c0fdd85
TS
5621 break;
5622 case 1:
7a387fff
TS
5623 switch (sel) {
5624 case 0:
2423f660 5625 /* ignored */
7a387fff 5626 rn = "Random";
2423f660 5627 break;
7a387fff 5628 case 1:
f31b035a 5629 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5630 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5631 rn = "VPEControl";
ead9360e 5632 break;
7a387fff 5633 case 2:
f31b035a 5634 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5635 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5636 rn = "VPEConf0";
ead9360e 5637 break;
7a387fff 5638 case 3:
f31b035a 5639 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5640 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5641 rn = "VPEConf1";
ead9360e 5642 break;
7a387fff 5643 case 4:
f31b035a 5644 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5645 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5646 rn = "YQMask";
ead9360e 5647 break;
7a387fff 5648 case 5:
f31b035a 5649 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5650 tcg_gen_st_tl(arg, cpu_env,
5651 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5652 rn = "VPESchedule";
ead9360e 5653 break;
7a387fff 5654 case 6:
f31b035a 5655 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5656 tcg_gen_st_tl(arg, cpu_env,
5657 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5658 rn = "VPEScheFBack";
ead9360e 5659 break;
7a387fff 5660 case 7:
f31b035a 5661 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5662 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5663 rn = "VPEOpt";
ead9360e 5664 break;
7a387fff 5665 default:
f31b035a 5666 goto cp0_unimplemented;
7a387fff 5667 }
8c0fdd85
TS
5668 break;
5669 case 2:
7a387fff
TS
5670 switch (sel) {
5671 case 0:
895c2d04 5672 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5673 rn = "EntryLo0";
5674 break;
7a387fff 5675 case 1:
f31b035a 5676 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5677 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5678 rn = "TCStatus";
ead9360e 5679 break;
7a387fff 5680 case 2:
f31b035a 5681 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5682 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5683 rn = "TCBind";
ead9360e 5684 break;
7a387fff 5685 case 3:
f31b035a 5686 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5687 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5688 rn = "TCRestart";
ead9360e 5689 break;
7a387fff 5690 case 4:
f31b035a 5691 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5692 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5693 rn = "TCHalt";
ead9360e 5694 break;
7a387fff 5695 case 5:
f31b035a 5696 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5697 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5698 rn = "TCContext";
ead9360e 5699 break;
7a387fff 5700 case 6:
f31b035a 5701 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5702 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5703 rn = "TCSchedule";
ead9360e 5704 break;
7a387fff 5705 case 7:
f31b035a 5706 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5707 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5708 rn = "TCScheFBack";
ead9360e 5709 break;
7a387fff 5710 default:
f31b035a 5711 goto cp0_unimplemented;
7a387fff 5712 }
8c0fdd85
TS
5713 break;
5714 case 3:
7a387fff
TS
5715 switch (sel) {
5716 case 0:
895c2d04 5717 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5718 rn = "EntryLo1";
5719 break;
01bc435b
YK
5720 case 1:
5721 CP0_CHECK(ctx->vp);
5722 /* ignored */
5723 rn = "GlobalNumber";
5724 break;
7a387fff 5725 default:
f31b035a 5726 goto cp0_unimplemented;
876d4b07 5727 }
8c0fdd85
TS
5728 break;
5729 case 4:
7a387fff
TS
5730 switch (sel) {
5731 case 0:
895c2d04 5732 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5733 rn = "Context";
5734 break;
7a387fff 5735 case 1:
895c2d04 5736// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5737 rn = "ContextConfig";
f31b035a 5738 goto cp0_unimplemented;
2423f660 5739// break;
d279279e 5740 case 2:
f31b035a
LA
5741 CP0_CHECK(ctx->ulri);
5742 tcg_gen_st_tl(arg, cpu_env,
5743 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5744 rn = "UserLocal";
d279279e 5745 break;
7a387fff 5746 default:
f31b035a 5747 goto cp0_unimplemented;
876d4b07 5748 }
8c0fdd85
TS
5749 break;
5750 case 5:
7a387fff
TS
5751 switch (sel) {
5752 case 0:
895c2d04 5753 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5754 rn = "PageMask";
5755 break;
7a387fff 5756 case 1:
d75c135e 5757 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5758 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5759 rn = "PageGrain";
e117f526 5760 ctx->bstate = BS_STOP;
2423f660 5761 break;
7a387fff 5762 default:
f31b035a 5763 goto cp0_unimplemented;
876d4b07 5764 }
8c0fdd85
TS
5765 break;
5766 case 6:
7a387fff
TS
5767 switch (sel) {
5768 case 0:
895c2d04 5769 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5770 rn = "Wired";
5771 break;
7a387fff 5772 case 1:
d75c135e 5773 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5774 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5775 rn = "SRSConf0";
ead9360e 5776 break;
7a387fff 5777 case 2:
d75c135e 5778 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5779 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5780 rn = "SRSConf1";
ead9360e 5781 break;
7a387fff 5782 case 3:
d75c135e 5783 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5784 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5785 rn = "SRSConf2";
ead9360e 5786 break;
7a387fff 5787 case 4:
d75c135e 5788 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5789 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5790 rn = "SRSConf3";
ead9360e 5791 break;
7a387fff 5792 case 5:
d75c135e 5793 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5794 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5795 rn = "SRSConf4";
ead9360e 5796 break;
7a387fff 5797 default:
f31b035a 5798 goto cp0_unimplemented;
876d4b07 5799 }
8c0fdd85
TS
5800 break;
5801 case 7:
7a387fff
TS
5802 switch (sel) {
5803 case 0:
d75c135e 5804 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5805 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5806 ctx->bstate = BS_STOP;
2423f660
TS
5807 rn = "HWREna";
5808 break;
7a387fff 5809 default:
f31b035a 5810 goto cp0_unimplemented;
876d4b07 5811 }
8c0fdd85
TS
5812 break;
5813 case 8:
aea14095
LA
5814 switch (sel) {
5815 case 0:
5816 /* ignored */
5817 rn = "BadVAddr";
5818 break;
5819 case 1:
5820 /* ignored */
5821 rn = "BadInstr";
5822 break;
5823 case 2:
5824 /* ignored */
5825 rn = "BadInstrP";
5826 break;
5827 default:
f31b035a 5828 goto cp0_unimplemented;
aea14095 5829 }
8c0fdd85
TS
5830 break;
5831 case 9:
7a387fff
TS
5832 switch (sel) {
5833 case 0:
895c2d04 5834 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5835 rn = "Count";
5836 break;
876d4b07 5837 /* 6,7 are implementation dependent */
7a387fff 5838 default:
f31b035a 5839 goto cp0_unimplemented;
876d4b07 5840 }
8c0fdd85
TS
5841 break;
5842 case 10:
7a387fff
TS
5843 switch (sel) {
5844 case 0:
895c2d04 5845 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5846 rn = "EntryHi";
5847 break;
7a387fff 5848 default:
f31b035a 5849 goto cp0_unimplemented;
876d4b07 5850 }
8c0fdd85
TS
5851 break;
5852 case 11:
7a387fff
TS
5853 switch (sel) {
5854 case 0:
895c2d04 5855 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5856 rn = "Compare";
5857 break;
5858 /* 6,7 are implementation dependent */
7a387fff 5859 default:
f31b035a 5860 goto cp0_unimplemented;
876d4b07 5861 }
8c0fdd85
TS
5862 break;
5863 case 12:
7a387fff
TS
5864 switch (sel) {
5865 case 0:
867abc7e 5866 save_cpu_state(ctx, 1);
895c2d04 5867 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5868 /* BS_STOP isn't good enough here, hflags may have changed. */
5869 gen_save_pc(ctx->pc + 4);
5870 ctx->bstate = BS_EXCP;
2423f660
TS
5871 rn = "Status";
5872 break;
7a387fff 5873 case 1:
d75c135e 5874 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5875 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5876 /* Stop translation as we may have switched the execution mode */
5877 ctx->bstate = BS_STOP;
2423f660
TS
5878 rn = "IntCtl";
5879 break;
7a387fff 5880 case 2:
d75c135e 5881 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5882 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5883 /* Stop translation as we may have switched the execution mode */
5884 ctx->bstate = BS_STOP;
2423f660
TS
5885 rn = "SRSCtl";
5886 break;
7a387fff 5887 case 3:
d75c135e 5888 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5889 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5890 /* Stop translation as we may have switched the execution mode */
5891 ctx->bstate = BS_STOP;
2423f660 5892 rn = "SRSMap";
fd88b6ab 5893 break;
7a387fff 5894 default:
f31b035a 5895 goto cp0_unimplemented;
876d4b07 5896 }
8c0fdd85
TS
5897 break;
5898 case 13:
7a387fff
TS
5899 switch (sel) {
5900 case 0:
867abc7e 5901 save_cpu_state(ctx, 1);
895c2d04 5902 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5903 rn = "Cause";
5904 break;
7a387fff 5905 default:
f31b035a 5906 goto cp0_unimplemented;
876d4b07 5907 }
8c0fdd85
TS
5908 break;
5909 case 14:
7a387fff
TS
5910 switch (sel) {
5911 case 0:
d54a299b 5912 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5913 rn = "EPC";
5914 break;
7a387fff 5915 default:
f31b035a 5916 goto cp0_unimplemented;
876d4b07 5917 }
8c0fdd85
TS
5918 break;
5919 case 15:
7a387fff
TS
5920 switch (sel) {
5921 case 0:
2423f660
TS
5922 /* ignored */
5923 rn = "PRid";
5924 break;
7a387fff 5925 case 1:
d75c135e 5926 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5927 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5928 rn = "EBase";
5929 break;
7a387fff 5930 default:
f31b035a 5931 goto cp0_unimplemented;
1579a72e 5932 }
8c0fdd85
TS
5933 break;
5934 case 16:
5935 switch (sel) {
5936 case 0:
895c2d04 5937 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5938 rn = "Config";
2423f660
TS
5939 /* Stop translation as we may have switched the execution mode */
5940 ctx->bstate = BS_STOP;
7a387fff
TS
5941 break;
5942 case 1:
e397ee33 5943 /* ignored, read only */
7a387fff
TS
5944 rn = "Config1";
5945 break;
5946 case 2:
895c2d04 5947 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5948 rn = "Config2";
2423f660
TS
5949 /* Stop translation as we may have switched the execution mode */
5950 ctx->bstate = BS_STOP;
8c0fdd85 5951 break;
7a387fff 5952 case 3:
90f12d73 5953 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5954 rn = "Config3";
90f12d73
MR
5955 /* Stop translation as we may have switched the execution mode */
5956 ctx->bstate = BS_STOP;
7a387fff 5957 break;
b4160af1
PJ
5958 case 4:
5959 gen_helper_mtc0_config4(cpu_env, arg);
5960 rn = "Config4";
5961 ctx->bstate = BS_STOP;
5962 break;
b4dd99a3
PJ
5963 case 5:
5964 gen_helper_mtc0_config5(cpu_env, arg);
5965 rn = "Config5";
5966 /* Stop translation as we may have switched the execution mode */
5967 ctx->bstate = BS_STOP;
5968 break;
e397ee33
TS
5969 /* 6,7 are implementation dependent */
5970 case 6:
5971 /* ignored */
5972 rn = "Config6";
5973 break;
5974 case 7:
5975 /* ignored */
5976 rn = "Config7";
5977 break;
8c0fdd85
TS
5978 default:
5979 rn = "Invalid config selector";
f31b035a 5980 goto cp0_unimplemented;
8c0fdd85
TS
5981 }
5982 break;
5983 case 17:
7a387fff
TS
5984 switch (sel) {
5985 case 0:
895c2d04 5986 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5987 rn = "LLAddr";
5988 break;
7a387fff 5989 default:
f31b035a 5990 goto cp0_unimplemented;
7a387fff 5991 }
8c0fdd85
TS
5992 break;
5993 case 18:
7a387fff 5994 switch (sel) {
fd88b6ab 5995 case 0 ... 7:
895c2d04 5996 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5997 rn = "WatchLo";
5998 break;
7a387fff 5999 default:
f31b035a 6000 goto cp0_unimplemented;
7a387fff 6001 }
8c0fdd85
TS
6002 break;
6003 case 19:
7a387fff 6004 switch (sel) {
fd88b6ab 6005 case 0 ... 7:
895c2d04 6006 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6007 rn = "WatchHi";
6008 break;
7a387fff 6009 default:
f31b035a 6010 goto cp0_unimplemented;
7a387fff 6011 }
8c0fdd85
TS
6012 break;
6013 case 20:
7a387fff
TS
6014 switch (sel) {
6015 case 0:
d26bc211 6016#if defined(TARGET_MIPS64)
d75c135e 6017 check_insn(ctx, ISA_MIPS3);
895c2d04 6018 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6019 rn = "XContext";
6020 break;
703eaf37 6021#endif
7a387fff 6022 default:
f31b035a 6023 goto cp0_unimplemented;
7a387fff 6024 }
8c0fdd85
TS
6025 break;
6026 case 21:
7a387fff 6027 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6028 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6029 switch (sel) {
6030 case 0:
895c2d04 6031 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6032 rn = "Framemask";
6033 break;
7a387fff 6034 default:
f31b035a 6035 goto cp0_unimplemented;
7a387fff
TS
6036 }
6037 break;
8c0fdd85 6038 case 22:
7a387fff
TS
6039 /* ignored */
6040 rn = "Diagnostic"; /* implementation dependent */
2423f660 6041 break;
8c0fdd85 6042 case 23:
7a387fff
TS
6043 switch (sel) {
6044 case 0:
895c2d04 6045 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6046 /* BS_STOP isn't good enough here, hflags may have changed. */
6047 gen_save_pc(ctx->pc + 4);
6048 ctx->bstate = BS_EXCP;
2423f660
TS
6049 rn = "Debug";
6050 break;
7a387fff 6051 case 1:
895c2d04 6052// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6053 rn = "TraceControl";
8487327a
TS
6054 /* Stop translation as we may have switched the execution mode */
6055 ctx->bstate = BS_STOP;
2423f660 6056// break;
7a387fff 6057 case 2:
895c2d04 6058// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6059 rn = "TraceControl2";
8487327a
TS
6060 /* Stop translation as we may have switched the execution mode */
6061 ctx->bstate = BS_STOP;
2423f660 6062// break;
7a387fff 6063 case 3:
8487327a
TS
6064 /* Stop translation as we may have switched the execution mode */
6065 ctx->bstate = BS_STOP;
895c2d04 6066// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6067 rn = "UserTraceData";
8487327a
TS
6068 /* Stop translation as we may have switched the execution mode */
6069 ctx->bstate = BS_STOP;
2423f660 6070// break;
7a387fff 6071 case 4:
895c2d04 6072// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6073 /* Stop translation as we may have switched the execution mode */
6074 ctx->bstate = BS_STOP;
2423f660
TS
6075 rn = "TraceBPC";
6076// break;
7a387fff 6077 default:
f31b035a 6078 goto cp0_unimplemented;
7a387fff 6079 }
8c0fdd85
TS
6080 break;
6081 case 24:
7a387fff
TS
6082 switch (sel) {
6083 case 0:
f1aa6320 6084 /* EJTAG support */
d54a299b 6085 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6086 rn = "DEPC";
6087 break;
7a387fff 6088 default:
f31b035a 6089 goto cp0_unimplemented;
7a387fff 6090 }
8c0fdd85
TS
6091 break;
6092 case 25:
7a387fff
TS
6093 switch (sel) {
6094 case 0:
895c2d04 6095 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6096 rn = "Performance0";
6097 break;
7a387fff 6098 case 1:
d9bea114 6099// gen_helper_mtc0_performance1(arg);
2423f660
TS
6100 rn = "Performance1";
6101// break;
7a387fff 6102 case 2:
d9bea114 6103// gen_helper_mtc0_performance2(arg);
2423f660
TS
6104 rn = "Performance2";
6105// break;
7a387fff 6106 case 3:
d9bea114 6107// gen_helper_mtc0_performance3(arg);
2423f660
TS
6108 rn = "Performance3";
6109// break;
7a387fff 6110 case 4:
d9bea114 6111// gen_helper_mtc0_performance4(arg);
2423f660
TS
6112 rn = "Performance4";
6113// break;
7a387fff 6114 case 5:
d9bea114 6115// gen_helper_mtc0_performance5(arg);
2423f660
TS
6116 rn = "Performance5";
6117// break;
7a387fff 6118 case 6:
d9bea114 6119// gen_helper_mtc0_performance6(arg);
2423f660
TS
6120 rn = "Performance6";
6121// break;
7a387fff 6122 case 7:
d9bea114 6123// gen_helper_mtc0_performance7(arg);
2423f660
TS
6124 rn = "Performance7";
6125// break;
7a387fff 6126 default:
f31b035a 6127 goto cp0_unimplemented;
7a387fff 6128 }
8c0fdd85
TS
6129 break;
6130 case 26:
2423f660 6131 /* ignored */
8c0fdd85 6132 rn = "ECC";
2423f660 6133 break;
8c0fdd85 6134 case 27:
7a387fff
TS
6135 switch (sel) {
6136 case 0 ... 3:
2423f660
TS
6137 /* ignored */
6138 rn = "CacheErr";
6139 break;
7a387fff 6140 default:
f31b035a 6141 goto cp0_unimplemented;
7a387fff 6142 }
8c0fdd85
TS
6143 break;
6144 case 28:
6145 switch (sel) {
6146 case 0:
7a387fff
TS
6147 case 2:
6148 case 4:
6149 case 6:
895c2d04 6150 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6151 rn = "TagLo";
6152 break;
7a387fff
TS
6153 case 1:
6154 case 3:
6155 case 5:
6156 case 7:
895c2d04 6157 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6158 rn = "DataLo";
6159 break;
8c0fdd85 6160 default:
f31b035a 6161 goto cp0_unimplemented;
8c0fdd85
TS
6162 }
6163 break;
6164 case 29:
7a387fff
TS
6165 switch (sel) {
6166 case 0:
6167 case 2:
6168 case 4:
6169 case 6:
895c2d04 6170 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6171 rn = "TagHi";
6172 break;
6173 case 1:
6174 case 3:
6175 case 5:
6176 case 7:
895c2d04 6177 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6178 rn = "DataHi";
6179 break;
6180 default:
6181 rn = "invalid sel";
f31b035a 6182 goto cp0_unimplemented;
7a387fff 6183 }
8c0fdd85
TS
6184 break;
6185 case 30:
7a387fff
TS
6186 switch (sel) {
6187 case 0:
d54a299b 6188 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6189 rn = "ErrorEPC";
6190 break;
7a387fff 6191 default:
f31b035a 6192 goto cp0_unimplemented;
7a387fff 6193 }
8c0fdd85
TS
6194 break;
6195 case 31:
7a387fff
TS
6196 switch (sel) {
6197 case 0:
f1aa6320 6198 /* EJTAG support */
7db13fae 6199 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6200 rn = "DESAVE";
6201 break;
e98c0d17 6202 case 2 ... 7:
f31b035a
LA
6203 CP0_CHECK(ctx->kscrexist & (1 << sel));
6204 tcg_gen_st_tl(arg, cpu_env,
6205 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6206 rn = "KScratch";
e98c0d17 6207 break;
7a387fff 6208 default:
f31b035a 6209 goto cp0_unimplemented;
7a387fff 6210 }
2423f660
TS
6211 /* Stop translation as we may have switched the execution mode */
6212 ctx->bstate = BS_STOP;
8c0fdd85
TS
6213 break;
6214 default:
f31b035a 6215 goto cp0_unimplemented;
8c0fdd85 6216 }
2abf314d 6217 (void)rn; /* avoid a compiler warning */
d12d51d5 6218 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6219 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6220 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6221 gen_io_end();
6222 ctx->bstate = BS_STOP;
6223 }
8c0fdd85
TS
6224 return;
6225
f31b035a 6226cp0_unimplemented:
d12d51d5 6227 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6228}
6229
d26bc211 6230#if defined(TARGET_MIPS64)
d75c135e 6231static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6232{
6233 const char *rn = "invalid";
6234
e189e748 6235 if (sel != 0)
d75c135e 6236 check_insn(ctx, ISA_MIPS64);
e189e748 6237
9c2149c8
TS
6238 switch (reg) {
6239 case 0:
6240 switch (sel) {
6241 case 0:
7db13fae 6242 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6243 rn = "Index";
6244 break;
6245 case 1:
f31b035a 6246 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6247 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6248 rn = "MVPControl";
ead9360e 6249 break;
9c2149c8 6250 case 2:
f31b035a 6251 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6252 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6253 rn = "MVPConf0";
ead9360e 6254 break;
9c2149c8 6255 case 3:
f31b035a 6256 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6257 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6258 rn = "MVPConf1";
ead9360e 6259 break;
01bc435b
YK
6260 case 4:
6261 CP0_CHECK(ctx->vp);
6262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6263 rn = "VPControl";
6264 break;
9c2149c8 6265 default:
f31b035a 6266 goto cp0_unimplemented;
9c2149c8
TS
6267 }
6268 break;
6269 case 1:
6270 switch (sel) {
6271 case 0:
f31b035a 6272 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6273 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6274 rn = "Random";
2423f660 6275 break;
9c2149c8 6276 case 1:
f31b035a 6277 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6279 rn = "VPEControl";
ead9360e 6280 break;
9c2149c8 6281 case 2:
f31b035a 6282 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6284 rn = "VPEConf0";
ead9360e 6285 break;
9c2149c8 6286 case 3:
f31b035a 6287 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6289 rn = "VPEConf1";
ead9360e 6290 break;
9c2149c8 6291 case 4:
f31b035a 6292 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6293 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6294 rn = "YQMask";
ead9360e 6295 break;
9c2149c8 6296 case 5:
f31b035a 6297 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6298 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6299 rn = "VPESchedule";
ead9360e 6300 break;
9c2149c8 6301 case 6:
f31b035a 6302 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6303 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6304 rn = "VPEScheFBack";
ead9360e 6305 break;
9c2149c8 6306 case 7:
f31b035a 6307 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6309 rn = "VPEOpt";
ead9360e 6310 break;
9c2149c8 6311 default:
f31b035a 6312 goto cp0_unimplemented;
9c2149c8
TS
6313 }
6314 break;
6315 case 2:
6316 switch (sel) {
6317 case 0:
7db13fae 6318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6319 rn = "EntryLo0";
6320 break;
9c2149c8 6321 case 1:
f31b035a 6322 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6323 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6324 rn = "TCStatus";
ead9360e 6325 break;
9c2149c8 6326 case 2:
f31b035a 6327 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6328 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6329 rn = "TCBind";
ead9360e 6330 break;
9c2149c8 6331 case 3:
f31b035a 6332 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6333 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6334 rn = "TCRestart";
ead9360e 6335 break;
9c2149c8 6336 case 4:
f31b035a 6337 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6338 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6339 rn = "TCHalt";
ead9360e 6340 break;
9c2149c8 6341 case 5:
f31b035a 6342 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6343 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6344 rn = "TCContext";
ead9360e 6345 break;
9c2149c8 6346 case 6:
f31b035a 6347 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6348 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6349 rn = "TCSchedule";
ead9360e 6350 break;
9c2149c8 6351 case 7:
f31b035a 6352 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6353 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6354 rn = "TCScheFBack";
ead9360e 6355 break;
9c2149c8 6356 default:
f31b035a 6357 goto cp0_unimplemented;
9c2149c8
TS
6358 }
6359 break;
6360 case 3:
6361 switch (sel) {
6362 case 0:
7db13fae 6363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6364 rn = "EntryLo1";
6365 break;
01bc435b
YK
6366 case 1:
6367 CP0_CHECK(ctx->vp);
6368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6369 rn = "GlobalNumber";
6370 break;
9c2149c8 6371 default:
f31b035a 6372 goto cp0_unimplemented;
1579a72e 6373 }
9c2149c8
TS
6374 break;
6375 case 4:
6376 switch (sel) {
6377 case 0:
7db13fae 6378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6379 rn = "Context";
6380 break;
9c2149c8 6381 case 1:
d9bea114 6382// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6383 rn = "ContextConfig";
f31b035a 6384 goto cp0_unimplemented;
2423f660 6385// break;
d279279e 6386 case 2:
f31b035a
LA
6387 CP0_CHECK(ctx->ulri);
6388 tcg_gen_ld_tl(arg, cpu_env,
6389 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6390 rn = "UserLocal";
d279279e 6391 break;
9c2149c8 6392 default:
f31b035a 6393 goto cp0_unimplemented;
876d4b07 6394 }
9c2149c8
TS
6395 break;
6396 case 5:
6397 switch (sel) {
6398 case 0:
7db13fae 6399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6400 rn = "PageMask";
6401 break;
9c2149c8 6402 case 1:
d75c135e 6403 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6405 rn = "PageGrain";
6406 break;
9c2149c8 6407 default:
f31b035a 6408 goto cp0_unimplemented;
876d4b07 6409 }
9c2149c8
TS
6410 break;
6411 case 6:
6412 switch (sel) {
6413 case 0:
7db13fae 6414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6415 rn = "Wired";
6416 break;
9c2149c8 6417 case 1:
d75c135e 6418 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6420 rn = "SRSConf0";
ead9360e 6421 break;
9c2149c8 6422 case 2:
d75c135e 6423 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6425 rn = "SRSConf1";
ead9360e 6426 break;
9c2149c8 6427 case 3:
d75c135e 6428 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6430 rn = "SRSConf2";
ead9360e 6431 break;
9c2149c8 6432 case 4:
d75c135e 6433 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6435 rn = "SRSConf3";
ead9360e 6436 break;
9c2149c8 6437 case 5:
d75c135e 6438 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6440 rn = "SRSConf4";
ead9360e 6441 break;
9c2149c8 6442 default:
f31b035a 6443 goto cp0_unimplemented;
876d4b07 6444 }
9c2149c8
TS
6445 break;
6446 case 7:
6447 switch (sel) {
6448 case 0:
d75c135e 6449 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6451 rn = "HWREna";
6452 break;
9c2149c8 6453 default:
f31b035a 6454 goto cp0_unimplemented;
876d4b07 6455 }
9c2149c8
TS
6456 break;
6457 case 8:
6458 switch (sel) {
6459 case 0:
7db13fae 6460 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6461 rn = "BadVAddr";
2423f660 6462 break;
aea14095 6463 case 1:
f31b035a
LA
6464 CP0_CHECK(ctx->bi);
6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6466 rn = "BadInstr";
aea14095
LA
6467 break;
6468 case 2:
f31b035a
LA
6469 CP0_CHECK(ctx->bp);
6470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6471 rn = "BadInstrP";
aea14095 6472 break;
9c2149c8 6473 default:
f31b035a 6474 goto cp0_unimplemented;
876d4b07 6475 }
9c2149c8
TS
6476 break;
6477 case 9:
6478 switch (sel) {
6479 case 0:
2e70f6ef 6480 /* Mark as an IO operation because we read the time. */
bd79255d 6481 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6482 gen_io_start();
bd79255d 6483 }
895c2d04 6484 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6485 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6486 gen_io_end();
2e70f6ef 6487 }
55807224
EI
6488 /* Break the TB to be able to take timer interrupts immediately
6489 after reading count. */
6490 ctx->bstate = BS_STOP;
2423f660
TS
6491 rn = "Count";
6492 break;
6493 /* 6,7 are implementation dependent */
9c2149c8 6494 default:
f31b035a 6495 goto cp0_unimplemented;
876d4b07 6496 }
9c2149c8
TS
6497 break;
6498 case 10:
6499 switch (sel) {
6500 case 0:
7db13fae 6501 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6502 rn = "EntryHi";
6503 break;
9c2149c8 6504 default:
f31b035a 6505 goto cp0_unimplemented;
876d4b07 6506 }
9c2149c8
TS
6507 break;
6508 case 11:
6509 switch (sel) {
6510 case 0:
7db13fae 6511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6512 rn = "Compare";
6513 break;
876d4b07 6514 /* 6,7 are implementation dependent */
9c2149c8 6515 default:
f31b035a 6516 goto cp0_unimplemented;
876d4b07 6517 }
9c2149c8
TS
6518 break;
6519 case 12:
6520 switch (sel) {
6521 case 0:
7db13fae 6522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6523 rn = "Status";
6524 break;
9c2149c8 6525 case 1:
d75c135e 6526 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6528 rn = "IntCtl";
6529 break;
9c2149c8 6530 case 2:
d75c135e 6531 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6533 rn = "SRSCtl";
6534 break;
9c2149c8 6535 case 3:
d75c135e 6536 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6538 rn = "SRSMap";
6539 break;
9c2149c8 6540 default:
f31b035a 6541 goto cp0_unimplemented;
876d4b07 6542 }
9c2149c8
TS
6543 break;
6544 case 13:
6545 switch (sel) {
6546 case 0:
7db13fae 6547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6548 rn = "Cause";
6549 break;
9c2149c8 6550 default:
f31b035a 6551 goto cp0_unimplemented;
876d4b07 6552 }
9c2149c8
TS
6553 break;
6554 case 14:
6555 switch (sel) {
6556 case 0:
7db13fae 6557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6558 rn = "EPC";
6559 break;
9c2149c8 6560 default:
f31b035a 6561 goto cp0_unimplemented;
876d4b07 6562 }
9c2149c8
TS
6563 break;
6564 case 15:
6565 switch (sel) {
6566 case 0:
7db13fae 6567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6568 rn = "PRid";
6569 break;
9c2149c8 6570 case 1:
d75c135e 6571 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6573 rn = "EBase";
6574 break;
9c2149c8 6575 default:
f31b035a 6576 goto cp0_unimplemented;
876d4b07 6577 }
9c2149c8
TS
6578 break;
6579 case 16:
6580 switch (sel) {
6581 case 0:
7db13fae 6582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6583 rn = "Config";
6584 break;
6585 case 1:
7db13fae 6586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6587 rn = "Config1";
6588 break;
6589 case 2:
7db13fae 6590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6591 rn = "Config2";
6592 break;
6593 case 3:
7db13fae 6594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6595 rn = "Config3";
6596 break;
faf1f68b
LA
6597 case 4:
6598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6599 rn = "Config4";
6600 break;
6601 case 5:
6602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6603 rn = "Config5";
6604 break;
9c2149c8 6605 /* 6,7 are implementation dependent */
f0b3f3ae 6606 case 6:
7db13fae 6607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6608 rn = "Config6";
6609 break;
6610 case 7:
7db13fae 6611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6612 rn = "Config7";
6613 break;
9c2149c8 6614 default:
f31b035a 6615 goto cp0_unimplemented;
9c2149c8
TS
6616 }
6617 break;
6618 case 17:
6619 switch (sel) {
6620 case 0:
895c2d04 6621 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6622 rn = "LLAddr";
6623 break;
9c2149c8 6624 default:
f31b035a 6625 goto cp0_unimplemented;
9c2149c8
TS
6626 }
6627 break;
6628 case 18:
6629 switch (sel) {
fd88b6ab 6630 case 0 ... 7:
895c2d04 6631 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6632 rn = "WatchLo";
6633 break;
9c2149c8 6634 default:
f31b035a 6635 goto cp0_unimplemented;
9c2149c8
TS
6636 }
6637 break;
6638 case 19:
6639 switch (sel) {
fd88b6ab 6640 case 0 ... 7:
895c2d04 6641 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6642 rn = "WatchHi";
6643 break;
9c2149c8 6644 default:
f31b035a 6645 goto cp0_unimplemented;
9c2149c8
TS
6646 }
6647 break;
6648 case 20:
6649 switch (sel) {
6650 case 0:
d75c135e 6651 check_insn(ctx, ISA_MIPS3);
7db13fae 6652 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6653 rn = "XContext";
6654 break;
9c2149c8 6655 default:
f31b035a 6656 goto cp0_unimplemented;
9c2149c8
TS
6657 }
6658 break;
6659 case 21:
6660 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6661 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6662 switch (sel) {
6663 case 0:
7db13fae 6664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6665 rn = "Framemask";
6666 break;
9c2149c8 6667 default:
f31b035a 6668 goto cp0_unimplemented;
9c2149c8
TS
6669 }
6670 break;
6671 case 22:
d9bea114 6672 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6673 rn = "'Diagnostic"; /* implementation dependent */
6674 break;
9c2149c8
TS
6675 case 23:
6676 switch (sel) {
6677 case 0:
895c2d04 6678 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6679 rn = "Debug";
6680 break;
9c2149c8 6681 case 1:
895c2d04 6682// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6683 rn = "TraceControl";
6684// break;
9c2149c8 6685 case 2:
895c2d04 6686// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6687 rn = "TraceControl2";
6688// break;
9c2149c8 6689 case 3:
895c2d04 6690// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6691 rn = "UserTraceData";
6692// break;
9c2149c8 6693 case 4:
895c2d04 6694// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6695 rn = "TraceBPC";
6696// break;
9c2149c8 6697 default:
f31b035a 6698 goto cp0_unimplemented;
9c2149c8
TS
6699 }
6700 break;
6701 case 24:
6702 switch (sel) {
6703 case 0:
f0b3f3ae 6704 /* EJTAG support */
7db13fae 6705 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6706 rn = "DEPC";
6707 break;
9c2149c8 6708 default:
f31b035a 6709 goto cp0_unimplemented;
9c2149c8
TS
6710 }
6711 break;
6712 case 25:
6713 switch (sel) {
6714 case 0:
7db13fae 6715 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6716 rn = "Performance0";
9c2149c8
TS
6717 break;
6718 case 1:
d9bea114 6719// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6720 rn = "Performance1";
6721// break;
9c2149c8 6722 case 2:
d9bea114 6723// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6724 rn = "Performance2";
6725// break;
9c2149c8 6726 case 3:
d9bea114 6727// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6728 rn = "Performance3";
6729// break;
9c2149c8 6730 case 4:
d9bea114 6731// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6732 rn = "Performance4";
6733// break;
9c2149c8 6734 case 5:
d9bea114 6735// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6736 rn = "Performance5";
6737// break;
9c2149c8 6738 case 6:
d9bea114 6739// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6740 rn = "Performance6";
6741// break;
9c2149c8 6742 case 7:
d9bea114 6743// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6744 rn = "Performance7";
6745// break;
9c2149c8 6746 default:
f31b035a 6747 goto cp0_unimplemented;
9c2149c8
TS
6748 }
6749 break;
6750 case 26:
d9bea114 6751 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6752 rn = "ECC";
6753 break;
9c2149c8
TS
6754 case 27:
6755 switch (sel) {
6756 /* ignored */
6757 case 0 ... 3:
d9bea114 6758 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6759 rn = "CacheErr";
6760 break;
9c2149c8 6761 default:
f31b035a 6762 goto cp0_unimplemented;
9c2149c8
TS
6763 }
6764 break;
6765 case 28:
6766 switch (sel) {
6767 case 0:
6768 case 2:
6769 case 4:
6770 case 6:
7db13fae 6771 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6772 rn = "TagLo";
6773 break;
6774 case 1:
6775 case 3:
6776 case 5:
6777 case 7:
7db13fae 6778 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6779 rn = "DataLo";
6780 break;
6781 default:
f31b035a 6782 goto cp0_unimplemented;
9c2149c8
TS
6783 }
6784 break;
6785 case 29:
6786 switch (sel) {
6787 case 0:
6788 case 2:
6789 case 4:
6790 case 6:
7db13fae 6791 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6792 rn = "TagHi";
6793 break;
6794 case 1:
6795 case 3:
6796 case 5:
6797 case 7:
7db13fae 6798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6799 rn = "DataHi";
6800 break;
6801 default:
f31b035a 6802 goto cp0_unimplemented;
9c2149c8
TS
6803 }
6804 break;
6805 case 30:
6806 switch (sel) {
6807 case 0:
7db13fae 6808 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6809 rn = "ErrorEPC";
6810 break;
9c2149c8 6811 default:
f31b035a 6812 goto cp0_unimplemented;
9c2149c8
TS
6813 }
6814 break;
6815 case 31:
6816 switch (sel) {
6817 case 0:
f0b3f3ae 6818 /* EJTAG support */
7db13fae 6819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6820 rn = "DESAVE";
6821 break;
e98c0d17 6822 case 2 ... 7:
f31b035a
LA
6823 CP0_CHECK(ctx->kscrexist & (1 << sel));
6824 tcg_gen_ld_tl(arg, cpu_env,
6825 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6826 rn = "KScratch";
e98c0d17 6827 break;
9c2149c8 6828 default:
f31b035a 6829 goto cp0_unimplemented;
9c2149c8
TS
6830 }
6831 break;
6832 default:
f31b035a 6833 goto cp0_unimplemented;
9c2149c8 6834 }
2abf314d 6835 (void)rn; /* avoid a compiler warning */
d12d51d5 6836 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6837 return;
6838
f31b035a 6839cp0_unimplemented:
d12d51d5 6840 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6841 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6842}
6843
d75c135e 6844static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6845{
6846 const char *rn = "invalid";
6847
e189e748 6848 if (sel != 0)
d75c135e 6849 check_insn(ctx, ISA_MIPS64);
e189e748 6850
bd79255d 6851 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6852 gen_io_start();
bd79255d 6853 }
2e70f6ef 6854
9c2149c8
TS
6855 switch (reg) {
6856 case 0:
6857 switch (sel) {
6858 case 0:
895c2d04 6859 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6860 rn = "Index";
6861 break;
6862 case 1:
f31b035a 6863 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6864 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6865 rn = "MVPControl";
ead9360e 6866 break;
9c2149c8 6867 case 2:
f31b035a 6868 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6869 /* ignored */
9c2149c8 6870 rn = "MVPConf0";
ead9360e 6871 break;
9c2149c8 6872 case 3:
f31b035a 6873 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6874 /* ignored */
9c2149c8 6875 rn = "MVPConf1";
ead9360e 6876 break;
01bc435b
YK
6877 case 4:
6878 CP0_CHECK(ctx->vp);
6879 /* ignored */
6880 rn = "VPControl";
6881 break;
9c2149c8 6882 default:
f31b035a 6883 goto cp0_unimplemented;
9c2149c8
TS
6884 }
6885 break;
6886 case 1:
6887 switch (sel) {
6888 case 0:
2423f660 6889 /* ignored */
9c2149c8 6890 rn = "Random";
2423f660 6891 break;
9c2149c8 6892 case 1:
f31b035a 6893 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6894 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6895 rn = "VPEControl";
ead9360e 6896 break;
9c2149c8 6897 case 2:
f31b035a 6898 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6899 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6900 rn = "VPEConf0";
ead9360e 6901 break;
9c2149c8 6902 case 3:
f31b035a 6903 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6904 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6905 rn = "VPEConf1";
ead9360e 6906 break;
9c2149c8 6907 case 4:
f31b035a 6908 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6909 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6910 rn = "YQMask";
ead9360e 6911 break;
9c2149c8 6912 case 5:
f31b035a 6913 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6914 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6915 rn = "VPESchedule";
ead9360e 6916 break;
9c2149c8 6917 case 6:
f31b035a 6918 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6919 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6920 rn = "VPEScheFBack";
ead9360e 6921 break;
9c2149c8 6922 case 7:
f31b035a 6923 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6924 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6925 rn = "VPEOpt";
ead9360e 6926 break;
9c2149c8 6927 default:
f31b035a 6928 goto cp0_unimplemented;
9c2149c8
TS
6929 }
6930 break;
6931 case 2:
6932 switch (sel) {
6933 case 0:
7207c7f9 6934 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6935 rn = "EntryLo0";
6936 break;
9c2149c8 6937 case 1:
f31b035a 6938 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6939 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6940 rn = "TCStatus";
ead9360e 6941 break;
9c2149c8 6942 case 2:
f31b035a 6943 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6944 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6945 rn = "TCBind";
ead9360e 6946 break;
9c2149c8 6947 case 3:
f31b035a 6948 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6949 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6950 rn = "TCRestart";
ead9360e 6951 break;
9c2149c8 6952 case 4:
f31b035a 6953 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6954 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6955 rn = "TCHalt";
ead9360e 6956 break;
9c2149c8 6957 case 5:
f31b035a 6958 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6959 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6960 rn = "TCContext";
ead9360e 6961 break;
9c2149c8 6962 case 6:
f31b035a 6963 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6964 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6965 rn = "TCSchedule";
ead9360e 6966 break;
9c2149c8 6967 case 7:
f31b035a 6968 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6969 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6970 rn = "TCScheFBack";
ead9360e 6971 break;
9c2149c8 6972 default:
f31b035a 6973 goto cp0_unimplemented;
9c2149c8
TS
6974 }
6975 break;
6976 case 3:
6977 switch (sel) {
6978 case 0:
7207c7f9 6979 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6980 rn = "EntryLo1";
6981 break;
01bc435b
YK
6982 case 1:
6983 CP0_CHECK(ctx->vp);
6984 /* ignored */
6985 rn = "GlobalNumber";
6986 break;
9c2149c8 6987 default:
f31b035a 6988 goto cp0_unimplemented;
876d4b07 6989 }
9c2149c8
TS
6990 break;
6991 case 4:
6992 switch (sel) {
6993 case 0:
895c2d04 6994 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6995 rn = "Context";
6996 break;
9c2149c8 6997 case 1:
895c2d04 6998// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6999 rn = "ContextConfig";
f31b035a 7000 goto cp0_unimplemented;
2423f660 7001// break;
d279279e 7002 case 2:
f31b035a
LA
7003 CP0_CHECK(ctx->ulri);
7004 tcg_gen_st_tl(arg, cpu_env,
7005 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7006 rn = "UserLocal";
d279279e 7007 break;
9c2149c8 7008 default:
f31b035a 7009 goto cp0_unimplemented;
876d4b07 7010 }
9c2149c8
TS
7011 break;
7012 case 5:
7013 switch (sel) {
7014 case 0:
895c2d04 7015 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7016 rn = "PageMask";
7017 break;
9c2149c8 7018 case 1:
d75c135e 7019 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7020 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7021 rn = "PageGrain";
7022 break;
9c2149c8 7023 default:
f31b035a 7024 goto cp0_unimplemented;
876d4b07 7025 }
9c2149c8
TS
7026 break;
7027 case 6:
7028 switch (sel) {
7029 case 0:
895c2d04 7030 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7031 rn = "Wired";
7032 break;
9c2149c8 7033 case 1:
d75c135e 7034 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7035 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7036 rn = "SRSConf0";
ead9360e 7037 break;
9c2149c8 7038 case 2:
d75c135e 7039 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7040 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7041 rn = "SRSConf1";
ead9360e 7042 break;
9c2149c8 7043 case 3:
d75c135e 7044 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7045 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7046 rn = "SRSConf2";
ead9360e 7047 break;
9c2149c8 7048 case 4:
d75c135e 7049 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7050 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7051 rn = "SRSConf3";
ead9360e 7052 break;
9c2149c8 7053 case 5:
d75c135e 7054 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7055 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7056 rn = "SRSConf4";
ead9360e 7057 break;
9c2149c8 7058 default:
f31b035a 7059 goto cp0_unimplemented;
876d4b07 7060 }
9c2149c8
TS
7061 break;
7062 case 7:
7063 switch (sel) {
7064 case 0:
d75c135e 7065 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7066 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7067 ctx->bstate = BS_STOP;
2423f660
TS
7068 rn = "HWREna";
7069 break;
9c2149c8 7070 default:
f31b035a 7071 goto cp0_unimplemented;
876d4b07 7072 }
9c2149c8
TS
7073 break;
7074 case 8:
aea14095
LA
7075 switch (sel) {
7076 case 0:
7077 /* ignored */
7078 rn = "BadVAddr";
7079 break;
7080 case 1:
7081 /* ignored */
7082 rn = "BadInstr";
7083 break;
7084 case 2:
7085 /* ignored */
7086 rn = "BadInstrP";
7087 break;
7088 default:
f31b035a 7089 goto cp0_unimplemented;
aea14095 7090 }
9c2149c8
TS
7091 break;
7092 case 9:
7093 switch (sel) {
7094 case 0:
895c2d04 7095 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7096 rn = "Count";
7097 break;
876d4b07 7098 /* 6,7 are implementation dependent */
9c2149c8 7099 default:
f31b035a 7100 goto cp0_unimplemented;
876d4b07
TS
7101 }
7102 /* Stop translation as we may have switched the execution mode */
7103 ctx->bstate = BS_STOP;
9c2149c8
TS
7104 break;
7105 case 10:
7106 switch (sel) {
7107 case 0:
895c2d04 7108 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7109 rn = "EntryHi";
7110 break;
9c2149c8 7111 default:
f31b035a 7112 goto cp0_unimplemented;
876d4b07 7113 }
9c2149c8
TS
7114 break;
7115 case 11:
7116 switch (sel) {
7117 case 0:
895c2d04 7118 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7119 rn = "Compare";
7120 break;
876d4b07 7121 /* 6,7 are implementation dependent */
9c2149c8 7122 default:
f31b035a 7123 goto cp0_unimplemented;
876d4b07 7124 }
de9a95f0
AJ
7125 /* Stop translation as we may have switched the execution mode */
7126 ctx->bstate = BS_STOP;
9c2149c8
TS
7127 break;
7128 case 12:
7129 switch (sel) {
7130 case 0:
867abc7e 7131 save_cpu_state(ctx, 1);
895c2d04 7132 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7133 /* BS_STOP isn't good enough here, hflags may have changed. */
7134 gen_save_pc(ctx->pc + 4);
7135 ctx->bstate = BS_EXCP;
2423f660
TS
7136 rn = "Status";
7137 break;
9c2149c8 7138 case 1:
d75c135e 7139 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7140 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7141 /* Stop translation as we may have switched the execution mode */
7142 ctx->bstate = BS_STOP;
2423f660
TS
7143 rn = "IntCtl";
7144 break;
9c2149c8 7145 case 2:
d75c135e 7146 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7147 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7148 /* Stop translation as we may have switched the execution mode */
7149 ctx->bstate = BS_STOP;
2423f660
TS
7150 rn = "SRSCtl";
7151 break;
9c2149c8 7152 case 3:
d75c135e 7153 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7154 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7155 /* Stop translation as we may have switched the execution mode */
7156 ctx->bstate = BS_STOP;
2423f660
TS
7157 rn = "SRSMap";
7158 break;
7159 default:
f31b035a 7160 goto cp0_unimplemented;
876d4b07 7161 }
9c2149c8
TS
7162 break;
7163 case 13:
7164 switch (sel) {
7165 case 0:
867abc7e 7166 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7167 /* Mark as an IO operation because we may trigger a software
7168 interrupt. */
bd79255d 7169 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7170 gen_io_start();
7171 }
895c2d04 7172 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7173 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7174 gen_io_end();
7175 }
7176 /* Stop translation as we may have triggered an intetrupt */
7177 ctx->bstate = BS_STOP;
2423f660
TS
7178 rn = "Cause";
7179 break;
9c2149c8 7180 default:
f31b035a 7181 goto cp0_unimplemented;
876d4b07 7182 }
9c2149c8
TS
7183 break;
7184 case 14:
7185 switch (sel) {
7186 case 0:
7db13fae 7187 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7188 rn = "EPC";
7189 break;
9c2149c8 7190 default:
f31b035a 7191 goto cp0_unimplemented;
876d4b07 7192 }
9c2149c8
TS
7193 break;
7194 case 15:
7195 switch (sel) {
7196 case 0:
2423f660
TS
7197 /* ignored */
7198 rn = "PRid";
7199 break;
9c2149c8 7200 case 1:
d75c135e 7201 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7202 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7203 rn = "EBase";
7204 break;
9c2149c8 7205 default:
f31b035a 7206 goto cp0_unimplemented;
876d4b07 7207 }
9c2149c8
TS
7208 break;
7209 case 16:
7210 switch (sel) {
7211 case 0:
895c2d04 7212 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7213 rn = "Config";
2423f660
TS
7214 /* Stop translation as we may have switched the execution mode */
7215 ctx->bstate = BS_STOP;
9c2149c8
TS
7216 break;
7217 case 1:
1fc7bf6e 7218 /* ignored, read only */
9c2149c8
TS
7219 rn = "Config1";
7220 break;
7221 case 2:
895c2d04 7222 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7223 rn = "Config2";
2423f660
TS
7224 /* Stop translation as we may have switched the execution mode */
7225 ctx->bstate = BS_STOP;
9c2149c8
TS
7226 break;
7227 case 3:
90f12d73 7228 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7229 rn = "Config3";
90f12d73
MR
7230 /* Stop translation as we may have switched the execution mode */
7231 ctx->bstate = BS_STOP;
9c2149c8 7232 break;
faf1f68b
LA
7233 case 4:
7234 /* currently ignored */
7235 rn = "Config4";
7236 break;
7237 case 5:
7238 gen_helper_mtc0_config5(cpu_env, arg);
7239 rn = "Config5";
7240 /* Stop translation as we may have switched the execution mode */
7241 ctx->bstate = BS_STOP;
7242 break;
9c2149c8
TS
7243 /* 6,7 are implementation dependent */
7244 default:
7245 rn = "Invalid config selector";
f31b035a 7246 goto cp0_unimplemented;
9c2149c8 7247 }
9c2149c8
TS
7248 break;
7249 case 17:
7250 switch (sel) {
7251 case 0:
895c2d04 7252 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7253 rn = "LLAddr";
7254 break;
9c2149c8 7255 default:
f31b035a 7256 goto cp0_unimplemented;
9c2149c8
TS
7257 }
7258 break;
7259 case 18:
7260 switch (sel) {
fd88b6ab 7261 case 0 ... 7:
895c2d04 7262 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7263 rn = "WatchLo";
7264 break;
9c2149c8 7265 default:
f31b035a 7266 goto cp0_unimplemented;
9c2149c8
TS
7267 }
7268 break;
7269 case 19:
7270 switch (sel) {
fd88b6ab 7271 case 0 ... 7:
895c2d04 7272 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7273 rn = "WatchHi";
7274 break;
9c2149c8 7275 default:
f31b035a 7276 goto cp0_unimplemented;
9c2149c8
TS
7277 }
7278 break;
7279 case 20:
7280 switch (sel) {
7281 case 0:
d75c135e 7282 check_insn(ctx, ISA_MIPS3);
895c2d04 7283 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7284 rn = "XContext";
7285 break;
9c2149c8 7286 default:
f31b035a 7287 goto cp0_unimplemented;
9c2149c8
TS
7288 }
7289 break;
7290 case 21:
7291 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7292 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7293 switch (sel) {
7294 case 0:
895c2d04 7295 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7296 rn = "Framemask";
7297 break;
9c2149c8 7298 default:
f31b035a 7299 goto cp0_unimplemented;
9c2149c8
TS
7300 }
7301 break;
7302 case 22:
7303 /* ignored */
7304 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7305 break;
9c2149c8
TS
7306 case 23:
7307 switch (sel) {
7308 case 0:
895c2d04 7309 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7310 /* BS_STOP isn't good enough here, hflags may have changed. */
7311 gen_save_pc(ctx->pc + 4);
7312 ctx->bstate = BS_EXCP;
2423f660
TS
7313 rn = "Debug";
7314 break;
9c2149c8 7315 case 1:
895c2d04 7316// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7317 /* Stop translation as we may have switched the execution mode */
7318 ctx->bstate = BS_STOP;
2423f660
TS
7319 rn = "TraceControl";
7320// break;
9c2149c8 7321 case 2:
895c2d04 7322// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7323 /* Stop translation as we may have switched the execution mode */
7324 ctx->bstate = BS_STOP;
2423f660
TS
7325 rn = "TraceControl2";
7326// break;
9c2149c8 7327 case 3:
895c2d04 7328// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7329 /* Stop translation as we may have switched the execution mode */
7330 ctx->bstate = BS_STOP;
2423f660
TS
7331 rn = "UserTraceData";
7332// break;
9c2149c8 7333 case 4:
895c2d04 7334// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7335 /* Stop translation as we may have switched the execution mode */
7336 ctx->bstate = BS_STOP;
2423f660
TS
7337 rn = "TraceBPC";
7338// break;
9c2149c8 7339 default:
f31b035a 7340 goto cp0_unimplemented;
9c2149c8 7341 }
9c2149c8
TS
7342 break;
7343 case 24:
7344 switch (sel) {
7345 case 0:
f1aa6320 7346 /* EJTAG support */
7db13fae 7347 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7348 rn = "DEPC";
7349 break;
9c2149c8 7350 default:
f31b035a 7351 goto cp0_unimplemented;
9c2149c8
TS
7352 }
7353 break;
7354 case 25:
7355 switch (sel) {
7356 case 0:
895c2d04 7357 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7358 rn = "Performance0";
7359 break;
9c2149c8 7360 case 1:
895c2d04 7361// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7362 rn = "Performance1";
7363// break;
9c2149c8 7364 case 2:
895c2d04 7365// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7366 rn = "Performance2";
7367// break;
9c2149c8 7368 case 3:
895c2d04 7369// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7370 rn = "Performance3";
7371// break;
9c2149c8 7372 case 4:
895c2d04 7373// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7374 rn = "Performance4";
7375// break;
9c2149c8 7376 case 5:
895c2d04 7377// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7378 rn = "Performance5";
7379// break;
9c2149c8 7380 case 6:
895c2d04 7381// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7382 rn = "Performance6";
7383// break;
9c2149c8 7384 case 7:
895c2d04 7385// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7386 rn = "Performance7";
7387// break;
9c2149c8 7388 default:
f31b035a 7389 goto cp0_unimplemented;
9c2149c8 7390 }
876d4b07 7391 break;
9c2149c8 7392 case 26:
876d4b07 7393 /* ignored */
9c2149c8 7394 rn = "ECC";
876d4b07 7395 break;
9c2149c8
TS
7396 case 27:
7397 switch (sel) {
7398 case 0 ... 3:
2423f660
TS
7399 /* ignored */
7400 rn = "CacheErr";
7401 break;
9c2149c8 7402 default:
f31b035a 7403 goto cp0_unimplemented;
9c2149c8 7404 }
876d4b07 7405 break;
9c2149c8
TS
7406 case 28:
7407 switch (sel) {
7408 case 0:
7409 case 2:
7410 case 4:
7411 case 6:
895c2d04 7412 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7413 rn = "TagLo";
7414 break;
7415 case 1:
7416 case 3:
7417 case 5:
7418 case 7:
895c2d04 7419 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7420 rn = "DataLo";
7421 break;
7422 default:
f31b035a 7423 goto cp0_unimplemented;
9c2149c8
TS
7424 }
7425 break;
7426 case 29:
7427 switch (sel) {
7428 case 0:
7429 case 2:
7430 case 4:
7431 case 6:
895c2d04 7432 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7433 rn = "TagHi";
7434 break;
7435 case 1:
7436 case 3:
7437 case 5:
7438 case 7:
895c2d04 7439 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7440 rn = "DataHi";
7441 break;
7442 default:
7443 rn = "invalid sel";
f31b035a 7444 goto cp0_unimplemented;
9c2149c8 7445 }
876d4b07 7446 break;
9c2149c8
TS
7447 case 30:
7448 switch (sel) {
7449 case 0:
7db13fae 7450 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7451 rn = "ErrorEPC";
7452 break;
9c2149c8 7453 default:
f31b035a 7454 goto cp0_unimplemented;
9c2149c8
TS
7455 }
7456 break;
7457 case 31:
7458 switch (sel) {
7459 case 0:
f1aa6320 7460 /* EJTAG support */
7db13fae 7461 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7462 rn = "DESAVE";
7463 break;
e98c0d17 7464 case 2 ... 7:
f31b035a
LA
7465 CP0_CHECK(ctx->kscrexist & (1 << sel));
7466 tcg_gen_st_tl(arg, cpu_env,
7467 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7468 rn = "KScratch";
e98c0d17 7469 break;
9c2149c8 7470 default:
f31b035a 7471 goto cp0_unimplemented;
9c2149c8 7472 }
876d4b07
TS
7473 /* Stop translation as we may have switched the execution mode */
7474 ctx->bstate = BS_STOP;
9c2149c8
TS
7475 break;
7476 default:
f31b035a 7477 goto cp0_unimplemented;
9c2149c8 7478 }
2abf314d 7479 (void)rn; /* avoid a compiler warning */
d12d51d5 7480 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7481 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7482 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7483 gen_io_end();
7484 ctx->bstate = BS_STOP;
7485 }
9c2149c8
TS
7486 return;
7487
f31b035a 7488cp0_unimplemented:
d12d51d5 7489 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7490}
d26bc211 7491#endif /* TARGET_MIPS64 */
9c2149c8 7492
7db13fae 7493static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7494 int u, int sel, int h)
7495{
7496 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7497 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7498
7499 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7500 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7501 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7502 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7503 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7504 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7505 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7506 else if (u == 0) {
7507 switch (rt) {
5a25ce94
EI
7508 case 1:
7509 switch (sel) {
7510 case 1:
895c2d04 7511 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7512 break;
7513 case 2:
895c2d04 7514 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7515 break;
7516 default:
7517 goto die;
7518 break;
7519 }
7520 break;
ead9360e
TS
7521 case 2:
7522 switch (sel) {
7523 case 1:
895c2d04 7524 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7525 break;
7526 case 2:
895c2d04 7527 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7528 break;
7529 case 3:
895c2d04 7530 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7531 break;
7532 case 4:
895c2d04 7533 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7534 break;
7535 case 5:
895c2d04 7536 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7537 break;
7538 case 6:
895c2d04 7539 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7540 break;
7541 case 7:
895c2d04 7542 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7543 break;
7544 default:
d75c135e 7545 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7546 break;
7547 }
7548 break;
7549 case 10:
7550 switch (sel) {
7551 case 0:
895c2d04 7552 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7553 break;
7554 default:
d75c135e 7555 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7556 break;
7557 }
7558 case 12:
7559 switch (sel) {
7560 case 0:
895c2d04 7561 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7562 break;
7563 default:
d75c135e 7564 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7565 break;
7566 }
5a25ce94
EI
7567 case 13:
7568 switch (sel) {
7569 case 0:
895c2d04 7570 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7571 break;
7572 default:
7573 goto die;
7574 break;
7575 }
7576 break;
7577 case 14:
7578 switch (sel) {
7579 case 0:
895c2d04 7580 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7581 break;
7582 default:
7583 goto die;
7584 break;
7585 }
7586 break;
7587 case 15:
7588 switch (sel) {
7589 case 1:
895c2d04 7590 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7591 break;
7592 default:
7593 goto die;
7594 break;
7595 }
7596 break;
7597 case 16:
7598 switch (sel) {
7599 case 0 ... 7:
895c2d04 7600 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7601 break;
7602 default:
7603 goto die;
7604 break;
7605 }
7606 break;
ead9360e
TS
7607 case 23:
7608 switch (sel) {
7609 case 0:
895c2d04 7610 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7611 break;
7612 default:
d75c135e 7613 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7614 break;
7615 }
7616 break;
7617 default:
d75c135e 7618 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7619 }
7620 } else switch (sel) {
7621 /* GPR registers. */
7622 case 0:
895c2d04 7623 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7624 break;
7625 /* Auxiliary CPU registers */
7626 case 1:
7627 switch (rt) {
7628 case 0:
895c2d04 7629 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7630 break;
7631 case 1:
895c2d04 7632 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7633 break;
7634 case 2:
895c2d04 7635 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7636 break;
7637 case 4:
895c2d04 7638 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7639 break;
7640 case 5:
895c2d04 7641 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7642 break;
7643 case 6:
895c2d04 7644 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7645 break;
7646 case 8:
895c2d04 7647 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7648 break;
7649 case 9:
895c2d04 7650 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7651 break;
7652 case 10:
895c2d04 7653 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7654 break;
7655 case 12:
895c2d04 7656 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7657 break;
7658 case 13:
895c2d04 7659 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7660 break;
7661 case 14:
895c2d04 7662 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7663 break;
7664 case 16:
895c2d04 7665 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7666 break;
7667 default:
7668 goto die;
7669 }
7670 break;
7671 /* Floating point (COP1). */
7672 case 2:
7673 /* XXX: For now we support only a single FPU context. */
7674 if (h == 0) {
a7812ae4 7675 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7676
7c979afd 7677 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7678 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7679 tcg_temp_free_i32(fp0);
ead9360e 7680 } else {
a7812ae4 7681 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7682
7f6613ce 7683 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7684 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7685 tcg_temp_free_i32(fp0);
ead9360e
TS
7686 }
7687 break;
7688 case 3:
7689 /* XXX: For now we support only a single FPU context. */
895c2d04 7690 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7691 break;
7692 /* COP2: Not implemented. */
7693 case 4:
7694 case 5:
7695 /* fall through */
7696 default:
7697 goto die;
7698 }
d12d51d5 7699 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7700 gen_store_gpr(t0, rd);
7701 tcg_temp_free(t0);
ead9360e
TS
7702 return;
7703
7704die:
1a3fd9c3 7705 tcg_temp_free(t0);
d12d51d5 7706 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7707 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7708}
7709
7db13fae 7710static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7711 int u, int sel, int h)
7712{
7713 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7714 TCGv t0 = tcg_temp_local_new();
ead9360e 7715
1a3fd9c3 7716 gen_load_gpr(t0, rt);
ead9360e 7717 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7718 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7719 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7720 /* NOP */ ;
7721 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7722 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7723 /* NOP */ ;
7724 else if (u == 0) {
7725 switch (rd) {
5a25ce94
EI
7726 case 1:
7727 switch (sel) {
7728 case 1:
895c2d04 7729 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7730 break;
7731 case 2:
895c2d04 7732 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7733 break;
7734 default:
7735 goto die;
7736 break;
7737 }
7738 break;
ead9360e
TS
7739 case 2:
7740 switch (sel) {
7741 case 1:
895c2d04 7742 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7743 break;
7744 case 2:
895c2d04 7745 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7746 break;
7747 case 3:
895c2d04 7748 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7749 break;
7750 case 4:
895c2d04 7751 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7752 break;
7753 case 5:
895c2d04 7754 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7755 break;
7756 case 6:
895c2d04 7757 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7758 break;
7759 case 7:
895c2d04 7760 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7761 break;
7762 default:
d75c135e 7763 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7764 break;
7765 }
7766 break;
7767 case 10:
7768 switch (sel) {
7769 case 0:
895c2d04 7770 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7771 break;
7772 default:
d75c135e 7773 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7774 break;
7775 }
7776 case 12:
7777 switch (sel) {
7778 case 0:
895c2d04 7779 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7780 break;
7781 default:
d75c135e 7782 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7783 break;
7784 }
5a25ce94
EI
7785 case 13:
7786 switch (sel) {
7787 case 0:
895c2d04 7788 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7789 break;
7790 default:
7791 goto die;
7792 break;
7793 }
7794 break;
7795 case 15:
7796 switch (sel) {
7797 case 1:
895c2d04 7798 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7799 break;
7800 default:
7801 goto die;
7802 break;
7803 }
7804 break;
ead9360e
TS
7805 case 23:
7806 switch (sel) {
7807 case 0:
895c2d04 7808 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7809 break;
7810 default:
d75c135e 7811 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7812 break;
7813 }
7814 break;
7815 default:
d75c135e 7816 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7817 }
7818 } else switch (sel) {
7819 /* GPR registers. */
7820 case 0:
895c2d04 7821 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7822 break;
7823 /* Auxiliary CPU registers */
7824 case 1:
7825 switch (rd) {
7826 case 0:
895c2d04 7827 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7828 break;
7829 case 1:
895c2d04 7830 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7831 break;
7832 case 2:
895c2d04 7833 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7834 break;
7835 case 4:
895c2d04 7836 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7837 break;
7838 case 5:
895c2d04 7839 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7840 break;
7841 case 6:
895c2d04 7842 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7843 break;
7844 case 8:
895c2d04 7845 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7846 break;
7847 case 9:
895c2d04 7848 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7849 break;
7850 case 10:
895c2d04 7851 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7852 break;
7853 case 12:
895c2d04 7854 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7855 break;
7856 case 13:
895c2d04 7857 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7858 break;
7859 case 14:
895c2d04 7860 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7861 break;
7862 case 16:
895c2d04 7863 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7864 break;
7865 default:
7866 goto die;
7867 }
7868 break;
7869 /* Floating point (COP1). */
7870 case 2:
7871 /* XXX: For now we support only a single FPU context. */
7872 if (h == 0) {
a7812ae4 7873 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7874
7875 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 7876 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 7877 tcg_temp_free_i32(fp0);
ead9360e 7878 } else {
a7812ae4 7879 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7880
7881 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7882 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7883 tcg_temp_free_i32(fp0);
ead9360e
TS
7884 }
7885 break;
7886 case 3:
7887 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7888 {
7889 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7890
7891 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7892 tcg_temp_free_i32(fs_tmp);
7893 }
4cf8a45f
YK
7894 /* Stop translation as we may have changed hflags */
7895 ctx->bstate = BS_STOP;
ead9360e
TS
7896 break;
7897 /* COP2: Not implemented. */
7898 case 4:
7899 case 5:
7900 /* fall through */
7901 default:
7902 goto die;
7903 }
d12d51d5 7904 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7905 tcg_temp_free(t0);
ead9360e
TS
7906 return;
7907
7908die:
1a3fd9c3 7909 tcg_temp_free(t0);
d12d51d5 7910 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 7911 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7912}
7913
7db13fae 7914static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7915{
287c4b84 7916 const char *opn = "ldst";
6af0bf9c 7917
2e15497c 7918 check_cp0_enabled(ctx);
6af0bf9c
FB
7919 switch (opc) {
7920 case OPC_MFC0:
7921 if (rt == 0) {
ead9360e 7922 /* Treat as NOP. */
6af0bf9c
FB
7923 return;
7924 }
d75c135e 7925 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7926 opn = "mfc0";
7927 break;
7928 case OPC_MTC0:
1a3fd9c3 7929 {
1fc7bf6e 7930 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7931
7932 gen_load_gpr(t0, rt);
d75c135e 7933 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7934 tcg_temp_free(t0);
7935 }
6af0bf9c
FB
7936 opn = "mtc0";
7937 break;
d26bc211 7938#if defined(TARGET_MIPS64)
9c2149c8 7939 case OPC_DMFC0:
d75c135e 7940 check_insn(ctx, ISA_MIPS3);
9c2149c8 7941 if (rt == 0) {
ead9360e 7942 /* Treat as NOP. */
9c2149c8
TS
7943 return;
7944 }
d75c135e 7945 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7946 opn = "dmfc0";
7947 break;
7948 case OPC_DMTC0:
d75c135e 7949 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7950 {
1fc7bf6e 7951 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7952
7953 gen_load_gpr(t0, rt);
d75c135e 7954 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7955 tcg_temp_free(t0);
7956 }
9c2149c8
TS
7957 opn = "dmtc0";
7958 break;
534ce69f 7959#endif
5204ea79
LA
7960 case OPC_MFHC0:
7961 check_mvh(ctx);
7962 if (rt == 0) {
7963 /* Treat as NOP. */
7964 return;
7965 }
7966 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7967 opn = "mfhc0";
7968 break;
7969 case OPC_MTHC0:
7970 check_mvh(ctx);
7971 {
7972 TCGv t0 = tcg_temp_new();
7973 gen_load_gpr(t0, rt);
7974 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7975 tcg_temp_free(t0);
7976 }
7977 opn = "mthc0";
7978 break;
ead9360e 7979 case OPC_MFTR:
d75c135e 7980 check_insn(ctx, ASE_MT);
ead9360e
TS
7981 if (rd == 0) {
7982 /* Treat as NOP. */
7983 return;
7984 }
6c5c1e20 7985 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7986 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7987 opn = "mftr";
7988 break;
7989 case OPC_MTTR:
d75c135e 7990 check_insn(ctx, ASE_MT);
6c5c1e20 7991 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7992 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7993 opn = "mttr";
7994 break;
6af0bf9c 7995 case OPC_TLBWI:
6af0bf9c 7996 opn = "tlbwi";
c01fccd2 7997 if (!env->tlb->helper_tlbwi)
29929e34 7998 goto die;
895c2d04 7999 gen_helper_tlbwi(cpu_env);
6af0bf9c 8000 break;
9456c2fb
LA
8001 case OPC_TLBINV:
8002 opn = "tlbinv";
8003 if (ctx->ie >= 2) {
8004 if (!env->tlb->helper_tlbinv) {
8005 goto die;
8006 }
8007 gen_helper_tlbinv(cpu_env);
8008 } /* treat as nop if TLBINV not supported */
8009 break;
8010 case OPC_TLBINVF:
8011 opn = "tlbinvf";
8012 if (ctx->ie >= 2) {
8013 if (!env->tlb->helper_tlbinvf) {
8014 goto die;
8015 }
8016 gen_helper_tlbinvf(cpu_env);
8017 } /* treat as nop if TLBINV not supported */
8018 break;
6af0bf9c 8019 case OPC_TLBWR:
6af0bf9c 8020 opn = "tlbwr";
c01fccd2 8021 if (!env->tlb->helper_tlbwr)
29929e34 8022 goto die;
895c2d04 8023 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8024 break;
8025 case OPC_TLBP:
6af0bf9c 8026 opn = "tlbp";
c01fccd2 8027 if (!env->tlb->helper_tlbp)
29929e34 8028 goto die;
895c2d04 8029 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8030 break;
8031 case OPC_TLBR:
6af0bf9c 8032 opn = "tlbr";
c01fccd2 8033 if (!env->tlb->helper_tlbr)
29929e34 8034 goto die;
895c2d04 8035 gen_helper_tlbr(cpu_env);
6af0bf9c 8036 break;
ce9782f4 8037 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8038 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8039 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8040 goto die;
ce9782f4
LA
8041 } else {
8042 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8043 if (ctx->opcode & (1 << bit_shift)) {
8044 /* OPC_ERETNC */
8045 opn = "eretnc";
8046 check_insn(ctx, ISA_MIPS32R5);
8047 gen_helper_eretnc(cpu_env);
8048 } else {
8049 /* OPC_ERET */
8050 opn = "eret";
8051 check_insn(ctx, ISA_MIPS2);
8052 gen_helper_eret(cpu_env);
8053 }
8054 ctx->bstate = BS_EXCP;
339cd2a8 8055 }
6af0bf9c
FB
8056 break;
8057 case OPC_DERET:
8058 opn = "deret";
d75c135e 8059 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8060 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8061 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8062 goto die;
8063 }
6af0bf9c 8064 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8065 MIPS_INVAL(opn);
9c708c7f 8066 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8067 } else {
895c2d04 8068 gen_helper_deret(cpu_env);
6af0bf9c
FB
8069 ctx->bstate = BS_EXCP;
8070 }
8071 break;
4ad40f36
FB
8072 case OPC_WAIT:
8073 opn = "wait";
d75c135e 8074 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8075 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8076 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8077 goto die;
8078 }
4ad40f36
FB
8079 /* If we get an exception, we want to restart at next instruction */
8080 ctx->pc += 4;
8081 save_cpu_state(ctx, 1);
8082 ctx->pc -= 4;
895c2d04 8083 gen_helper_wait(cpu_env);
4ad40f36
FB
8084 ctx->bstate = BS_EXCP;
8085 break;
6af0bf9c 8086 default:
29929e34 8087 die:
923617a3 8088 MIPS_INVAL(opn);
9c708c7f 8089 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8090 return;
8091 }
2abf314d 8092 (void)opn; /* avoid a compiler warning */
6af0bf9c 8093}
f1aa6320 8094#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8095
6ea83fed 8096/* CP1 Branches (before delay slot) */
d75c135e
AJ
8097static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8098 int32_t cc, int32_t offset)
6ea83fed
FB
8099{
8100 target_ulong btarget;
a7812ae4 8101 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8102
339cd2a8 8103 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8104 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8105 goto out;
8106 }
8107
e189e748 8108 if (cc != 0)
d75c135e 8109 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8110
6ea83fed
FB
8111 btarget = ctx->pc + 4 + offset;
8112
7a387fff
TS
8113 switch (op) {
8114 case OPC_BC1F:
d94536f4
AJ
8115 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8116 tcg_gen_not_i32(t0, t0);
8117 tcg_gen_andi_i32(t0, t0, 1);
8118 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8119 goto not_likely;
7a387fff 8120 case OPC_BC1FL:
d94536f4
AJ
8121 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8122 tcg_gen_not_i32(t0, t0);
8123 tcg_gen_andi_i32(t0, t0, 1);
8124 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8125 goto likely;
7a387fff 8126 case OPC_BC1T:
d94536f4
AJ
8127 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8128 tcg_gen_andi_i32(t0, t0, 1);
8129 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8130 goto not_likely;
7a387fff 8131 case OPC_BC1TL:
d94536f4
AJ
8132 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8133 tcg_gen_andi_i32(t0, t0, 1);
8134 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8135 likely:
8136 ctx->hflags |= MIPS_HFLAG_BL;
8137 break;
5a5012ec 8138 case OPC_BC1FANY2:
a16336e4 8139 {
d94536f4
AJ
8140 TCGv_i32 t1 = tcg_temp_new_i32();
8141 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8142 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8143 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8144 tcg_temp_free_i32(t1);
d94536f4
AJ
8145 tcg_gen_andi_i32(t0, t0, 1);
8146 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8147 }
5a5012ec
TS
8148 goto not_likely;
8149 case OPC_BC1TANY2:
a16336e4 8150 {
d94536f4
AJ
8151 TCGv_i32 t1 = tcg_temp_new_i32();
8152 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8153 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8154 tcg_gen_or_i32(t0, t0, t1);
8155 tcg_temp_free_i32(t1);
8156 tcg_gen_andi_i32(t0, t0, 1);
8157 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8158 }
5a5012ec
TS
8159 goto not_likely;
8160 case OPC_BC1FANY4:
a16336e4 8161 {
d94536f4
AJ
8162 TCGv_i32 t1 = tcg_temp_new_i32();
8163 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8164 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8165 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8166 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8167 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8168 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8169 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8170 tcg_temp_free_i32(t1);
d94536f4
AJ
8171 tcg_gen_andi_i32(t0, t0, 1);
8172 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8173 }
5a5012ec
TS
8174 goto not_likely;
8175 case OPC_BC1TANY4:
a16336e4 8176 {
d94536f4
AJ
8177 TCGv_i32 t1 = tcg_temp_new_i32();
8178 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8179 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8180 tcg_gen_or_i32(t0, t0, t1);
8181 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8182 tcg_gen_or_i32(t0, t0, t1);
8183 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8184 tcg_gen_or_i32(t0, t0, t1);
8185 tcg_temp_free_i32(t1);
8186 tcg_gen_andi_i32(t0, t0, 1);
8187 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8188 }
5a5012ec
TS
8189 not_likely:
8190 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8191 break;
8192 default:
9d68ac14 8193 MIPS_INVAL("cp1 cond branch");
9c708c7f 8194 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8195 goto out;
6ea83fed 8196 }
6ea83fed 8197 ctx->btarget = btarget;
b231c103 8198 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8199 out:
a7812ae4 8200 tcg_temp_free_i32(t0);
6ea83fed
FB
8201}
8202
31837be3
YK
8203/* R6 CP1 Branches */
8204static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8205 int32_t ft, int32_t offset,
8206 int delayslot_size)
31837be3
YK
8207{
8208 target_ulong btarget;
31837be3
YK
8209 TCGv_i64 t0 = tcg_temp_new_i64();
8210
8211 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8212#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8213 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8214 "\n", ctx->pc);
31837be3 8215#endif
9c708c7f 8216 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8217 goto out;
8218 }
8219
8220 gen_load_fpr64(ctx, t0, ft);
8221 tcg_gen_andi_i64(t0, t0, 1);
8222
8223 btarget = addr_add(ctx, ctx->pc + 4, offset);
8224
8225 switch (op) {
8226 case OPC_BC1EQZ:
8227 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8228 ctx->hflags |= MIPS_HFLAG_BC;
8229 break;
8230 case OPC_BC1NEZ:
8231 /* t0 already set */
31837be3
YK
8232 ctx->hflags |= MIPS_HFLAG_BC;
8233 break;
8234 default:
9d68ac14 8235 MIPS_INVAL("cp1 cond branch");
9c708c7f 8236 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8237 goto out;
8238 }
8239
8240 tcg_gen_trunc_i64_tl(bcond, t0);
8241
31837be3 8242 ctx->btarget = btarget;
65935f07
YK
8243
8244 switch (delayslot_size) {
8245 case 2:
8246 ctx->hflags |= MIPS_HFLAG_BDS16;
8247 break;
8248 case 4:
8249 ctx->hflags |= MIPS_HFLAG_BDS32;
8250 break;
8251 }
31837be3
YK
8252
8253out:
8254 tcg_temp_free_i64(t0);
8255}
8256
6af0bf9c 8257/* Coprocessor 1 (FPU) */
5a5012ec 8258
5a5012ec
TS
8259#define FOP(func, fmt) (((fmt) << 21) | (func))
8260
bf4120ad
NF
8261enum fopcode {
8262 OPC_ADD_S = FOP(0, FMT_S),
8263 OPC_SUB_S = FOP(1, FMT_S),
8264 OPC_MUL_S = FOP(2, FMT_S),
8265 OPC_DIV_S = FOP(3, FMT_S),
8266 OPC_SQRT_S = FOP(4, FMT_S),
8267 OPC_ABS_S = FOP(5, FMT_S),
8268 OPC_MOV_S = FOP(6, FMT_S),
8269 OPC_NEG_S = FOP(7, FMT_S),
8270 OPC_ROUND_L_S = FOP(8, FMT_S),
8271 OPC_TRUNC_L_S = FOP(9, FMT_S),
8272 OPC_CEIL_L_S = FOP(10, FMT_S),
8273 OPC_FLOOR_L_S = FOP(11, FMT_S),
8274 OPC_ROUND_W_S = FOP(12, FMT_S),
8275 OPC_TRUNC_W_S = FOP(13, FMT_S),
8276 OPC_CEIL_W_S = FOP(14, FMT_S),
8277 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8278 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8279 OPC_MOVCF_S = FOP(17, FMT_S),
8280 OPC_MOVZ_S = FOP(18, FMT_S),
8281 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8282 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8283 OPC_RECIP_S = FOP(21, FMT_S),
8284 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8285 OPC_SELNEZ_S = FOP(23, FMT_S),
8286 OPC_MADDF_S = FOP(24, FMT_S),
8287 OPC_MSUBF_S = FOP(25, FMT_S),
8288 OPC_RINT_S = FOP(26, FMT_S),
8289 OPC_CLASS_S = FOP(27, FMT_S),
8290 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8291 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8292 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8293 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8294 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8295 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8296 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8297 OPC_RSQRT2_S = FOP(31, FMT_S),
8298 OPC_CVT_D_S = FOP(33, FMT_S),
8299 OPC_CVT_W_S = FOP(36, FMT_S),
8300 OPC_CVT_L_S = FOP(37, FMT_S),
8301 OPC_CVT_PS_S = FOP(38, FMT_S),
8302 OPC_CMP_F_S = FOP (48, FMT_S),
8303 OPC_CMP_UN_S = FOP (49, FMT_S),
8304 OPC_CMP_EQ_S = FOP (50, FMT_S),
8305 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8306 OPC_CMP_OLT_S = FOP (52, FMT_S),
8307 OPC_CMP_ULT_S = FOP (53, FMT_S),
8308 OPC_CMP_OLE_S = FOP (54, FMT_S),
8309 OPC_CMP_ULE_S = FOP (55, FMT_S),
8310 OPC_CMP_SF_S = FOP (56, FMT_S),
8311 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8312 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8313 OPC_CMP_NGL_S = FOP (59, FMT_S),
8314 OPC_CMP_LT_S = FOP (60, FMT_S),
8315 OPC_CMP_NGE_S = FOP (61, FMT_S),
8316 OPC_CMP_LE_S = FOP (62, FMT_S),
8317 OPC_CMP_NGT_S = FOP (63, FMT_S),
8318
8319 OPC_ADD_D = FOP(0, FMT_D),
8320 OPC_SUB_D = FOP(1, FMT_D),
8321 OPC_MUL_D = FOP(2, FMT_D),
8322 OPC_DIV_D = FOP(3, FMT_D),
8323 OPC_SQRT_D = FOP(4, FMT_D),
8324 OPC_ABS_D = FOP(5, FMT_D),
8325 OPC_MOV_D = FOP(6, FMT_D),
8326 OPC_NEG_D = FOP(7, FMT_D),
8327 OPC_ROUND_L_D = FOP(8, FMT_D),
8328 OPC_TRUNC_L_D = FOP(9, FMT_D),
8329 OPC_CEIL_L_D = FOP(10, FMT_D),
8330 OPC_FLOOR_L_D = FOP(11, FMT_D),
8331 OPC_ROUND_W_D = FOP(12, FMT_D),
8332 OPC_TRUNC_W_D = FOP(13, FMT_D),
8333 OPC_CEIL_W_D = FOP(14, FMT_D),
8334 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8335 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8336 OPC_MOVCF_D = FOP(17, FMT_D),
8337 OPC_MOVZ_D = FOP(18, FMT_D),
8338 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8339 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8340 OPC_RECIP_D = FOP(21, FMT_D),
8341 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8342 OPC_SELNEZ_D = FOP(23, FMT_D),
8343 OPC_MADDF_D = FOP(24, FMT_D),
8344 OPC_MSUBF_D = FOP(25, FMT_D),
8345 OPC_RINT_D = FOP(26, FMT_D),
8346 OPC_CLASS_D = FOP(27, FMT_D),
8347 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8348 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8349 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8350 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8351 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8352 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8353 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8354 OPC_RSQRT2_D = FOP(31, FMT_D),
8355 OPC_CVT_S_D = FOP(32, FMT_D),
8356 OPC_CVT_W_D = FOP(36, FMT_D),
8357 OPC_CVT_L_D = FOP(37, FMT_D),
8358 OPC_CMP_F_D = FOP (48, FMT_D),
8359 OPC_CMP_UN_D = FOP (49, FMT_D),
8360 OPC_CMP_EQ_D = FOP (50, FMT_D),
8361 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8362 OPC_CMP_OLT_D = FOP (52, FMT_D),
8363 OPC_CMP_ULT_D = FOP (53, FMT_D),
8364 OPC_CMP_OLE_D = FOP (54, FMT_D),
8365 OPC_CMP_ULE_D = FOP (55, FMT_D),
8366 OPC_CMP_SF_D = FOP (56, FMT_D),
8367 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8368 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8369 OPC_CMP_NGL_D = FOP (59, FMT_D),
8370 OPC_CMP_LT_D = FOP (60, FMT_D),
8371 OPC_CMP_NGE_D = FOP (61, FMT_D),
8372 OPC_CMP_LE_D = FOP (62, FMT_D),
8373 OPC_CMP_NGT_D = FOP (63, FMT_D),
8374
8375 OPC_CVT_S_W = FOP(32, FMT_W),
8376 OPC_CVT_D_W = FOP(33, FMT_W),
8377 OPC_CVT_S_L = FOP(32, FMT_L),
8378 OPC_CVT_D_L = FOP(33, FMT_L),
8379 OPC_CVT_PS_PW = FOP(38, FMT_W),
8380
8381 OPC_ADD_PS = FOP(0, FMT_PS),
8382 OPC_SUB_PS = FOP(1, FMT_PS),
8383 OPC_MUL_PS = FOP(2, FMT_PS),
8384 OPC_DIV_PS = FOP(3, FMT_PS),
8385 OPC_ABS_PS = FOP(5, FMT_PS),
8386 OPC_MOV_PS = FOP(6, FMT_PS),
8387 OPC_NEG_PS = FOP(7, FMT_PS),
8388 OPC_MOVCF_PS = FOP(17, FMT_PS),
8389 OPC_MOVZ_PS = FOP(18, FMT_PS),
8390 OPC_MOVN_PS = FOP(19, FMT_PS),
8391 OPC_ADDR_PS = FOP(24, FMT_PS),
8392 OPC_MULR_PS = FOP(26, FMT_PS),
8393 OPC_RECIP2_PS = FOP(28, FMT_PS),
8394 OPC_RECIP1_PS = FOP(29, FMT_PS),
8395 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8396 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8397
8398 OPC_CVT_S_PU = FOP(32, FMT_PS),
8399 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8400 OPC_CVT_S_PL = FOP(40, FMT_PS),
8401 OPC_PLL_PS = FOP(44, FMT_PS),
8402 OPC_PLU_PS = FOP(45, FMT_PS),
8403 OPC_PUL_PS = FOP(46, FMT_PS),
8404 OPC_PUU_PS = FOP(47, FMT_PS),
8405 OPC_CMP_F_PS = FOP (48, FMT_PS),
8406 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8407 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8408 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8409 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8410 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8411 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8412 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8413 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8414 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8415 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8416 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8417 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8418 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8419 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8420 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8421};
8422
3f493883
YK
8423enum r6_f_cmp_op {
8424 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8425 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8426 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8427 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8428 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8429 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8430 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8431 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8432 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8433 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8434 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8435 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8436 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8437 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8438 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8439 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8440 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8441 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8442 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8443 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8444 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8445 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8446
8447 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8448 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8449 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8450 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8451 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8452 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8453 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8454 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8455 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8456 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8457 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8458 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8459 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8460 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8461 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8462 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8463 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8464 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8465 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8466 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8467 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8468 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8469};
7a387fff 8470static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8471{
72c3a3ee 8472 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8473
8474 switch (opc) {
8475 case OPC_MFC1:
b6d96bed 8476 {
a7812ae4 8477 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8478
7c979afd 8479 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8480 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8481 tcg_temp_free_i32(fp0);
6958549d 8482 }
6c5c1e20 8483 gen_store_gpr(t0, rt);
6ea83fed
FB
8484 break;
8485 case OPC_MTC1:
6c5c1e20 8486 gen_load_gpr(t0, rt);
b6d96bed 8487 {
a7812ae4 8488 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8489
8490 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8491 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8492 tcg_temp_free_i32(fp0);
6958549d 8493 }
6ea83fed
FB
8494 break;
8495 case OPC_CFC1:
895c2d04 8496 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8497 gen_store_gpr(t0, rt);
6ea83fed
FB
8498 break;
8499 case OPC_CTC1:
6c5c1e20 8500 gen_load_gpr(t0, rt);
9c708c7f 8501 save_cpu_state(ctx, 0);
736d120a
PJ
8502 {
8503 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8504
8505 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8506 tcg_temp_free_i32(fs_tmp);
8507 }
4cf8a45f
YK
8508 /* Stop translation as we may have changed hflags */
8509 ctx->bstate = BS_STOP;
6ea83fed 8510 break;
72c3a3ee 8511#if defined(TARGET_MIPS64)
9c2149c8 8512 case OPC_DMFC1:
72c3a3ee 8513 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8514 gen_store_gpr(t0, rt);
5a5012ec 8515 break;
9c2149c8 8516 case OPC_DMTC1:
6c5c1e20 8517 gen_load_gpr(t0, rt);
72c3a3ee 8518 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8519 break;
72c3a3ee 8520#endif
5a5012ec 8521 case OPC_MFHC1:
b6d96bed 8522 {
a7812ae4 8523 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8524
7f6613ce 8525 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8526 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8527 tcg_temp_free_i32(fp0);
6958549d 8528 }
6c5c1e20 8529 gen_store_gpr(t0, rt);
5a5012ec
TS
8530 break;
8531 case OPC_MTHC1:
6c5c1e20 8532 gen_load_gpr(t0, rt);
b6d96bed 8533 {
a7812ae4 8534 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8535
8536 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8537 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8538 tcg_temp_free_i32(fp0);
6958549d 8539 }
5a5012ec 8540 break;
6ea83fed 8541 default:
9d68ac14 8542 MIPS_INVAL("cp1 move");
9c708c7f 8543 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8544 goto out;
6ea83fed 8545 }
6c5c1e20
TS
8546
8547 out:
8548 tcg_temp_free(t0);
6ea83fed
FB
8549}
8550
5a5012ec
TS
8551static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8552{
42a268c2 8553 TCGLabel *l1;
e214b9bb 8554 TCGCond cond;
af58f9ca
AJ
8555 TCGv_i32 t0;
8556
8557 if (rd == 0) {
8558 /* Treat as NOP. */
8559 return;
8560 }
6ea83fed 8561
e214b9bb 8562 if (tf)
e214b9bb 8563 cond = TCG_COND_EQ;
27848470
TS
8564 else
8565 cond = TCG_COND_NE;
8566
af58f9ca
AJ
8567 l1 = gen_new_label();
8568 t0 = tcg_temp_new_i32();
fa31af0e 8569 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8570 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8571 tcg_temp_free_i32(t0);
af58f9ca
AJ
8572 if (rs == 0) {
8573 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8574 } else {
8575 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8576 }
e214b9bb 8577 gen_set_label(l1);
5a5012ec
TS
8578}
8579
7c979afd
LA
8580static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8581 int tf)
a16336e4 8582{
a16336e4 8583 int cond;
cbc37b28 8584 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8585 TCGLabel *l1 = gen_new_label();
a16336e4 8586
a16336e4
TS
8587 if (tf)
8588 cond = TCG_COND_EQ;
8589 else
8590 cond = TCG_COND_NE;
8591
fa31af0e 8592 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8593 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8594 gen_load_fpr32(ctx, t0, fs);
8595 gen_store_fpr32(ctx, t0, fd);
a16336e4 8596 gen_set_label(l1);
cbc37b28 8597 tcg_temp_free_i32(t0);
5a5012ec 8598}
a16336e4 8599
b6d96bed 8600static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8601{
a16336e4 8602 int cond;
cbc37b28
AJ
8603 TCGv_i32 t0 = tcg_temp_new_i32();
8604 TCGv_i64 fp0;
42a268c2 8605 TCGLabel *l1 = gen_new_label();
a16336e4 8606
a16336e4
TS
8607 if (tf)
8608 cond = TCG_COND_EQ;
8609 else
8610 cond = TCG_COND_NE;
8611
fa31af0e 8612 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8613 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8614 tcg_temp_free_i32(t0);
11f94258 8615 fp0 = tcg_temp_new_i64();
9bf3eb2c 8616 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8617 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8618 tcg_temp_free_i64(fp0);
cbc37b28 8619 gen_set_label(l1);
a16336e4
TS
8620}
8621
7f6613ce
PJ
8622static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8623 int cc, int tf)
a16336e4
TS
8624{
8625 int cond;
cbc37b28 8626 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8627 TCGLabel *l1 = gen_new_label();
8628 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8629
8630 if (tf)
8631 cond = TCG_COND_EQ;
8632 else
8633 cond = TCG_COND_NE;
8634
fa31af0e 8635 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8636 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8637 gen_load_fpr32(ctx, t0, fs);
8638 gen_store_fpr32(ctx, t0, fd);
a16336e4 8639 gen_set_label(l1);
9bf3eb2c 8640
fa31af0e 8641 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8642 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8643 gen_load_fpr32h(ctx, t0, fs);
8644 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8645 tcg_temp_free_i32(t0);
a16336e4 8646 gen_set_label(l2);
a16336e4
TS
8647}
8648
e7f16abb
LA
8649static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8650 int fs)
8651{
8652 TCGv_i32 t1 = tcg_const_i32(0);
8653 TCGv_i32 fp0 = tcg_temp_new_i32();
8654 TCGv_i32 fp1 = tcg_temp_new_i32();
8655 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8656 gen_load_fpr32(ctx, fp0, fd);
8657 gen_load_fpr32(ctx, fp1, ft);
8658 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8659
8660 switch (op1) {
8661 case OPC_SEL_S:
8662 tcg_gen_andi_i32(fp0, fp0, 1);
8663 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8664 break;
8665 case OPC_SELEQZ_S:
8666 tcg_gen_andi_i32(fp1, fp1, 1);
8667 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8668 break;
8669 case OPC_SELNEZ_S:
8670 tcg_gen_andi_i32(fp1, fp1, 1);
8671 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8672 break;
8673 default:
8674 MIPS_INVAL("gen_sel_s");
9c708c7f 8675 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8676 break;
8677 }
8678
7c979afd 8679 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8680 tcg_temp_free_i32(fp2);
8681 tcg_temp_free_i32(fp1);
8682 tcg_temp_free_i32(fp0);
8683 tcg_temp_free_i32(t1);
8684}
8685
8686static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8687 int fs)
8688{
8689 TCGv_i64 t1 = tcg_const_i64(0);
8690 TCGv_i64 fp0 = tcg_temp_new_i64();
8691 TCGv_i64 fp1 = tcg_temp_new_i64();
8692 TCGv_i64 fp2 = tcg_temp_new_i64();
8693 gen_load_fpr64(ctx, fp0, fd);
8694 gen_load_fpr64(ctx, fp1, ft);
8695 gen_load_fpr64(ctx, fp2, fs);
8696
8697 switch (op1) {
8698 case OPC_SEL_D:
8699 tcg_gen_andi_i64(fp0, fp0, 1);
8700 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8701 break;
8702 case OPC_SELEQZ_D:
8703 tcg_gen_andi_i64(fp1, fp1, 1);
8704 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8705 break;
8706 case OPC_SELNEZ_D:
8707 tcg_gen_andi_i64(fp1, fp1, 1);
8708 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8709 break;
8710 default:
8711 MIPS_INVAL("gen_sel_d");
9c708c7f 8712 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8713 break;
8714 }
8715
8716 gen_store_fpr64(ctx, fp0, fd);
8717 tcg_temp_free_i64(fp2);
8718 tcg_temp_free_i64(fp1);
8719 tcg_temp_free_i64(fp0);
8720 tcg_temp_free_i64(t1);
8721}
6ea83fed 8722
bf4120ad 8723static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8724 int ft, int fs, int fd, int cc)
6ea83fed 8725{
7a387fff 8726 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8727 switch (op1) {
8728 case OPC_ADD_S:
b6d96bed 8729 {
a7812ae4
PB
8730 TCGv_i32 fp0 = tcg_temp_new_i32();
8731 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8732
7c979afd
LA
8733 gen_load_fpr32(ctx, fp0, fs);
8734 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8735 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8736 tcg_temp_free_i32(fp1);
7c979afd 8737 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8738 tcg_temp_free_i32(fp0);
b6d96bed 8739 }
5a5012ec 8740 break;
bf4120ad 8741 case OPC_SUB_S:
b6d96bed 8742 {
a7812ae4
PB
8743 TCGv_i32 fp0 = tcg_temp_new_i32();
8744 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8745
7c979afd
LA
8746 gen_load_fpr32(ctx, fp0, fs);
8747 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8748 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8749 tcg_temp_free_i32(fp1);
7c979afd 8750 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8751 tcg_temp_free_i32(fp0);
b6d96bed 8752 }
5a5012ec 8753 break;
bf4120ad 8754 case OPC_MUL_S:
b6d96bed 8755 {
a7812ae4
PB
8756 TCGv_i32 fp0 = tcg_temp_new_i32();
8757 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8758
7c979afd
LA
8759 gen_load_fpr32(ctx, fp0, fs);
8760 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8761 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8762 tcg_temp_free_i32(fp1);
7c979afd 8763 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8764 tcg_temp_free_i32(fp0);
b6d96bed 8765 }
5a5012ec 8766 break;
bf4120ad 8767 case OPC_DIV_S:
b6d96bed 8768 {
a7812ae4
PB
8769 TCGv_i32 fp0 = tcg_temp_new_i32();
8770 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8771
7c979afd
LA
8772 gen_load_fpr32(ctx, fp0, fs);
8773 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8774 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8775 tcg_temp_free_i32(fp1);
7c979afd 8776 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8777 tcg_temp_free_i32(fp0);
b6d96bed 8778 }
5a5012ec 8779 break;
bf4120ad 8780 case OPC_SQRT_S:
b6d96bed 8781 {
a7812ae4 8782 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8783
7c979afd 8784 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8785 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 8786 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8787 tcg_temp_free_i32(fp0);
b6d96bed 8788 }
5a5012ec 8789 break;
bf4120ad 8790 case OPC_ABS_S:
b6d96bed 8791 {
a7812ae4 8792 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8793
7c979afd 8794 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8795 gen_helper_float_abs_s(fp0, fp0);
7c979afd 8796 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8797 tcg_temp_free_i32(fp0);
b6d96bed 8798 }
5a5012ec 8799 break;
bf4120ad 8800 case OPC_MOV_S:
b6d96bed 8801 {
a7812ae4 8802 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8803
7c979afd
LA
8804 gen_load_fpr32(ctx, fp0, fs);
8805 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8806 tcg_temp_free_i32(fp0);
b6d96bed 8807 }
5a5012ec 8808 break;
bf4120ad 8809 case OPC_NEG_S:
b6d96bed 8810 {
a7812ae4 8811 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8812
7c979afd 8813 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 8814 gen_helper_float_chs_s(fp0, fp0);
7c979afd 8815 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8816 tcg_temp_free_i32(fp0);
b6d96bed 8817 }
5a5012ec 8818 break;
bf4120ad 8819 case OPC_ROUND_L_S:
5e755519 8820 check_cp1_64bitmode(ctx);
b6d96bed 8821 {
a7812ae4
PB
8822 TCGv_i32 fp32 = tcg_temp_new_i32();
8823 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8824
7c979afd 8825 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8826 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8827 tcg_temp_free_i32(fp32);
b6d96bed 8828 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8829 tcg_temp_free_i64(fp64);
b6d96bed 8830 }
5a5012ec 8831 break;
bf4120ad 8832 case OPC_TRUNC_L_S:
5e755519 8833 check_cp1_64bitmode(ctx);
b6d96bed 8834 {
a7812ae4
PB
8835 TCGv_i32 fp32 = tcg_temp_new_i32();
8836 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8837
7c979afd 8838 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8839 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8840 tcg_temp_free_i32(fp32);
b6d96bed 8841 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8842 tcg_temp_free_i64(fp64);
b6d96bed 8843 }
5a5012ec 8844 break;
bf4120ad 8845 case OPC_CEIL_L_S:
5e755519 8846 check_cp1_64bitmode(ctx);
b6d96bed 8847 {
a7812ae4
PB
8848 TCGv_i32 fp32 = tcg_temp_new_i32();
8849 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8850
7c979afd 8851 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8852 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8853 tcg_temp_free_i32(fp32);
b6d96bed 8854 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8855 tcg_temp_free_i64(fp64);
b6d96bed 8856 }
5a5012ec 8857 break;
bf4120ad 8858 case OPC_FLOOR_L_S:
5e755519 8859 check_cp1_64bitmode(ctx);
b6d96bed 8860 {
a7812ae4
PB
8861 TCGv_i32 fp32 = tcg_temp_new_i32();
8862 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 8863
7c979afd 8864 gen_load_fpr32(ctx, fp32, fs);
895c2d04 8865 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8866 tcg_temp_free_i32(fp32);
b6d96bed 8867 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8868 tcg_temp_free_i64(fp64);
b6d96bed 8869 }
5a5012ec 8870 break;
bf4120ad 8871 case OPC_ROUND_W_S:
b6d96bed 8872 {
a7812ae4 8873 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8874
7c979afd 8875 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8876 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 8877 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8878 tcg_temp_free_i32(fp0);
b6d96bed 8879 }
5a5012ec 8880 break;
bf4120ad 8881 case OPC_TRUNC_W_S:
b6d96bed 8882 {
a7812ae4 8883 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8884
7c979afd 8885 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8886 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 8887 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8888 tcg_temp_free_i32(fp0);
b6d96bed 8889 }
5a5012ec 8890 break;
bf4120ad 8891 case OPC_CEIL_W_S:
b6d96bed 8892 {
a7812ae4 8893 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8894
7c979afd 8895 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8896 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 8897 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8898 tcg_temp_free_i32(fp0);
b6d96bed 8899 }
5a5012ec 8900 break;
bf4120ad 8901 case OPC_FLOOR_W_S:
b6d96bed 8902 {
a7812ae4 8903 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8904
7c979afd 8905 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8906 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 8907 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8908 tcg_temp_free_i32(fp0);
b6d96bed 8909 }
5a5012ec 8910 break;
e7f16abb
LA
8911 case OPC_SEL_S:
8912 check_insn(ctx, ISA_MIPS32R6);
8913 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8914 break;
8915 case OPC_SELEQZ_S:
8916 check_insn(ctx, ISA_MIPS32R6);
8917 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
8918 break;
8919 case OPC_SELNEZ_S:
8920 check_insn(ctx, ISA_MIPS32R6);
8921 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 8922 break;
bf4120ad 8923 case OPC_MOVCF_S:
fecd2646 8924 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 8925 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8926 break;
bf4120ad 8927 case OPC_MOVZ_S:
fecd2646 8928 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8929 {
42a268c2 8930 TCGLabel *l1 = gen_new_label();
c9297f4d 8931 TCGv_i32 fp0;
a16336e4 8932
c9297f4d
AJ
8933 if (ft != 0) {
8934 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8935 }
8936 fp0 = tcg_temp_new_i32();
7c979afd
LA
8937 gen_load_fpr32(ctx, fp0, fs);
8938 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8939 tcg_temp_free_i32(fp0);
a16336e4
TS
8940 gen_set_label(l1);
8941 }
5a5012ec 8942 break;
bf4120ad 8943 case OPC_MOVN_S:
fecd2646 8944 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 8945 {
42a268c2 8946 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
8947 TCGv_i32 fp0;
8948
8949 if (ft != 0) {
8950 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8951 fp0 = tcg_temp_new_i32();
7c979afd
LA
8952 gen_load_fpr32(ctx, fp0, fs);
8953 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
8954 tcg_temp_free_i32(fp0);
8955 gen_set_label(l1);
8956 }
a16336e4 8957 }
5a5012ec 8958 break;
bf4120ad 8959 case OPC_RECIP_S:
b6d96bed 8960 {
a7812ae4 8961 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8962
7c979afd 8963 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8964 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 8965 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8966 tcg_temp_free_i32(fp0);
b6d96bed 8967 }
57fa1fb3 8968 break;
bf4120ad 8969 case OPC_RSQRT_S:
b6d96bed 8970 {
a7812ae4 8971 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8972
7c979afd 8973 gen_load_fpr32(ctx, fp0, fs);
895c2d04 8974 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 8975 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8976 tcg_temp_free_i32(fp0);
b6d96bed 8977 }
57fa1fb3 8978 break;
e7f16abb
LA
8979 case OPC_MADDF_S:
8980 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8981 {
a7812ae4
PB
8982 TCGv_i32 fp0 = tcg_temp_new_i32();
8983 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8984 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8985 gen_load_fpr32(ctx, fp0, fs);
8986 gen_load_fpr32(ctx, fp1, ft);
8987 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 8988 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 8989 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 8990 tcg_temp_free_i32(fp2);
a7812ae4 8991 tcg_temp_free_i32(fp1);
a7812ae4 8992 tcg_temp_free_i32(fp0);
b6d96bed 8993 }
57fa1fb3 8994 break;
e7f16abb
LA
8995 case OPC_MSUBF_S:
8996 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8997 {
a7812ae4 8998 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8999 TCGv_i32 fp1 = tcg_temp_new_i32();
9000 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9001 gen_load_fpr32(ctx, fp0, fs);
9002 gen_load_fpr32(ctx, fp1, ft);
9003 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9004 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9005 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9006 tcg_temp_free_i32(fp2);
9007 tcg_temp_free_i32(fp1);
a7812ae4 9008 tcg_temp_free_i32(fp0);
b6d96bed 9009 }
57fa1fb3 9010 break;
e7f16abb
LA
9011 case OPC_RINT_S:
9012 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9013 {
a7812ae4 9014 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9015 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9016 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9017 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9018 tcg_temp_free_i32(fp0);
b6d96bed 9019 }
57fa1fb3 9020 break;
e7f16abb
LA
9021 case OPC_CLASS_S:
9022 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9023 {
e7f16abb 9024 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9025 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9026 gen_helper_float_class_s(fp0, fp0);
7c979afd 9027 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9028 tcg_temp_free_i32(fp0);
e7f16abb
LA
9029 }
9030 break;
9031 case OPC_MIN_S: /* OPC_RECIP2_S */
9032 if (ctx->insn_flags & ISA_MIPS32R6) {
9033 /* OPC_MIN_S */
a7812ae4
PB
9034 TCGv_i32 fp0 = tcg_temp_new_i32();
9035 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9036 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9037 gen_load_fpr32(ctx, fp0, fs);
9038 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9039 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9040 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9041 tcg_temp_free_i32(fp2);
9042 tcg_temp_free_i32(fp1);
9043 tcg_temp_free_i32(fp0);
e7f16abb
LA
9044 } else {
9045 /* OPC_RECIP2_S */
9046 check_cp1_64bitmode(ctx);
9047 {
9048 TCGv_i32 fp0 = tcg_temp_new_i32();
9049 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9050
7c979afd
LA
9051 gen_load_fpr32(ctx, fp0, fs);
9052 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9053 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9054 tcg_temp_free_i32(fp1);
7c979afd 9055 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9056 tcg_temp_free_i32(fp0);
9057 }
e7f16abb
LA
9058 }
9059 break;
9060 case OPC_MINA_S: /* OPC_RECIP1_S */
9061 if (ctx->insn_flags & ISA_MIPS32R6) {
9062 /* OPC_MINA_S */
9063 TCGv_i32 fp0 = tcg_temp_new_i32();
9064 TCGv_i32 fp1 = tcg_temp_new_i32();
9065 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9066 gen_load_fpr32(ctx, fp0, fs);
9067 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9068 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9069 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9070 tcg_temp_free_i32(fp2);
9071 tcg_temp_free_i32(fp1);
9072 tcg_temp_free_i32(fp0);
e7f16abb
LA
9073 } else {
9074 /* OPC_RECIP1_S */
9075 check_cp1_64bitmode(ctx);
9076 {
9077 TCGv_i32 fp0 = tcg_temp_new_i32();
9078
7c979afd 9079 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9080 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9081 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9082 tcg_temp_free_i32(fp0);
9083 }
e7f16abb
LA
9084 }
9085 break;
9086 case OPC_MAX_S: /* OPC_RSQRT1_S */
9087 if (ctx->insn_flags & ISA_MIPS32R6) {
9088 /* OPC_MAX_S */
9089 TCGv_i32 fp0 = tcg_temp_new_i32();
9090 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9091 gen_load_fpr32(ctx, fp0, fs);
9092 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9093 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9094 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9095 tcg_temp_free_i32(fp1);
9096 tcg_temp_free_i32(fp0);
e7f16abb
LA
9097 } else {
9098 /* OPC_RSQRT1_S */
9099 check_cp1_64bitmode(ctx);
9100 {
9101 TCGv_i32 fp0 = tcg_temp_new_i32();
9102
7c979afd 9103 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9104 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9105 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9106 tcg_temp_free_i32(fp0);
9107 }
e7f16abb
LA
9108 }
9109 break;
9110 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9111 if (ctx->insn_flags & ISA_MIPS32R6) {
9112 /* OPC_MAXA_S */
9113 TCGv_i32 fp0 = tcg_temp_new_i32();
9114 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9115 gen_load_fpr32(ctx, fp0, fs);
9116 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9117 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9118 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9119 tcg_temp_free_i32(fp1);
a7812ae4 9120 tcg_temp_free_i32(fp0);
e7f16abb
LA
9121 } else {
9122 /* OPC_RSQRT2_S */
9123 check_cp1_64bitmode(ctx);
9124 {
9125 TCGv_i32 fp0 = tcg_temp_new_i32();
9126 TCGv_i32 fp1 = tcg_temp_new_i32();
9127
7c979afd
LA
9128 gen_load_fpr32(ctx, fp0, fs);
9129 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9130 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9131 tcg_temp_free_i32(fp1);
7c979afd 9132 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9133 tcg_temp_free_i32(fp0);
9134 }
b6d96bed 9135 }
57fa1fb3 9136 break;
bf4120ad 9137 case OPC_CVT_D_S:
5e755519 9138 check_cp1_registers(ctx, fd);
b6d96bed 9139 {
a7812ae4
PB
9140 TCGv_i32 fp32 = tcg_temp_new_i32();
9141 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9142
7c979afd 9143 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9144 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9145 tcg_temp_free_i32(fp32);
b6d96bed 9146 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9147 tcg_temp_free_i64(fp64);
b6d96bed 9148 }
5a5012ec 9149 break;
bf4120ad 9150 case OPC_CVT_W_S:
b6d96bed 9151 {
a7812ae4 9152 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9153
7c979afd 9154 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9155 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9156 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9157 tcg_temp_free_i32(fp0);
b6d96bed 9158 }
5a5012ec 9159 break;
bf4120ad 9160 case OPC_CVT_L_S:
5e755519 9161 check_cp1_64bitmode(ctx);
b6d96bed 9162 {
a7812ae4
PB
9163 TCGv_i32 fp32 = tcg_temp_new_i32();
9164 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9165
7c979afd 9166 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9167 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9168 tcg_temp_free_i32(fp32);
b6d96bed 9169 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9170 tcg_temp_free_i64(fp64);
b6d96bed 9171 }
5a5012ec 9172 break;
bf4120ad 9173 case OPC_CVT_PS_S:
e29c9628 9174 check_ps(ctx);
b6d96bed 9175 {
a7812ae4
PB
9176 TCGv_i64 fp64 = tcg_temp_new_i64();
9177 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9178 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9179
7c979afd
LA
9180 gen_load_fpr32(ctx, fp32_0, fs);
9181 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9182 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9183 tcg_temp_free_i32(fp32_1);
9184 tcg_temp_free_i32(fp32_0);
36aa55dc 9185 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9186 tcg_temp_free_i64(fp64);
b6d96bed 9187 }
5a5012ec 9188 break;
bf4120ad
NF
9189 case OPC_CMP_F_S:
9190 case OPC_CMP_UN_S:
9191 case OPC_CMP_EQ_S:
9192 case OPC_CMP_UEQ_S:
9193 case OPC_CMP_OLT_S:
9194 case OPC_CMP_ULT_S:
9195 case OPC_CMP_OLE_S:
9196 case OPC_CMP_ULE_S:
9197 case OPC_CMP_SF_S:
9198 case OPC_CMP_NGLE_S:
9199 case OPC_CMP_SEQ_S:
9200 case OPC_CMP_NGL_S:
9201 case OPC_CMP_LT_S:
9202 case OPC_CMP_NGE_S:
9203 case OPC_CMP_LE_S:
9204 case OPC_CMP_NGT_S:
fecd2646 9205 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9206 if (ctx->opcode & (1 << 6)) {
9207 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9208 } else {
9209 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9210 }
5a5012ec 9211 break;
bf4120ad 9212 case OPC_ADD_D:
5e755519 9213 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9214 {
a7812ae4
PB
9215 TCGv_i64 fp0 = tcg_temp_new_i64();
9216 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9217
9218 gen_load_fpr64(ctx, fp0, fs);
9219 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9220 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9221 tcg_temp_free_i64(fp1);
b6d96bed 9222 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9223 tcg_temp_free_i64(fp0);
b6d96bed 9224 }
6ea83fed 9225 break;
bf4120ad 9226 case OPC_SUB_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_sub_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_MUL_D:
5e755519 9241 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9242 {
a7812ae4
PB
9243 TCGv_i64 fp0 = tcg_temp_new_i64();
9244 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9245
9246 gen_load_fpr64(ctx, fp0, fs);
9247 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9248 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9249 tcg_temp_free_i64(fp1);
b6d96bed 9250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9251 tcg_temp_free_i64(fp0);
b6d96bed 9252 }
6ea83fed 9253 break;
bf4120ad 9254 case OPC_DIV_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_div_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_SQRT_D:
5e755519 9269 check_cp1_registers(ctx, fs | fd);
b6d96bed 9270 {
a7812ae4 9271 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9272
9273 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9274 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9275 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9276 tcg_temp_free_i64(fp0);
b6d96bed 9277 }
6ea83fed 9278 break;
bf4120ad 9279 case OPC_ABS_D:
5e755519 9280 check_cp1_registers(ctx, fs | fd);
b6d96bed 9281 {
a7812ae4 9282 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9283
9284 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9285 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9286 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9287 tcg_temp_free_i64(fp0);
b6d96bed 9288 }
6ea83fed 9289 break;
bf4120ad 9290 case OPC_MOV_D:
5e755519 9291 check_cp1_registers(ctx, fs | fd);
b6d96bed 9292 {
a7812ae4 9293 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9294
9295 gen_load_fpr64(ctx, fp0, fs);
9296 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9297 tcg_temp_free_i64(fp0);
b6d96bed 9298 }
6ea83fed 9299 break;
bf4120ad 9300 case OPC_NEG_D:
5e755519 9301 check_cp1_registers(ctx, fs | fd);
b6d96bed 9302 {
a7812ae4 9303 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9304
9305 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9306 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9307 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9308 tcg_temp_free_i64(fp0);
b6d96bed 9309 }
6ea83fed 9310 break;
bf4120ad 9311 case OPC_ROUND_L_D:
5e755519 9312 check_cp1_64bitmode(ctx);
b6d96bed 9313 {
a7812ae4 9314 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9315
9316 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9317 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9318 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9319 tcg_temp_free_i64(fp0);
b6d96bed 9320 }
5a5012ec 9321 break;
bf4120ad 9322 case OPC_TRUNC_L_D:
5e755519 9323 check_cp1_64bitmode(ctx);
b6d96bed 9324 {
a7812ae4 9325 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9326
9327 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9328 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9329 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9330 tcg_temp_free_i64(fp0);
b6d96bed 9331 }
5a5012ec 9332 break;
bf4120ad 9333 case OPC_CEIL_L_D:
5e755519 9334 check_cp1_64bitmode(ctx);
b6d96bed 9335 {
a7812ae4 9336 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9337
9338 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9339 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9340 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9341 tcg_temp_free_i64(fp0);
b6d96bed 9342 }
5a5012ec 9343 break;
bf4120ad 9344 case OPC_FLOOR_L_D:
5e755519 9345 check_cp1_64bitmode(ctx);
b6d96bed 9346 {
a7812ae4 9347 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9348
9349 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9350 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9351 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9352 tcg_temp_free_i64(fp0);
b6d96bed 9353 }
5a5012ec 9354 break;
bf4120ad 9355 case OPC_ROUND_W_D:
5e755519 9356 check_cp1_registers(ctx, fs);
b6d96bed 9357 {
a7812ae4
PB
9358 TCGv_i32 fp32 = tcg_temp_new_i32();
9359 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9360
9361 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9362 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9363 tcg_temp_free_i64(fp64);
7c979afd 9364 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9365 tcg_temp_free_i32(fp32);
b6d96bed 9366 }
6ea83fed 9367 break;
bf4120ad 9368 case OPC_TRUNC_W_D:
5e755519 9369 check_cp1_registers(ctx, fs);
b6d96bed 9370 {
a7812ae4
PB
9371 TCGv_i32 fp32 = tcg_temp_new_i32();
9372 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9373
9374 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9375 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9376 tcg_temp_free_i64(fp64);
7c979afd 9377 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9378 tcg_temp_free_i32(fp32);
b6d96bed 9379 }
6ea83fed 9380 break;
bf4120ad 9381 case OPC_CEIL_W_D:
5e755519 9382 check_cp1_registers(ctx, fs);
b6d96bed 9383 {
a7812ae4
PB
9384 TCGv_i32 fp32 = tcg_temp_new_i32();
9385 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9386
9387 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9388 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9389 tcg_temp_free_i64(fp64);
7c979afd 9390 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9391 tcg_temp_free_i32(fp32);
b6d96bed 9392 }
6ea83fed 9393 break;
bf4120ad 9394 case OPC_FLOOR_W_D:
5e755519 9395 check_cp1_registers(ctx, fs);
b6d96bed 9396 {
a7812ae4
PB
9397 TCGv_i32 fp32 = tcg_temp_new_i32();
9398 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9399
9400 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9401 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9402 tcg_temp_free_i64(fp64);
7c979afd 9403 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9404 tcg_temp_free_i32(fp32);
b6d96bed 9405 }
6ea83fed 9406 break;
e7f16abb
LA
9407 case OPC_SEL_D:
9408 check_insn(ctx, ISA_MIPS32R6);
9409 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9410 break;
9411 case OPC_SELEQZ_D:
9412 check_insn(ctx, ISA_MIPS32R6);
9413 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9414 break;
9415 case OPC_SELNEZ_D:
9416 check_insn(ctx, ISA_MIPS32R6);
9417 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9418 break;
bf4120ad 9419 case OPC_MOVCF_D:
fecd2646 9420 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9421 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9422 break;
bf4120ad 9423 case OPC_MOVZ_D:
fecd2646 9424 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9425 {
42a268c2 9426 TCGLabel *l1 = gen_new_label();
c9297f4d 9427 TCGv_i64 fp0;
a16336e4 9428
c9297f4d
AJ
9429 if (ft != 0) {
9430 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9431 }
9432 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9433 gen_load_fpr64(ctx, fp0, fs);
9434 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9435 tcg_temp_free_i64(fp0);
a16336e4
TS
9436 gen_set_label(l1);
9437 }
5a5012ec 9438 break;
bf4120ad 9439 case OPC_MOVN_D:
fecd2646 9440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9441 {
42a268c2 9442 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9443 TCGv_i64 fp0;
9444
9445 if (ft != 0) {
9446 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9447 fp0 = tcg_temp_new_i64();
9448 gen_load_fpr64(ctx, fp0, fs);
9449 gen_store_fpr64(ctx, fp0, fd);
9450 tcg_temp_free_i64(fp0);
9451 gen_set_label(l1);
9452 }
a16336e4 9453 }
6ea83fed 9454 break;
bf4120ad 9455 case OPC_RECIP_D:
ca6c7803 9456 check_cp1_registers(ctx, fs | fd);
b6d96bed 9457 {
a7812ae4 9458 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9459
9460 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9461 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9462 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9463 tcg_temp_free_i64(fp0);
b6d96bed 9464 }
57fa1fb3 9465 break;
bf4120ad 9466 case OPC_RSQRT_D:
ca6c7803 9467 check_cp1_registers(ctx, fs | fd);
b6d96bed 9468 {
a7812ae4 9469 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9470
9471 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9472 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9473 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9474 tcg_temp_free_i64(fp0);
b6d96bed 9475 }
57fa1fb3 9476 break;
e7f16abb
LA
9477 case OPC_MADDF_D:
9478 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9479 {
a7812ae4
PB
9480 TCGv_i64 fp0 = tcg_temp_new_i64();
9481 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9482 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9483 gen_load_fpr64(ctx, fp0, fs);
9484 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9485 gen_load_fpr64(ctx, fp2, fd);
9486 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9487 gen_store_fpr64(ctx, fp2, fd);
9488 tcg_temp_free_i64(fp2);
a7812ae4 9489 tcg_temp_free_i64(fp1);
a7812ae4 9490 tcg_temp_free_i64(fp0);
b6d96bed 9491 }
57fa1fb3 9492 break;
e7f16abb
LA
9493 case OPC_MSUBF_D:
9494 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9495 {
a7812ae4 9496 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9497 TCGv_i64 fp1 = tcg_temp_new_i64();
9498 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9499 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9500 gen_load_fpr64(ctx, fp1, ft);
9501 gen_load_fpr64(ctx, fp2, fd);
9502 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9503 gen_store_fpr64(ctx, fp2, fd);
9504 tcg_temp_free_i64(fp2);
9505 tcg_temp_free_i64(fp1);
a7812ae4 9506 tcg_temp_free_i64(fp0);
b6d96bed 9507 }
57fa1fb3 9508 break;
e7f16abb
LA
9509 case OPC_RINT_D:
9510 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9511 {
a7812ae4 9512 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9513 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9514 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9515 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9516 tcg_temp_free_i64(fp0);
b6d96bed 9517 }
57fa1fb3 9518 break;
e7f16abb
LA
9519 case OPC_CLASS_D:
9520 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9521 {
e7f16abb
LA
9522 TCGv_i64 fp0 = tcg_temp_new_i64();
9523 gen_load_fpr64(ctx, fp0, fs);
9524 gen_helper_float_class_d(fp0, fp0);
9525 gen_store_fpr64(ctx, fp0, fd);
9526 tcg_temp_free_i64(fp0);
e7f16abb
LA
9527 }
9528 break;
9529 case OPC_MIN_D: /* OPC_RECIP2_D */
9530 if (ctx->insn_flags & ISA_MIPS32R6) {
9531 /* OPC_MIN_D */
a7812ae4
PB
9532 TCGv_i64 fp0 = tcg_temp_new_i64();
9533 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9534 gen_load_fpr64(ctx, fp0, fs);
9535 gen_load_fpr64(ctx, fp1, ft);
9536 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9537 gen_store_fpr64(ctx, fp1, fd);
9538 tcg_temp_free_i64(fp1);
9539 tcg_temp_free_i64(fp0);
e7f16abb
LA
9540 } else {
9541 /* OPC_RECIP2_D */
9542 check_cp1_64bitmode(ctx);
9543 {
9544 TCGv_i64 fp0 = tcg_temp_new_i64();
9545 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9546
e7f16abb
LA
9547 gen_load_fpr64(ctx, fp0, fs);
9548 gen_load_fpr64(ctx, fp1, ft);
9549 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9550 tcg_temp_free_i64(fp1);
9551 gen_store_fpr64(ctx, fp0, fd);
9552 tcg_temp_free_i64(fp0);
9553 }
e7f16abb
LA
9554 }
9555 break;
9556 case OPC_MINA_D: /* OPC_RECIP1_D */
9557 if (ctx->insn_flags & ISA_MIPS32R6) {
9558 /* OPC_MINA_D */
9559 TCGv_i64 fp0 = tcg_temp_new_i64();
9560 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9561 gen_load_fpr64(ctx, fp0, fs);
9562 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9563 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9564 gen_store_fpr64(ctx, fp1, fd);
9565 tcg_temp_free_i64(fp1);
9566 tcg_temp_free_i64(fp0);
e7f16abb
LA
9567 } else {
9568 /* OPC_RECIP1_D */
9569 check_cp1_64bitmode(ctx);
9570 {
9571 TCGv_i64 fp0 = tcg_temp_new_i64();
9572
9573 gen_load_fpr64(ctx, fp0, fs);
9574 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9575 gen_store_fpr64(ctx, fp0, fd);
9576 tcg_temp_free_i64(fp0);
9577 }
e7f16abb
LA
9578 }
9579 break;
9580 case OPC_MAX_D: /* OPC_RSQRT1_D */
9581 if (ctx->insn_flags & ISA_MIPS32R6) {
9582 /* OPC_MAX_D */
9583 TCGv_i64 fp0 = tcg_temp_new_i64();
9584 TCGv_i64 fp1 = tcg_temp_new_i64();
9585 gen_load_fpr64(ctx, fp0, fs);
9586 gen_load_fpr64(ctx, fp1, ft);
9587 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9588 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9589 tcg_temp_free_i64(fp1);
a7812ae4 9590 tcg_temp_free_i64(fp0);
e7f16abb
LA
9591 } else {
9592 /* OPC_RSQRT1_D */
9593 check_cp1_64bitmode(ctx);
9594 {
9595 TCGv_i64 fp0 = tcg_temp_new_i64();
9596
9597 gen_load_fpr64(ctx, fp0, fs);
9598 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9599 gen_store_fpr64(ctx, fp0, fd);
9600 tcg_temp_free_i64(fp0);
9601 }
e7f16abb
LA
9602 }
9603 break;
9604 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9605 if (ctx->insn_flags & ISA_MIPS32R6) {
9606 /* OPC_MAXA_D */
9607 TCGv_i64 fp0 = tcg_temp_new_i64();
9608 TCGv_i64 fp1 = tcg_temp_new_i64();
9609 gen_load_fpr64(ctx, fp0, fs);
9610 gen_load_fpr64(ctx, fp1, ft);
9611 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9612 gen_store_fpr64(ctx, fp1, fd);
9613 tcg_temp_free_i64(fp1);
9614 tcg_temp_free_i64(fp0);
e7f16abb
LA
9615 } else {
9616 /* OPC_RSQRT2_D */
9617 check_cp1_64bitmode(ctx);
9618 {
9619 TCGv_i64 fp0 = tcg_temp_new_i64();
9620 TCGv_i64 fp1 = tcg_temp_new_i64();
9621
9622 gen_load_fpr64(ctx, fp0, fs);
9623 gen_load_fpr64(ctx, fp1, ft);
9624 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9625 tcg_temp_free_i64(fp1);
9626 gen_store_fpr64(ctx, fp0, fd);
9627 tcg_temp_free_i64(fp0);
9628 }
b6d96bed 9629 }
57fa1fb3 9630 break;
bf4120ad
NF
9631 case OPC_CMP_F_D:
9632 case OPC_CMP_UN_D:
9633 case OPC_CMP_EQ_D:
9634 case OPC_CMP_UEQ_D:
9635 case OPC_CMP_OLT_D:
9636 case OPC_CMP_ULT_D:
9637 case OPC_CMP_OLE_D:
9638 case OPC_CMP_ULE_D:
9639 case OPC_CMP_SF_D:
9640 case OPC_CMP_NGLE_D:
9641 case OPC_CMP_SEQ_D:
9642 case OPC_CMP_NGL_D:
9643 case OPC_CMP_LT_D:
9644 case OPC_CMP_NGE_D:
9645 case OPC_CMP_LE_D:
9646 case OPC_CMP_NGT_D:
fecd2646 9647 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9648 if (ctx->opcode & (1 << 6)) {
9649 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9650 } else {
9651 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9652 }
6ea83fed 9653 break;
bf4120ad 9654 case OPC_CVT_S_D:
5e755519 9655 check_cp1_registers(ctx, fs);
b6d96bed 9656 {
a7812ae4
PB
9657 TCGv_i32 fp32 = tcg_temp_new_i32();
9658 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9659
9660 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9661 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9662 tcg_temp_free_i64(fp64);
7c979afd 9663 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9664 tcg_temp_free_i32(fp32);
b6d96bed 9665 }
5a5012ec 9666 break;
bf4120ad 9667 case OPC_CVT_W_D:
5e755519 9668 check_cp1_registers(ctx, fs);
b6d96bed 9669 {
a7812ae4
PB
9670 TCGv_i32 fp32 = tcg_temp_new_i32();
9671 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9672
9673 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9674 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9675 tcg_temp_free_i64(fp64);
7c979afd 9676 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9677 tcg_temp_free_i32(fp32);
b6d96bed 9678 }
5a5012ec 9679 break;
bf4120ad 9680 case OPC_CVT_L_D:
5e755519 9681 check_cp1_64bitmode(ctx);
b6d96bed 9682 {
a7812ae4 9683 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9684
9685 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9686 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9687 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9688 tcg_temp_free_i64(fp0);
b6d96bed 9689 }
5a5012ec 9690 break;
bf4120ad 9691 case OPC_CVT_S_W:
b6d96bed 9692 {
a7812ae4 9693 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9694
7c979afd 9695 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9696 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 9697 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9698 tcg_temp_free_i32(fp0);
b6d96bed 9699 }
6ea83fed 9700 break;
bf4120ad 9701 case OPC_CVT_D_W:
5e755519 9702 check_cp1_registers(ctx, fd);
b6d96bed 9703 {
a7812ae4
PB
9704 TCGv_i32 fp32 = tcg_temp_new_i32();
9705 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9706
7c979afd 9707 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9708 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9709 tcg_temp_free_i32(fp32);
b6d96bed 9710 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9711 tcg_temp_free_i64(fp64);
b6d96bed 9712 }
5a5012ec 9713 break;
bf4120ad 9714 case OPC_CVT_S_L:
5e755519 9715 check_cp1_64bitmode(ctx);
b6d96bed 9716 {
a7812ae4
PB
9717 TCGv_i32 fp32 = tcg_temp_new_i32();
9718 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9719
9720 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9721 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9722 tcg_temp_free_i64(fp64);
7c979afd 9723 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9724 tcg_temp_free_i32(fp32);
b6d96bed 9725 }
5a5012ec 9726 break;
bf4120ad 9727 case OPC_CVT_D_L:
5e755519 9728 check_cp1_64bitmode(ctx);
b6d96bed 9729 {
a7812ae4 9730 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9731
9732 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9733 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9734 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9735 tcg_temp_free_i64(fp0);
b6d96bed 9736 }
5a5012ec 9737 break;
bf4120ad 9738 case OPC_CVT_PS_PW:
e29c9628 9739 check_ps(ctx);
b6d96bed 9740 {
a7812ae4 9741 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9742
9743 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9744 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9745 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9746 tcg_temp_free_i64(fp0);
b6d96bed 9747 }
5a5012ec 9748 break;
bf4120ad 9749 case OPC_ADD_PS:
e29c9628 9750 check_ps(ctx);
b6d96bed 9751 {
a7812ae4
PB
9752 TCGv_i64 fp0 = tcg_temp_new_i64();
9753 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9754
9755 gen_load_fpr64(ctx, fp0, fs);
9756 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9757 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9758 tcg_temp_free_i64(fp1);
b6d96bed 9759 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9760 tcg_temp_free_i64(fp0);
b6d96bed 9761 }
6ea83fed 9762 break;
bf4120ad 9763 case OPC_SUB_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_sub_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_MUL_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_mul_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_ABS_PS:
e29c9628 9792 check_ps(ctx);
b6d96bed 9793 {
a7812ae4 9794 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9795
9796 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9797 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9798 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9799 tcg_temp_free_i64(fp0);
b6d96bed 9800 }
6ea83fed 9801 break;
bf4120ad 9802 case OPC_MOV_PS:
e29c9628 9803 check_ps(ctx);
b6d96bed 9804 {
a7812ae4 9805 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9806
9807 gen_load_fpr64(ctx, fp0, fs);
9808 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9809 tcg_temp_free_i64(fp0);
b6d96bed 9810 }
6ea83fed 9811 break;
bf4120ad 9812 case OPC_NEG_PS:
e29c9628 9813 check_ps(ctx);
b6d96bed 9814 {
a7812ae4 9815 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9816
9817 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9818 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9819 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9820 tcg_temp_free_i64(fp0);
b6d96bed 9821 }
6ea83fed 9822 break;
bf4120ad 9823 case OPC_MOVCF_PS:
e29c9628 9824 check_ps(ctx);
7f6613ce 9825 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 9826 break;
bf4120ad 9827 case OPC_MOVZ_PS:
e29c9628 9828 check_ps(ctx);
a16336e4 9829 {
42a268c2 9830 TCGLabel *l1 = gen_new_label();
30a3848b 9831 TCGv_i64 fp0;
a16336e4 9832
c9297f4d
AJ
9833 if (ft != 0)
9834 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9835 fp0 = tcg_temp_new_i64();
9836 gen_load_fpr64(ctx, fp0, fs);
9837 gen_store_fpr64(ctx, fp0, fd);
9838 tcg_temp_free_i64(fp0);
a16336e4
TS
9839 gen_set_label(l1);
9840 }
6ea83fed 9841 break;
bf4120ad 9842 case OPC_MOVN_PS:
e29c9628 9843 check_ps(ctx);
a16336e4 9844 {
42a268c2 9845 TCGLabel *l1 = gen_new_label();
30a3848b 9846 TCGv_i64 fp0;
c9297f4d
AJ
9847
9848 if (ft != 0) {
9849 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9850 fp0 = tcg_temp_new_i64();
9851 gen_load_fpr64(ctx, fp0, fs);
9852 gen_store_fpr64(ctx, fp0, fd);
9853 tcg_temp_free_i64(fp0);
9854 gen_set_label(l1);
9855 }
a16336e4 9856 }
6ea83fed 9857 break;
bf4120ad 9858 case OPC_ADDR_PS:
e29c9628 9859 check_ps(ctx);
b6d96bed 9860 {
a7812ae4
PB
9861 TCGv_i64 fp0 = tcg_temp_new_i64();
9862 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9863
9864 gen_load_fpr64(ctx, fp0, ft);
9865 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9866 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9867 tcg_temp_free_i64(fp1);
b6d96bed 9868 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9869 tcg_temp_free_i64(fp0);
b6d96bed 9870 }
fbcc6828 9871 break;
bf4120ad 9872 case OPC_MULR_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_mulr_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 }
57fa1fb3 9885 break;
bf4120ad 9886 case OPC_RECIP2_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, fs);
d22d7289 9893 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9894 gen_helper_float_recip2_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_RECIP1_PS:
e29c9628 9901 check_ps(ctx);
b6d96bed 9902 {
a7812ae4 9903 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9904
9905 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9906 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9907 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9908 tcg_temp_free_i64(fp0);
b6d96bed 9909 }
57fa1fb3 9910 break;
bf4120ad 9911 case OPC_RSQRT1_PS:
e29c9628 9912 check_ps(ctx);
b6d96bed 9913 {
a7812ae4 9914 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9915
9916 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9917 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9918 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9919 tcg_temp_free_i64(fp0);
b6d96bed 9920 }
57fa1fb3 9921 break;
bf4120ad 9922 case OPC_RSQRT2_PS:
e29c9628 9923 check_ps(ctx);
b6d96bed 9924 {
a7812ae4
PB
9925 TCGv_i64 fp0 = tcg_temp_new_i64();
9926 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9927
9928 gen_load_fpr64(ctx, fp0, fs);
9929 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9930 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9931 tcg_temp_free_i64(fp1);
b6d96bed 9932 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9933 tcg_temp_free_i64(fp0);
b6d96bed 9934 }
57fa1fb3 9935 break;
bf4120ad 9936 case OPC_CVT_S_PU:
5e755519 9937 check_cp1_64bitmode(ctx);
b6d96bed 9938 {
a7812ae4 9939 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9940
7f6613ce 9941 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9942 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 9943 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9944 tcg_temp_free_i32(fp0);
b6d96bed 9945 }
dd016883 9946 break;
bf4120ad 9947 case OPC_CVT_PW_PS:
e29c9628 9948 check_ps(ctx);
b6d96bed 9949 {
a7812ae4 9950 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9951
9952 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9953 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9954 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9955 tcg_temp_free_i64(fp0);
b6d96bed 9956 }
6ea83fed 9957 break;
bf4120ad 9958 case OPC_CVT_S_PL:
5e755519 9959 check_cp1_64bitmode(ctx);
b6d96bed 9960 {
a7812ae4 9961 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9962
7c979afd 9963 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9964 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 9965 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9966 tcg_temp_free_i32(fp0);
b6d96bed 9967 }
6ea83fed 9968 break;
bf4120ad 9969 case OPC_PLL_PS:
e29c9628 9970 check_ps(ctx);
b6d96bed 9971 {
a7812ae4
PB
9972 TCGv_i32 fp0 = tcg_temp_new_i32();
9973 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9974
7c979afd
LA
9975 gen_load_fpr32(ctx, fp0, fs);
9976 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 9977 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 9978 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
9979 tcg_temp_free_i32(fp0);
9980 tcg_temp_free_i32(fp1);
b6d96bed 9981 }
6ea83fed 9982 break;
bf4120ad 9983 case OPC_PLU_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 9989 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 9990 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 9991 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 9992 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9993 tcg_temp_free_i32(fp0);
9994 tcg_temp_free_i32(fp1);
b6d96bed 9995 }
5a5012ec 9996 break;
bf4120ad 9997 case OPC_PUL_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
7f6613ce 10003 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10004 gen_load_fpr32(ctx, fp1, ft);
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_PUU_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
PJ
10017 gen_load_fpr32h(ctx, fp0, fs);
10018 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 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
NF
10025 case OPC_CMP_F_PS:
10026 case OPC_CMP_UN_PS:
10027 case OPC_CMP_EQ_PS:
10028 case OPC_CMP_UEQ_PS:
10029 case OPC_CMP_OLT_PS:
10030 case OPC_CMP_ULT_PS:
10031 case OPC_CMP_OLE_PS:
10032 case OPC_CMP_ULE_PS:
10033 case OPC_CMP_SF_PS:
10034 case OPC_CMP_NGLE_PS:
10035 case OPC_CMP_SEQ_PS:
10036 case OPC_CMP_NGL_PS:
10037 case OPC_CMP_LT_PS:
10038 case OPC_CMP_NGE_PS:
10039 case OPC_CMP_LE_PS:
10040 case OPC_CMP_NGT_PS:
8153667c
NF
10041 if (ctx->opcode & (1 << 6)) {
10042 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10043 } else {
10044 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10045 }
6ea83fed 10046 break;
5a5012ec 10047 default:
9d68ac14 10048 MIPS_INVAL("farith");
9c708c7f 10049 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10050 return;
10051 }
6ea83fed 10052}
6af0bf9c 10053
5a5012ec 10054/* Coprocessor 3 (FPU) */
5e755519
TS
10055static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10056 int fd, int fs, int base, int index)
7a387fff 10057{
4e2474d6 10058 TCGv t0 = tcg_temp_new();
7a387fff 10059
93b12ccc 10060 if (base == 0) {
6c5c1e20 10061 gen_load_gpr(t0, index);
93b12ccc 10062 } else if (index == 0) {
6c5c1e20 10063 gen_load_gpr(t0, base);
93b12ccc 10064 } else {
05168674 10065 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10066 }
5a5012ec 10067 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10068 memory access. */
5a5012ec
TS
10069 switch (opc) {
10070 case OPC_LWXC1:
8c0ab41f 10071 check_cop1x(ctx);
b6d96bed 10072 {
a7812ae4 10073 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10074
5f68f5ae 10075 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10076 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10077 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10078 tcg_temp_free_i32(fp0);
b6d96bed 10079 }
5a5012ec
TS
10080 break;
10081 case OPC_LDXC1:
8c0ab41f
AJ
10082 check_cop1x(ctx);
10083 check_cp1_registers(ctx, fd);
b6d96bed 10084 {
a7812ae4 10085 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10086 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10087 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10088 tcg_temp_free_i64(fp0);
b6d96bed 10089 }
5a5012ec
TS
10090 break;
10091 case OPC_LUXC1:
8c0ab41f 10092 check_cp1_64bitmode(ctx);
6c5c1e20 10093 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10094 {
a7812ae4 10095 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10096
5f68f5ae 10097 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10098 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10099 tcg_temp_free_i64(fp0);
b6d96bed 10100 }
5a5012ec
TS
10101 break;
10102 case OPC_SWXC1:
8c0ab41f 10103 check_cop1x(ctx);
b6d96bed 10104 {
a7812ae4 10105 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10106 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10107 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10108 tcg_temp_free_i32(fp0);
b6d96bed 10109 }
5a5012ec
TS
10110 break;
10111 case OPC_SDXC1:
8c0ab41f
AJ
10112 check_cop1x(ctx);
10113 check_cp1_registers(ctx, fs);
b6d96bed 10114 {
a7812ae4 10115 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10116 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10117 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10118 tcg_temp_free_i64(fp0);
b6d96bed 10119 }
5a5012ec
TS
10120 break;
10121 case OPC_SUXC1:
8c0ab41f 10122 check_cp1_64bitmode(ctx);
6c5c1e20 10123 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10124 {
a7812ae4 10125 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10126 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10127 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10128 tcg_temp_free_i64(fp0);
b6d96bed 10129 }
5a5012ec 10130 break;
5a5012ec 10131 }
6c5c1e20 10132 tcg_temp_free(t0);
5a5012ec
TS
10133}
10134
5e755519
TS
10135static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10136 int fd, int fr, int fs, int ft)
5a5012ec 10137{
5a5012ec
TS
10138 switch (opc) {
10139 case OPC_ALNV_PS:
e29c9628 10140 check_ps(ctx);
a16336e4 10141 {
a7812ae4 10142 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10143 TCGv_i32 fp = tcg_temp_new_i32();
10144 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10145 TCGLabel *l1 = gen_new_label();
10146 TCGLabel *l2 = gen_new_label();
a16336e4 10147
6c5c1e20
TS
10148 gen_load_gpr(t0, fr);
10149 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10150
10151 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10152 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10153 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10154 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10155 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10156 tcg_gen_br(l2);
10157 gen_set_label(l1);
6c5c1e20
TS
10158 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10159 tcg_temp_free(t0);
a16336e4 10160#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10161 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10162 gen_load_fpr32h(ctx, fph, ft);
10163 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10164 gen_store_fpr32(ctx, fph, fd);
a16336e4 10165#else
7f6613ce 10166 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10167 gen_load_fpr32(ctx, fp, ft);
10168 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10169 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10170#endif
10171 gen_set_label(l2);
c905fdac
AJ
10172 tcg_temp_free_i32(fp);
10173 tcg_temp_free_i32(fph);
a16336e4 10174 }
5a5012ec
TS
10175 break;
10176 case OPC_MADD_S:
b8aa4598 10177 check_cop1x(ctx);
b6d96bed 10178 {
a7812ae4
PB
10179 TCGv_i32 fp0 = tcg_temp_new_i32();
10180 TCGv_i32 fp1 = tcg_temp_new_i32();
10181 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10182
7c979afd
LA
10183 gen_load_fpr32(ctx, fp0, fs);
10184 gen_load_fpr32(ctx, fp1, ft);
10185 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10186 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10187 tcg_temp_free_i32(fp0);
10188 tcg_temp_free_i32(fp1);
7c979afd 10189 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10190 tcg_temp_free_i32(fp2);
b6d96bed 10191 }
5a5012ec
TS
10192 break;
10193 case OPC_MADD_D:
b8aa4598
TS
10194 check_cop1x(ctx);
10195 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10196 {
a7812ae4
PB
10197 TCGv_i64 fp0 = tcg_temp_new_i64();
10198 TCGv_i64 fp1 = tcg_temp_new_i64();
10199 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10200
10201 gen_load_fpr64(ctx, fp0, fs);
10202 gen_load_fpr64(ctx, fp1, ft);
10203 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10204 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10205 tcg_temp_free_i64(fp0);
10206 tcg_temp_free_i64(fp1);
b6d96bed 10207 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10208 tcg_temp_free_i64(fp2);
b6d96bed 10209 }
5a5012ec
TS
10210 break;
10211 case OPC_MADD_PS:
e29c9628 10212 check_ps(ctx);
b6d96bed 10213 {
a7812ae4
PB
10214 TCGv_i64 fp0 = tcg_temp_new_i64();
10215 TCGv_i64 fp1 = tcg_temp_new_i64();
10216 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10217
10218 gen_load_fpr64(ctx, fp0, fs);
10219 gen_load_fpr64(ctx, fp1, ft);
10220 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10221 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10222 tcg_temp_free_i64(fp0);
10223 tcg_temp_free_i64(fp1);
b6d96bed 10224 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10225 tcg_temp_free_i64(fp2);
b6d96bed 10226 }
5a5012ec
TS
10227 break;
10228 case OPC_MSUB_S:
b8aa4598 10229 check_cop1x(ctx);
b6d96bed 10230 {
a7812ae4
PB
10231 TCGv_i32 fp0 = tcg_temp_new_i32();
10232 TCGv_i32 fp1 = tcg_temp_new_i32();
10233 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10234
7c979afd
LA
10235 gen_load_fpr32(ctx, fp0, fs);
10236 gen_load_fpr32(ctx, fp1, ft);
10237 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10238 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10239 tcg_temp_free_i32(fp0);
10240 tcg_temp_free_i32(fp1);
7c979afd 10241 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10242 tcg_temp_free_i32(fp2);
b6d96bed 10243 }
5a5012ec
TS
10244 break;
10245 case OPC_MSUB_D:
b8aa4598
TS
10246 check_cop1x(ctx);
10247 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10248 {
a7812ae4
PB
10249 TCGv_i64 fp0 = tcg_temp_new_i64();
10250 TCGv_i64 fp1 = tcg_temp_new_i64();
10251 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10252
10253 gen_load_fpr64(ctx, fp0, fs);
10254 gen_load_fpr64(ctx, fp1, ft);
10255 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10256 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10257 tcg_temp_free_i64(fp0);
10258 tcg_temp_free_i64(fp1);
b6d96bed 10259 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10260 tcg_temp_free_i64(fp2);
b6d96bed 10261 }
5a5012ec
TS
10262 break;
10263 case OPC_MSUB_PS:
e29c9628 10264 check_ps(ctx);
b6d96bed 10265 {
a7812ae4
PB
10266 TCGv_i64 fp0 = tcg_temp_new_i64();
10267 TCGv_i64 fp1 = tcg_temp_new_i64();
10268 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10269
10270 gen_load_fpr64(ctx, fp0, fs);
10271 gen_load_fpr64(ctx, fp1, ft);
10272 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10273 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10274 tcg_temp_free_i64(fp0);
10275 tcg_temp_free_i64(fp1);
b6d96bed 10276 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10277 tcg_temp_free_i64(fp2);
b6d96bed 10278 }
5a5012ec
TS
10279 break;
10280 case OPC_NMADD_S:
b8aa4598 10281 check_cop1x(ctx);
b6d96bed 10282 {
a7812ae4
PB
10283 TCGv_i32 fp0 = tcg_temp_new_i32();
10284 TCGv_i32 fp1 = tcg_temp_new_i32();
10285 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10286
7c979afd
LA
10287 gen_load_fpr32(ctx, fp0, fs);
10288 gen_load_fpr32(ctx, fp1, ft);
10289 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10290 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10291 tcg_temp_free_i32(fp0);
10292 tcg_temp_free_i32(fp1);
7c979afd 10293 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10294 tcg_temp_free_i32(fp2);
b6d96bed 10295 }
5a5012ec
TS
10296 break;
10297 case OPC_NMADD_D:
b8aa4598
TS
10298 check_cop1x(ctx);
10299 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10300 {
a7812ae4
PB
10301 TCGv_i64 fp0 = tcg_temp_new_i64();
10302 TCGv_i64 fp1 = tcg_temp_new_i64();
10303 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10304
10305 gen_load_fpr64(ctx, fp0, fs);
10306 gen_load_fpr64(ctx, fp1, ft);
10307 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10308 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10309 tcg_temp_free_i64(fp0);
10310 tcg_temp_free_i64(fp1);
b6d96bed 10311 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10312 tcg_temp_free_i64(fp2);
b6d96bed 10313 }
5a5012ec
TS
10314 break;
10315 case OPC_NMADD_PS:
e29c9628 10316 check_ps(ctx);
b6d96bed 10317 {
a7812ae4
PB
10318 TCGv_i64 fp0 = tcg_temp_new_i64();
10319 TCGv_i64 fp1 = tcg_temp_new_i64();
10320 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10321
10322 gen_load_fpr64(ctx, fp0, fs);
10323 gen_load_fpr64(ctx, fp1, ft);
10324 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10325 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10326 tcg_temp_free_i64(fp0);
10327 tcg_temp_free_i64(fp1);
b6d96bed 10328 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10329 tcg_temp_free_i64(fp2);
b6d96bed 10330 }
5a5012ec
TS
10331 break;
10332 case OPC_NMSUB_S:
b8aa4598 10333 check_cop1x(ctx);
b6d96bed 10334 {
a7812ae4
PB
10335 TCGv_i32 fp0 = tcg_temp_new_i32();
10336 TCGv_i32 fp1 = tcg_temp_new_i32();
10337 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10338
7c979afd
LA
10339 gen_load_fpr32(ctx, fp0, fs);
10340 gen_load_fpr32(ctx, fp1, ft);
10341 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10342 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10343 tcg_temp_free_i32(fp0);
10344 tcg_temp_free_i32(fp1);
7c979afd 10345 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10346 tcg_temp_free_i32(fp2);
b6d96bed 10347 }
5a5012ec
TS
10348 break;
10349 case OPC_NMSUB_D:
b8aa4598
TS
10350 check_cop1x(ctx);
10351 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10352 {
a7812ae4
PB
10353 TCGv_i64 fp0 = tcg_temp_new_i64();
10354 TCGv_i64 fp1 = tcg_temp_new_i64();
10355 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10356
10357 gen_load_fpr64(ctx, fp0, fs);
10358 gen_load_fpr64(ctx, fp1, ft);
10359 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10360 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10361 tcg_temp_free_i64(fp0);
10362 tcg_temp_free_i64(fp1);
b6d96bed 10363 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10364 tcg_temp_free_i64(fp2);
b6d96bed 10365 }
5a5012ec
TS
10366 break;
10367 case OPC_NMSUB_PS:
e29c9628 10368 check_ps(ctx);
b6d96bed 10369 {
a7812ae4
PB
10370 TCGv_i64 fp0 = tcg_temp_new_i64();
10371 TCGv_i64 fp1 = tcg_temp_new_i64();
10372 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10373
10374 gen_load_fpr64(ctx, fp0, fs);
10375 gen_load_fpr64(ctx, fp1, ft);
10376 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10377 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10378 tcg_temp_free_i64(fp0);
10379 tcg_temp_free_i64(fp1);
b6d96bed 10380 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10381 tcg_temp_free_i64(fp2);
b6d96bed 10382 }
5a5012ec 10383 break;
923617a3 10384 default:
9d68ac14 10385 MIPS_INVAL("flt3_arith");
9c708c7f 10386 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10387 return;
10388 }
7a387fff
TS
10389}
10390
b00c7218 10391static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10392{
10393 TCGv t0;
10394
b3167288
RH
10395#if !defined(CONFIG_USER_ONLY)
10396 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10397 Therefore only check the ISA in system mode. */
d75c135e 10398 check_insn(ctx, ISA_MIPS32R2);
b3167288 10399#endif
26ebe468
NF
10400 t0 = tcg_temp_new();
10401
10402 switch (rd) {
10403 case 0:
895c2d04 10404 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10405 gen_store_gpr(t0, rt);
10406 break;
10407 case 1:
895c2d04 10408 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10409 gen_store_gpr(t0, rt);
10410 break;
10411 case 2:
895c2d04 10412 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10413 gen_store_gpr(t0, rt);
10414 break;
10415 case 3:
895c2d04 10416 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10417 gen_store_gpr(t0, rt);
10418 break;
b00c7218
YK
10419 case 4:
10420 check_insn(ctx, ISA_MIPS32R6);
10421 if (sel != 0) {
10422 /* Performance counter registers are not implemented other than
10423 * control register 0.
10424 */
10425 generate_exception(ctx, EXCP_RI);
10426 }
10427 gen_helper_rdhwr_performance(t0, cpu_env);
10428 gen_store_gpr(t0, rt);
10429 break;
10430 case 5:
10431 check_insn(ctx, ISA_MIPS32R6);
10432 gen_helper_rdhwr_xnp(t0, cpu_env);
10433 gen_store_gpr(t0, rt);
10434 break;
26ebe468
NF
10435 case 29:
10436#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10437 tcg_gen_ld_tl(t0, cpu_env,
10438 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10439 gen_store_gpr(t0, rt);
10440 break;
10441#else
d279279e
PJ
10442 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10443 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10444 tcg_gen_ld_tl(t0, cpu_env,
10445 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10446 gen_store_gpr(t0, rt);
10447 } else {
9c708c7f 10448 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10449 }
10450 break;
26ebe468
NF
10451#endif
10452 default: /* Invalid */
10453 MIPS_INVAL("rdhwr");
9c708c7f 10454 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10455 break;
10456 }
10457 tcg_temp_free(t0);
10458}
10459
a5f53390
LA
10460static inline void clear_branch_hflags(DisasContext *ctx)
10461{
10462 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10463 if (ctx->bstate == BS_NONE) {
10464 save_cpu_state(ctx, 0);
10465 } else {
10466 /* it is not safe to save ctx->hflags as hflags may be changed
10467 in execution time by the instruction in delay / forbidden slot. */
10468 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10469 }
10470}
10471
31837be3 10472static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10473{
10474 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10475 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10476 /* Branches completion */
a5f53390 10477 clear_branch_hflags(ctx);
c9602061 10478 ctx->bstate = BS_BRANCH;
c9602061 10479 /* FIXME: Need to clear can_do_io. */
364d4831 10480 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10481 case MIPS_HFLAG_FBNSLOT:
339cd2a8
LA
10482 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10483 break;
c9602061
NF
10484 case MIPS_HFLAG_B:
10485 /* unconditional branch */
364d4831
NF
10486 if (proc_hflags & MIPS_HFLAG_BX) {
10487 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10488 }
c9602061
NF
10489 gen_goto_tb(ctx, 0, ctx->btarget);
10490 break;
10491 case MIPS_HFLAG_BL:
10492 /* blikely taken case */
c9602061
NF
10493 gen_goto_tb(ctx, 0, ctx->btarget);
10494 break;
10495 case MIPS_HFLAG_BC:
10496 /* Conditional branch */
c9602061 10497 {
42a268c2 10498 TCGLabel *l1 = gen_new_label();
c9602061
NF
10499
10500 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10501 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10502 gen_set_label(l1);
10503 gen_goto_tb(ctx, 0, ctx->btarget);
10504 }
10505 break;
10506 case MIPS_HFLAG_BR:
10507 /* unconditional branch to register */
d75c135e 10508 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10509 TCGv t0 = tcg_temp_new();
10510 TCGv_i32 t1 = tcg_temp_new_i32();
10511
10512 tcg_gen_andi_tl(t0, btarget, 0x1);
10513 tcg_gen_trunc_tl_i32(t1, t0);
10514 tcg_temp_free(t0);
10515 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10516 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10517 tcg_gen_or_i32(hflags, hflags, t1);
10518 tcg_temp_free_i32(t1);
10519
10520 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10521 } else {
10522 tcg_gen_mov_tl(cpu_PC, btarget);
10523 }
c9602061
NF
10524 if (ctx->singlestep_enabled) {
10525 save_cpu_state(ctx, 0);
9c708c7f 10526 gen_helper_raise_exception_debug(cpu_env);
c9602061
NF
10527 }
10528 tcg_gen_exit_tb(0);
10529 break;
10530 default:
a5f53390
LA
10531 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10532 abort();
c9602061
NF
10533 }
10534 }
10535}
10536
6893f074
YK
10537/* Compact Branches */
10538static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10539 int rs, int rt, int32_t offset)
10540{
10541 int bcond_compute = 0;
10542 TCGv t0 = tcg_temp_new();
10543 TCGv t1 = tcg_temp_new();
65935f07 10544 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10545
10546 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10547#ifdef MIPS_DEBUG_DISAS
10548 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10549 "\n", ctx->pc);
10550#endif
9c708c7f 10551 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10552 goto out;
10553 }
10554
10555 /* Load needed operands and calculate btarget */
10556 switch (opc) {
10557 /* compact branch */
10558 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10559 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10560 gen_load_gpr(t0, rs);
10561 gen_load_gpr(t1, rt);
10562 bcond_compute = 1;
10563 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10564 if (rs <= rt && rs == 0) {
10565 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 10566 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10567 }
10568 break;
10569 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10570 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10571 gen_load_gpr(t0, rs);
10572 gen_load_gpr(t1, rt);
10573 bcond_compute = 1;
10574 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10575 break;
10576 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10577 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10578 if (rs == 0 || rs == rt) {
10579 /* OPC_BLEZALC, OPC_BGEZALC */
10580 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 10581 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10582 }
10583 gen_load_gpr(t0, rs);
10584 gen_load_gpr(t1, rt);
10585 bcond_compute = 1;
10586 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10587 break;
10588 case OPC_BC:
10589 case OPC_BALC:
10590 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10591 break;
10592 case OPC_BEQZC:
10593 case OPC_BNEZC:
10594 if (rs != 0) {
10595 /* OPC_BEQZC, OPC_BNEZC */
10596 gen_load_gpr(t0, rs);
10597 bcond_compute = 1;
10598 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10599 } else {
10600 /* OPC_JIC, OPC_JIALC */
10601 TCGv tbase = tcg_temp_new();
10602 TCGv toffset = tcg_temp_new();
10603
10604 gen_load_gpr(tbase, rt);
10605 tcg_gen_movi_tl(toffset, offset);
10606 gen_op_addr_add(ctx, btarget, tbase, toffset);
10607 tcg_temp_free(tbase);
10608 tcg_temp_free(toffset);
10609 }
10610 break;
10611 default:
10612 MIPS_INVAL("Compact branch/jump");
9c708c7f 10613 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10614 goto out;
10615 }
10616
10617 if (bcond_compute == 0) {
10618 /* Uncoditional compact branch */
10619 switch (opc) {
10620 case OPC_JIALC:
65935f07 10621 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10622 /* Fallthrough */
10623 case OPC_JIC:
10624 ctx->hflags |= MIPS_HFLAG_BR;
10625 break;
10626 case OPC_BALC:
65935f07 10627 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
10628 /* Fallthrough */
10629 case OPC_BC:
10630 ctx->hflags |= MIPS_HFLAG_B;
10631 break;
10632 default:
10633 MIPS_INVAL("Compact branch/jump");
9c708c7f 10634 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10635 goto out;
10636 }
10637
10638 /* Generating branch here as compact branches don't have delay slot */
10639 gen_branch(ctx, 4);
10640 } else {
10641 /* Conditional compact branch */
10642 TCGLabel *fs = gen_new_label();
10643 save_cpu_state(ctx, 0);
10644
10645 switch (opc) {
10646 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10647 if (rs == 0 && rt != 0) {
10648 /* OPC_BLEZALC */
10649 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10650 } else if (rs != 0 && rt != 0 && rs == rt) {
10651 /* OPC_BGEZALC */
10652 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10653 } else {
10654 /* OPC_BGEUC */
10655 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10656 }
10657 break;
10658 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10659 if (rs == 0 && rt != 0) {
10660 /* OPC_BGTZALC */
10661 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10662 } else if (rs != 0 && rt != 0 && rs == rt) {
10663 /* OPC_BLTZALC */
10664 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10665 } else {
10666 /* OPC_BLTUC */
10667 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10668 }
10669 break;
10670 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10671 if (rs == 0 && rt != 0) {
10672 /* OPC_BLEZC */
10673 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10674 } else if (rs != 0 && rt != 0 && rs == rt) {
10675 /* OPC_BGEZC */
10676 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10677 } else {
10678 /* OPC_BGEC */
10679 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10680 }
10681 break;
10682 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10683 if (rs == 0 && rt != 0) {
10684 /* OPC_BGTZC */
10685 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10686 } else if (rs != 0 && rt != 0 && rs == rt) {
10687 /* OPC_BLTZC */
10688 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10689 } else {
10690 /* OPC_BLTC */
10691 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10692 }
10693 break;
10694 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10695 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10696 if (rs >= rt) {
10697 /* OPC_BOVC, OPC_BNVC */
10698 TCGv t2 = tcg_temp_new();
10699 TCGv t3 = tcg_temp_new();
10700 TCGv t4 = tcg_temp_new();
10701 TCGv input_overflow = tcg_temp_new();
10702
10703 gen_load_gpr(t0, rs);
10704 gen_load_gpr(t1, rt);
10705 tcg_gen_ext32s_tl(t2, t0);
10706 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10707 tcg_gen_ext32s_tl(t3, t1);
10708 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10709 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10710
10711 tcg_gen_add_tl(t4, t2, t3);
10712 tcg_gen_ext32s_tl(t4, t4);
10713 tcg_gen_xor_tl(t2, t2, t3);
10714 tcg_gen_xor_tl(t3, t4, t3);
10715 tcg_gen_andc_tl(t2, t3, t2);
10716 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10717 tcg_gen_or_tl(t4, t4, input_overflow);
10718 if (opc == OPC_BOVC) {
10719 /* OPC_BOVC */
10720 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10721 } else {
10722 /* OPC_BNVC */
10723 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10724 }
10725 tcg_temp_free(input_overflow);
10726 tcg_temp_free(t4);
10727 tcg_temp_free(t3);
10728 tcg_temp_free(t2);
10729 } else if (rs < rt && rs == 0) {
10730 /* OPC_BEQZALC, OPC_BNEZALC */
10731 if (opc == OPC_BEQZALC) {
10732 /* OPC_BEQZALC */
10733 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10734 } else {
10735 /* OPC_BNEZALC */
10736 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10737 }
10738 } else {
10739 /* OPC_BEQC, OPC_BNEC */
10740 if (opc == OPC_BEQC) {
10741 /* OPC_BEQC */
10742 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10743 } else {
10744 /* OPC_BNEC */
10745 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10746 }
10747 }
10748 break;
10749 case OPC_BEQZC:
10750 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10751 break;
10752 case OPC_BNEZC:
10753 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10754 break;
10755 default:
10756 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 10757 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10758 goto out;
10759 }
10760
10761 /* Generating branch here as compact branches don't have delay slot */
10762 gen_goto_tb(ctx, 1, ctx->btarget);
10763 gen_set_label(fs);
10764
10765 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
10766 }
10767
10768out:
10769 tcg_temp_free(t0);
10770 tcg_temp_free(t1);
10771}
10772
7a387fff 10773/* ISA extensions (ASEs) */
6af0bf9c 10774/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10775
10776/* MIPS16 major opcodes */
10777enum {
10778 M16_OPC_ADDIUSP = 0x00,
10779 M16_OPC_ADDIUPC = 0x01,
10780 M16_OPC_B = 0x02,
10781 M16_OPC_JAL = 0x03,
10782 M16_OPC_BEQZ = 0x04,
10783 M16_OPC_BNEQZ = 0x05,
10784 M16_OPC_SHIFT = 0x06,
10785 M16_OPC_LD = 0x07,
10786 M16_OPC_RRIA = 0x08,
10787 M16_OPC_ADDIU8 = 0x09,
10788 M16_OPC_SLTI = 0x0a,
10789 M16_OPC_SLTIU = 0x0b,
10790 M16_OPC_I8 = 0x0c,
10791 M16_OPC_LI = 0x0d,
10792 M16_OPC_CMPI = 0x0e,
10793 M16_OPC_SD = 0x0f,
10794 M16_OPC_LB = 0x10,
10795 M16_OPC_LH = 0x11,
10796 M16_OPC_LWSP = 0x12,
10797 M16_OPC_LW = 0x13,
10798 M16_OPC_LBU = 0x14,
10799 M16_OPC_LHU = 0x15,
10800 M16_OPC_LWPC = 0x16,
10801 M16_OPC_LWU = 0x17,
10802 M16_OPC_SB = 0x18,
10803 M16_OPC_SH = 0x19,
10804 M16_OPC_SWSP = 0x1a,
10805 M16_OPC_SW = 0x1b,
10806 M16_OPC_RRR = 0x1c,
10807 M16_OPC_RR = 0x1d,
10808 M16_OPC_EXTEND = 0x1e,
10809 M16_OPC_I64 = 0x1f
10810};
10811
10812/* I8 funct field */
10813enum {
10814 I8_BTEQZ = 0x0,
10815 I8_BTNEZ = 0x1,
10816 I8_SWRASP = 0x2,
10817 I8_ADJSP = 0x3,
10818 I8_SVRS = 0x4,
10819 I8_MOV32R = 0x5,
10820 I8_MOVR32 = 0x7
10821};
10822
10823/* RRR f field */
10824enum {
10825 RRR_DADDU = 0x0,
10826 RRR_ADDU = 0x1,
10827 RRR_DSUBU = 0x2,
10828 RRR_SUBU = 0x3
10829};
10830
10831/* RR funct field */
10832enum {
10833 RR_JR = 0x00,
10834 RR_SDBBP = 0x01,
10835 RR_SLT = 0x02,
10836 RR_SLTU = 0x03,
10837 RR_SLLV = 0x04,
10838 RR_BREAK = 0x05,
10839 RR_SRLV = 0x06,
10840 RR_SRAV = 0x07,
10841 RR_DSRL = 0x08,
10842 RR_CMP = 0x0a,
10843 RR_NEG = 0x0b,
10844 RR_AND = 0x0c,
10845 RR_OR = 0x0d,
10846 RR_XOR = 0x0e,
10847 RR_NOT = 0x0f,
10848 RR_MFHI = 0x10,
10849 RR_CNVT = 0x11,
10850 RR_MFLO = 0x12,
10851 RR_DSRA = 0x13,
10852 RR_DSLLV = 0x14,
10853 RR_DSRLV = 0x16,
10854 RR_DSRAV = 0x17,
10855 RR_MULT = 0x18,
10856 RR_MULTU = 0x19,
10857 RR_DIV = 0x1a,
10858 RR_DIVU = 0x1b,
10859 RR_DMULT = 0x1c,
10860 RR_DMULTU = 0x1d,
10861 RR_DDIV = 0x1e,
10862 RR_DDIVU = 0x1f
10863};
10864
10865/* I64 funct field */
10866enum {
10867 I64_LDSP = 0x0,
10868 I64_SDSP = 0x1,
10869 I64_SDRASP = 0x2,
10870 I64_DADJSP = 0x3,
10871 I64_LDPC = 0x4,
364d4831 10872 I64_DADDIU5 = 0x5,
6ea219d0
NF
10873 I64_DADDIUPC = 0x6,
10874 I64_DADDIUSP = 0x7
10875};
10876
10877/* RR ry field for CNVT */
10878enum {
10879 RR_RY_CNVT_ZEB = 0x0,
10880 RR_RY_CNVT_ZEH = 0x1,
10881 RR_RY_CNVT_ZEW = 0x2,
10882 RR_RY_CNVT_SEB = 0x4,
10883 RR_RY_CNVT_SEH = 0x5,
10884 RR_RY_CNVT_SEW = 0x6,
10885};
10886
364d4831
NF
10887static int xlat (int r)
10888{
10889 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10890
10891 return map[r];
10892}
10893
10894static void gen_mips16_save (DisasContext *ctx,
10895 int xsregs, int aregs,
10896 int do_ra, int do_s0, int do_s1,
10897 int framesize)
10898{
10899 TCGv t0 = tcg_temp_new();
10900 TCGv t1 = tcg_temp_new();
c48245f0 10901 TCGv t2 = tcg_temp_new();
364d4831
NF
10902 int args, astatic;
10903
10904 switch (aregs) {
10905 case 0:
10906 case 1:
10907 case 2:
10908 case 3:
10909 case 11:
10910 args = 0;
10911 break;
10912 case 4:
10913 case 5:
10914 case 6:
10915 case 7:
10916 args = 1;
10917 break;
10918 case 8:
10919 case 9:
10920 case 10:
10921 args = 2;
10922 break;
10923 case 12:
10924 case 13:
10925 args = 3;
10926 break;
10927 case 14:
10928 args = 4;
10929 break;
10930 default:
9c708c7f 10931 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
10932 return;
10933 }
10934
10935 switch (args) {
10936 case 4:
10937 gen_base_offset_addr(ctx, t0, 29, 12);
10938 gen_load_gpr(t1, 7);
5f68f5ae 10939 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10940 /* Fall through */
10941 case 3:
10942 gen_base_offset_addr(ctx, t0, 29, 8);
10943 gen_load_gpr(t1, 6);
5f68f5ae 10944 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10945 /* Fall through */
10946 case 2:
10947 gen_base_offset_addr(ctx, t0, 29, 4);
10948 gen_load_gpr(t1, 5);
5f68f5ae 10949 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10950 /* Fall through */
10951 case 1:
10952 gen_base_offset_addr(ctx, t0, 29, 0);
10953 gen_load_gpr(t1, 4);
5f68f5ae 10954 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10955 }
10956
10957 gen_load_gpr(t0, 29);
10958
5f68f5ae 10959#define DECR_AND_STORE(reg) do { \
c48245f0
MR
10960 tcg_gen_movi_tl(t2, -4); \
10961 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
10962 gen_load_gpr(t1, reg); \
10963 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10964 } while (0)
10965
10966 if (do_ra) {
10967 DECR_AND_STORE(31);
10968 }
10969
10970 switch (xsregs) {
10971 case 7:
10972 DECR_AND_STORE(30);
10973 /* Fall through */
10974 case 6:
10975 DECR_AND_STORE(23);
10976 /* Fall through */
10977 case 5:
10978 DECR_AND_STORE(22);
10979 /* Fall through */
10980 case 4:
10981 DECR_AND_STORE(21);
10982 /* Fall through */
10983 case 3:
10984 DECR_AND_STORE(20);
10985 /* Fall through */
10986 case 2:
10987 DECR_AND_STORE(19);
10988 /* Fall through */
10989 case 1:
10990 DECR_AND_STORE(18);
10991 }
10992
10993 if (do_s1) {
10994 DECR_AND_STORE(17);
10995 }
10996 if (do_s0) {
10997 DECR_AND_STORE(16);
10998 }
10999
11000 switch (aregs) {
11001 case 0:
11002 case 4:
11003 case 8:
11004 case 12:
11005 case 14:
11006 astatic = 0;
11007 break;
11008 case 1:
11009 case 5:
11010 case 9:
11011 case 13:
11012 astatic = 1;
11013 break;
11014 case 2:
11015 case 6:
11016 case 10:
11017 astatic = 2;
11018 break;
11019 case 3:
11020 case 7:
11021 astatic = 3;
11022 break;
11023 case 11:
11024 astatic = 4;
11025 break;
11026 default:
9c708c7f 11027 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11028 return;
11029 }
11030
11031 if (astatic > 0) {
11032 DECR_AND_STORE(7);
11033 if (astatic > 1) {
11034 DECR_AND_STORE(6);
11035 if (astatic > 2) {
11036 DECR_AND_STORE(5);
11037 if (astatic > 3) {
11038 DECR_AND_STORE(4);
11039 }
11040 }
11041 }
11042 }
11043#undef DECR_AND_STORE
11044
c48245f0
MR
11045 tcg_gen_movi_tl(t2, -framesize);
11046 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11047 tcg_temp_free(t0);
11048 tcg_temp_free(t1);
c48245f0 11049 tcg_temp_free(t2);
364d4831
NF
11050}
11051
11052static void gen_mips16_restore (DisasContext *ctx,
11053 int xsregs, int aregs,
11054 int do_ra, int do_s0, int do_s1,
11055 int framesize)
11056{
11057 int astatic;
11058 TCGv t0 = tcg_temp_new();
11059 TCGv t1 = tcg_temp_new();
c48245f0 11060 TCGv t2 = tcg_temp_new();
364d4831 11061
c48245f0
MR
11062 tcg_gen_movi_tl(t2, framesize);
11063 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11064
5f68f5ae 11065#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11066 tcg_gen_movi_tl(t2, -4); \
11067 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11068 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11069 gen_store_gpr(t1, reg); \
364d4831
NF
11070 } while (0)
11071
11072 if (do_ra) {
11073 DECR_AND_LOAD(31);
11074 }
11075
11076 switch (xsregs) {
11077 case 7:
11078 DECR_AND_LOAD(30);
11079 /* Fall through */
11080 case 6:
11081 DECR_AND_LOAD(23);
11082 /* Fall through */
11083 case 5:
11084 DECR_AND_LOAD(22);
11085 /* Fall through */
11086 case 4:
11087 DECR_AND_LOAD(21);
11088 /* Fall through */
11089 case 3:
11090 DECR_AND_LOAD(20);
11091 /* Fall through */
11092 case 2:
11093 DECR_AND_LOAD(19);
11094 /* Fall through */
11095 case 1:
11096 DECR_AND_LOAD(18);
11097 }
11098
11099 if (do_s1) {
11100 DECR_AND_LOAD(17);
11101 }
11102 if (do_s0) {
11103 DECR_AND_LOAD(16);
11104 }
11105
11106 switch (aregs) {
11107 case 0:
11108 case 4:
11109 case 8:
11110 case 12:
11111 case 14:
11112 astatic = 0;
11113 break;
11114 case 1:
11115 case 5:
11116 case 9:
11117 case 13:
11118 astatic = 1;
11119 break;
11120 case 2:
11121 case 6:
11122 case 10:
11123 astatic = 2;
11124 break;
11125 case 3:
11126 case 7:
11127 astatic = 3;
11128 break;
11129 case 11:
11130 astatic = 4;
11131 break;
11132 default:
9c708c7f 11133 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11134 return;
11135 }
11136
11137 if (astatic > 0) {
11138 DECR_AND_LOAD(7);
11139 if (astatic > 1) {
11140 DECR_AND_LOAD(6);
11141 if (astatic > 2) {
11142 DECR_AND_LOAD(5);
11143 if (astatic > 3) {
11144 DECR_AND_LOAD(4);
11145 }
11146 }
11147 }
11148 }
11149#undef DECR_AND_LOAD
11150
c48245f0
MR
11151 tcg_gen_movi_tl(t2, framesize);
11152 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11153 tcg_temp_free(t0);
11154 tcg_temp_free(t1);
c48245f0 11155 tcg_temp_free(t2);
364d4831
NF
11156}
11157
11158static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11159 int is_64_bit, int extended)
11160{
11161 TCGv t0;
11162
11163 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11164 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11165 return;
11166 }
11167
11168 t0 = tcg_temp_new();
11169
11170 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11171 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11172 if (!is_64_bit) {
11173 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11174 }
11175
11176 tcg_temp_free(t0);
11177}
11178
11179#if defined(TARGET_MIPS64)
d75c135e 11180static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11181 int ry, int funct, int16_t offset,
11182 int extended)
11183{
11184 switch (funct) {
11185 case I64_LDSP:
d9224450 11186 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11187 check_mips_64(ctx);
11188 offset = extended ? offset : offset << 3;
d75c135e 11189 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11190 break;
11191 case I64_SDSP:
d9224450 11192 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11193 check_mips_64(ctx);
11194 offset = extended ? offset : offset << 3;
5c13fdfd 11195 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11196 break;
11197 case I64_SDRASP:
d9224450 11198 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11199 check_mips_64(ctx);
11200 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11201 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11202 break;
11203 case I64_DADJSP:
d9224450 11204 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11205 check_mips_64(ctx);
11206 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11207 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11208 break;
11209 case I64_LDPC:
d9224450
MR
11210 check_insn(ctx, ISA_MIPS3);
11211 check_mips_64(ctx);
364d4831 11212 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11213 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11214 } else {
11215 offset = extended ? offset : offset << 3;
d75c135e 11216 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11217 }
11218 break;
11219 case I64_DADDIU5:
d9224450 11220 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11221 check_mips_64(ctx);
11222 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11223 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11224 break;
11225 case I64_DADDIUPC:
d9224450 11226 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11227 check_mips_64(ctx);
11228 offset = extended ? offset : offset << 2;
11229 gen_addiupc(ctx, ry, offset, 1, extended);
11230 break;
11231 case I64_DADDIUSP:
d9224450 11232 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11233 check_mips_64(ctx);
11234 offset = extended ? offset : offset << 2;
d75c135e 11235 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11236 break;
11237 }
11238}
11239#endif
11240
240ce26a 11241static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11242{
895c2d04 11243 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11244 int op, rx, ry, funct, sa;
11245 int16_t imm, offset;
11246
11247 ctx->opcode = (ctx->opcode << 16) | extend;
11248 op = (ctx->opcode >> 11) & 0x1f;
11249 sa = (ctx->opcode >> 22) & 0x1f;
11250 funct = (ctx->opcode >> 8) & 0x7;
11251 rx = xlat((ctx->opcode >> 8) & 0x7);
11252 ry = xlat((ctx->opcode >> 5) & 0x7);
11253 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11254 | ((ctx->opcode >> 21) & 0x3f) << 5
11255 | (ctx->opcode & 0x1f));
11256
11257 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11258 counterparts. */
11259 switch (op) {
11260 case M16_OPC_ADDIUSP:
d75c135e 11261 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11262 break;
11263 case M16_OPC_ADDIUPC:
11264 gen_addiupc(ctx, rx, imm, 0, 1);
11265 break;
11266 case M16_OPC_B:
b231c103 11267 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11268 /* No delay slot, so just process as a normal instruction */
11269 break;
11270 case M16_OPC_BEQZ:
b231c103 11271 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11272 /* No delay slot, so just process as a normal instruction */
11273 break;
11274 case M16_OPC_BNEQZ:
b231c103 11275 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11276 /* No delay slot, so just process as a normal instruction */
11277 break;
11278 case M16_OPC_SHIFT:
11279 switch (ctx->opcode & 0x3) {
11280 case 0x0:
d75c135e 11281 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11282 break;
11283 case 0x1:
11284#if defined(TARGET_MIPS64)
11285 check_mips_64(ctx);
d75c135e 11286 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11287#else
9c708c7f 11288 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11289#endif
11290 break;
11291 case 0x2:
d75c135e 11292 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11293 break;
11294 case 0x3:
d75c135e 11295 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11296 break;
11297 }
11298 break;
11299#if defined(TARGET_MIPS64)
11300 case M16_OPC_LD:
d9224450 11301 check_insn(ctx, ISA_MIPS3);
d75de749 11302 check_mips_64(ctx);
d75c135e 11303 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11304 break;
11305#endif
11306 case M16_OPC_RRIA:
11307 imm = ctx->opcode & 0xf;
11308 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11309 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11310 imm = (int16_t) (imm << 1) >> 1;
11311 if ((ctx->opcode >> 4) & 0x1) {
11312#if defined(TARGET_MIPS64)
11313 check_mips_64(ctx);
d75c135e 11314 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11315#else
9c708c7f 11316 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11317#endif
11318 } else {
d75c135e 11319 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11320 }
11321 break;
11322 case M16_OPC_ADDIU8:
d75c135e 11323 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11324 break;
11325 case M16_OPC_SLTI:
d75c135e 11326 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11327 break;
11328 case M16_OPC_SLTIU:
d75c135e 11329 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11330 break;
11331 case M16_OPC_I8:
11332 switch (funct) {
11333 case I8_BTEQZ:
b231c103 11334 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11335 break;
11336 case I8_BTNEZ:
b231c103 11337 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11338 break;
11339 case I8_SWRASP:
5c13fdfd 11340 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11341 break;
11342 case I8_ADJSP:
d75c135e 11343 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11344 break;
11345 case I8_SVRS:
d9224450 11346 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11347 {
11348 int xsregs = (ctx->opcode >> 24) & 0x7;
11349 int aregs = (ctx->opcode >> 16) & 0xf;
11350 int do_ra = (ctx->opcode >> 6) & 0x1;
11351 int do_s0 = (ctx->opcode >> 5) & 0x1;
11352 int do_s1 = (ctx->opcode >> 4) & 0x1;
11353 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11354 | (ctx->opcode & 0xf)) << 3;
11355
11356 if (ctx->opcode & (1 << 7)) {
11357 gen_mips16_save(ctx, xsregs, aregs,
11358 do_ra, do_s0, do_s1,
11359 framesize);
11360 } else {
11361 gen_mips16_restore(ctx, xsregs, aregs,
11362 do_ra, do_s0, do_s1,
11363 framesize);
11364 }
11365 }
11366 break;
11367 default:
9c708c7f 11368 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11369 break;
11370 }
11371 break;
11372 case M16_OPC_LI:
11373 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11374 break;
11375 case M16_OPC_CMPI:
11376 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11377 break;
11378#if defined(TARGET_MIPS64)
11379 case M16_OPC_SD:
d9224450
MR
11380 check_insn(ctx, ISA_MIPS3);
11381 check_mips_64(ctx);
5c13fdfd 11382 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11383 break;
11384#endif
11385 case M16_OPC_LB:
d75c135e 11386 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11387 break;
11388 case M16_OPC_LH:
d75c135e 11389 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11390 break;
11391 case M16_OPC_LWSP:
d75c135e 11392 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11393 break;
11394 case M16_OPC_LW:
d75c135e 11395 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11396 break;
11397 case M16_OPC_LBU:
d75c135e 11398 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11399 break;
11400 case M16_OPC_LHU:
d75c135e 11401 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11402 break;
11403 case M16_OPC_LWPC:
d75c135e 11404 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11405 break;
11406#if defined(TARGET_MIPS64)
11407 case M16_OPC_LWU:
d9224450
MR
11408 check_insn(ctx, ISA_MIPS3);
11409 check_mips_64(ctx);
d75c135e 11410 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11411 break;
11412#endif
11413 case M16_OPC_SB:
5c13fdfd 11414 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11415 break;
11416 case M16_OPC_SH:
5c13fdfd 11417 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11418 break;
11419 case M16_OPC_SWSP:
5c13fdfd 11420 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11421 break;
11422 case M16_OPC_SW:
5c13fdfd 11423 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11424 break;
11425#if defined(TARGET_MIPS64)
11426 case M16_OPC_I64:
d75c135e 11427 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11428 break;
11429#endif
11430 default:
9c708c7f 11431 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11432 break;
11433 }
11434
11435 return 4;
11436}
11437
3b3c1694
LA
11438static inline bool is_uhi(int sdbbp_code)
11439{
11440#ifdef CONFIG_USER_ONLY
11441 return false;
11442#else
11443 return semihosting_enabled() && sdbbp_code == 1;
11444#endif
11445}
11446
240ce26a 11447static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11448{
11449 int rx, ry;
11450 int sa;
11451 int op, cnvt_op, op1, offset;
11452 int funct;
11453 int n_bytes;
11454
11455 op = (ctx->opcode >> 11) & 0x1f;
11456 sa = (ctx->opcode >> 2) & 0x7;
11457 sa = sa == 0 ? 8 : sa;
11458 rx = xlat((ctx->opcode >> 8) & 0x7);
11459 cnvt_op = (ctx->opcode >> 5) & 0x7;
11460 ry = xlat((ctx->opcode >> 5) & 0x7);
11461 op1 = offset = ctx->opcode & 0x1f;
11462
11463 n_bytes = 2;
11464
11465 switch (op) {
11466 case M16_OPC_ADDIUSP:
11467 {
11468 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11469
d75c135e 11470 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11471 }
11472 break;
11473 case M16_OPC_ADDIUPC:
11474 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11475 break;
11476 case M16_OPC_B:
11477 offset = (ctx->opcode & 0x7ff) << 1;
11478 offset = (int16_t)(offset << 4) >> 4;
b231c103 11479 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11480 /* No delay slot, so just process as a normal instruction */
11481 break;
11482 case M16_OPC_JAL:
895c2d04 11483 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11484 offset = (((ctx->opcode & 0x1f) << 21)
11485 | ((ctx->opcode >> 5) & 0x1f) << 16
11486 | offset) << 2;
b231c103
YK
11487 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11488 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11489 n_bytes = 4;
364d4831
NF
11490 break;
11491 case M16_OPC_BEQZ:
b231c103
YK
11492 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11493 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11494 /* No delay slot, so just process as a normal instruction */
11495 break;
11496 case M16_OPC_BNEQZ:
b231c103
YK
11497 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11498 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11499 /* No delay slot, so just process as a normal instruction */
11500 break;
11501 case M16_OPC_SHIFT:
11502 switch (ctx->opcode & 0x3) {
11503 case 0x0:
d75c135e 11504 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11505 break;
11506 case 0x1:
11507#if defined(TARGET_MIPS64)
d9224450 11508 check_insn(ctx, ISA_MIPS3);
364d4831 11509 check_mips_64(ctx);
d75c135e 11510 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11511#else
9c708c7f 11512 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11513#endif
11514 break;
11515 case 0x2:
d75c135e 11516 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11517 break;
11518 case 0x3:
d75c135e 11519 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11520 break;
11521 }
11522 break;
11523#if defined(TARGET_MIPS64)
11524 case M16_OPC_LD:
d9224450 11525 check_insn(ctx, ISA_MIPS3);
364d4831 11526 check_mips_64(ctx);
d75c135e 11527 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11528 break;
11529#endif
11530 case M16_OPC_RRIA:
11531 {
11532 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11533
11534 if ((ctx->opcode >> 4) & 1) {
11535#if defined(TARGET_MIPS64)
d9224450 11536 check_insn(ctx, ISA_MIPS3);
364d4831 11537 check_mips_64(ctx);
d75c135e 11538 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11539#else
9c708c7f 11540 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11541#endif
11542 } else {
d75c135e 11543 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11544 }
11545 }
11546 break;
11547 case M16_OPC_ADDIU8:
11548 {
11549 int16_t imm = (int8_t) ctx->opcode;
11550
d75c135e 11551 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11552 }
11553 break;
11554 case M16_OPC_SLTI:
11555 {
11556 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11557 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11558 }
11559 break;
11560 case M16_OPC_SLTIU:
11561 {
11562 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11563 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11564 }
11565 break;
11566 case M16_OPC_I8:
11567 {
11568 int reg32;
11569
11570 funct = (ctx->opcode >> 8) & 0x7;
11571 switch (funct) {
11572 case I8_BTEQZ:
11573 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11574 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11575 break;
11576 case I8_BTNEZ:
11577 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11578 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11579 break;
11580 case I8_SWRASP:
5c13fdfd 11581 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11582 break;
11583 case I8_ADJSP:
d75c135e 11584 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11585 ((int8_t)ctx->opcode) << 3);
11586 break;
11587 case I8_SVRS:
d9224450 11588 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11589 {
11590 int do_ra = ctx->opcode & (1 << 6);
11591 int do_s0 = ctx->opcode & (1 << 5);
11592 int do_s1 = ctx->opcode & (1 << 4);
11593 int framesize = ctx->opcode & 0xf;
11594
11595 if (framesize == 0) {
11596 framesize = 128;
11597 } else {
11598 framesize = framesize << 3;
11599 }
11600
11601 if (ctx->opcode & (1 << 7)) {
11602 gen_mips16_save(ctx, 0, 0,
11603 do_ra, do_s0, do_s1, framesize);
11604 } else {
11605 gen_mips16_restore(ctx, 0, 0,
11606 do_ra, do_s0, do_s1, framesize);
11607 }
11608 }
11609 break;
11610 case I8_MOV32R:
11611 {
11612 int rz = xlat(ctx->opcode & 0x7);
11613
11614 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11615 ((ctx->opcode >> 5) & 0x7);
d75c135e 11616 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11617 }
11618 break;
11619 case I8_MOVR32:
11620 reg32 = ctx->opcode & 0x1f;
d75c135e 11621 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11622 break;
11623 default:
9c708c7f 11624 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11625 break;
11626 }
11627 }
11628 break;
11629 case M16_OPC_LI:
11630 {
11631 int16_t imm = (uint8_t) ctx->opcode;
11632
d75c135e 11633 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11634 }
11635 break;
11636 case M16_OPC_CMPI:
11637 {
11638 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11639 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11640 }
11641 break;
11642#if defined(TARGET_MIPS64)
11643 case M16_OPC_SD:
d9224450 11644 check_insn(ctx, ISA_MIPS3);
364d4831 11645 check_mips_64(ctx);
5c13fdfd 11646 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11647 break;
11648#endif
11649 case M16_OPC_LB:
d75c135e 11650 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11651 break;
11652 case M16_OPC_LH:
d75c135e 11653 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11654 break;
11655 case M16_OPC_LWSP:
d75c135e 11656 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11657 break;
11658 case M16_OPC_LW:
d75c135e 11659 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11660 break;
11661 case M16_OPC_LBU:
d75c135e 11662 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11663 break;
11664 case M16_OPC_LHU:
d75c135e 11665 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11666 break;
11667 case M16_OPC_LWPC:
d75c135e 11668 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11669 break;
11670#if defined (TARGET_MIPS64)
11671 case M16_OPC_LWU:
d9224450 11672 check_insn(ctx, ISA_MIPS3);
364d4831 11673 check_mips_64(ctx);
d75c135e 11674 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11675 break;
11676#endif
11677 case M16_OPC_SB:
5c13fdfd 11678 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11679 break;
11680 case M16_OPC_SH:
5c13fdfd 11681 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11682 break;
11683 case M16_OPC_SWSP:
5c13fdfd 11684 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11685 break;
11686 case M16_OPC_SW:
5c13fdfd 11687 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11688 break;
11689 case M16_OPC_RRR:
11690 {
11691 int rz = xlat((ctx->opcode >> 2) & 0x7);
11692 int mips32_op;
11693
11694 switch (ctx->opcode & 0x3) {
11695 case RRR_ADDU:
11696 mips32_op = OPC_ADDU;
11697 break;
11698 case RRR_SUBU:
11699 mips32_op = OPC_SUBU;
11700 break;
11701#if defined(TARGET_MIPS64)
11702 case RRR_DADDU:
11703 mips32_op = OPC_DADDU;
d9224450 11704 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11705 check_mips_64(ctx);
11706 break;
11707 case RRR_DSUBU:
11708 mips32_op = OPC_DSUBU;
d9224450 11709 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11710 check_mips_64(ctx);
11711 break;
11712#endif
11713 default:
9c708c7f 11714 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11715 goto done;
11716 }
11717
d75c135e 11718 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11719 done:
11720 ;
11721 }
11722 break;
11723 case M16_OPC_RR:
11724 switch (op1) {
11725 case RR_JR:
11726 {
11727 int nd = (ctx->opcode >> 7) & 0x1;
11728 int link = (ctx->opcode >> 6) & 0x1;
11729 int ra = (ctx->opcode >> 5) & 0x1;
11730
d9224450
MR
11731 if (nd) {
11732 check_insn(ctx, ISA_MIPS32);
11733 }
11734
364d4831 11735 if (link) {
b231c103 11736 op = OPC_JALR;
364d4831
NF
11737 } else {
11738 op = OPC_JR;
11739 }
11740
b231c103
YK
11741 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11742 (nd ? 0 : 2));
364d4831
NF
11743 }
11744 break;
11745 case RR_SDBBP:
3b3c1694
LA
11746 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11747 gen_helper_do_semihosting(cpu_env);
11748 } else {
11749 /* XXX: not clear which exception should be raised
11750 * when in debug mode...
11751 */
11752 check_insn(ctx, ISA_MIPS32);
9c708c7f 11753 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 11754 }
364d4831
NF
11755 break;
11756 case RR_SLT:
d75c135e 11757 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11758 break;
11759 case RR_SLTU:
d75c135e 11760 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11761 break;
11762 case RR_BREAK:
9c708c7f 11763 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
11764 break;
11765 case RR_SLLV:
d75c135e 11766 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11767 break;
11768 case RR_SRLV:
d75c135e 11769 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11770 break;
11771 case RR_SRAV:
d75c135e 11772 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11773 break;
11774#if defined (TARGET_MIPS64)
11775 case RR_DSRL:
d9224450 11776 check_insn(ctx, ISA_MIPS3);
364d4831 11777 check_mips_64(ctx);
d75c135e 11778 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11779 break;
11780#endif
11781 case RR_CMP:
d75c135e 11782 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11783 break;
11784 case RR_NEG:
d75c135e 11785 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11786 break;
11787 case RR_AND:
d75c135e 11788 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11789 break;
11790 case RR_OR:
d75c135e 11791 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11792 break;
11793 case RR_XOR:
d75c135e 11794 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11795 break;
11796 case RR_NOT:
d75c135e 11797 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11798 break;
11799 case RR_MFHI:
26135ead 11800 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11801 break;
11802 case RR_CNVT:
d9224450 11803 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11804 switch (cnvt_op) {
11805 case RR_RY_CNVT_ZEB:
11806 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11807 break;
11808 case RR_RY_CNVT_ZEH:
11809 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11810 break;
11811 case RR_RY_CNVT_SEB:
11812 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11813 break;
11814 case RR_RY_CNVT_SEH:
11815 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11816 break;
11817#if defined (TARGET_MIPS64)
11818 case RR_RY_CNVT_ZEW:
d9224450 11819 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11820 check_mips_64(ctx);
11821 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11822 break;
11823 case RR_RY_CNVT_SEW:
d9224450 11824 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11825 check_mips_64(ctx);
11826 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11827 break;
11828#endif
11829 default:
9c708c7f 11830 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11831 break;
11832 }
11833 break;
11834 case RR_MFLO:
26135ead 11835 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11836 break;
11837#if defined (TARGET_MIPS64)
11838 case RR_DSRA:
d9224450 11839 check_insn(ctx, ISA_MIPS3);
364d4831 11840 check_mips_64(ctx);
d75c135e 11841 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11842 break;
11843 case RR_DSLLV:
d9224450 11844 check_insn(ctx, ISA_MIPS3);
364d4831 11845 check_mips_64(ctx);
d75c135e 11846 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11847 break;
11848 case RR_DSRLV:
d9224450 11849 check_insn(ctx, ISA_MIPS3);
364d4831 11850 check_mips_64(ctx);
d75c135e 11851 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11852 break;
11853 case RR_DSRAV:
d9224450 11854 check_insn(ctx, ISA_MIPS3);
364d4831 11855 check_mips_64(ctx);
d75c135e 11856 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11857 break;
11858#endif
11859 case RR_MULT:
26135ead 11860 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11861 break;
11862 case RR_MULTU:
26135ead 11863 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11864 break;
11865 case RR_DIV:
26135ead 11866 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11867 break;
11868 case RR_DIVU:
26135ead 11869 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11870 break;
11871#if defined (TARGET_MIPS64)
11872 case RR_DMULT:
d9224450 11873 check_insn(ctx, ISA_MIPS3);
364d4831 11874 check_mips_64(ctx);
26135ead 11875 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11876 break;
11877 case RR_DMULTU:
d9224450 11878 check_insn(ctx, ISA_MIPS3);
364d4831 11879 check_mips_64(ctx);
26135ead 11880 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11881 break;
11882 case RR_DDIV:
d9224450 11883 check_insn(ctx, ISA_MIPS3);
364d4831 11884 check_mips_64(ctx);
26135ead 11885 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11886 break;
11887 case RR_DDIVU:
d9224450 11888 check_insn(ctx, ISA_MIPS3);
364d4831 11889 check_mips_64(ctx);
26135ead 11890 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11891 break;
11892#endif
11893 default:
9c708c7f 11894 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11895 break;
11896 }
11897 break;
11898 case M16_OPC_EXTEND:
240ce26a 11899 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11900 n_bytes = 4;
11901 break;
11902#if defined(TARGET_MIPS64)
11903 case M16_OPC_I64:
11904 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11905 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11906 break;
11907#endif
11908 default:
9c708c7f 11909 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11910 break;
11911 }
11912
11913 return n_bytes;
11914}
11915
211da992 11916/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11917
211da992
CWR
11918/*
11919 * microMIPS32/microMIPS64 major opcodes
11920 *
11921 * 1. MIPS Architecture for Programmers Volume II-B:
11922 * The microMIPS32 Instruction Set (Revision 3.05)
11923 *
11924 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11925 *
11926 * 2. MIPS Architecture For Programmers Volume II-A:
11927 * The MIPS64 Instruction Set (Revision 3.51)
11928 */
6af0bf9c 11929
3c824109
NF
11930enum {
11931 POOL32A = 0x00,
11932 POOL16A = 0x01,
11933 LBU16 = 0x02,
11934 MOVE16 = 0x03,
11935 ADDI32 = 0x04,
3a1f4268
YK
11936 R6_LUI = 0x04,
11937 AUI = 0x04,
3c824109
NF
11938 LBU32 = 0x05,
11939 SB32 = 0x06,
11940 LB32 = 0x07,
11941
11942 POOL32B = 0x08,
11943 POOL16B = 0x09,
11944 LHU16 = 0x0a,
11945 ANDI16 = 0x0b,
11946 ADDIU32 = 0x0c,
11947 LHU32 = 0x0d,
11948 SH32 = 0x0e,
11949 LH32 = 0x0f,
11950
11951 POOL32I = 0x10,
11952 POOL16C = 0x11,
11953 LWSP16 = 0x12,
11954 POOL16D = 0x13,
11955 ORI32 = 0x14,
11956 POOL32F = 0x15,
211da992
CWR
11957 POOL32S = 0x16, /* MIPS64 */
11958 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
11959
11960 POOL32C = 0x18,
11961 LWGP16 = 0x19,
11962 LW16 = 0x1a,
11963 POOL16E = 0x1b,
11964 XORI32 = 0x1c,
11965 JALS32 = 0x1d,
3a1f4268
YK
11966 BOVC = 0x1d,
11967 BEQC = 0x1d,
11968 BEQZALC = 0x1d,
3c824109 11969 ADDIUPC = 0x1e,
3a1f4268
YK
11970 PCREL = 0x1e,
11971 BNVC = 0x1f,
11972 BNEC = 0x1f,
11973 BNEZALC = 0x1f,
3c824109 11974
3a1f4268
YK
11975 R6_BEQZC = 0x20,
11976 JIC = 0x20,
3c824109
NF
11977 POOL16F = 0x21,
11978 SB16 = 0x22,
11979 BEQZ16 = 0x23,
3a1f4268 11980 BEQZC16 = 0x23,
3c824109
NF
11981 SLTI32 = 0x24,
11982 BEQ32 = 0x25,
3a1f4268 11983 BC = 0x25,
3c824109
NF
11984 SWC132 = 0x26,
11985 LWC132 = 0x27,
11986
3a1f4268 11987 /* 0x29 is reserved */
3c824109 11988 RES_29 = 0x29,
3a1f4268
YK
11989 R6_BNEZC = 0x28,
11990 JIALC = 0x28,
3c824109
NF
11991 SH16 = 0x2a,
11992 BNEZ16 = 0x2b,
3a1f4268 11993 BNEZC16 = 0x2b,
3c824109
NF
11994 SLTIU32 = 0x2c,
11995 BNE32 = 0x2d,
3a1f4268 11996 BALC = 0x2d,
3c824109
NF
11997 SDC132 = 0x2e,
11998 LDC132 = 0x2f,
11999
3a1f4268 12000 /* 0x31 is reserved */
3c824109 12001 RES_31 = 0x31,
3a1f4268
YK
12002 BLEZALC = 0x30,
12003 BGEZALC = 0x30,
12004 BGEUC = 0x30,
3c824109
NF
12005 SWSP16 = 0x32,
12006 B16 = 0x33,
3a1f4268 12007 BC16 = 0x33,
3c824109
NF
12008 ANDI32 = 0x34,
12009 J32 = 0x35,
3a1f4268
YK
12010 BGTZC = 0x35,
12011 BLTZC = 0x35,
12012 BLTC = 0x35,
211da992
CWR
12013 SD32 = 0x36, /* MIPS64 */
12014 LD32 = 0x37, /* MIPS64 */
3c824109 12015
3a1f4268 12016 /* 0x39 is reserved */
3c824109 12017 RES_39 = 0x39,
3a1f4268
YK
12018 BGTZALC = 0x38,
12019 BLTZALC = 0x38,
12020 BLTUC = 0x38,
3c824109
NF
12021 SW16 = 0x3a,
12022 LI16 = 0x3b,
12023 JALX32 = 0x3c,
12024 JAL32 = 0x3d,
3a1f4268
YK
12025 BLEZC = 0x3d,
12026 BGEZC = 0x3d,
12027 BGEC = 0x3d,
3c824109
NF
12028 SW32 = 0x3e,
12029 LW32 = 0x3f
12030};
12031
3a1f4268
YK
12032/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12033enum {
12034 ADDIUPC_00 = 0x00,
12035 ADDIUPC_07 = 0x07,
12036 AUIPC = 0x1e,
12037 ALUIPC = 0x1f,
12038 LWPC_08 = 0x08,
12039 LWPC_0F = 0x0F,
12040};
12041
3c824109
NF
12042/* POOL32A encoding of minor opcode field */
12043
12044enum {
12045 /* These opcodes are distinguished only by bits 9..6; those bits are
12046 * what are recorded below. */
12047 SLL32 = 0x0,
12048 SRL32 = 0x1,
12049 SRA = 0x2,
12050 ROTR = 0x3,
3a1f4268
YK
12051 SELEQZ = 0x5,
12052 SELNEZ = 0x6,
b00c7218 12053 R6_RDHWR = 0x7,
3c824109
NF
12054
12055 SLLV = 0x0,
12056 SRLV = 0x1,
12057 SRAV = 0x2,
12058 ROTRV = 0x3,
12059 ADD = 0x4,
12060 ADDU32 = 0x5,
12061 SUB = 0x6,
12062 SUBU32 = 0x7,
12063 MUL = 0x8,
12064 AND = 0x9,
12065 OR32 = 0xa,
12066 NOR = 0xb,
12067 XOR32 = 0xc,
12068 SLT = 0xd,
12069 SLTU = 0xe,
12070
12071 MOVN = 0x0,
3a1f4268 12072 R6_MUL = 0x0,
3c824109 12073 MOVZ = 0x1,
3a1f4268
YK
12074 MUH = 0x1,
12075 MULU = 0x2,
12076 MUHU = 0x3,
3c824109 12077 LWXS = 0x4,
3a1f4268
YK
12078 R6_DIV = 0x4,
12079 MOD = 0x5,
12080 R6_DIVU = 0x6,
12081 MODU = 0x7,
3c824109
NF
12082
12083 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12084 BREAK32 = 0x07,
3c824109 12085 INS = 0x0c,
3a1f4268
YK
12086 LSA = 0x0f,
12087 ALIGN = 0x1f,
3c824109 12088 EXT = 0x2c,
bb238210
YK
12089 POOL32AXF = 0x3c,
12090 SIGRIE = 0x3f
3c824109
NF
12091};
12092
12093/* POOL32AXF encoding of minor opcode field extension */
12094
d132c79f
CWR
12095/*
12096 * 1. MIPS Architecture for Programmers Volume II-B:
12097 * The microMIPS32 Instruction Set (Revision 3.05)
12098 *
12099 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12100 *
12101 * 2. MIPS Architecture for Programmers VolumeIV-e:
12102 * The MIPS DSP Application-Specific Extension
12103 * to the microMIPS32 Architecture (Revision 2.34)
12104 *
12105 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12106 */
12107
3c824109
NF
12108enum {
12109 /* bits 11..6 */
12110 TEQ = 0x00,
12111 TGE = 0x08,
12112 TGEU = 0x10,
12113 TLT = 0x20,
12114 TLTU = 0x28,
12115 TNE = 0x30,
12116
12117 MFC0 = 0x03,
12118 MTC0 = 0x0b,
12119
d132c79f
CWR
12120 /* begin of microMIPS32 DSP */
12121
3c824109
NF
12122 /* bits 13..12 for 0x01 */
12123 MFHI_ACC = 0x0,
12124 MFLO_ACC = 0x1,
12125 MTHI_ACC = 0x2,
12126 MTLO_ACC = 0x3,
12127
12128 /* bits 13..12 for 0x2a */
12129 MADD_ACC = 0x0,
12130 MADDU_ACC = 0x1,
12131 MSUB_ACC = 0x2,
12132 MSUBU_ACC = 0x3,
12133
12134 /* bits 13..12 for 0x32 */
12135 MULT_ACC = 0x0,
6801038b 12136 MULTU_ACC = 0x1,
3c824109 12137
d132c79f
CWR
12138 /* end of microMIPS32 DSP */
12139
3c824109 12140 /* bits 15..12 for 0x2c */
3a1f4268 12141 BITSWAP = 0x0,
3c824109
NF
12142 SEB = 0x2,
12143 SEH = 0x3,
12144 CLO = 0x4,
12145 CLZ = 0x5,
12146 RDHWR = 0x6,
12147 WSBH = 0x7,
12148 MULT = 0x8,
12149 MULTU = 0x9,
12150 DIV = 0xa,
12151 DIVU = 0xb,
12152 MADD = 0xc,
12153 MADDU = 0xd,
12154 MSUB = 0xe,
12155 MSUBU = 0xf,
12156
12157 /* bits 15..12 for 0x34 */
12158 MFC2 = 0x4,
12159 MTC2 = 0x5,
12160 MFHC2 = 0x8,
12161 MTHC2 = 0x9,
12162 CFC2 = 0xc,
12163 CTC2 = 0xd,
12164
12165 /* bits 15..12 for 0x3c */
12166 JALR = 0x0,
12167 JR = 0x0, /* alias */
3a1f4268
YK
12168 JALRC = 0x0,
12169 JRC = 0x0,
3c824109 12170 JALR_HB = 0x1,
3a1f4268 12171 JALRC_HB = 0x1,
3c824109
NF
12172 JALRS = 0x4,
12173 JALRS_HB = 0x5,
12174
12175 /* bits 15..12 for 0x05 */
12176 RDPGPR = 0xe,
12177 WRPGPR = 0xf,
12178
12179 /* bits 15..12 for 0x0d */
12180 TLBP = 0x0,
12181 TLBR = 0x1,
12182 TLBWI = 0x2,
12183 TLBWR = 0x3,
e60ec063
YK
12184 TLBINV = 0x4,
12185 TLBINVF = 0x5,
3c824109
NF
12186 WAIT = 0x9,
12187 IRET = 0xd,
12188 DERET = 0xe,
12189 ERET = 0xf,
12190
12191 /* bits 15..12 for 0x15 */
12192 DMT = 0x0,
12193 DVPE = 0x1,
12194 EMT = 0x2,
12195 EVPE = 0x3,
12196
12197 /* bits 15..12 for 0x1d */
12198 DI = 0x4,
12199 EI = 0x5,
12200
12201 /* bits 15..12 for 0x2d */
12202 SYNC = 0x6,
12203 SYSCALL = 0x8,
12204 SDBBP = 0xd,
12205
12206 /* bits 15..12 for 0x35 */
12207 MFHI32 = 0x0,
12208 MFLO32 = 0x1,
12209 MTHI32 = 0x2,
12210 MTLO32 = 0x3,
12211};
12212
12213/* POOL32B encoding of minor opcode field (bits 15..12) */
12214
12215enum {
12216 LWC2 = 0x0,
12217 LWP = 0x1,
12218 LDP = 0x4,
12219 LWM32 = 0x5,
12220 CACHE = 0x6,
12221 LDM = 0x7,
12222 SWC2 = 0x8,
12223 SWP = 0x9,
12224 SDP = 0xc,
12225 SWM32 = 0xd,
12226 SDM = 0xf
12227};
12228
12229/* POOL32C encoding of minor opcode field (bits 15..12) */
12230
12231enum {
12232 LWL = 0x0,
12233 SWL = 0x8,
12234 LWR = 0x1,
12235 SWR = 0x9,
12236 PREF = 0x2,
12237 /* 0xa is reserved */
12238 LL = 0x3,
12239 SC = 0xb,
12240 LDL = 0x4,
12241 SDL = 0xc,
12242 LDR = 0x5,
12243 SDR = 0xd,
12244 /* 0x6 is reserved */
12245 LWU = 0xe,
12246 LLD = 0x7,
12247 SCD = 0xf
12248};
12249
12250/* POOL32F encoding of minor opcode field (bits 5..0) */
12251
12252enum {
12253 /* These are the bit 7..6 values */
12254 ADD_FMT = 0x0,
3c824109
NF
12255
12256 SUB_FMT = 0x1,
3c824109
NF
12257
12258 MUL_FMT = 0x2,
12259
12260 DIV_FMT = 0x3,
12261
12262 /* These are the bit 8..6 values */
3a1f4268 12263 MOVN_FMT = 0x0,
3c824109
NF
12264 RSQRT2_FMT = 0x0,
12265 MOVF_FMT = 0x0,
3a1f4268
YK
12266 RINT_FMT = 0x0,
12267 SELNEZ_FMT = 0x0,
3c824109 12268
3a1f4268 12269 MOVZ_FMT = 0x1,
3c824109
NF
12270 LWXC1 = 0x1,
12271 MOVT_FMT = 0x1,
3a1f4268
YK
12272 CLASS_FMT = 0x1,
12273 SELEQZ_FMT = 0x1,
3c824109
NF
12274
12275 PLL_PS = 0x2,
12276 SWXC1 = 0x2,
3a1f4268 12277 SEL_FMT = 0x2,
3c824109
NF
12278
12279 PLU_PS = 0x3,
12280 LDXC1 = 0x3,
12281
3a1f4268 12282 MOVN_FMT_04 = 0x4,
3c824109
NF
12283 PUL_PS = 0x4,
12284 SDXC1 = 0x4,
12285 RECIP2_FMT = 0x4,
12286
3a1f4268 12287 MOVZ_FMT_05 = 0x05,
3c824109
NF
12288 PUU_PS = 0x5,
12289 LUXC1 = 0x5,
12290
12291 CVT_PS_S = 0x6,
12292 SUXC1 = 0x6,
12293 ADDR_PS = 0x6,
12294 PREFX = 0x6,
3a1f4268 12295 MADDF_FMT = 0x6,
3c824109
NF
12296
12297 MULR_PS = 0x7,
3a1f4268 12298 MSUBF_FMT = 0x7,
3c824109
NF
12299
12300 MADD_S = 0x01,
12301 MADD_D = 0x09,
12302 MADD_PS = 0x11,
12303 ALNV_PS = 0x19,
12304 MSUB_S = 0x21,
12305 MSUB_D = 0x29,
12306 MSUB_PS = 0x31,
12307
12308 NMADD_S = 0x02,
12309 NMADD_D = 0x0a,
12310 NMADD_PS = 0x12,
12311 NMSUB_S = 0x22,
12312 NMSUB_D = 0x2a,
12313 NMSUB_PS = 0x32,
12314
3a1f4268
YK
12315 MIN_FMT = 0x3,
12316 MAX_FMT = 0xb,
12317 MINA_FMT = 0x23,
12318 MAXA_FMT = 0x2b,
3c824109
NF
12319 POOL32FXF = 0x3b,
12320
12321 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12322 C_COND_FMT = 0x3c,
12323
12324 CMP_CONDN_S = 0x5,
12325 CMP_CONDN_D = 0x15
3c824109
NF
12326};
12327
12328/* POOL32Fxf encoding of minor opcode extension field */
12329
12330enum {
12331 CVT_L = 0x04,
12332 RSQRT_FMT = 0x08,
12333 FLOOR_L = 0x0c,
12334 CVT_PW_PS = 0x1c,
12335 CVT_W = 0x24,
12336 SQRT_FMT = 0x28,
12337 FLOOR_W = 0x2c,
12338 CVT_PS_PW = 0x3c,
12339 CFC1 = 0x40,
12340 RECIP_FMT = 0x48,
12341 CEIL_L = 0x4c,
12342 CTC1 = 0x60,
12343 CEIL_W = 0x6c,
12344 MFC1 = 0x80,
12345 CVT_S_PL = 0x84,
12346 TRUNC_L = 0x8c,
12347 MTC1 = 0xa0,
12348 CVT_S_PU = 0xa4,
12349 TRUNC_W = 0xac,
12350 MFHC1 = 0xc0,
12351 ROUND_L = 0xcc,
12352 MTHC1 = 0xe0,
12353 ROUND_W = 0xec,
12354
12355 MOV_FMT = 0x01,
12356 MOVF = 0x05,
12357 ABS_FMT = 0x0d,
12358 RSQRT1_FMT = 0x1d,
12359 MOVT = 0x25,
12360 NEG_FMT = 0x2d,
12361 CVT_D = 0x4d,
12362 RECIP1_FMT = 0x5d,
12363 CVT_S = 0x6d
12364};
12365
12366/* POOL32I encoding of minor opcode field (bits 25..21) */
12367
12368enum {
12369 BLTZ = 0x00,
12370 BLTZAL = 0x01,
12371 BGEZ = 0x02,
12372 BGEZAL = 0x03,
12373 BLEZ = 0x04,
12374 BNEZC = 0x05,
12375 BGTZ = 0x06,
12376 BEQZC = 0x07,
12377 TLTI = 0x08,
3a1f4268 12378 BC1EQZC = 0x08,
3c824109 12379 TGEI = 0x09,
3a1f4268 12380 BC1NEZC = 0x09,
3c824109 12381 TLTIU = 0x0a,
3a1f4268 12382 BC2EQZC = 0x0a,
3c824109 12383 TGEIU = 0x0b,
3a1f4268 12384 BC2NEZC = 0x0a,
3c824109 12385 TNEI = 0x0c,
3a1f4268 12386 R6_SYNCI = 0x0c,
3c824109
NF
12387 LUI = 0x0d,
12388 TEQI = 0x0e,
12389 SYNCI = 0x10,
12390 BLTZALS = 0x11,
12391 BGEZALS = 0x13,
12392 BC2F = 0x14,
12393 BC2T = 0x15,
12394 BPOSGE64 = 0x1a,
12395 BPOSGE32 = 0x1b,
12396 /* These overlap and are distinguished by bit16 of the instruction */
12397 BC1F = 0x1c,
12398 BC1T = 0x1d,
12399 BC1ANY2F = 0x1c,
12400 BC1ANY2T = 0x1d,
12401 BC1ANY4F = 0x1e,
12402 BC1ANY4T = 0x1f
12403};
12404
12405/* POOL16A encoding of minor opcode field */
12406
12407enum {
12408 ADDU16 = 0x0,
12409 SUBU16 = 0x1
12410};
12411
12412/* POOL16B encoding of minor opcode field */
12413
12414enum {
12415 SLL16 = 0x0,
12416 SRL16 = 0x1
12417};
12418
12419/* POOL16C encoding of minor opcode field */
12420
12421enum {
12422 NOT16 = 0x00,
12423 XOR16 = 0x04,
12424 AND16 = 0x08,
12425 OR16 = 0x0c,
12426 LWM16 = 0x10,
12427 SWM16 = 0x14,
12428 JR16 = 0x18,
12429 JRC16 = 0x1a,
12430 JALR16 = 0x1c,
12431 JALR16S = 0x1e,
12432 MFHI16 = 0x20,
12433 MFLO16 = 0x24,
12434 BREAK16 = 0x28,
12435 SDBBP16 = 0x2c,
12436 JRADDIUSP = 0x30
12437};
12438
3a1f4268
YK
12439/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12440
12441enum {
12442 R6_NOT16 = 0x00,
12443 R6_AND16 = 0x01,
12444 R6_LWM16 = 0x02,
12445 R6_JRC16 = 0x03,
12446 MOVEP = 0x04,
12447 MOVEP_07 = 0x07,
12448 R6_XOR16 = 0x08,
12449 R6_OR16 = 0x09,
12450 R6_SWM16 = 0x0a,
12451 JALRC16 = 0x0b,
12452 MOVEP_0C = 0x0c,
12453 MOVEP_0F = 0x0f,
12454 JRCADDIUSP = 0x13,
12455 R6_BREAK16 = 0x1b,
12456 R6_SDBBP16 = 0x3b
12457};
12458
3c824109
NF
12459/* POOL16D encoding of minor opcode field */
12460
12461enum {
12462 ADDIUS5 = 0x0,
12463 ADDIUSP = 0x1
12464};
12465
12466/* POOL16E encoding of minor opcode field */
12467
12468enum {
12469 ADDIUR2 = 0x0,
12470 ADDIUR1SP = 0x1
12471};
12472
12473static int mmreg (int r)
12474{
12475 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12476
12477 return map[r];
12478}
12479
12480/* Used for 16-bit store instructions. */
12481static int mmreg2 (int r)
12482{
12483 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12484
12485 return map[r];
12486}
12487
12488#define uMIPS_RD(op) ((op >> 7) & 0x7)
12489#define uMIPS_RS(op) ((op >> 4) & 0x7)
12490#define uMIPS_RS2(op) uMIPS_RS(op)
12491#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12492#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12493#define uMIPS_RS5(op) (op & 0x1f)
12494
12495/* Signed immediate */
12496#define SIMM(op, start, width) \
12497 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12498 << (32-width)) \
12499 >> (32-width))
12500/* Zero-extended immediate */
12501#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12502
d75c135e 12503static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12504{
12505 int rd = mmreg(uMIPS_RD(ctx->opcode));
12506
d75c135e 12507 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12508}
12509
d75c135e 12510static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12511{
12512 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12513 int rd = mmreg(uMIPS_RD(ctx->opcode));
12514 int rs = mmreg(uMIPS_RS(ctx->opcode));
12515
d75c135e 12516 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12517}
12518
d75c135e 12519static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12520{
12521 int encoded = ZIMM(ctx->opcode, 1, 9);
12522 int decoded;
12523
12524 if (encoded <= 1) {
12525 decoded = 256 + encoded;
12526 } else if (encoded <= 255) {
12527 decoded = encoded;
12528 } else if (encoded <= 509) {
12529 decoded = encoded - 512;
12530 } else {
12531 decoded = encoded - 768;
12532 }
12533
d75c135e 12534 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12535}
12536
d75c135e 12537static void gen_addius5(DisasContext *ctx)
3c824109
NF
12538{
12539 int imm = SIMM(ctx->opcode, 1, 4);
12540 int rd = (ctx->opcode >> 5) & 0x1f;
12541
d75c135e 12542 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12543}
12544
d75c135e 12545static void gen_andi16(DisasContext *ctx)
3c824109
NF
12546{
12547 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12548 31, 32, 63, 64, 255, 32768, 65535 };
12549 int rd = mmreg(uMIPS_RD(ctx->opcode));
12550 int rs = mmreg(uMIPS_RS(ctx->opcode));
12551 int encoded = ZIMM(ctx->opcode, 0, 4);
12552
d75c135e 12553 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12554}
12555
12556static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12557 int base, int16_t offset)
12558{
12559 TCGv t0, t1;
12560 TCGv_i32 t2;
12561
12562 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12563 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12564 return;
12565 }
12566
12567 t0 = tcg_temp_new();
12568
12569 gen_base_offset_addr(ctx, t0, base, offset);
12570
12571 t1 = tcg_const_tl(reglist);
12572 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12573
3c824109
NF
12574 save_cpu_state(ctx, 1);
12575 switch (opc) {
12576 case LWM32:
895c2d04 12577 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12578 break;
12579 case SWM32:
895c2d04 12580 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12581 break;
12582#ifdef TARGET_MIPS64
12583 case LDM:
895c2d04 12584 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12585 break;
12586 case SDM:
895c2d04 12587 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12588 break;
6af0bf9c 12589#endif
3c824109 12590 }
3c824109 12591 tcg_temp_free(t0);
33087598 12592 tcg_temp_free(t1);
3c824109
NF
12593 tcg_temp_free_i32(t2);
12594}
6af0bf9c 12595
3c824109 12596
240ce26a 12597static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12598{
3c824109
NF
12599 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12600 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12601
3c824109
NF
12602 switch (((ctx->opcode) >> 4) & 0x3f) {
12603 case NOT16 + 0:
12604 case NOT16 + 1:
12605 case NOT16 + 2:
12606 case NOT16 + 3:
d75c135e 12607 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12608 break;
12609 case XOR16 + 0:
12610 case XOR16 + 1:
12611 case XOR16 + 2:
12612 case XOR16 + 3:
d75c135e 12613 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12614 break;
12615 case AND16 + 0:
12616 case AND16 + 1:
12617 case AND16 + 2:
12618 case AND16 + 3:
d75c135e 12619 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12620 break;
12621 case OR16 + 0:
12622 case OR16 + 1:
12623 case OR16 + 2:
12624 case OR16 + 3:
d75c135e 12625 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12626 break;
12627 case LWM16 + 0:
12628 case LWM16 + 1:
12629 case LWM16 + 2:
12630 case LWM16 + 3:
12631 {
12632 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12633 int offset = ZIMM(ctx->opcode, 0, 4);
12634
12635 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12636 29, offset << 2);
12637 }
12638 break;
12639 case SWM16 + 0:
12640 case SWM16 + 1:
12641 case SWM16 + 2:
12642 case SWM16 + 3:
12643 {
12644 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12645 int offset = ZIMM(ctx->opcode, 0, 4);
12646
12647 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12648 29, offset << 2);
12649 }
12650 break;
12651 case JR16 + 0:
12652 case JR16 + 1:
12653 {
12654 int reg = ctx->opcode & 0x1f;
12655
b231c103 12656 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12657 }
3c824109
NF
12658 break;
12659 case JRC16 + 0:
12660 case JRC16 + 1:
12661 {
12662 int reg = ctx->opcode & 0x1f;
b231c103 12663 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12664 /* Let normal delay slot handling in our caller take us
12665 to the branch target. */
12666 }
12667 break;
12668 case JALR16 + 0:
12669 case JALR16 + 1:
b231c103
YK
12670 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12671 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12672 break;
3c824109
NF
12673 case JALR16S + 0:
12674 case JALR16S + 1:
b231c103
YK
12675 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12676 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12677 break;
12678 case MFHI16 + 0:
12679 case MFHI16 + 1:
26135ead 12680 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12681 break;
12682 case MFLO16 + 0:
12683 case MFLO16 + 1:
26135ead 12684 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12685 break;
12686 case BREAK16:
9c708c7f 12687 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
12688 break;
12689 case SDBBP16:
3b3c1694
LA
12690 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12691 gen_helper_do_semihosting(cpu_env);
12692 } else {
12693 /* XXX: not clear which exception should be raised
12694 * when in debug mode...
12695 */
12696 check_insn(ctx, ISA_MIPS32);
9c708c7f 12697 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12698 }
3c824109
NF
12699 break;
12700 case JRADDIUSP + 0:
12701 case JRADDIUSP + 1:
12702 {
12703 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12704 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12705 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12706 /* Let normal delay slot handling in our caller take us
12707 to the branch target. */
12708 }
12709 break;
12710 default:
9c708c7f 12711 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12712 break;
12713 }
12714}
12715
ed7ce6c0
YK
12716static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12717 int enc_rs)
12718{
12719 int rd, rs, re, rt;
12720 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12721 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12722 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12723 rd = rd_enc[enc_dest];
12724 re = re_enc[enc_dest];
12725 rs = rs_rt_enc[enc_rs];
12726 rt = rs_rt_enc[enc_rt];
12727 if (rs) {
12728 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12729 } else {
12730 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12731 }
12732 if (rt) {
12733 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12734 } else {
12735 tcg_gen_movi_tl(cpu_gpr[re], 0);
12736 }
12737}
12738
12739static void gen_pool16c_r6_insn(DisasContext *ctx)
12740{
12741 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12742 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12743
12744 switch (ctx->opcode & 0xf) {
12745 case R6_NOT16:
12746 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12747 break;
12748 case R6_AND16:
12749 gen_logic(ctx, OPC_AND, rt, rt, rs);
12750 break;
12751 case R6_LWM16:
12752 {
12753 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12754 int offset = extract32(ctx->opcode, 4, 4);
12755 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12756 }
12757 break;
12758 case R6_JRC16: /* JRCADDIUSP */
12759 if ((ctx->opcode >> 4) & 1) {
12760 /* JRCADDIUSP */
12761 int imm = extract32(ctx->opcode, 5, 5);
12762 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12763 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12764 } else {
12765 /* JRC16 */
12766 int rs = extract32(ctx->opcode, 5, 5);
12767 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12768 }
12769 break;
12770 case MOVEP ... MOVEP_07:
12771 case MOVEP_0C ... MOVEP_0F:
12772 {
12773 int enc_dest = uMIPS_RD(ctx->opcode);
12774 int enc_rt = uMIPS_RS2(ctx->opcode);
12775 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12776 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12777 }
12778 break;
12779 case R6_XOR16:
12780 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12781 break;
12782 case R6_OR16:
12783 gen_logic(ctx, OPC_OR, rt, rt, rs);
12784 break;
12785 case R6_SWM16:
12786 {
12787 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12788 int offset = extract32(ctx->opcode, 4, 4);
12789 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12790 }
12791 break;
12792 case JALRC16: /* BREAK16, SDBBP16 */
12793 switch (ctx->opcode & 0x3f) {
12794 case JALRC16:
12795 case JALRC16 + 0x20:
12796 /* JALRC16 */
12797 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12798 31, 0, 0);
12799 break;
12800 case R6_BREAK16:
12801 /* BREAK16 */
12802 generate_exception(ctx, EXCP_BREAK);
12803 break;
12804 case R6_SDBBP16:
12805 /* SDBBP16 */
060ebfef
LA
12806 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12807 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 12808 } else {
060ebfef
LA
12809 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12810 generate_exception(ctx, EXCP_RI);
12811 } else {
12812 generate_exception(ctx, EXCP_DBp);
12813 }
ed7ce6c0
YK
12814 }
12815 break;
12816 }
12817 break;
12818 default:
12819 generate_exception(ctx, EXCP_RI);
12820 break;
12821 }
12822}
12823
3c824109
NF
12824static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12825{
12826 TCGv t0 = tcg_temp_new();
12827 TCGv t1 = tcg_temp_new();
12828
12829 gen_load_gpr(t0, base);
12830
12831 if (index != 0) {
12832 gen_load_gpr(t1, index);
12833 tcg_gen_shli_tl(t1, t1, 2);
12834 gen_op_addr_add(ctx, t0, t1, t0);
12835 }
12836
5f68f5ae 12837 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12838 gen_store_gpr(t1, rd);
12839
12840 tcg_temp_free(t0);
12841 tcg_temp_free(t1);
12842}
12843
12844static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12845 int base, int16_t offset)
12846{
3c824109
NF
12847 TCGv t0, t1;
12848
36c6711b 12849 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 12850 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
12851 return;
12852 }
12853
3c824109
NF
12854 t0 = tcg_temp_new();
12855 t1 = tcg_temp_new();
8e9ade68 12856
3c824109
NF
12857 gen_base_offset_addr(ctx, t0, base, offset);
12858
12859 switch (opc) {
12860 case LWP:
36c6711b 12861 if (rd == base) {
9c708c7f 12862 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
12863 return;
12864 }
5f68f5ae 12865 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12866 gen_store_gpr(t1, rd);
12867 tcg_gen_movi_tl(t1, 4);
12868 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12869 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 12870 gen_store_gpr(t1, rd+1);
3c824109
NF
12871 break;
12872 case SWP:
3c824109 12873 gen_load_gpr(t1, rd);
5f68f5ae 12874 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12875 tcg_gen_movi_tl(t1, 4);
12876 gen_op_addr_add(ctx, t0, t0, t1);
12877 gen_load_gpr(t1, rd+1);
5f68f5ae 12878 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12879 break;
12880#ifdef TARGET_MIPS64
12881 case LDP:
36c6711b 12882 if (rd == base) {
9c708c7f 12883 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
12884 return;
12885 }
5f68f5ae 12886 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12887 gen_store_gpr(t1, rd);
12888 tcg_gen_movi_tl(t1, 8);
12889 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12890 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 12891 gen_store_gpr(t1, rd+1);
3c824109
NF
12892 break;
12893 case SDP:
3c824109 12894 gen_load_gpr(t1, rd);
5f68f5ae 12895 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12896 tcg_gen_movi_tl(t1, 8);
12897 gen_op_addr_add(ctx, t0, t0, t1);
12898 gen_load_gpr(t1, rd+1);
5f68f5ae 12899 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12900 break;
12901#endif
6af0bf9c 12902 }
3c824109
NF
12903 tcg_temp_free(t0);
12904 tcg_temp_free(t1);
12905}
618b0fe9 12906
240ce26a 12907static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12908{
12909 int extension = (ctx->opcode >> 6) & 0x3f;
12910 int minor = (ctx->opcode >> 12) & 0xf;
12911 uint32_t mips32_op;
12912
12913 switch (extension) {
12914 case TEQ:
12915 mips32_op = OPC_TEQ;
12916 goto do_trap;
12917 case TGE:
12918 mips32_op = OPC_TGE;
12919 goto do_trap;
12920 case TGEU:
12921 mips32_op = OPC_TGEU;
12922 goto do_trap;
12923 case TLT:
12924 mips32_op = OPC_TLT;
12925 goto do_trap;
12926 case TLTU:
12927 mips32_op = OPC_TLTU;
12928 goto do_trap;
12929 case TNE:
12930 mips32_op = OPC_TNE;
12931 do_trap:
12932 gen_trap(ctx, mips32_op, rs, rt, -1);
12933 break;
12934#ifndef CONFIG_USER_ONLY
12935 case MFC0:
12936 case MFC0 + 32:
2e15497c 12937 check_cp0_enabled(ctx);
3c824109
NF
12938 if (rt == 0) {
12939 /* Treat as NOP. */
12940 break;
12941 }
d75c135e 12942 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12943 break;
12944 case MTC0:
12945 case MTC0 + 32:
2e15497c 12946 check_cp0_enabled(ctx);
3c824109
NF
12947 {
12948 TCGv t0 = tcg_temp_new();
618b0fe9 12949
3c824109 12950 gen_load_gpr(t0, rt);
d75c135e 12951 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12952 tcg_temp_free(t0);
12953 }
12954 break;
12955#endif
a1fc6246
LA
12956 case 0x2a:
12957 switch (minor & 3) {
12958 case MADD_ACC:
12959 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12960 break;
12961 case MADDU_ACC:
12962 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12963 break;
12964 case MSUB_ACC:
12965 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12966 break;
12967 case MSUBU_ACC:
12968 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12969 break;
12970 default:
12971 goto pool32axf_invalid;
12972 }
12973 break;
12974 case 0x32:
12975 switch (minor & 3) {
12976 case MULT_ACC:
12977 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12978 break;
12979 case MULTU_ACC:
12980 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12981 break;
12982 default:
12983 goto pool32axf_invalid;
12984 }
12985 break;
3c824109
NF
12986 case 0x2c:
12987 switch (minor) {
e0332095
YK
12988 case BITSWAP:
12989 check_insn(ctx, ISA_MIPS32R6);
12990 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
12991 break;
3c824109
NF
12992 case SEB:
12993 gen_bshfl(ctx, OPC_SEB, rs, rt);
12994 break;
12995 case SEH:
12996 gen_bshfl(ctx, OPC_SEH, rs, rt);
12997 break;
12998 case CLO:
12999 mips32_op = OPC_CLO;
13000 goto do_cl;
13001 case CLZ:
13002 mips32_op = OPC_CLZ;
13003 do_cl:
d75c135e 13004 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13005 gen_cl(ctx, mips32_op, rt, rs);
13006 break;
13007 case RDHWR:
b00c7218
YK
13008 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13009 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13010 break;
13011 case WSBH:
13012 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13013 break;
13014 case MULT:
9e8f441a 13015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13016 mips32_op = OPC_MULT;
26135ead 13017 goto do_mul;
3c824109 13018 case MULTU:
9e8f441a 13019 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13020 mips32_op = OPC_MULTU;
26135ead 13021 goto do_mul;
3c824109 13022 case DIV:
9e8f441a 13023 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13024 mips32_op = OPC_DIV;
26135ead 13025 goto do_div;
3c824109 13026 case DIVU:
9e8f441a 13027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13028 mips32_op = OPC_DIVU;
26135ead
RS
13029 goto do_div;
13030 do_div:
13031 check_insn(ctx, ISA_MIPS32);
13032 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13033 break;
3c824109 13034 case MADD:
9e8f441a 13035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13036 mips32_op = OPC_MADD;
26135ead 13037 goto do_mul;
3c824109 13038 case MADDU:
9e8f441a 13039 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13040 mips32_op = OPC_MADDU;
26135ead 13041 goto do_mul;
3c824109 13042 case MSUB:
9e8f441a 13043 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13044 mips32_op = OPC_MSUB;
26135ead 13045 goto do_mul;
3c824109 13046 case MSUBU:
9e8f441a 13047 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13048 mips32_op = OPC_MSUBU;
26135ead 13049 do_mul:
d75c135e 13050 check_insn(ctx, ISA_MIPS32);
a1fc6246 13051 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13052 break;
13053 default:
13054 goto pool32axf_invalid;
13055 }
13056 break;
13057 case 0x34:
13058 switch (minor) {
13059 case MFC2:
13060 case MTC2:
13061 case MFHC2:
13062 case MTHC2:
13063 case CFC2:
13064 case CTC2:
13065 generate_exception_err(ctx, EXCP_CpU, 2);
13066 break;
13067 default:
13068 goto pool32axf_invalid;
13069 }
13070 break;
13071 case 0x3c:
13072 switch (minor) {
65935f07
YK
13073 case JALR: /* JALRC */
13074 case JALR_HB: /* JALRC_HB */
13075 if (ctx->insn_flags & ISA_MIPS32R6) {
13076 /* JALRC, JALRC_HB */
13077 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13078 } else {
13079 /* JALR, JALR_HB */
13080 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13081 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13082 }
3c824109
NF
13083 break;
13084 case JALRS:
13085 case JALRS_HB:
9e8f441a 13086 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13087 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13088 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13089 break;
13090 default:
13091 goto pool32axf_invalid;
13092 }
13093 break;
13094 case 0x05:
13095 switch (minor) {
13096 case RDPGPR:
2e15497c 13097 check_cp0_enabled(ctx);
d75c135e 13098 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13099 gen_load_srsgpr(rs, rt);
3c824109
NF
13100 break;
13101 case WRPGPR:
2e15497c 13102 check_cp0_enabled(ctx);
d75c135e 13103 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13104 gen_store_srsgpr(rs, rt);
3c824109
NF
13105 break;
13106 default:
13107 goto pool32axf_invalid;
13108 }
13109 break;
13110#ifndef CONFIG_USER_ONLY
13111 case 0x0d:
13112 switch (minor) {
13113 case TLBP:
13114 mips32_op = OPC_TLBP;
13115 goto do_cp0;
13116 case TLBR:
13117 mips32_op = OPC_TLBR;
13118 goto do_cp0;
13119 case TLBWI:
13120 mips32_op = OPC_TLBWI;
13121 goto do_cp0;
13122 case TLBWR:
13123 mips32_op = OPC_TLBWR;
13124 goto do_cp0;
e60ec063
YK
13125 case TLBINV:
13126 mips32_op = OPC_TLBINV;
13127 goto do_cp0;
13128 case TLBINVF:
13129 mips32_op = OPC_TLBINVF;
13130 goto do_cp0;
3c824109
NF
13131 case WAIT:
13132 mips32_op = OPC_WAIT;
13133 goto do_cp0;
13134 case DERET:
13135 mips32_op = OPC_DERET;
13136 goto do_cp0;
13137 case ERET:
13138 mips32_op = OPC_ERET;
13139 do_cp0:
13140 gen_cp0(env, ctx, mips32_op, rt, rs);
13141 break;
13142 default:
13143 goto pool32axf_invalid;
13144 }
13145 break;
13146 case 0x1d:
13147 switch (minor) {
13148 case DI:
2e15497c 13149 check_cp0_enabled(ctx);
3c824109
NF
13150 {
13151 TCGv t0 = tcg_temp_new();
13152
13153 save_cpu_state(ctx, 1);
895c2d04 13154 gen_helper_di(t0, cpu_env);
3c824109
NF
13155 gen_store_gpr(t0, rs);
13156 /* Stop translation as we may have switched the execution mode */
13157 ctx->bstate = BS_STOP;
13158 tcg_temp_free(t0);
13159 }
13160 break;
13161 case EI:
2e15497c 13162 check_cp0_enabled(ctx);
3c824109
NF
13163 {
13164 TCGv t0 = tcg_temp_new();
13165
13166 save_cpu_state(ctx, 1);
895c2d04 13167 gen_helper_ei(t0, cpu_env);
3c824109
NF
13168 gen_store_gpr(t0, rs);
13169 /* Stop translation as we may have switched the execution mode */
13170 ctx->bstate = BS_STOP;
13171 tcg_temp_free(t0);
13172 }
13173 break;
13174 default:
13175 goto pool32axf_invalid;
13176 }
13177 break;
13178#endif
13179 case 0x2d:
13180 switch (minor) {
13181 case SYNC:
13182 /* NOP */
13183 break;
13184 case SYSCALL:
9c708c7f 13185 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13186 break;
13187 case SDBBP:
3b3c1694
LA
13188 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13189 gen_helper_do_semihosting(cpu_env);
13190 } else {
13191 check_insn(ctx, ISA_MIPS32);
e0332095 13192 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13193 generate_exception_end(ctx, EXCP_RI);
e0332095 13194 } else {
9c708c7f 13195 generate_exception_end(ctx, EXCP_DBp);
e0332095 13196 }
3b3c1694 13197 }
3c824109
NF
13198 break;
13199 default:
13200 goto pool32axf_invalid;
13201 }
13202 break;
a1fc6246 13203 case 0x01:
26135ead 13204 switch (minor & 3) {
a1fc6246 13205 case MFHI_ACC:
26135ead 13206 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13207 break;
a1fc6246 13208 case MFLO_ACC:
26135ead 13209 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13210 break;
a1fc6246 13211 case MTHI_ACC:
26135ead 13212 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13213 break;
a1fc6246 13214 case MTLO_ACC:
26135ead 13215 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13216 break;
13217 default:
13218 goto pool32axf_invalid;
13219 }
13220 break;
a1fc6246 13221 case 0x35:
9e8f441a 13222 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13223 switch (minor) {
13224 case MFHI32:
13225 gen_HILO(ctx, OPC_MFHI, 0, rs);
13226 break;
13227 case MFLO32:
13228 gen_HILO(ctx, OPC_MFLO, 0, rs);
13229 break;
13230 case MTHI32:
13231 gen_HILO(ctx, OPC_MTHI, 0, rs);
13232 break;
13233 case MTLO32:
13234 gen_HILO(ctx, OPC_MTLO, 0, rs);
13235 break;
13236 default:
13237 goto pool32axf_invalid;
13238 }
13239 break;
3c824109
NF
13240 default:
13241 pool32axf_invalid:
13242 MIPS_INVAL("pool32axf");
9c708c7f 13243 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13244 break;
13245 }
13246}
13247
13248/* Values for microMIPS fmt field. Variable-width, depending on which
13249 formats the instruction supports. */
13250
13251enum {
13252 FMT_SD_S = 0,
13253 FMT_SD_D = 1,
13254
13255 FMT_SDPS_S = 0,
13256 FMT_SDPS_D = 1,
13257 FMT_SDPS_PS = 2,
13258
13259 FMT_SWL_S = 0,
13260 FMT_SWL_W = 1,
13261 FMT_SWL_L = 2,
13262
13263 FMT_DWL_D = 0,
13264 FMT_DWL_W = 1,
13265 FMT_DWL_L = 2
13266};
13267
d75c135e 13268static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13269{
13270 int extension = (ctx->opcode >> 6) & 0x3ff;
13271 uint32_t mips32_op;
13272
13273#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13274#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13275#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13276
13277 switch (extension) {
13278 case FLOAT_1BIT_FMT(CFC1, 0):
13279 mips32_op = OPC_CFC1;
13280 goto do_cp1;
13281 case FLOAT_1BIT_FMT(CTC1, 0):
13282 mips32_op = OPC_CTC1;
13283 goto do_cp1;
13284 case FLOAT_1BIT_FMT(MFC1, 0):
13285 mips32_op = OPC_MFC1;
13286 goto do_cp1;
13287 case FLOAT_1BIT_FMT(MTC1, 0):
13288 mips32_op = OPC_MTC1;
13289 goto do_cp1;
13290 case FLOAT_1BIT_FMT(MFHC1, 0):
13291 mips32_op = OPC_MFHC1;
13292 goto do_cp1;
13293 case FLOAT_1BIT_FMT(MTHC1, 0):
13294 mips32_op = OPC_MTHC1;
13295 do_cp1:
13296 gen_cp1(ctx, mips32_op, rt, rs);
13297 break;
13298
13299 /* Reciprocal square root */
13300 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13301 mips32_op = OPC_RSQRT_S;
13302 goto do_unaryfp;
13303 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13304 mips32_op = OPC_RSQRT_D;
13305 goto do_unaryfp;
13306
13307 /* Square root */
13308 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13309 mips32_op = OPC_SQRT_S;
13310 goto do_unaryfp;
13311 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13312 mips32_op = OPC_SQRT_D;
13313 goto do_unaryfp;
13314
13315 /* Reciprocal */
13316 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13317 mips32_op = OPC_RECIP_S;
13318 goto do_unaryfp;
13319 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13320 mips32_op = OPC_RECIP_D;
13321 goto do_unaryfp;
13322
13323 /* Floor */
13324 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13325 mips32_op = OPC_FLOOR_L_S;
13326 goto do_unaryfp;
13327 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13328 mips32_op = OPC_FLOOR_L_D;
13329 goto do_unaryfp;
13330 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13331 mips32_op = OPC_FLOOR_W_S;
13332 goto do_unaryfp;
13333 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13334 mips32_op = OPC_FLOOR_W_D;
13335 goto do_unaryfp;
13336
13337 /* Ceiling */
13338 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13339 mips32_op = OPC_CEIL_L_S;
13340 goto do_unaryfp;
13341 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13342 mips32_op = OPC_CEIL_L_D;
13343 goto do_unaryfp;
13344 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13345 mips32_op = OPC_CEIL_W_S;
13346 goto do_unaryfp;
13347 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13348 mips32_op = OPC_CEIL_W_D;
13349 goto do_unaryfp;
13350
13351 /* Truncation */
13352 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13353 mips32_op = OPC_TRUNC_L_S;
13354 goto do_unaryfp;
13355 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13356 mips32_op = OPC_TRUNC_L_D;
13357 goto do_unaryfp;
13358 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13359 mips32_op = OPC_TRUNC_W_S;
13360 goto do_unaryfp;
13361 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13362 mips32_op = OPC_TRUNC_W_D;
13363 goto do_unaryfp;
13364
13365 /* Round */
13366 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13367 mips32_op = OPC_ROUND_L_S;
13368 goto do_unaryfp;
13369 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13370 mips32_op = OPC_ROUND_L_D;
13371 goto do_unaryfp;
13372 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13373 mips32_op = OPC_ROUND_W_S;
13374 goto do_unaryfp;
13375 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13376 mips32_op = OPC_ROUND_W_D;
13377 goto do_unaryfp;
13378
13379 /* Integer to floating-point conversion */
13380 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13381 mips32_op = OPC_CVT_L_S;
13382 goto do_unaryfp;
13383 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13384 mips32_op = OPC_CVT_L_D;
13385 goto do_unaryfp;
13386 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13387 mips32_op = OPC_CVT_W_S;
13388 goto do_unaryfp;
13389 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13390 mips32_op = OPC_CVT_W_D;
13391 goto do_unaryfp;
13392
13393 /* Paired-foo conversions */
13394 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13395 mips32_op = OPC_CVT_S_PL;
13396 goto do_unaryfp;
13397 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13398 mips32_op = OPC_CVT_S_PU;
13399 goto do_unaryfp;
13400 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13401 mips32_op = OPC_CVT_PW_PS;
13402 goto do_unaryfp;
13403 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13404 mips32_op = OPC_CVT_PS_PW;
13405 goto do_unaryfp;
13406
13407 /* Floating-point moves */
13408 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13409 mips32_op = OPC_MOV_S;
13410 goto do_unaryfp;
13411 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13412 mips32_op = OPC_MOV_D;
13413 goto do_unaryfp;
13414 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13415 mips32_op = OPC_MOV_PS;
13416 goto do_unaryfp;
13417
13418 /* Absolute value */
13419 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13420 mips32_op = OPC_ABS_S;
13421 goto do_unaryfp;
13422 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13423 mips32_op = OPC_ABS_D;
13424 goto do_unaryfp;
13425 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13426 mips32_op = OPC_ABS_PS;
13427 goto do_unaryfp;
13428
13429 /* Negation */
13430 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13431 mips32_op = OPC_NEG_S;
13432 goto do_unaryfp;
13433 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13434 mips32_op = OPC_NEG_D;
13435 goto do_unaryfp;
13436 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13437 mips32_op = OPC_NEG_PS;
13438 goto do_unaryfp;
13439
13440 /* Reciprocal square root step */
13441 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13442 mips32_op = OPC_RSQRT1_S;
13443 goto do_unaryfp;
13444 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13445 mips32_op = OPC_RSQRT1_D;
13446 goto do_unaryfp;
13447 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13448 mips32_op = OPC_RSQRT1_PS;
13449 goto do_unaryfp;
13450
13451 /* Reciprocal step */
13452 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13453 mips32_op = OPC_RECIP1_S;
13454 goto do_unaryfp;
13455 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13456 mips32_op = OPC_RECIP1_S;
13457 goto do_unaryfp;
13458 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13459 mips32_op = OPC_RECIP1_PS;
13460 goto do_unaryfp;
13461
13462 /* Conversions from double */
13463 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13464 mips32_op = OPC_CVT_D_S;
13465 goto do_unaryfp;
13466 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13467 mips32_op = OPC_CVT_D_W;
13468 goto do_unaryfp;
13469 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13470 mips32_op = OPC_CVT_D_L;
13471 goto do_unaryfp;
13472
13473 /* Conversions from single */
13474 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13475 mips32_op = OPC_CVT_S_D;
13476 goto do_unaryfp;
13477 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13478 mips32_op = OPC_CVT_S_W;
13479 goto do_unaryfp;
13480 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13481 mips32_op = OPC_CVT_S_L;
13482 do_unaryfp:
13483 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13484 break;
13485
13486 /* Conditional moves on floating-point codes */
13487 case COND_FLOAT_MOV(MOVT, 0):
13488 case COND_FLOAT_MOV(MOVT, 1):
13489 case COND_FLOAT_MOV(MOVT, 2):
13490 case COND_FLOAT_MOV(MOVT, 3):
13491 case COND_FLOAT_MOV(MOVT, 4):
13492 case COND_FLOAT_MOV(MOVT, 5):
13493 case COND_FLOAT_MOV(MOVT, 6):
13494 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13495 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13496 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13497 break;
13498 case COND_FLOAT_MOV(MOVF, 0):
13499 case COND_FLOAT_MOV(MOVF, 1):
13500 case COND_FLOAT_MOV(MOVF, 2):
13501 case COND_FLOAT_MOV(MOVF, 3):
13502 case COND_FLOAT_MOV(MOVF, 4):
13503 case COND_FLOAT_MOV(MOVF, 5):
13504 case COND_FLOAT_MOV(MOVF, 6):
13505 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13506 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13507 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13508 break;
13509 default:
13510 MIPS_INVAL("pool32fxf");
9c708c7f 13511 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13512 break;
13513 }
13514}
13515
f60eeb0c 13516static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13517{
13518 int32_t offset;
13519 uint16_t insn;
13520 int rt, rs, rd, rr;
13521 int16_t imm;
13522 uint32_t op, minor, mips32_op;
13523 uint32_t cond, fmt, cc;
13524
895c2d04 13525 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13526 ctx->opcode = (ctx->opcode << 16) | insn;
13527
13528 rt = (ctx->opcode >> 21) & 0x1f;
13529 rs = (ctx->opcode >> 16) & 0x1f;
13530 rd = (ctx->opcode >> 11) & 0x1f;
13531 rr = (ctx->opcode >> 6) & 0x1f;
13532 imm = (int16_t) ctx->opcode;
13533
13534 op = (ctx->opcode >> 26) & 0x3f;
13535 switch (op) {
13536 case POOL32A:
13537 minor = ctx->opcode & 0x3f;
13538 switch (minor) {
13539 case 0x00:
13540 minor = (ctx->opcode >> 6) & 0xf;
13541 switch (minor) {
13542 case SLL32:
13543 mips32_op = OPC_SLL;
13544 goto do_shifti;
13545 case SRA:
13546 mips32_op = OPC_SRA;
13547 goto do_shifti;
13548 case SRL32:
13549 mips32_op = OPC_SRL;
13550 goto do_shifti;
13551 case ROTR:
13552 mips32_op = OPC_ROTR;
13553 do_shifti:
d75c135e 13554 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13555 break;
e0332095
YK
13556 case SELEQZ:
13557 check_insn(ctx, ISA_MIPS32R6);
13558 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13559 break;
13560 case SELNEZ:
13561 check_insn(ctx, ISA_MIPS32R6);
13562 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13563 break;
b00c7218
YK
13564 case R6_RDHWR:
13565 check_insn(ctx, ISA_MIPS32R6);
13566 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13567 break;
3c824109
NF
13568 default:
13569 goto pool32a_invalid;
13570 }
13571 break;
13572 case 0x10:
13573 minor = (ctx->opcode >> 6) & 0xf;
13574 switch (minor) {
13575 /* Arithmetic */
13576 case ADD:
13577 mips32_op = OPC_ADD;
13578 goto do_arith;
13579 case ADDU32:
13580 mips32_op = OPC_ADDU;
13581 goto do_arith;
13582 case SUB:
13583 mips32_op = OPC_SUB;
13584 goto do_arith;
13585 case SUBU32:
13586 mips32_op = OPC_SUBU;
13587 goto do_arith;
13588 case MUL:
9e8f441a 13589 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13590 mips32_op = OPC_MUL;
13591 do_arith:
d75c135e 13592 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13593 break;
13594 /* Shifts */
13595 case SLLV:
13596 mips32_op = OPC_SLLV;
13597 goto do_shift;
13598 case SRLV:
13599 mips32_op = OPC_SRLV;
13600 goto do_shift;
13601 case SRAV:
13602 mips32_op = OPC_SRAV;
13603 goto do_shift;
13604 case ROTRV:
13605 mips32_op = OPC_ROTRV;
13606 do_shift:
d75c135e 13607 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13608 break;
13609 /* Logical operations */
13610 case AND:
13611 mips32_op = OPC_AND;
13612 goto do_logic;
13613 case OR32:
13614 mips32_op = OPC_OR;
13615 goto do_logic;
13616 case NOR:
13617 mips32_op = OPC_NOR;
13618 goto do_logic;
13619 case XOR32:
13620 mips32_op = OPC_XOR;
13621 do_logic:
d75c135e 13622 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13623 break;
13624 /* Set less than */
13625 case SLT:
13626 mips32_op = OPC_SLT;
13627 goto do_slt;
13628 case SLTU:
13629 mips32_op = OPC_SLTU;
13630 do_slt:
d75c135e 13631 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13632 break;
13633 default:
13634 goto pool32a_invalid;
13635 }
13636 break;
13637 case 0x18:
13638 minor = (ctx->opcode >> 6) & 0xf;
13639 switch (minor) {
13640 /* Conditional moves */
e0332095
YK
13641 case MOVN: /* MUL */
13642 if (ctx->insn_flags & ISA_MIPS32R6) {
13643 /* MUL */
13644 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13645 } else {
13646 /* MOVN */
13647 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13648 }
13649 break;
13650 case MOVZ: /* MUH */
13651 if (ctx->insn_flags & ISA_MIPS32R6) {
13652 /* MUH */
13653 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13654 } else {
13655 /* MOVZ */
13656 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13657 }
13658 break;
13659 case MULU:
13660 check_insn(ctx, ISA_MIPS32R6);
13661 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13662 break;
13663 case MUHU:
13664 check_insn(ctx, ISA_MIPS32R6);
13665 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13666 break;
13667 case LWXS: /* DIV */
13668 if (ctx->insn_flags & ISA_MIPS32R6) {
13669 /* DIV */
13670 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13671 } else {
13672 /* LWXS */
13673 gen_ldxs(ctx, rs, rt, rd);
13674 }
13675 break;
13676 case MOD:
13677 check_insn(ctx, ISA_MIPS32R6);
13678 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13679 break;
13680 case R6_DIVU:
13681 check_insn(ctx, ISA_MIPS32R6);
13682 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 13683 break;
e0332095
YK
13684 case MODU:
13685 check_insn(ctx, ISA_MIPS32R6);
13686 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
13687 break;
13688 default:
13689 goto pool32a_invalid;
13690 }
13691 break;
13692 case INS:
13693 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13694 return;
e0332095
YK
13695 case LSA:
13696 check_insn(ctx, ISA_MIPS32R6);
13697 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13698 extract32(ctx->opcode, 9, 2));
13699 break;
13700 case ALIGN:
13701 check_insn(ctx, ISA_MIPS32R6);
13702 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13703 extract32(ctx->opcode, 9, 2));
13704 break;
3c824109
NF
13705 case EXT:
13706 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13707 return;
13708 case POOL32AXF:
240ce26a 13709 gen_pool32axf(env, ctx, rt, rs);
3c824109 13710 break;
dbd8af98 13711 case BREAK32:
9c708c7f 13712 generate_exception_end(ctx, EXCP_BREAK);
3c824109 13713 break;
bb238210
YK
13714 case SIGRIE:
13715 check_insn(ctx, ISA_MIPS32R6);
13716 generate_exception_end(ctx, EXCP_RI);
13717 break;
3c824109
NF
13718 default:
13719 pool32a_invalid:
13720 MIPS_INVAL("pool32a");
9c708c7f 13721 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13722 break;
13723 }
13724 break;
13725 case POOL32B:
13726 minor = (ctx->opcode >> 12) & 0xf;
13727 switch (minor) {
13728 case CACHE:
2e15497c 13729 check_cp0_enabled(ctx);
3c824109
NF
13730 /* Treat as no-op. */
13731 break;
13732 case LWC2:
13733 case SWC2:
13734 /* COP2: Not implemented. */
13735 generate_exception_err(ctx, EXCP_CpU, 2);
13736 break;
3c824109
NF
13737#ifdef TARGET_MIPS64
13738 case LDP:
13739 case SDP:
d9224450
MR
13740 check_insn(ctx, ISA_MIPS3);
13741 check_mips_64(ctx);
13742 /* Fallthrough */
3c824109 13743#endif
d9224450
MR
13744 case LWP:
13745 case SWP:
3c824109
NF
13746 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13747 break;
3c824109
NF
13748#ifdef TARGET_MIPS64
13749 case LDM:
13750 case SDM:
d9224450
MR
13751 check_insn(ctx, ISA_MIPS3);
13752 check_mips_64(ctx);
13753 /* Fallthrough */
3c824109 13754#endif
d9224450
MR
13755 case LWM32:
13756 case SWM32:
3c824109
NF
13757 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13758 break;
13759 default:
13760 MIPS_INVAL("pool32b");
9c708c7f 13761 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13762 break;
13763 }
13764 break;
13765 case POOL32F:
5ab5c041 13766 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13767 minor = ctx->opcode & 0x3f;
13768 check_cp1_enabled(ctx);
13769 switch (minor) {
13770 case ALNV_PS:
9e8f441a 13771 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13772 mips32_op = OPC_ALNV_PS;
13773 goto do_madd;
13774 case MADD_S:
9e8f441a 13775 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13776 mips32_op = OPC_MADD_S;
13777 goto do_madd;
13778 case MADD_D:
9e8f441a 13779 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13780 mips32_op = OPC_MADD_D;
13781 goto do_madd;
13782 case MADD_PS:
9e8f441a 13783 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13784 mips32_op = OPC_MADD_PS;
13785 goto do_madd;
13786 case MSUB_S:
9e8f441a 13787 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13788 mips32_op = OPC_MSUB_S;
13789 goto do_madd;
13790 case MSUB_D:
9e8f441a 13791 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13792 mips32_op = OPC_MSUB_D;
13793 goto do_madd;
13794 case MSUB_PS:
9e8f441a 13795 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13796 mips32_op = OPC_MSUB_PS;
13797 goto do_madd;
13798 case NMADD_S:
9e8f441a 13799 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13800 mips32_op = OPC_NMADD_S;
13801 goto do_madd;
13802 case NMADD_D:
9e8f441a 13803 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13804 mips32_op = OPC_NMADD_D;
13805 goto do_madd;
13806 case NMADD_PS:
9e8f441a 13807 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13808 mips32_op = OPC_NMADD_PS;
13809 goto do_madd;
13810 case NMSUB_S:
9e8f441a 13811 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13812 mips32_op = OPC_NMSUB_S;
13813 goto do_madd;
13814 case NMSUB_D:
9e8f441a 13815 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13816 mips32_op = OPC_NMSUB_D;
13817 goto do_madd;
13818 case NMSUB_PS:
9e8f441a 13819 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13820 mips32_op = OPC_NMSUB_PS;
13821 do_madd:
13822 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13823 break;
13824 case CABS_COND_FMT:
9e8f441a 13825 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13826 cond = (ctx->opcode >> 6) & 0xf;
13827 cc = (ctx->opcode >> 13) & 0x7;
13828 fmt = (ctx->opcode >> 10) & 0x3;
13829 switch (fmt) {
13830 case 0x0:
13831 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13832 break;
13833 case 0x1:
13834 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13835 break;
13836 case 0x2:
13837 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13838 break;
13839 default:
13840 goto pool32f_invalid;
13841 }
13842 break;
13843 case C_COND_FMT:
9e8f441a 13844 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13845 cond = (ctx->opcode >> 6) & 0xf;
13846 cc = (ctx->opcode >> 13) & 0x7;
13847 fmt = (ctx->opcode >> 10) & 0x3;
13848 switch (fmt) {
13849 case 0x0:
13850 gen_cmp_s(ctx, cond, rt, rs, cc);
13851 break;
13852 case 0x1:
13853 gen_cmp_d(ctx, cond, rt, rs, cc);
13854 break;
13855 case 0x2:
13856 gen_cmp_ps(ctx, cond, rt, rs, cc);
13857 break;
13858 default:
13859 goto pool32f_invalid;
13860 }
13861 break;
2a24a7ba
YK
13862 case CMP_CONDN_S:
13863 check_insn(ctx, ISA_MIPS32R6);
13864 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13865 break;
13866 case CMP_CONDN_D:
13867 check_insn(ctx, ISA_MIPS32R6);
13868 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13869 break;
3c824109 13870 case POOL32FXF:
d75c135e 13871 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13872 break;
13873 case 0x00:
13874 /* PLL foo */
13875 switch ((ctx->opcode >> 6) & 0x7) {
13876 case PLL_PS:
13877 mips32_op = OPC_PLL_PS;
13878 goto do_ps;
13879 case PLU_PS:
13880 mips32_op = OPC_PLU_PS;
13881 goto do_ps;
13882 case PUL_PS:
13883 mips32_op = OPC_PUL_PS;
13884 goto do_ps;
13885 case PUU_PS:
13886 mips32_op = OPC_PUU_PS;
13887 goto do_ps;
13888 case CVT_PS_S:
9e8f441a 13889 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13890 mips32_op = OPC_CVT_PS_S;
13891 do_ps:
13892 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13893 break;
13894 default:
13895 goto pool32f_invalid;
13896 }
13897 break;
2a24a7ba
YK
13898 case MIN_FMT:
13899 check_insn(ctx, ISA_MIPS32R6);
13900 switch ((ctx->opcode >> 9) & 0x3) {
13901 case FMT_SDPS_S:
13902 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13903 break;
13904 case FMT_SDPS_D:
13905 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13906 break;
13907 default:
13908 goto pool32f_invalid;
13909 }
13910 break;
3c824109
NF
13911 case 0x08:
13912 /* [LS][WDU]XC1 */
13913 switch ((ctx->opcode >> 6) & 0x7) {
13914 case LWXC1:
9e8f441a 13915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13916 mips32_op = OPC_LWXC1;
13917 goto do_ldst_cp1;
13918 case SWXC1:
9e8f441a 13919 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13920 mips32_op = OPC_SWXC1;
13921 goto do_ldst_cp1;
13922 case LDXC1:
9e8f441a 13923 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13924 mips32_op = OPC_LDXC1;
13925 goto do_ldst_cp1;
13926 case SDXC1:
9e8f441a 13927 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13928 mips32_op = OPC_SDXC1;
13929 goto do_ldst_cp1;
13930 case LUXC1:
9e8f441a 13931 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13932 mips32_op = OPC_LUXC1;
13933 goto do_ldst_cp1;
13934 case SUXC1:
9e8f441a 13935 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13936 mips32_op = OPC_SUXC1;
13937 do_ldst_cp1:
13938 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13939 break;
13940 default:
13941 goto pool32f_invalid;
13942 }
13943 break;
2a24a7ba
YK
13944 case MAX_FMT:
13945 check_insn(ctx, ISA_MIPS32R6);
13946 switch ((ctx->opcode >> 9) & 0x3) {
13947 case FMT_SDPS_S:
13948 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13949 break;
13950 case FMT_SDPS_D:
13951 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13952 break;
13953 default:
13954 goto pool32f_invalid;
13955 }
13956 break;
3c824109
NF
13957 case 0x18:
13958 /* 3D insns */
9e8f441a 13959 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13960 fmt = (ctx->opcode >> 9) & 0x3;
13961 switch ((ctx->opcode >> 6) & 0x7) {
13962 case RSQRT2_FMT:
13963 switch (fmt) {
13964 case FMT_SDPS_S:
13965 mips32_op = OPC_RSQRT2_S;
13966 goto do_3d;
13967 case FMT_SDPS_D:
13968 mips32_op = OPC_RSQRT2_D;
13969 goto do_3d;
13970 case FMT_SDPS_PS:
13971 mips32_op = OPC_RSQRT2_PS;
13972 goto do_3d;
13973 default:
13974 goto pool32f_invalid;
13975 }
13976 break;
13977 case RECIP2_FMT:
13978 switch (fmt) {
13979 case FMT_SDPS_S:
13980 mips32_op = OPC_RECIP2_S;
13981 goto do_3d;
13982 case FMT_SDPS_D:
13983 mips32_op = OPC_RECIP2_D;
13984 goto do_3d;
13985 case FMT_SDPS_PS:
13986 mips32_op = OPC_RECIP2_PS;
13987 goto do_3d;
13988 default:
13989 goto pool32f_invalid;
13990 }
13991 break;
13992 case ADDR_PS:
13993 mips32_op = OPC_ADDR_PS;
13994 goto do_3d;
13995 case MULR_PS:
13996 mips32_op = OPC_MULR_PS;
13997 do_3d:
13998 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13999 break;
14000 default:
14001 goto pool32f_invalid;
14002 }
14003 break;
14004 case 0x20:
2a24a7ba 14005 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14006 cc = (ctx->opcode >> 13) & 0x7;
14007 fmt = (ctx->opcode >> 9) & 0x3;
14008 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14009 case MOVF_FMT: /* RINT_FMT */
14010 if (ctx->insn_flags & ISA_MIPS32R6) {
14011 /* RINT_FMT */
14012 switch (fmt) {
14013 case FMT_SDPS_S:
14014 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14015 break;
14016 case FMT_SDPS_D:
14017 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14018 break;
14019 default:
14020 goto pool32f_invalid;
14021 }
14022 } else {
14023 /* MOVF_FMT */
14024 switch (fmt) {
14025 case FMT_SDPS_S:
14026 gen_movcf_s(ctx, rs, rt, cc, 0);
14027 break;
14028 case FMT_SDPS_D:
14029 gen_movcf_d(ctx, rs, rt, cc, 0);
14030 break;
14031 case FMT_SDPS_PS:
14032 check_ps(ctx);
14033 gen_movcf_ps(ctx, rs, rt, cc, 0);
14034 break;
14035 default:
14036 goto pool32f_invalid;
14037 }
3c824109
NF
14038 }
14039 break;
2a24a7ba
YK
14040 case MOVT_FMT: /* CLASS_FMT */
14041 if (ctx->insn_flags & ISA_MIPS32R6) {
14042 /* CLASS_FMT */
14043 switch (fmt) {
14044 case FMT_SDPS_S:
14045 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14046 break;
14047 case FMT_SDPS_D:
14048 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14049 break;
14050 default:
14051 goto pool32f_invalid;
14052 }
14053 } else {
14054 /* MOVT_FMT */
14055 switch (fmt) {
14056 case FMT_SDPS_S:
14057 gen_movcf_s(ctx, rs, rt, cc, 1);
14058 break;
14059 case FMT_SDPS_D:
14060 gen_movcf_d(ctx, rs, rt, cc, 1);
14061 break;
14062 case FMT_SDPS_PS:
14063 check_ps(ctx);
14064 gen_movcf_ps(ctx, rs, rt, cc, 1);
14065 break;
14066 default:
14067 goto pool32f_invalid;
14068 }
3c824109
NF
14069 }
14070 break;
14071 case PREFX:
9e8f441a 14072 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14073 break;
14074 default:
14075 goto pool32f_invalid;
14076 }
14077 break;
14078#define FINSN_3ARG_SDPS(prfx) \
14079 switch ((ctx->opcode >> 8) & 0x3) { \
14080 case FMT_SDPS_S: \
14081 mips32_op = OPC_##prfx##_S; \
14082 goto do_fpop; \
14083 case FMT_SDPS_D: \
14084 mips32_op = OPC_##prfx##_D; \
14085 goto do_fpop; \
14086 case FMT_SDPS_PS: \
e29c9628 14087 check_ps(ctx); \
3c824109
NF
14088 mips32_op = OPC_##prfx##_PS; \
14089 goto do_fpop; \
14090 default: \
14091 goto pool32f_invalid; \
14092 }
2a24a7ba
YK
14093 case MINA_FMT:
14094 check_insn(ctx, ISA_MIPS32R6);
14095 switch ((ctx->opcode >> 9) & 0x3) {
14096 case FMT_SDPS_S:
14097 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14098 break;
14099 case FMT_SDPS_D:
14100 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14101 break;
14102 default:
14103 goto pool32f_invalid;
14104 }
14105 break;
14106 case MAXA_FMT:
14107 check_insn(ctx, ISA_MIPS32R6);
14108 switch ((ctx->opcode >> 9) & 0x3) {
14109 case FMT_SDPS_S:
14110 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14111 break;
14112 case FMT_SDPS_D:
14113 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14114 break;
14115 default:
14116 goto pool32f_invalid;
14117 }
14118 break;
3c824109
NF
14119 case 0x30:
14120 /* regular FP ops */
14121 switch ((ctx->opcode >> 6) & 0x3) {
14122 case ADD_FMT:
14123 FINSN_3ARG_SDPS(ADD);
14124 break;
14125 case SUB_FMT:
14126 FINSN_3ARG_SDPS(SUB);
14127 break;
14128 case MUL_FMT:
14129 FINSN_3ARG_SDPS(MUL);
14130 break;
14131 case DIV_FMT:
14132 fmt = (ctx->opcode >> 8) & 0x3;
14133 if (fmt == 1) {
14134 mips32_op = OPC_DIV_D;
14135 } else if (fmt == 0) {
14136 mips32_op = OPC_DIV_S;
14137 } else {
14138 goto pool32f_invalid;
14139 }
14140 goto do_fpop;
14141 default:
14142 goto pool32f_invalid;
14143 }
14144 break;
14145 case 0x38:
14146 /* cmovs */
2a24a7ba
YK
14147 switch ((ctx->opcode >> 6) & 0x7) {
14148 case MOVN_FMT: /* SELNEZ_FMT */
14149 if (ctx->insn_flags & ISA_MIPS32R6) {
14150 /* SELNEZ_FMT */
14151 switch ((ctx->opcode >> 9) & 0x3) {
14152 case FMT_SDPS_S:
14153 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14154 break;
14155 case FMT_SDPS_D:
14156 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14157 break;
14158 default:
14159 goto pool32f_invalid;
14160 }
14161 } else {
14162 /* MOVN_FMT */
14163 FINSN_3ARG_SDPS(MOVN);
14164 }
14165 break;
14166 case MOVN_FMT_04:
14167 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14168 FINSN_3ARG_SDPS(MOVN);
14169 break;
2a24a7ba
YK
14170 case MOVZ_FMT: /* SELEQZ_FMT */
14171 if (ctx->insn_flags & ISA_MIPS32R6) {
14172 /* SELEQZ_FMT */
14173 switch ((ctx->opcode >> 9) & 0x3) {
14174 case FMT_SDPS_S:
14175 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14176 break;
14177 case FMT_SDPS_D:
14178 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14179 break;
14180 default:
14181 goto pool32f_invalid;
14182 }
14183 } else {
14184 /* MOVZ_FMT */
14185 FINSN_3ARG_SDPS(MOVZ);
14186 }
14187 break;
14188 case MOVZ_FMT_05:
14189 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14190 FINSN_3ARG_SDPS(MOVZ);
14191 break;
2a24a7ba
YK
14192 case SEL_FMT:
14193 check_insn(ctx, ISA_MIPS32R6);
14194 switch ((ctx->opcode >> 9) & 0x3) {
14195 case FMT_SDPS_S:
14196 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14197 break;
14198 case FMT_SDPS_D:
14199 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14200 break;
14201 default:
14202 goto pool32f_invalid;
14203 }
14204 break;
14205 case MADDF_FMT:
14206 check_insn(ctx, ISA_MIPS32R6);
14207 switch ((ctx->opcode >> 9) & 0x3) {
14208 case FMT_SDPS_S:
14209 mips32_op = OPC_MADDF_S;
14210 goto do_fpop;
14211 case FMT_SDPS_D:
14212 mips32_op = OPC_MADDF_D;
14213 goto do_fpop;
14214 default:
14215 goto pool32f_invalid;
14216 }
14217 break;
14218 case MSUBF_FMT:
14219 check_insn(ctx, ISA_MIPS32R6);
14220 switch ((ctx->opcode >> 9) & 0x3) {
14221 case FMT_SDPS_S:
14222 mips32_op = OPC_MSUBF_S;
14223 goto do_fpop;
14224 case FMT_SDPS_D:
14225 mips32_op = OPC_MSUBF_D;
14226 goto do_fpop;
14227 default:
14228 goto pool32f_invalid;
14229 }
14230 break;
3c824109
NF
14231 default:
14232 goto pool32f_invalid;
14233 }
14234 break;
14235 do_fpop:
14236 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14237 break;
14238 default:
14239 pool32f_invalid:
14240 MIPS_INVAL("pool32f");
9c708c7f 14241 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14242 break;
14243 }
14244 } else {
14245 generate_exception_err(ctx, EXCP_CpU, 1);
14246 }
14247 break;
14248 case POOL32I:
14249 minor = (ctx->opcode >> 21) & 0x1f;
14250 switch (minor) {
14251 case BLTZ:
9e8f441a 14252 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14253 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14254 break;
3c824109 14255 case BLTZAL:
9e8f441a 14256 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14257 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14258 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14259 break;
3c824109 14260 case BLTZALS:
9e8f441a 14261 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14262 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14263 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14264 break;
3c824109 14265 case BGEZ:
9e8f441a 14266 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14267 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14268 break;
3c824109 14269 case BGEZAL:
9e8f441a 14270 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14271 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14272 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14273 break;
3c824109 14274 case BGEZALS:
9e8f441a 14275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14276 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14277 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14278 break;
3c824109 14279 case BLEZ:
9e8f441a 14280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14281 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14282 break;
3c824109 14283 case BGTZ:
9e8f441a 14284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14285 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14286 break;
14287
14288 /* Traps */
65935f07
YK
14289 case TLTI: /* BC1EQZC */
14290 if (ctx->insn_flags & ISA_MIPS32R6) {
14291 /* BC1EQZC */
14292 check_cp1_enabled(ctx);
14293 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14294 } else {
14295 /* TLTI */
14296 mips32_op = OPC_TLTI;
14297 goto do_trapi;
14298 }
14299 break;
14300 case TGEI: /* BC1NEZC */
14301 if (ctx->insn_flags & ISA_MIPS32R6) {
14302 /* BC1NEZC */
14303 check_cp1_enabled(ctx);
14304 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14305 } else {
14306 /* TGEI */
14307 mips32_op = OPC_TGEI;
14308 goto do_trapi;
14309 }
14310 break;
3c824109 14311 case TLTIU:
9e8f441a 14312 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14313 mips32_op = OPC_TLTIU;
14314 goto do_trapi;
14315 case TGEIU:
9e8f441a 14316 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14317 mips32_op = OPC_TGEIU;
14318 goto do_trapi;
3b4a5489
YK
14319 case TNEI: /* SYNCI */
14320 if (ctx->insn_flags & ISA_MIPS32R6) {
14321 /* SYNCI */
14322 /* Break the TB to be able to sync copied instructions
14323 immediately */
14324 ctx->bstate = BS_STOP;
14325 } else {
14326 /* TNEI */
14327 mips32_op = OPC_TNEI;
14328 goto do_trapi;
14329 }
14330 break;
3c824109 14331 case TEQI:
9e8f441a 14332 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14333 mips32_op = OPC_TEQI;
14334 do_trapi:
14335 gen_trap(ctx, mips32_op, rs, -1, imm);
14336 break;
14337
14338 case BNEZC:
14339 case BEQZC:
9e8f441a 14340 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14341 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14342 4, rs, 0, imm << 1, 0);
3c824109
NF
14343 /* Compact branches don't have a delay slot, so just let
14344 the normal delay slot handling take us to the branch
14345 target. */
14346 break;
14347 case LUI:
9e8f441a 14348 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14349 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14350 break;
14351 case SYNCI:
9e8f441a 14352 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14353 /* Break the TB to be able to sync copied instructions
14354 immediately */
14355 ctx->bstate = BS_STOP;
3c824109
NF
14356 break;
14357 case BC2F:
14358 case BC2T:
9e8f441a 14359 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14360 /* COP2: Not implemented. */
14361 generate_exception_err(ctx, EXCP_CpU, 2);
14362 break;
14363 case BC1F:
9e8f441a 14364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14365 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14366 goto do_cp1branch;
14367 case BC1T:
9e8f441a 14368 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14369 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14370 goto do_cp1branch;
14371 case BC1ANY4F:
9e8f441a 14372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14373 mips32_op = OPC_BC1FANY4;
14374 goto do_cp1mips3d;
14375 case BC1ANY4T:
9e8f441a 14376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14377 mips32_op = OPC_BC1TANY4;
14378 do_cp1mips3d:
14379 check_cop1x(ctx);
d75c135e 14380 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14381 /* Fall through */
14382 do_cp1branch:
272f458d
MR
14383 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14384 check_cp1_enabled(ctx);
14385 gen_compute_branch1(ctx, mips32_op,
14386 (ctx->opcode >> 18) & 0x7, imm << 1);
14387 } else {
14388 generate_exception_err(ctx, EXCP_CpU, 1);
14389 }
3c824109
NF
14390 break;
14391 case BPOSGE64:
14392 case BPOSGE32:
14393 /* MIPS DSP: not implemented */
14394 /* Fall through */
14395 default:
14396 MIPS_INVAL("pool32i");
9c708c7f 14397 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14398 break;
14399 }
14400 break;
14401 case POOL32C:
14402 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14403 offset = sextract32(ctx->opcode, 0,
14404 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14405 switch (minor) {
14406 case LWL:
9e8f441a 14407 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14408 mips32_op = OPC_LWL;
5c13fdfd 14409 goto do_ld_lr;
3c824109 14410 case SWL:
9e8f441a 14411 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14412 mips32_op = OPC_SWL;
5c13fdfd 14413 goto do_st_lr;
3c824109 14414 case LWR:
9e8f441a 14415 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14416 mips32_op = OPC_LWR;
5c13fdfd 14417 goto do_ld_lr;
3c824109 14418 case SWR:
9e8f441a 14419 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14420 mips32_op = OPC_SWR;
5c13fdfd 14421 goto do_st_lr;
3c824109
NF
14422#if defined(TARGET_MIPS64)
14423 case LDL:
d9224450
MR
14424 check_insn(ctx, ISA_MIPS3);
14425 check_mips_64(ctx);
9e8f441a 14426 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14427 mips32_op = OPC_LDL;
5c13fdfd 14428 goto do_ld_lr;
3c824109 14429 case SDL:
d9224450
MR
14430 check_insn(ctx, ISA_MIPS3);
14431 check_mips_64(ctx);
9e8f441a 14432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14433 mips32_op = OPC_SDL;
5c13fdfd 14434 goto do_st_lr;
3c824109 14435 case LDR:
d9224450
MR
14436 check_insn(ctx, ISA_MIPS3);
14437 check_mips_64(ctx);
9e8f441a 14438 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14439 mips32_op = OPC_LDR;
5c13fdfd 14440 goto do_ld_lr;
3c824109 14441 case SDR:
d9224450
MR
14442 check_insn(ctx, ISA_MIPS3);
14443 check_mips_64(ctx);
9e8f441a 14444 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14445 mips32_op = OPC_SDR;
5c13fdfd 14446 goto do_st_lr;
3c824109 14447 case LWU:
d9224450
MR
14448 check_insn(ctx, ISA_MIPS3);
14449 check_mips_64(ctx);
3c824109 14450 mips32_op = OPC_LWU;
5c13fdfd 14451 goto do_ld_lr;
3c824109 14452 case LLD:
d9224450
MR
14453 check_insn(ctx, ISA_MIPS3);
14454 check_mips_64(ctx);
3c824109 14455 mips32_op = OPC_LLD;
5c13fdfd 14456 goto do_ld_lr;
3c824109
NF
14457#endif
14458 case LL:
14459 mips32_op = OPC_LL;
5c13fdfd
AJ
14460 goto do_ld_lr;
14461 do_ld_lr:
3b4a5489 14462 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14463 break;
14464 do_st_lr:
14465 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14466 break;
14467 case SC:
3b4a5489 14468 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14469 break;
14470#if defined(TARGET_MIPS64)
14471 case SCD:
d9224450
MR
14472 check_insn(ctx, ISA_MIPS3);
14473 check_mips_64(ctx);
3b4a5489 14474 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14475 break;
14476#endif
14477 case PREF:
14478 /* Treat as no-op */
3b4a5489
YK
14479 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14480 /* hint codes 24-31 are reserved and signal RI */
14481 generate_exception(ctx, EXCP_RI);
14482 }
3c824109
NF
14483 break;
14484 default:
14485 MIPS_INVAL("pool32c");
9c708c7f 14486 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14487 break;
14488 }
14489 break;
ab39ee45
YK
14490 case ADDI32: /* AUI, LUI */
14491 if (ctx->insn_flags & ISA_MIPS32R6) {
14492 /* AUI, LUI */
14493 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14494 } else {
14495 /* ADDI32 */
14496 mips32_op = OPC_ADDI;
14497 goto do_addi;
14498 }
14499 break;
3c824109
NF
14500 case ADDIU32:
14501 mips32_op = OPC_ADDIU;
14502 do_addi:
d75c135e 14503 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14504 break;
14505
14506 /* Logical operations */
14507 case ORI32:
14508 mips32_op = OPC_ORI;
14509 goto do_logici;
14510 case XORI32:
14511 mips32_op = OPC_XORI;
14512 goto do_logici;
14513 case ANDI32:
14514 mips32_op = OPC_ANDI;
14515 do_logici:
d75c135e 14516 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14517 break;
14518
14519 /* Set less than immediate */
14520 case SLTI32:
14521 mips32_op = OPC_SLTI;
14522 goto do_slti;
14523 case SLTIU32:
14524 mips32_op = OPC_SLTIU;
14525 do_slti:
d75c135e 14526 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14527 break;
14528 case JALX32:
9e8f441a 14529 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14530 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14531 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14532 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14533 break;
65935f07
YK
14534 case JALS32: /* BOVC, BEQC, BEQZALC */
14535 if (ctx->insn_flags & ISA_MIPS32R6) {
14536 if (rs >= rt) {
14537 /* BOVC */
14538 mips32_op = OPC_BOVC;
14539 } else if (rs < rt && rs == 0) {
14540 /* BEQZALC */
14541 mips32_op = OPC_BEQZALC;
14542 } else {
14543 /* BEQC */
14544 mips32_op = OPC_BEQC;
14545 }
14546 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14547 } else {
14548 /* JALS32 */
14549 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14550 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14551 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14552 }
3c824109 14553 break;
65935f07
YK
14554 case BEQ32: /* BC */
14555 if (ctx->insn_flags & ISA_MIPS32R6) {
14556 /* BC */
14557 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14558 sextract32(ctx->opcode << 1, 0, 27));
14559 } else {
14560 /* BEQ32 */
14561 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14562 }
3c824109 14563 break;
65935f07
YK
14564 case BNE32: /* BALC */
14565 if (ctx->insn_flags & ISA_MIPS32R6) {
14566 /* BALC */
14567 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14568 sextract32(ctx->opcode << 1, 0, 27));
14569 } else {
14570 /* BNE32 */
14571 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14572 }
3c824109 14573 break;
65935f07
YK
14574 case J32: /* BGTZC, BLTZC, BLTC */
14575 if (ctx->insn_flags & ISA_MIPS32R6) {
14576 if (rs == 0 && rt != 0) {
14577 /* BGTZC */
14578 mips32_op = OPC_BGTZC;
14579 } else if (rs != 0 && rt != 0 && rs == rt) {
14580 /* BLTZC */
14581 mips32_op = OPC_BLTZC;
14582 } else {
14583 /* BLTC */
14584 mips32_op = OPC_BLTC;
14585 }
14586 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14587 } else {
14588 /* J32 */
14589 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14590 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14591 }
3c824109 14592 break;
65935f07
YK
14593 case JAL32: /* BLEZC, BGEZC, BGEC */
14594 if (ctx->insn_flags & ISA_MIPS32R6) {
14595 if (rs == 0 && rt != 0) {
14596 /* BLEZC */
14597 mips32_op = OPC_BLEZC;
14598 } else if (rs != 0 && rt != 0 && rs == rt) {
14599 /* BGEZC */
14600 mips32_op = OPC_BGEZC;
14601 } else {
14602 /* BGEC */
14603 mips32_op = OPC_BGEC;
14604 }
14605 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14606 } else {
14607 /* JAL32 */
14608 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14609 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14610 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14611 }
3c824109
NF
14612 break;
14613 /* Floating point (COP1) */
14614 case LWC132:
14615 mips32_op = OPC_LWC1;
14616 goto do_cop1;
14617 case LDC132:
14618 mips32_op = OPC_LDC1;
14619 goto do_cop1;
14620 case SWC132:
14621 mips32_op = OPC_SWC1;
14622 goto do_cop1;
14623 case SDC132:
14624 mips32_op = OPC_SDC1;
14625 do_cop1:
5ab5c041 14626 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 14627 break;
ab39ee45
YK
14628 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14629 if (ctx->insn_flags & ISA_MIPS32R6) {
14630 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14631 switch ((ctx->opcode >> 16) & 0x1f) {
14632 case ADDIUPC_00 ... ADDIUPC_07:
14633 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14634 break;
14635 case AUIPC:
14636 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14637 break;
14638 case ALUIPC:
14639 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14640 break;
14641 case LWPC_08 ... LWPC_0F:
14642 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14643 break;
14644 default:
14645 generate_exception(ctx, EXCP_RI);
14646 break;
14647 }
14648 } else {
14649 /* ADDIUPC */
3c824109
NF
14650 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14651 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14652
14653 gen_addiupc(ctx, reg, offset, 0, 0);
14654 }
14655 break;
65935f07
YK
14656 case BNVC: /* BNEC, BNEZALC */
14657 check_insn(ctx, ISA_MIPS32R6);
14658 if (rs >= rt) {
14659 /* BNVC */
14660 mips32_op = OPC_BNVC;
14661 } else if (rs < rt && rs == 0) {
14662 /* BNEZALC */
14663 mips32_op = OPC_BNEZALC;
14664 } else {
14665 /* BNEC */
14666 mips32_op = OPC_BNEC;
14667 }
14668 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14669 break;
14670 case R6_BNEZC: /* JIALC */
14671 check_insn(ctx, ISA_MIPS32R6);
14672 if (rt != 0) {
14673 /* BNEZC */
14674 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14675 sextract32(ctx->opcode << 1, 0, 22));
14676 } else {
14677 /* JIALC */
14678 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14679 }
14680 break;
14681 case R6_BEQZC: /* JIC */
14682 check_insn(ctx, ISA_MIPS32R6);
14683 if (rt != 0) {
14684 /* BEQZC */
14685 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14686 sextract32(ctx->opcode << 1, 0, 22));
14687 } else {
14688 /* JIC */
14689 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14690 }
14691 break;
14692 case BLEZALC: /* BGEZALC, BGEUC */
14693 check_insn(ctx, ISA_MIPS32R6);
14694 if (rs == 0 && rt != 0) {
14695 /* BLEZALC */
14696 mips32_op = OPC_BLEZALC;
14697 } else if (rs != 0 && rt != 0 && rs == rt) {
14698 /* BGEZALC */
14699 mips32_op = OPC_BGEZALC;
14700 } else {
14701 /* BGEUC */
14702 mips32_op = OPC_BGEUC;
14703 }
14704 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14705 break;
14706 case BGTZALC: /* BLTZALC, BLTUC */
14707 check_insn(ctx, ISA_MIPS32R6);
14708 if (rs == 0 && rt != 0) {
14709 /* BGTZALC */
14710 mips32_op = OPC_BGTZALC;
14711 } else if (rs != 0 && rt != 0 && rs == rt) {
14712 /* BLTZALC */
14713 mips32_op = OPC_BLTZALC;
14714 } else {
14715 /* BLTUC */
14716 mips32_op = OPC_BLTUC;
14717 }
14718 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14719 break;
3c824109
NF
14720 /* Loads and stores */
14721 case LB32:
14722 mips32_op = OPC_LB;
5c13fdfd 14723 goto do_ld;
3c824109
NF
14724 case LBU32:
14725 mips32_op = OPC_LBU;
5c13fdfd 14726 goto do_ld;
3c824109
NF
14727 case LH32:
14728 mips32_op = OPC_LH;
5c13fdfd 14729 goto do_ld;
3c824109
NF
14730 case LHU32:
14731 mips32_op = OPC_LHU;
5c13fdfd 14732 goto do_ld;
3c824109
NF
14733 case LW32:
14734 mips32_op = OPC_LW;
5c13fdfd 14735 goto do_ld;
3c824109
NF
14736#ifdef TARGET_MIPS64
14737 case LD32:
d9224450
MR
14738 check_insn(ctx, ISA_MIPS3);
14739 check_mips_64(ctx);
3c824109 14740 mips32_op = OPC_LD;
5c13fdfd 14741 goto do_ld;
3c824109 14742 case SD32:
d9224450
MR
14743 check_insn(ctx, ISA_MIPS3);
14744 check_mips_64(ctx);
3c824109 14745 mips32_op = OPC_SD;
5c13fdfd 14746 goto do_st;
3c824109
NF
14747#endif
14748 case SB32:
14749 mips32_op = OPC_SB;
5c13fdfd 14750 goto do_st;
3c824109
NF
14751 case SH32:
14752 mips32_op = OPC_SH;
5c13fdfd 14753 goto do_st;
3c824109
NF
14754 case SW32:
14755 mips32_op = OPC_SW;
5c13fdfd
AJ
14756 goto do_st;
14757 do_ld:
d75c135e 14758 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
14759 break;
14760 do_st:
14761 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14762 break;
14763 default:
9c708c7f 14764 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14765 break;
14766 }
14767}
14768
240ce26a 14769static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14770{
14771 uint32_t op;
14772
14773 /* make sure instructions are on a halfword boundary */
14774 if (ctx->pc & 0x1) {
14775 env->CP0_BadVAddr = ctx->pc;
9c708c7f 14776 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
14777 return 2;
14778 }
14779
14780 op = (ctx->opcode >> 10) & 0x3f;
14781 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
14782 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14783 switch (op & 0x7) { /* MSB-3..MSB-5 */
14784 case 0:
14785 /* POOL32A, POOL32B, POOL32I, POOL32C */
14786 case 4:
14787 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14788 case 5:
14789 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14790 case 6:
14791 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14792 case 7:
14793 /* LB32, LH32, LWC132, LDC132, LW32 */
14794 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 14795 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14796 return 2;
14797 }
14798 break;
b231c103
YK
14799 case 1:
14800 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14801 case 2:
14802 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14803 case 3:
14804 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14805 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 14806 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14807 return 2;
14808 }
14809 break;
3c824109
NF
14810 }
14811 }
b231c103 14812
3c824109
NF
14813 switch (op) {
14814 case POOL16A:
14815 {
14816 int rd = mmreg(uMIPS_RD(ctx->opcode));
14817 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14818 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14819 uint32_t opc = 0;
14820
14821 switch (ctx->opcode & 0x1) {
14822 case ADDU16:
14823 opc = OPC_ADDU;
14824 break;
14825 case SUBU16:
14826 opc = OPC_SUBU;
14827 break;
14828 }
ed7ce6c0
YK
14829 if (ctx->insn_flags & ISA_MIPS32R6) {
14830 /* In the Release 6 the register number location in
14831 * the instruction encoding has changed.
14832 */
14833 gen_arith(ctx, opc, rs1, rd, rs2);
14834 } else {
14835 gen_arith(ctx, opc, rd, rs1, rs2);
14836 }
3c824109
NF
14837 }
14838 break;
14839 case POOL16B:
14840 {
14841 int rd = mmreg(uMIPS_RD(ctx->opcode));
14842 int rs = mmreg(uMIPS_RS(ctx->opcode));
14843 int amount = (ctx->opcode >> 1) & 0x7;
14844 uint32_t opc = 0;
14845 amount = amount == 0 ? 8 : amount;
14846
14847 switch (ctx->opcode & 0x1) {
14848 case SLL16:
14849 opc = OPC_SLL;
14850 break;
14851 case SRL16:
14852 opc = OPC_SRL;
14853 break;
14854 }
14855
d75c135e 14856 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
14857 }
14858 break;
14859 case POOL16C:
ed7ce6c0
YK
14860 if (ctx->insn_flags & ISA_MIPS32R6) {
14861 gen_pool16c_r6_insn(ctx);
14862 } else {
14863 gen_pool16c_insn(ctx);
14864 }
3c824109
NF
14865 break;
14866 case LWGP16:
14867 {
14868 int rd = mmreg(uMIPS_RD(ctx->opcode));
14869 int rb = 28; /* GP */
14870 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14871
d75c135e 14872 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14873 }
14874 break;
14875 case POOL16F:
9e8f441a 14876 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14877 if (ctx->opcode & 1) {
9c708c7f 14878 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14879 } else {
14880 /* MOVEP */
14881 int enc_dest = uMIPS_RD(ctx->opcode);
14882 int enc_rt = uMIPS_RS2(ctx->opcode);
14883 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 14884 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
14885 }
14886 break;
14887 case LBU16:
14888 {
14889 int rd = mmreg(uMIPS_RD(ctx->opcode));
14890 int rb = mmreg(uMIPS_RS(ctx->opcode));
14891 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14892 offset = (offset == 0xf ? -1 : offset);
14893
d75c135e 14894 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14895 }
14896 break;
14897 case LHU16:
14898 {
14899 int rd = mmreg(uMIPS_RD(ctx->opcode));
14900 int rb = mmreg(uMIPS_RS(ctx->opcode));
14901 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14902
d75c135e 14903 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14904 }
14905 break;
14906 case LWSP16:
14907 {
14908 int rd = (ctx->opcode >> 5) & 0x1f;
14909 int rb = 29; /* SP */
14910 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14911
d75c135e 14912 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14913 }
14914 break;
14915 case LW16:
14916 {
14917 int rd = mmreg(uMIPS_RD(ctx->opcode));
14918 int rb = mmreg(uMIPS_RS(ctx->opcode));
14919 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14920
d75c135e 14921 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14922 }
14923 break;
14924 case SB16:
14925 {
14926 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14927 int rb = mmreg(uMIPS_RS(ctx->opcode));
14928 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14929
5c13fdfd 14930 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14931 }
14932 break;
14933 case SH16:
14934 {
14935 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14936 int rb = mmreg(uMIPS_RS(ctx->opcode));
14937 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14938
5c13fdfd 14939 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14940 }
14941 break;
14942 case SWSP16:
14943 {
14944 int rd = (ctx->opcode >> 5) & 0x1f;
14945 int rb = 29; /* SP */
14946 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14947
5c13fdfd 14948 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14949 }
14950 break;
14951 case SW16:
14952 {
14953 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14954 int rb = mmreg(uMIPS_RS(ctx->opcode));
14955 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14956
5c13fdfd 14957 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14958 }
14959 break;
14960 case MOVE16:
14961 {
14962 int rd = uMIPS_RD5(ctx->opcode);
14963 int rs = uMIPS_RS5(ctx->opcode);
14964
7215d7e7 14965 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14966 }
14967 break;
14968 case ANDI16:
d75c135e 14969 gen_andi16(ctx);
3c824109
NF
14970 break;
14971 case POOL16D:
14972 switch (ctx->opcode & 0x1) {
14973 case ADDIUS5:
d75c135e 14974 gen_addius5(ctx);
3c824109
NF
14975 break;
14976 case ADDIUSP:
d75c135e 14977 gen_addiusp(ctx);
3c824109
NF
14978 break;
14979 }
14980 break;
14981 case POOL16E:
14982 switch (ctx->opcode & 0x1) {
14983 case ADDIUR2:
d75c135e 14984 gen_addiur2(ctx);
3c824109
NF
14985 break;
14986 case ADDIUR1SP:
d75c135e 14987 gen_addiur1sp(ctx);
3c824109
NF
14988 break;
14989 }
14990 break;
65935f07 14991 case B16: /* BC16 */
3c824109 14992 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
14993 sextract32(ctx->opcode, 0, 10) << 1,
14994 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 14995 break;
65935f07
YK
14996 case BNEZ16: /* BNEZC16 */
14997 case BEQZ16: /* BEQZC16 */
3c824109
NF
14998 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14999 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15000 0, sextract32(ctx->opcode, 0, 7) << 1,
15001 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15002
3c824109
NF
15003 break;
15004 case LI16:
15005 {
15006 int reg = mmreg(uMIPS_RD(ctx->opcode));
15007 int imm = ZIMM(ctx->opcode, 0, 7);
15008
15009 imm = (imm == 0x7f ? -1 : imm);
15010 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15011 }
15012 break;
3c824109 15013 case RES_29:
3c824109 15014 case RES_31:
3c824109 15015 case RES_39:
9c708c7f 15016 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15017 break;
15018 default:
f60eeb0c 15019 decode_micromips32_opc(env, ctx);
3c824109
NF
15020 return 4;
15021 }
15022
15023 return 2;
15024}
15025
15026/* SmartMIPS extension to MIPS32 */
15027
15028#if defined(TARGET_MIPS64)
15029
15030/* MDMX extension to MIPS64 */
15031
15032#endif
15033
9b1a1d68 15034/* MIPSDSP functions. */
d75c135e 15035static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15036 int rd, int base, int offset)
15037{
9b1a1d68
JL
15038 TCGv t0;
15039
9b1a1d68
JL
15040 check_dsp(ctx);
15041 t0 = tcg_temp_new();
15042
15043 if (base == 0) {
15044 gen_load_gpr(t0, offset);
15045 } else if (offset == 0) {
15046 gen_load_gpr(t0, base);
15047 } else {
15048 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15049 }
15050
9b1a1d68
JL
15051 switch (opc) {
15052 case OPC_LBUX:
5f68f5ae 15053 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15054 gen_store_gpr(t0, rd);
9b1a1d68
JL
15055 break;
15056 case OPC_LHX:
5f68f5ae 15057 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15058 gen_store_gpr(t0, rd);
9b1a1d68
JL
15059 break;
15060 case OPC_LWX:
5f68f5ae 15061 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15062 gen_store_gpr(t0, rd);
9b1a1d68
JL
15063 break;
15064#if defined(TARGET_MIPS64)
15065 case OPC_LDX:
5f68f5ae 15066 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15067 gen_store_gpr(t0, rd);
9b1a1d68
JL
15068 break;
15069#endif
15070 }
9b1a1d68
JL
15071 tcg_temp_free(t0);
15072}
15073
461c08df
JL
15074static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15075 int ret, int v1, int v2)
15076{
461c08df
JL
15077 TCGv v1_t;
15078 TCGv v2_t;
15079
15080 if (ret == 0) {
15081 /* Treat as NOP. */
461c08df
JL
15082 return;
15083 }
15084
15085 v1_t = tcg_temp_new();
15086 v2_t = tcg_temp_new();
15087
15088 gen_load_gpr(v1_t, v1);
15089 gen_load_gpr(v2_t, v2);
15090
15091 switch (op1) {
15092 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15093 case OPC_MULT_G_2E:
15094 check_dspr2(ctx);
15095 switch (op2) {
15096 case OPC_ADDUH_QB:
15097 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15098 break;
15099 case OPC_ADDUH_R_QB:
15100 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15101 break;
15102 case OPC_ADDQH_PH:
15103 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15104 break;
15105 case OPC_ADDQH_R_PH:
15106 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15107 break;
15108 case OPC_ADDQH_W:
15109 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15110 break;
15111 case OPC_ADDQH_R_W:
15112 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15113 break;
15114 case OPC_SUBUH_QB:
15115 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15116 break;
15117 case OPC_SUBUH_R_QB:
15118 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15119 break;
15120 case OPC_SUBQH_PH:
15121 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15122 break;
15123 case OPC_SUBQH_R_PH:
15124 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15125 break;
15126 case OPC_SUBQH_W:
15127 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15128 break;
15129 case OPC_SUBQH_R_W:
15130 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15131 break;
15132 }
15133 break;
15134 case OPC_ABSQ_S_PH_DSP:
15135 switch (op2) {
15136 case OPC_ABSQ_S_QB:
15137 check_dspr2(ctx);
15138 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15139 break;
15140 case OPC_ABSQ_S_PH:
15141 check_dsp(ctx);
15142 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15143 break;
15144 case OPC_ABSQ_S_W:
15145 check_dsp(ctx);
15146 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15147 break;
15148 case OPC_PRECEQ_W_PHL:
15149 check_dsp(ctx);
15150 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15151 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15152 break;
15153 case OPC_PRECEQ_W_PHR:
15154 check_dsp(ctx);
15155 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15156 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15157 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15158 break;
15159 case OPC_PRECEQU_PH_QBL:
15160 check_dsp(ctx);
15161 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15162 break;
15163 case OPC_PRECEQU_PH_QBR:
15164 check_dsp(ctx);
15165 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15166 break;
15167 case OPC_PRECEQU_PH_QBLA:
15168 check_dsp(ctx);
15169 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15170 break;
15171 case OPC_PRECEQU_PH_QBRA:
15172 check_dsp(ctx);
15173 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15174 break;
15175 case OPC_PRECEU_PH_QBL:
15176 check_dsp(ctx);
15177 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15178 break;
15179 case OPC_PRECEU_PH_QBR:
15180 check_dsp(ctx);
15181 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15182 break;
15183 case OPC_PRECEU_PH_QBLA:
15184 check_dsp(ctx);
15185 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15186 break;
15187 case OPC_PRECEU_PH_QBRA:
15188 check_dsp(ctx);
15189 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15190 break;
15191 }
15192 break;
15193 case OPC_ADDU_QB_DSP:
15194 switch (op2) {
15195 case OPC_ADDQ_PH:
15196 check_dsp(ctx);
15197 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15198 break;
15199 case OPC_ADDQ_S_PH:
15200 check_dsp(ctx);
15201 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15202 break;
15203 case OPC_ADDQ_S_W:
15204 check_dsp(ctx);
15205 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15206 break;
15207 case OPC_ADDU_QB:
15208 check_dsp(ctx);
15209 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15210 break;
15211 case OPC_ADDU_S_QB:
15212 check_dsp(ctx);
15213 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15214 break;
15215 case OPC_ADDU_PH:
15216 check_dspr2(ctx);
15217 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15218 break;
15219 case OPC_ADDU_S_PH:
15220 check_dspr2(ctx);
15221 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15222 break;
15223 case OPC_SUBQ_PH:
15224 check_dsp(ctx);
15225 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15226 break;
15227 case OPC_SUBQ_S_PH:
15228 check_dsp(ctx);
15229 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15230 break;
15231 case OPC_SUBQ_S_W:
15232 check_dsp(ctx);
15233 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15234 break;
15235 case OPC_SUBU_QB:
15236 check_dsp(ctx);
15237 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15238 break;
15239 case OPC_SUBU_S_QB:
15240 check_dsp(ctx);
15241 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15242 break;
15243 case OPC_SUBU_PH:
15244 check_dspr2(ctx);
15245 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15246 break;
15247 case OPC_SUBU_S_PH:
15248 check_dspr2(ctx);
15249 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15250 break;
15251 case OPC_ADDSC:
15252 check_dsp(ctx);
15253 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15254 break;
15255 case OPC_ADDWC:
15256 check_dsp(ctx);
15257 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15258 break;
15259 case OPC_MODSUB:
15260 check_dsp(ctx);
15261 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15262 break;
15263 case OPC_RADDU_W_QB:
15264 check_dsp(ctx);
15265 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15266 break;
15267 }
15268 break;
15269 case OPC_CMPU_EQ_QB_DSP:
15270 switch (op2) {
15271 case OPC_PRECR_QB_PH:
15272 check_dspr2(ctx);
15273 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15274 break;
15275 case OPC_PRECRQ_QB_PH:
15276 check_dsp(ctx);
15277 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15278 break;
15279 case OPC_PRECR_SRA_PH_W:
15280 check_dspr2(ctx);
15281 {
15282 TCGv_i32 sa_t = tcg_const_i32(v2);
15283 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15284 cpu_gpr[ret]);
15285 tcg_temp_free_i32(sa_t);
15286 break;
15287 }
15288 case OPC_PRECR_SRA_R_PH_W:
15289 check_dspr2(ctx);
15290 {
15291 TCGv_i32 sa_t = tcg_const_i32(v2);
15292 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15293 cpu_gpr[ret]);
15294 tcg_temp_free_i32(sa_t);
15295 break;
15296 }
15297 case OPC_PRECRQ_PH_W:
15298 check_dsp(ctx);
15299 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15300 break;
15301 case OPC_PRECRQ_RS_PH_W:
15302 check_dsp(ctx);
15303 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15304 break;
15305 case OPC_PRECRQU_S_QB_PH:
15306 check_dsp(ctx);
15307 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15308 break;
15309 }
15310 break;
15311#ifdef TARGET_MIPS64
15312 case OPC_ABSQ_S_QH_DSP:
15313 switch (op2) {
15314 case OPC_PRECEQ_L_PWL:
15315 check_dsp(ctx);
15316 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15317 break;
15318 case OPC_PRECEQ_L_PWR:
15319 check_dsp(ctx);
15320 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15321 break;
15322 case OPC_PRECEQ_PW_QHL:
15323 check_dsp(ctx);
15324 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15325 break;
15326 case OPC_PRECEQ_PW_QHR:
15327 check_dsp(ctx);
15328 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15329 break;
15330 case OPC_PRECEQ_PW_QHLA:
15331 check_dsp(ctx);
15332 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15333 break;
15334 case OPC_PRECEQ_PW_QHRA:
15335 check_dsp(ctx);
15336 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15337 break;
15338 case OPC_PRECEQU_QH_OBL:
15339 check_dsp(ctx);
15340 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15341 break;
15342 case OPC_PRECEQU_QH_OBR:
15343 check_dsp(ctx);
15344 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15345 break;
15346 case OPC_PRECEQU_QH_OBLA:
15347 check_dsp(ctx);
15348 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15349 break;
15350 case OPC_PRECEQU_QH_OBRA:
15351 check_dsp(ctx);
15352 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15353 break;
15354 case OPC_PRECEU_QH_OBL:
15355 check_dsp(ctx);
15356 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15357 break;
15358 case OPC_PRECEU_QH_OBR:
15359 check_dsp(ctx);
15360 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15361 break;
15362 case OPC_PRECEU_QH_OBLA:
15363 check_dsp(ctx);
15364 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15365 break;
15366 case OPC_PRECEU_QH_OBRA:
15367 check_dsp(ctx);
15368 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15369 break;
15370 case OPC_ABSQ_S_OB:
15371 check_dspr2(ctx);
15372 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15373 break;
15374 case OPC_ABSQ_S_PW:
15375 check_dsp(ctx);
15376 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15377 break;
15378 case OPC_ABSQ_S_QH:
15379 check_dsp(ctx);
15380 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15381 break;
15382 }
15383 break;
15384 case OPC_ADDU_OB_DSP:
15385 switch (op2) {
15386 case OPC_RADDU_L_OB:
15387 check_dsp(ctx);
15388 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15389 break;
15390 case OPC_SUBQ_PW:
15391 check_dsp(ctx);
15392 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15393 break;
15394 case OPC_SUBQ_S_PW:
15395 check_dsp(ctx);
15396 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15397 break;
15398 case OPC_SUBQ_QH:
15399 check_dsp(ctx);
15400 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15401 break;
15402 case OPC_SUBQ_S_QH:
15403 check_dsp(ctx);
15404 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15405 break;
15406 case OPC_SUBU_OB:
15407 check_dsp(ctx);
15408 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15409 break;
15410 case OPC_SUBU_S_OB:
15411 check_dsp(ctx);
15412 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15413 break;
15414 case OPC_SUBU_QH:
15415 check_dspr2(ctx);
15416 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15417 break;
15418 case OPC_SUBU_S_QH:
15419 check_dspr2(ctx);
15420 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15421 break;
15422 case OPC_SUBUH_OB:
15423 check_dspr2(ctx);
15424 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15425 break;
15426 case OPC_SUBUH_R_OB:
15427 check_dspr2(ctx);
15428 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15429 break;
15430 case OPC_ADDQ_PW:
15431 check_dsp(ctx);
15432 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15433 break;
15434 case OPC_ADDQ_S_PW:
15435 check_dsp(ctx);
15436 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15437 break;
15438 case OPC_ADDQ_QH:
15439 check_dsp(ctx);
15440 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15441 break;
15442 case OPC_ADDQ_S_QH:
15443 check_dsp(ctx);
15444 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15445 break;
15446 case OPC_ADDU_OB:
15447 check_dsp(ctx);
15448 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15449 break;
15450 case OPC_ADDU_S_OB:
15451 check_dsp(ctx);
15452 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15453 break;
15454 case OPC_ADDU_QH:
15455 check_dspr2(ctx);
15456 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15457 break;
15458 case OPC_ADDU_S_QH:
15459 check_dspr2(ctx);
15460 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15461 break;
15462 case OPC_ADDUH_OB:
15463 check_dspr2(ctx);
15464 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15465 break;
15466 case OPC_ADDUH_R_OB:
15467 check_dspr2(ctx);
15468 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15469 break;
15470 }
15471 break;
15472 case OPC_CMPU_EQ_OB_DSP:
15473 switch (op2) {
15474 case OPC_PRECR_OB_QH:
15475 check_dspr2(ctx);
15476 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15477 break;
15478 case OPC_PRECR_SRA_QH_PW:
15479 check_dspr2(ctx);
15480 {
15481 TCGv_i32 ret_t = tcg_const_i32(ret);
15482 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15483 tcg_temp_free_i32(ret_t);
15484 break;
15485 }
15486 case OPC_PRECR_SRA_R_QH_PW:
15487 check_dspr2(ctx);
15488 {
15489 TCGv_i32 sa_v = tcg_const_i32(ret);
15490 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15491 tcg_temp_free_i32(sa_v);
15492 break;
15493 }
15494 case OPC_PRECRQ_OB_QH:
15495 check_dsp(ctx);
15496 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15497 break;
15498 case OPC_PRECRQ_PW_L:
15499 check_dsp(ctx);
15500 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15501 break;
15502 case OPC_PRECRQ_QH_PW:
15503 check_dsp(ctx);
15504 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15505 break;
15506 case OPC_PRECRQ_RS_QH_PW:
15507 check_dsp(ctx);
15508 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15509 break;
15510 case OPC_PRECRQU_S_OB_QH:
15511 check_dsp(ctx);
15512 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15513 break;
15514 }
15515 break;
15516#endif
15517 }
15518
15519 tcg_temp_free(v1_t);
15520 tcg_temp_free(v2_t);
461c08df 15521}
9b1a1d68 15522
77c5fa8b
JL
15523static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15524 int ret, int v1, int v2)
15525{
15526 uint32_t op2;
77c5fa8b
JL
15527 TCGv t0;
15528 TCGv v1_t;
15529 TCGv v2_t;
15530
15531 if (ret == 0) {
15532 /* Treat as NOP. */
77c5fa8b
JL
15533 return;
15534 }
15535
15536 t0 = tcg_temp_new();
15537 v1_t = tcg_temp_new();
15538 v2_t = tcg_temp_new();
15539
15540 tcg_gen_movi_tl(t0, v1);
15541 gen_load_gpr(v1_t, v1);
15542 gen_load_gpr(v2_t, v2);
15543
15544 switch (opc) {
15545 case OPC_SHLL_QB_DSP:
15546 {
15547 op2 = MASK_SHLL_QB(ctx->opcode);
15548 switch (op2) {
15549 case OPC_SHLL_QB:
15550 check_dsp(ctx);
15551 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15552 break;
15553 case OPC_SHLLV_QB:
15554 check_dsp(ctx);
15555 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15556 break;
15557 case OPC_SHLL_PH:
15558 check_dsp(ctx);
15559 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15560 break;
15561 case OPC_SHLLV_PH:
15562 check_dsp(ctx);
15563 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15564 break;
15565 case OPC_SHLL_S_PH:
15566 check_dsp(ctx);
15567 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15568 break;
15569 case OPC_SHLLV_S_PH:
15570 check_dsp(ctx);
15571 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15572 break;
15573 case OPC_SHLL_S_W:
15574 check_dsp(ctx);
15575 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15576 break;
15577 case OPC_SHLLV_S_W:
15578 check_dsp(ctx);
15579 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15580 break;
15581 case OPC_SHRL_QB:
15582 check_dsp(ctx);
15583 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15584 break;
15585 case OPC_SHRLV_QB:
15586 check_dsp(ctx);
15587 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15588 break;
15589 case OPC_SHRL_PH:
15590 check_dspr2(ctx);
15591 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15592 break;
15593 case OPC_SHRLV_PH:
15594 check_dspr2(ctx);
15595 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15596 break;
15597 case OPC_SHRA_QB:
15598 check_dspr2(ctx);
15599 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15600 break;
15601 case OPC_SHRA_R_QB:
15602 check_dspr2(ctx);
15603 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15604 break;
15605 case OPC_SHRAV_QB:
15606 check_dspr2(ctx);
15607 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15608 break;
15609 case OPC_SHRAV_R_QB:
15610 check_dspr2(ctx);
15611 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15612 break;
15613 case OPC_SHRA_PH:
15614 check_dsp(ctx);
15615 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15616 break;
15617 case OPC_SHRA_R_PH:
15618 check_dsp(ctx);
15619 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15620 break;
15621 case OPC_SHRAV_PH:
15622 check_dsp(ctx);
15623 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15624 break;
15625 case OPC_SHRAV_R_PH:
15626 check_dsp(ctx);
15627 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15628 break;
15629 case OPC_SHRA_R_W:
15630 check_dsp(ctx);
15631 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15632 break;
15633 case OPC_SHRAV_R_W:
15634 check_dsp(ctx);
15635 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15636 break;
15637 default: /* Invalid */
15638 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 15639 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15640 break;
15641 }
15642 break;
15643 }
15644#ifdef TARGET_MIPS64
15645 case OPC_SHLL_OB_DSP:
15646 op2 = MASK_SHLL_OB(ctx->opcode);
15647 switch (op2) {
15648 case OPC_SHLL_PW:
15649 check_dsp(ctx);
15650 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15651 break;
15652 case OPC_SHLLV_PW:
15653 check_dsp(ctx);
15654 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15655 break;
15656 case OPC_SHLL_S_PW:
15657 check_dsp(ctx);
15658 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15659 break;
15660 case OPC_SHLLV_S_PW:
15661 check_dsp(ctx);
15662 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15663 break;
15664 case OPC_SHLL_OB:
15665 check_dsp(ctx);
15666 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15667 break;
15668 case OPC_SHLLV_OB:
15669 check_dsp(ctx);
15670 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15671 break;
15672 case OPC_SHLL_QH:
15673 check_dsp(ctx);
15674 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15675 break;
15676 case OPC_SHLLV_QH:
15677 check_dsp(ctx);
15678 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15679 break;
15680 case OPC_SHLL_S_QH:
15681 check_dsp(ctx);
15682 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15683 break;
15684 case OPC_SHLLV_S_QH:
15685 check_dsp(ctx);
15686 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15687 break;
15688 case OPC_SHRA_OB:
15689 check_dspr2(ctx);
15690 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15691 break;
15692 case OPC_SHRAV_OB:
15693 check_dspr2(ctx);
15694 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15695 break;
15696 case OPC_SHRA_R_OB:
15697 check_dspr2(ctx);
15698 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15699 break;
15700 case OPC_SHRAV_R_OB:
15701 check_dspr2(ctx);
15702 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15703 break;
15704 case OPC_SHRA_PW:
15705 check_dsp(ctx);
15706 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15707 break;
15708 case OPC_SHRAV_PW:
15709 check_dsp(ctx);
15710 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15711 break;
15712 case OPC_SHRA_R_PW:
15713 check_dsp(ctx);
15714 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15715 break;
15716 case OPC_SHRAV_R_PW:
15717 check_dsp(ctx);
15718 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15719 break;
15720 case OPC_SHRA_QH:
15721 check_dsp(ctx);
15722 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15723 break;
15724 case OPC_SHRAV_QH:
15725 check_dsp(ctx);
15726 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15727 break;
15728 case OPC_SHRA_R_QH:
15729 check_dsp(ctx);
15730 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15731 break;
15732 case OPC_SHRAV_R_QH:
15733 check_dsp(ctx);
15734 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15735 break;
15736 case OPC_SHRL_OB:
15737 check_dsp(ctx);
15738 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15739 break;
15740 case OPC_SHRLV_OB:
15741 check_dsp(ctx);
15742 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15743 break;
15744 case OPC_SHRL_QH:
15745 check_dspr2(ctx);
15746 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15747 break;
15748 case OPC_SHRLV_QH:
15749 check_dspr2(ctx);
15750 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15751 break;
15752 default: /* Invalid */
15753 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 15754 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
15755 break;
15756 }
15757 break;
15758#endif
15759 }
15760
15761 tcg_temp_free(t0);
15762 tcg_temp_free(v1_t);
15763 tcg_temp_free(v2_t);
77c5fa8b
JL
15764}
15765
a22260ae
JL
15766static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15767 int ret, int v1, int v2, int check_ret)
15768{
a22260ae
JL
15769 TCGv_i32 t0;
15770 TCGv v1_t;
15771 TCGv v2_t;
15772
15773 if ((ret == 0) && (check_ret == 1)) {
15774 /* Treat as NOP. */
a22260ae
JL
15775 return;
15776 }
15777
15778 t0 = tcg_temp_new_i32();
15779 v1_t = tcg_temp_new();
15780 v2_t = tcg_temp_new();
15781
15782 tcg_gen_movi_i32(t0, ret);
15783 gen_load_gpr(v1_t, v1);
15784 gen_load_gpr(v2_t, v2);
15785
15786 switch (op1) {
15787 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15788 * the same mask and op1. */
15789 case OPC_MULT_G_2E:
639eadb9 15790 check_dspr2(ctx);
a22260ae
JL
15791 switch (op2) {
15792 case OPC_MUL_PH:
15793 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15794 break;
15795 case OPC_MUL_S_PH:
15796 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15797 break;
15798 case OPC_MULQ_S_W:
15799 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15800 break;
15801 case OPC_MULQ_RS_W:
15802 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15803 break;
15804 }
15805 break;
15806 case OPC_DPA_W_PH_DSP:
15807 switch (op2) {
15808 case OPC_DPAU_H_QBL:
15809 check_dsp(ctx);
15810 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15811 break;
15812 case OPC_DPAU_H_QBR:
15813 check_dsp(ctx);
15814 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15815 break;
15816 case OPC_DPSU_H_QBL:
15817 check_dsp(ctx);
15818 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15819 break;
15820 case OPC_DPSU_H_QBR:
15821 check_dsp(ctx);
15822 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15823 break;
15824 case OPC_DPA_W_PH:
15825 check_dspr2(ctx);
15826 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15827 break;
15828 case OPC_DPAX_W_PH:
15829 check_dspr2(ctx);
15830 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15831 break;
15832 case OPC_DPAQ_S_W_PH:
15833 check_dsp(ctx);
15834 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15835 break;
15836 case OPC_DPAQX_S_W_PH:
15837 check_dspr2(ctx);
15838 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15839 break;
15840 case OPC_DPAQX_SA_W_PH:
15841 check_dspr2(ctx);
15842 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15843 break;
15844 case OPC_DPS_W_PH:
15845 check_dspr2(ctx);
15846 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15847 break;
15848 case OPC_DPSX_W_PH:
15849 check_dspr2(ctx);
15850 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15851 break;
15852 case OPC_DPSQ_S_W_PH:
15853 check_dsp(ctx);
15854 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15855 break;
15856 case OPC_DPSQX_S_W_PH:
15857 check_dspr2(ctx);
15858 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15859 break;
15860 case OPC_DPSQX_SA_W_PH:
15861 check_dspr2(ctx);
15862 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15863 break;
15864 case OPC_MULSAQ_S_W_PH:
15865 check_dsp(ctx);
15866 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15867 break;
15868 case OPC_DPAQ_SA_L_W:
15869 check_dsp(ctx);
15870 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15871 break;
15872 case OPC_DPSQ_SA_L_W:
15873 check_dsp(ctx);
15874 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15875 break;
15876 case OPC_MAQ_S_W_PHL:
15877 check_dsp(ctx);
15878 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15879 break;
15880 case OPC_MAQ_S_W_PHR:
15881 check_dsp(ctx);
15882 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15883 break;
15884 case OPC_MAQ_SA_W_PHL:
15885 check_dsp(ctx);
15886 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15887 break;
15888 case OPC_MAQ_SA_W_PHR:
15889 check_dsp(ctx);
15890 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15891 break;
15892 case OPC_MULSA_W_PH:
15893 check_dspr2(ctx);
15894 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15895 break;
15896 }
15897 break;
15898#ifdef TARGET_MIPS64
15899 case OPC_DPAQ_W_QH_DSP:
15900 {
15901 int ac = ret & 0x03;
15902 tcg_gen_movi_i32(t0, ac);
15903
15904 switch (op2) {
15905 case OPC_DMADD:
15906 check_dsp(ctx);
15907 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15908 break;
15909 case OPC_DMADDU:
15910 check_dsp(ctx);
15911 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15912 break;
15913 case OPC_DMSUB:
15914 check_dsp(ctx);
15915 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15916 break;
15917 case OPC_DMSUBU:
15918 check_dsp(ctx);
15919 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15920 break;
15921 case OPC_DPA_W_QH:
15922 check_dspr2(ctx);
15923 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15924 break;
15925 case OPC_DPAQ_S_W_QH:
15926 check_dsp(ctx);
15927 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15928 break;
15929 case OPC_DPAQ_SA_L_PW:
15930 check_dsp(ctx);
15931 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15932 break;
15933 case OPC_DPAU_H_OBL:
15934 check_dsp(ctx);
15935 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15936 break;
15937 case OPC_DPAU_H_OBR:
15938 check_dsp(ctx);
15939 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15940 break;
15941 case OPC_DPS_W_QH:
15942 check_dspr2(ctx);
15943 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15944 break;
15945 case OPC_DPSQ_S_W_QH:
15946 check_dsp(ctx);
15947 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15948 break;
15949 case OPC_DPSQ_SA_L_PW:
15950 check_dsp(ctx);
15951 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15952 break;
15953 case OPC_DPSU_H_OBL:
15954 check_dsp(ctx);
15955 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15956 break;
15957 case OPC_DPSU_H_OBR:
15958 check_dsp(ctx);
15959 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15960 break;
15961 case OPC_MAQ_S_L_PWL:
15962 check_dsp(ctx);
15963 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15964 break;
15965 case OPC_MAQ_S_L_PWR:
15966 check_dsp(ctx);
15967 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15968 break;
15969 case OPC_MAQ_S_W_QHLL:
15970 check_dsp(ctx);
15971 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15972 break;
15973 case OPC_MAQ_SA_W_QHLL:
15974 check_dsp(ctx);
15975 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15976 break;
15977 case OPC_MAQ_S_W_QHLR:
15978 check_dsp(ctx);
15979 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15980 break;
15981 case OPC_MAQ_SA_W_QHLR:
15982 check_dsp(ctx);
15983 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15984 break;
15985 case OPC_MAQ_S_W_QHRL:
15986 check_dsp(ctx);
15987 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15988 break;
15989 case OPC_MAQ_SA_W_QHRL:
15990 check_dsp(ctx);
15991 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15992 break;
15993 case OPC_MAQ_S_W_QHRR:
15994 check_dsp(ctx);
15995 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15996 break;
15997 case OPC_MAQ_SA_W_QHRR:
15998 check_dsp(ctx);
15999 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16000 break;
16001 case OPC_MULSAQ_S_L_PW:
16002 check_dsp(ctx);
16003 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16004 break;
16005 case OPC_MULSAQ_S_W_QH:
16006 check_dsp(ctx);
16007 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16008 break;
16009 }
16010 }
16011 break;
16012#endif
16013 case OPC_ADDU_QB_DSP:
16014 switch (op2) {
16015 case OPC_MULEU_S_PH_QBL:
16016 check_dsp(ctx);
16017 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16018 break;
16019 case OPC_MULEU_S_PH_QBR:
16020 check_dsp(ctx);
16021 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16022 break;
16023 case OPC_MULQ_RS_PH:
16024 check_dsp(ctx);
16025 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16026 break;
16027 case OPC_MULEQ_S_W_PHL:
16028 check_dsp(ctx);
16029 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16030 break;
16031 case OPC_MULEQ_S_W_PHR:
16032 check_dsp(ctx);
16033 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16034 break;
16035 case OPC_MULQ_S_PH:
16036 check_dspr2(ctx);
16037 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16038 break;
16039 }
16040 break;
16041#ifdef TARGET_MIPS64
16042 case OPC_ADDU_OB_DSP:
16043 switch (op2) {
16044 case OPC_MULEQ_S_PW_QHL:
16045 check_dsp(ctx);
16046 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16047 break;
16048 case OPC_MULEQ_S_PW_QHR:
16049 check_dsp(ctx);
16050 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16051 break;
16052 case OPC_MULEU_S_QH_OBL:
16053 check_dsp(ctx);
16054 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16055 break;
16056 case OPC_MULEU_S_QH_OBR:
16057 check_dsp(ctx);
16058 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16059 break;
16060 case OPC_MULQ_RS_QH:
16061 check_dsp(ctx);
16062 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16063 break;
16064 }
16065 break;
16066#endif
16067 }
16068
16069 tcg_temp_free_i32(t0);
16070 tcg_temp_free(v1_t);
16071 tcg_temp_free(v2_t);
a22260ae
JL
16072}
16073
d75c135e 16074static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16075 int ret, int val)
16076{
1cb6686c
JL
16077 int16_t imm;
16078 TCGv t0;
16079 TCGv val_t;
16080
16081 if (ret == 0) {
16082 /* Treat as NOP. */
1cb6686c
JL
16083 return;
16084 }
16085
16086 t0 = tcg_temp_new();
16087 val_t = tcg_temp_new();
16088 gen_load_gpr(val_t, val);
16089
16090 switch (op1) {
16091 case OPC_ABSQ_S_PH_DSP:
16092 switch (op2) {
16093 case OPC_BITREV:
16094 check_dsp(ctx);
16095 gen_helper_bitrev(cpu_gpr[ret], val_t);
16096 break;
16097 case OPC_REPL_QB:
16098 check_dsp(ctx);
16099 {
16100 target_long result;
16101 imm = (ctx->opcode >> 16) & 0xFF;
16102 result = (uint32_t)imm << 24 |
16103 (uint32_t)imm << 16 |
16104 (uint32_t)imm << 8 |
16105 (uint32_t)imm;
16106 result = (int32_t)result;
16107 tcg_gen_movi_tl(cpu_gpr[ret], result);
16108 }
16109 break;
16110 case OPC_REPLV_QB:
16111 check_dsp(ctx);
16112 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16113 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16114 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16115 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16116 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16117 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16118 break;
16119 case OPC_REPL_PH:
16120 check_dsp(ctx);
16121 {
16122 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16123 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16124 tcg_gen_movi_tl(cpu_gpr[ret], \
16125 (target_long)((int32_t)imm << 16 | \
c4aaba92 16126 (uint16_t)imm));
1cb6686c
JL
16127 }
16128 break;
16129 case OPC_REPLV_PH:
16130 check_dsp(ctx);
16131 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16132 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16133 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16134 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16135 break;
16136 }
16137 break;
16138#ifdef TARGET_MIPS64
16139 case OPC_ABSQ_S_QH_DSP:
16140 switch (op2) {
16141 case OPC_REPL_OB:
16142 check_dsp(ctx);
16143 {
16144 target_long temp;
16145
16146 imm = (ctx->opcode >> 16) & 0xFF;
16147 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16148 temp = (temp << 16) | temp;
16149 temp = (temp << 32) | temp;
16150 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16151 break;
16152 }
16153 case OPC_REPL_PW:
16154 check_dsp(ctx);
16155 {
16156 target_long temp;
16157
16158 imm = (ctx->opcode >> 16) & 0x03FF;
16159 imm = (int16_t)(imm << 6) >> 6;
16160 temp = ((target_long)imm << 32) \
16161 | ((target_long)imm & 0xFFFFFFFF);
16162 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16163 break;
16164 }
16165 case OPC_REPL_QH:
16166 check_dsp(ctx);
16167 {
16168 target_long temp;
16169
16170 imm = (ctx->opcode >> 16) & 0x03FF;
16171 imm = (int16_t)(imm << 6) >> 6;
16172
16173 temp = ((uint64_t)(uint16_t)imm << 48) |
16174 ((uint64_t)(uint16_t)imm << 32) |
16175 ((uint64_t)(uint16_t)imm << 16) |
16176 (uint64_t)(uint16_t)imm;
16177 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16178 break;
16179 }
16180 case OPC_REPLV_OB:
16181 check_dsp(ctx);
16182 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16183 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16184 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16185 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16186 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16187 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16188 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16189 break;
16190 case OPC_REPLV_PW:
16191 check_dsp(ctx);
16192 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16193 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16194 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16195 break;
16196 case OPC_REPLV_QH:
16197 check_dsp(ctx);
16198 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
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 }
16205 break;
16206#endif
16207 }
16208 tcg_temp_free(t0);
16209 tcg_temp_free(val_t);
1cb6686c
JL
16210}
16211
26690560
JL
16212static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16213 uint32_t op1, uint32_t op2,
16214 int ret, int v1, int v2, int check_ret)
16215{
26690560
JL
16216 TCGv t1;
16217 TCGv v1_t;
16218 TCGv v2_t;
16219
16220 if ((ret == 0) && (check_ret == 1)) {
16221 /* Treat as NOP. */
26690560
JL
16222 return;
16223 }
16224
26690560
JL
16225 t1 = tcg_temp_new();
16226 v1_t = tcg_temp_new();
16227 v2_t = tcg_temp_new();
16228
16229 gen_load_gpr(v1_t, v1);
16230 gen_load_gpr(v2_t, v2);
16231
16232 switch (op1) {
26690560
JL
16233 case OPC_CMPU_EQ_QB_DSP:
16234 switch (op2) {
16235 case OPC_CMPU_EQ_QB:
16236 check_dsp(ctx);
16237 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16238 break;
16239 case OPC_CMPU_LT_QB:
16240 check_dsp(ctx);
16241 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16242 break;
16243 case OPC_CMPU_LE_QB:
16244 check_dsp(ctx);
16245 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16246 break;
16247 case OPC_CMPGU_EQ_QB:
16248 check_dsp(ctx);
16249 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16250 break;
16251 case OPC_CMPGU_LT_QB:
16252 check_dsp(ctx);
16253 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16254 break;
16255 case OPC_CMPGU_LE_QB:
16256 check_dsp(ctx);
16257 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16258 break;
16259 case OPC_CMPGDU_EQ_QB:
16260 check_dspr2(ctx);
16261 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16262 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16263 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16264 tcg_gen_shli_tl(t1, t1, 24);
16265 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16266 break;
16267 case OPC_CMPGDU_LT_QB:
16268 check_dspr2(ctx);
16269 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16270 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16271 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16272 tcg_gen_shli_tl(t1, t1, 24);
16273 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16274 break;
16275 case OPC_CMPGDU_LE_QB:
16276 check_dspr2(ctx);
16277 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16278 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16279 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16280 tcg_gen_shli_tl(t1, t1, 24);
16281 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16282 break;
16283 case OPC_CMP_EQ_PH:
16284 check_dsp(ctx);
16285 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16286 break;
16287 case OPC_CMP_LT_PH:
16288 check_dsp(ctx);
16289 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16290 break;
16291 case OPC_CMP_LE_PH:
16292 check_dsp(ctx);
16293 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16294 break;
16295 case OPC_PICK_QB:
16296 check_dsp(ctx);
16297 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16298 break;
16299 case OPC_PICK_PH:
16300 check_dsp(ctx);
16301 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16302 break;
16303 case OPC_PACKRL_PH:
16304 check_dsp(ctx);
16305 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16306 break;
16307 }
16308 break;
16309#ifdef TARGET_MIPS64
16310 case OPC_CMPU_EQ_OB_DSP:
16311 switch (op2) {
16312 case OPC_CMP_EQ_PW:
16313 check_dsp(ctx);
16314 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16315 break;
16316 case OPC_CMP_LT_PW:
16317 check_dsp(ctx);
16318 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16319 break;
16320 case OPC_CMP_LE_PW:
16321 check_dsp(ctx);
16322 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16323 break;
16324 case OPC_CMP_EQ_QH:
16325 check_dsp(ctx);
16326 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16327 break;
16328 case OPC_CMP_LT_QH:
16329 check_dsp(ctx);
16330 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16331 break;
16332 case OPC_CMP_LE_QH:
16333 check_dsp(ctx);
16334 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16335 break;
16336 case OPC_CMPGDU_EQ_OB:
16337 check_dspr2(ctx);
16338 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16339 break;
16340 case OPC_CMPGDU_LT_OB:
16341 check_dspr2(ctx);
16342 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16343 break;
16344 case OPC_CMPGDU_LE_OB:
16345 check_dspr2(ctx);
16346 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16347 break;
16348 case OPC_CMPGU_EQ_OB:
16349 check_dsp(ctx);
16350 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16351 break;
16352 case OPC_CMPGU_LT_OB:
16353 check_dsp(ctx);
16354 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16355 break;
16356 case OPC_CMPGU_LE_OB:
16357 check_dsp(ctx);
16358 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16359 break;
16360 case OPC_CMPU_EQ_OB:
16361 check_dsp(ctx);
16362 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16363 break;
16364 case OPC_CMPU_LT_OB:
16365 check_dsp(ctx);
16366 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16367 break;
16368 case OPC_CMPU_LE_OB:
16369 check_dsp(ctx);
16370 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16371 break;
16372 case OPC_PACKRL_PW:
16373 check_dsp(ctx);
16374 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16375 break;
16376 case OPC_PICK_OB:
16377 check_dsp(ctx);
16378 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16379 break;
16380 case OPC_PICK_PW:
16381 check_dsp(ctx);
16382 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16383 break;
16384 case OPC_PICK_QH:
16385 check_dsp(ctx);
16386 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16387 break;
16388 }
16389 break;
df6126a7
AJ
16390#endif
16391 }
16392
16393 tcg_temp_free(t1);
16394 tcg_temp_free(v1_t);
16395 tcg_temp_free(v2_t);
df6126a7
AJ
16396}
16397
16398static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16399 uint32_t op1, int rt, int rs, int sa)
16400{
df6126a7
AJ
16401 TCGv t0;
16402
16403 check_dspr2(ctx);
16404
16405 if (rt == 0) {
16406 /* Treat as NOP. */
df6126a7
AJ
16407 return;
16408 }
16409
16410 t0 = tcg_temp_new();
16411 gen_load_gpr(t0, rs);
16412
16413 switch (op1) {
16414 case OPC_APPEND_DSP:
16415 switch (MASK_APPEND(ctx->opcode)) {
16416 case OPC_APPEND:
16417 if (sa != 0) {
16418 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16419 }
16420 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16421 break;
16422 case OPC_PREPEND:
16423 if (sa != 0) {
16424 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16425 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16426 tcg_gen_shli_tl(t0, t0, 32 - sa);
16427 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16428 }
16429 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16430 break;
16431 case OPC_BALIGN:
16432 sa &= 3;
16433 if (sa != 0 && sa != 2) {
16434 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16435 tcg_gen_ext32u_tl(t0, t0);
16436 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16437 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16438 }
16439 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16440 break;
16441 default: /* Invalid */
16442 MIPS_INVAL("MASK APPEND");
9c708c7f 16443 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16444 break;
16445 }
16446 break;
16447#ifdef TARGET_MIPS64
26690560 16448 case OPC_DAPPEND_DSP:
df6126a7 16449 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16450 case OPC_DAPPEND:
df6126a7
AJ
16451 if (sa != 0) {
16452 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16453 }
26690560
JL
16454 break;
16455 case OPC_PREPENDD:
df6126a7
AJ
16456 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16457 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16458 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16459 break;
16460 case OPC_PREPENDW:
df6126a7
AJ
16461 if (sa != 0) {
16462 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16463 tcg_gen_shli_tl(t0, t0, 64 - sa);
16464 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16465 }
26690560
JL
16466 break;
16467 case OPC_DBALIGN:
df6126a7
AJ
16468 sa &= 7;
16469 if (sa != 0 && sa != 2 && sa != 4) {
16470 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16471 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16472 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16473 }
26690560
JL
16474 break;
16475 default: /* Invalid */
16476 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16477 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16478 break;
16479 }
16480 break;
16481#endif
16482 }
df6126a7 16483 tcg_temp_free(t0);
26690560
JL
16484}
16485
b53371ed
JL
16486static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16487 int ret, int v1, int v2, int check_ret)
16488
16489{
b53371ed
JL
16490 TCGv t0;
16491 TCGv t1;
16492 TCGv v1_t;
16493 TCGv v2_t;
16494 int16_t imm;
16495
16496 if ((ret == 0) && (check_ret == 1)) {
16497 /* Treat as NOP. */
b53371ed
JL
16498 return;
16499 }
16500
16501 t0 = tcg_temp_new();
16502 t1 = tcg_temp_new();
16503 v1_t = tcg_temp_new();
16504 v2_t = tcg_temp_new();
16505
16506 gen_load_gpr(v1_t, v1);
16507 gen_load_gpr(v2_t, v2);
16508
16509 switch (op1) {
16510 case OPC_EXTR_W_DSP:
16511 check_dsp(ctx);
16512 switch (op2) {
16513 case OPC_EXTR_W:
16514 tcg_gen_movi_tl(t0, v2);
16515 tcg_gen_movi_tl(t1, v1);
16516 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16517 break;
16518 case OPC_EXTR_R_W:
16519 tcg_gen_movi_tl(t0, v2);
16520 tcg_gen_movi_tl(t1, v1);
16521 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16522 break;
16523 case OPC_EXTR_RS_W:
16524 tcg_gen_movi_tl(t0, v2);
16525 tcg_gen_movi_tl(t1, v1);
16526 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16527 break;
16528 case OPC_EXTR_S_H:
16529 tcg_gen_movi_tl(t0, v2);
16530 tcg_gen_movi_tl(t1, v1);
16531 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16532 break;
16533 case OPC_EXTRV_S_H:
16534 tcg_gen_movi_tl(t0, v2);
16535 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16536 break;
16537 case OPC_EXTRV_W:
16538 tcg_gen_movi_tl(t0, v2);
16539 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16540 break;
16541 case OPC_EXTRV_R_W:
16542 tcg_gen_movi_tl(t0, v2);
16543 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16544 break;
16545 case OPC_EXTRV_RS_W:
16546 tcg_gen_movi_tl(t0, v2);
16547 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16548 break;
16549 case OPC_EXTP:
16550 tcg_gen_movi_tl(t0, v2);
16551 tcg_gen_movi_tl(t1, v1);
16552 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16553 break;
16554 case OPC_EXTPV:
16555 tcg_gen_movi_tl(t0, v2);
16556 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16557 break;
16558 case OPC_EXTPDP:
16559 tcg_gen_movi_tl(t0, v2);
16560 tcg_gen_movi_tl(t1, v1);
16561 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16562 break;
16563 case OPC_EXTPDPV:
16564 tcg_gen_movi_tl(t0, v2);
16565 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16566 break;
16567 case OPC_SHILO:
16568 imm = (ctx->opcode >> 20) & 0x3F;
16569 tcg_gen_movi_tl(t0, ret);
16570 tcg_gen_movi_tl(t1, imm);
16571 gen_helper_shilo(t0, t1, cpu_env);
16572 break;
16573 case OPC_SHILOV:
16574 tcg_gen_movi_tl(t0, ret);
16575 gen_helper_shilo(t0, v1_t, cpu_env);
16576 break;
16577 case OPC_MTHLIP:
16578 tcg_gen_movi_tl(t0, ret);
16579 gen_helper_mthlip(t0, v1_t, cpu_env);
16580 break;
16581 case OPC_WRDSP:
16582 imm = (ctx->opcode >> 11) & 0x3FF;
16583 tcg_gen_movi_tl(t0, imm);
16584 gen_helper_wrdsp(v1_t, t0, cpu_env);
16585 break;
16586 case OPC_RDDSP:
16587 imm = (ctx->opcode >> 16) & 0x03FF;
16588 tcg_gen_movi_tl(t0, imm);
16589 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16590 break;
16591 }
16592 break;
16593#ifdef TARGET_MIPS64
16594 case OPC_DEXTR_W_DSP:
16595 check_dsp(ctx);
16596 switch (op2) {
16597 case OPC_DMTHLIP:
16598 tcg_gen_movi_tl(t0, ret);
16599 gen_helper_dmthlip(v1_t, t0, cpu_env);
16600 break;
16601 case OPC_DSHILO:
16602 {
16603 int shift = (ctx->opcode >> 19) & 0x7F;
16604 int ac = (ctx->opcode >> 11) & 0x03;
16605 tcg_gen_movi_tl(t0, shift);
16606 tcg_gen_movi_tl(t1, ac);
16607 gen_helper_dshilo(t0, t1, cpu_env);
16608 break;
16609 }
16610 case OPC_DSHILOV:
16611 {
16612 int ac = (ctx->opcode >> 11) & 0x03;
16613 tcg_gen_movi_tl(t0, ac);
16614 gen_helper_dshilo(v1_t, t0, cpu_env);
16615 break;
16616 }
16617 case OPC_DEXTP:
16618 tcg_gen_movi_tl(t0, v2);
16619 tcg_gen_movi_tl(t1, v1);
16620
16621 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16622 break;
16623 case OPC_DEXTPV:
16624 tcg_gen_movi_tl(t0, v2);
16625 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16626 break;
16627 case OPC_DEXTPDP:
16628 tcg_gen_movi_tl(t0, v2);
16629 tcg_gen_movi_tl(t1, v1);
16630 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16631 break;
16632 case OPC_DEXTPDPV:
16633 tcg_gen_movi_tl(t0, v2);
16634 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16635 break;
16636 case OPC_DEXTR_L:
16637 tcg_gen_movi_tl(t0, v2);
16638 tcg_gen_movi_tl(t1, v1);
16639 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16640 break;
16641 case OPC_DEXTR_R_L:
16642 tcg_gen_movi_tl(t0, v2);
16643 tcg_gen_movi_tl(t1, v1);
16644 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16645 break;
16646 case OPC_DEXTR_RS_L:
16647 tcg_gen_movi_tl(t0, v2);
16648 tcg_gen_movi_tl(t1, v1);
16649 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16650 break;
16651 case OPC_DEXTR_W:
16652 tcg_gen_movi_tl(t0, v2);
16653 tcg_gen_movi_tl(t1, v1);
16654 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16655 break;
16656 case OPC_DEXTR_R_W:
16657 tcg_gen_movi_tl(t0, v2);
16658 tcg_gen_movi_tl(t1, v1);
16659 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16660 break;
16661 case OPC_DEXTR_RS_W:
16662 tcg_gen_movi_tl(t0, v2);
16663 tcg_gen_movi_tl(t1, v1);
16664 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16665 break;
16666 case OPC_DEXTR_S_H:
16667 tcg_gen_movi_tl(t0, v2);
16668 tcg_gen_movi_tl(t1, v1);
16669 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16670 break;
16671 case OPC_DEXTRV_S_H:
16672 tcg_gen_movi_tl(t0, v2);
16673 tcg_gen_movi_tl(t1, v1);
16674 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16675 break;
16676 case OPC_DEXTRV_L:
16677 tcg_gen_movi_tl(t0, v2);
16678 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16679 break;
16680 case OPC_DEXTRV_R_L:
16681 tcg_gen_movi_tl(t0, v2);
16682 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16683 break;
16684 case OPC_DEXTRV_RS_L:
16685 tcg_gen_movi_tl(t0, v2);
16686 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16687 break;
16688 case OPC_DEXTRV_W:
16689 tcg_gen_movi_tl(t0, v2);
16690 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16691 break;
16692 case OPC_DEXTRV_R_W:
16693 tcg_gen_movi_tl(t0, v2);
16694 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16695 break;
16696 case OPC_DEXTRV_RS_W:
16697 tcg_gen_movi_tl(t0, v2);
16698 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16699 break;
16700 }
16701 break;
16702#endif
16703 }
16704
16705 tcg_temp_free(t0);
16706 tcg_temp_free(t1);
16707 tcg_temp_free(v1_t);
16708 tcg_temp_free(v2_t);
b53371ed
JL
16709}
16710
9b1a1d68
JL
16711/* End MIPSDSP functions. */
16712
10dc65db
LA
16713static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16714{
4267d3e6 16715 int rs, rt, rd, sa;
b42ee5e1 16716 uint32_t op1, op2;
10dc65db
LA
16717
16718 rs = (ctx->opcode >> 21) & 0x1f;
16719 rt = (ctx->opcode >> 16) & 0x1f;
16720 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16721 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16722
16723 op1 = MASK_SPECIAL(ctx->opcode);
16724 switch (op1) {
d4ea6acd 16725 case OPC_LSA:
1f1b4c00 16726 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16727 break;
b42ee5e1
LA
16728 case OPC_MULT ... OPC_DIVU:
16729 op2 = MASK_R6_MULDIV(ctx->opcode);
16730 switch (op2) {
16731 case R6_OPC_MUL:
16732 case R6_OPC_MUH:
16733 case R6_OPC_MULU:
16734 case R6_OPC_MUHU:
16735 case R6_OPC_DIV:
16736 case R6_OPC_MOD:
16737 case R6_OPC_DIVU:
16738 case R6_OPC_MODU:
16739 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16740 break;
16741 default:
16742 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16743 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16744 break;
16745 }
16746 break;
10dc65db
LA
16747 case OPC_SELEQZ:
16748 case OPC_SELNEZ:
16749 gen_cond_move(ctx, op1, rd, rs, rt);
16750 break;
4267d3e6
LA
16751 case R6_OPC_CLO:
16752 case R6_OPC_CLZ:
16753 if (rt == 0 && sa == 1) {
16754 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16755 We need additionally to check other fields */
16756 gen_cl(ctx, op1, rd, rs);
16757 } else {
9c708c7f 16758 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16759 }
16760 break;
16761 case R6_OPC_SDBBP:
3b3c1694
LA
16762 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16763 gen_helper_do_semihosting(cpu_env);
faf1f68b 16764 } else {
3b3c1694 16765 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 16766 generate_exception_end(ctx, EXCP_RI);
3b3c1694 16767 } else {
9c708c7f 16768 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 16769 }
faf1f68b 16770 }
4267d3e6 16771 break;
b42ee5e1 16772#if defined(TARGET_MIPS64)
d4ea6acd
LA
16773 case OPC_DLSA:
16774 check_mips_64(ctx);
1f1b4c00 16775 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 16776 break;
4267d3e6
LA
16777 case R6_OPC_DCLO:
16778 case R6_OPC_DCLZ:
16779 if (rt == 0 && sa == 1) {
16780 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16781 We need additionally to check other fields */
16782 check_mips_64(ctx);
16783 gen_cl(ctx, op1, rd, rs);
16784 } else {
9c708c7f 16785 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16786 }
16787 break;
b42ee5e1
LA
16788 case OPC_DMULT ... OPC_DDIVU:
16789 op2 = MASK_R6_MULDIV(ctx->opcode);
16790 switch (op2) {
16791 case R6_OPC_DMUL:
16792 case R6_OPC_DMUH:
16793 case R6_OPC_DMULU:
16794 case R6_OPC_DMUHU:
16795 case R6_OPC_DDIV:
16796 case R6_OPC_DMOD:
16797 case R6_OPC_DDIVU:
16798 case R6_OPC_DMODU:
16799 check_mips_64(ctx);
16800 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16801 break;
16802 default:
16803 MIPS_INVAL("special_r6 muldiv");
9c708c7f 16804 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
16805 break;
16806 }
16807 break;
16808#endif
10dc65db
LA
16809 default: /* Invalid */
16810 MIPS_INVAL("special_r6");
9c708c7f 16811 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
16812 break;
16813 }
16814}
16815
16816static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16817{
b42ee5e1 16818 int rs, rt, rd, sa;
10dc65db
LA
16819 uint32_t op1;
16820
16821 rs = (ctx->opcode >> 21) & 0x1f;
16822 rt = (ctx->opcode >> 16) & 0x1f;
16823 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16824 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16825
16826 op1 = MASK_SPECIAL(ctx->opcode);
16827 switch (op1) {
16828 case OPC_MOVN: /* Conditional move */
16829 case OPC_MOVZ:
16830 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16831 INSN_LOONGSON2E | INSN_LOONGSON2F);
16832 gen_cond_move(ctx, op1, rd, rs, rt);
16833 break;
16834 case OPC_MFHI: /* Move from HI/LO */
16835 case OPC_MFLO:
16836 gen_HILO(ctx, op1, rs & 3, rd);
16837 break;
16838 case OPC_MTHI:
16839 case OPC_MTLO: /* Move to HI/LO */
16840 gen_HILO(ctx, op1, rd & 3, rs);
16841 break;
16842 case OPC_MOVCI:
16843 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16844 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16845 check_cp1_enabled(ctx);
16846 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16847 (ctx->opcode >> 16) & 1);
16848 } else {
16849 generate_exception_err(ctx, EXCP_CpU, 1);
16850 }
16851 break;
b42ee5e1
LA
16852 case OPC_MULT:
16853 case OPC_MULTU:
16854 if (sa) {
16855 check_insn(ctx, INSN_VR54XX);
16856 op1 = MASK_MUL_VR54XX(ctx->opcode);
16857 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16858 } else {
16859 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16860 }
16861 break;
16862 case OPC_DIV:
16863 case OPC_DIVU:
16864 gen_muldiv(ctx, op1, 0, rs, rt);
16865 break;
16866#if defined(TARGET_MIPS64)
16867 case OPC_DMULT ... OPC_DDIVU:
16868 check_insn(ctx, ISA_MIPS3);
16869 check_mips_64(ctx);
16870 gen_muldiv(ctx, op1, 0, rs, rt);
16871 break;
16872#endif
0aefa333 16873 case OPC_JR:
b231c103 16874 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16875 break;
4267d3e6
LA
16876 case OPC_SPIM:
16877#ifdef MIPS_STRICT_STANDARD
16878 MIPS_INVAL("SPIM");
9c708c7f 16879 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16880#else
16881 /* Implemented as RI exception for now. */
16882 MIPS_INVAL("spim (unofficial)");
9c708c7f 16883 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
16884#endif
16885 break;
10dc65db
LA
16886 default: /* Invalid */
16887 MIPS_INVAL("special_legacy");
9c708c7f 16888 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
16889 break;
16890 }
16891}
16892
099e5b4d 16893static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16894{
3c824109 16895 int rs, rt, rd, sa;
099e5b4d 16896 uint32_t op1;
3c824109 16897
3c824109
NF
16898 rs = (ctx->opcode >> 21) & 0x1f;
16899 rt = (ctx->opcode >> 16) & 0x1f;
16900 rd = (ctx->opcode >> 11) & 0x1f;
16901 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16902
16903 op1 = MASK_SPECIAL(ctx->opcode);
16904 switch (op1) {
16905 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16906 if (sa == 5 && rd == 0 &&
16907 rs == 0 && rt == 0) { /* PAUSE */
16908 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16909 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 16910 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
16911 break;
16912 }
16913 }
16914 /* Fallthrough */
099e5b4d
LA
16915 case OPC_SRA:
16916 gen_shift_imm(ctx, op1, rd, rt, sa);
16917 break;
16918 case OPC_SRL:
16919 switch ((ctx->opcode >> 21) & 0x1f) {
16920 case 1:
16921 /* rotr is decoded as srl on non-R2 CPUs */
16922 if (ctx->insn_flags & ISA_MIPS32R2) {
16923 op1 = OPC_ROTR;
ea63e2c3 16924 }
099e5b4d
LA
16925 /* Fallthrough */
16926 case 0:
16927 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16928 break;
099e5b4d 16929 default:
9c708c7f 16930 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 16931 break;
099e5b4d
LA
16932 }
16933 break;
099e5b4d
LA
16934 case OPC_ADD ... OPC_SUBU:
16935 gen_arith(ctx, op1, rd, rs, rt);
16936 break;
16937 case OPC_SLLV: /* Shifts */
16938 case OPC_SRAV:
16939 gen_shift(ctx, op1, rd, rs, rt);
16940 break;
16941 case OPC_SRLV:
16942 switch ((ctx->opcode >> 6) & 0x1f) {
16943 case 1:
16944 /* rotrv is decoded as srlv on non-R2 CPUs */
16945 if (ctx->insn_flags & ISA_MIPS32R2) {
16946 op1 = OPC_ROTRV;
26135ead 16947 }
099e5b4d
LA
16948 /* Fallthrough */
16949 case 0:
16950 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16951 break;
099e5b4d 16952 default:
9c708c7f 16953 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 16954 break;
099e5b4d
LA
16955 }
16956 break;
16957 case OPC_SLT: /* Set on less than */
16958 case OPC_SLTU:
16959 gen_slt(ctx, op1, rd, rs, rt);
16960 break;
16961 case OPC_AND: /* Logic*/
16962 case OPC_OR:
16963 case OPC_NOR:
16964 case OPC_XOR:
16965 gen_logic(ctx, op1, rd, rs, rt);
16966 break;
0aefa333 16967 case OPC_JALR:
b231c103 16968 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16969 break;
16970 case OPC_TGE ... OPC_TEQ: /* Traps */
16971 case OPC_TNE:
d9224450 16972 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16973 gen_trap(ctx, op1, rs, rt, -1);
16974 break;
d4ea6acd 16975 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16976 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16977 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16978 decode_opc_special_r6(env, ctx);
16979 } else {
16980 /* Pmon entry point, also R4010 selsl */
b48cfdff 16981#ifdef MIPS_STRICT_STANDARD
d4ea6acd 16982 MIPS_INVAL("PMON / selsl");
9c708c7f 16983 generate_exception_end(ctx, EXCP_RI);
b48cfdff 16984#else
d4ea6acd 16985 gen_helper_0e0i(pmon, sa);
b48cfdff 16986#endif
d4ea6acd 16987 }
099e5b4d
LA
16988 break;
16989 case OPC_SYSCALL:
9c708c7f 16990 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
16991 break;
16992 case OPC_BREAK:
9c708c7f 16993 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 16994 break;
099e5b4d 16995 case OPC_SYNC:
d9224450 16996 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16997 /* Treat as NOP. */
16998 break;
4ad40f36 16999
d26bc211 17000#if defined(TARGET_MIPS64)
099e5b4d
LA
17001 /* MIPS64 specific opcodes */
17002 case OPC_DSLL:
17003 case OPC_DSRA:
17004 case OPC_DSLL32:
17005 case OPC_DSRA32:
17006 check_insn(ctx, ISA_MIPS3);
17007 check_mips_64(ctx);
17008 gen_shift_imm(ctx, op1, rd, rt, sa);
17009 break;
17010 case OPC_DSRL:
17011 switch ((ctx->opcode >> 21) & 0x1f) {
17012 case 1:
17013 /* drotr is decoded as dsrl on non-R2 CPUs */
17014 if (ctx->insn_flags & ISA_MIPS32R2) {
17015 op1 = OPC_DROTR;
ea63e2c3 17016 }
099e5b4d
LA
17017 /* Fallthrough */
17018 case 0:
d75c135e 17019 check_insn(ctx, ISA_MIPS3);
e189e748 17020 check_mips_64(ctx);
099e5b4d 17021 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17022 break;
099e5b4d 17023 default:
9c708c7f 17024 generate_exception_end(ctx, EXCP_RI);
460f00c4 17025 break;
099e5b4d
LA
17026 }
17027 break;
17028 case OPC_DSRL32:
17029 switch ((ctx->opcode >> 21) & 0x1f) {
17030 case 1:
17031 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17032 if (ctx->insn_flags & ISA_MIPS32R2) {
17033 op1 = OPC_DROTR32;
ea63e2c3 17034 }
099e5b4d
LA
17035 /* Fallthrough */
17036 case 0:
d75c135e 17037 check_insn(ctx, ISA_MIPS3);
e189e748 17038 check_mips_64(ctx);
099e5b4d 17039 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17040 break;
099e5b4d 17041 default:
9c708c7f 17042 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17043 break;
17044 }
17045 break;
099e5b4d
LA
17046 case OPC_DADD ... OPC_DSUBU:
17047 check_insn(ctx, ISA_MIPS3);
17048 check_mips_64(ctx);
17049 gen_arith(ctx, op1, rd, rs, rt);
17050 break;
17051 case OPC_DSLLV:
17052 case OPC_DSRAV:
17053 check_insn(ctx, ISA_MIPS3);
17054 check_mips_64(ctx);
17055 gen_shift(ctx, op1, rd, rs, rt);
17056 break;
17057 case OPC_DSRLV:
17058 switch ((ctx->opcode >> 6) & 0x1f) {
17059 case 1:
17060 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17061 if (ctx->insn_flags & ISA_MIPS32R2) {
17062 op1 = OPC_DROTRV;
6af0bf9c 17063 }
099e5b4d
LA
17064 /* Fallthrough */
17065 case 0:
17066 check_insn(ctx, ISA_MIPS3);
e189e748 17067 check_mips_64(ctx);
099e5b4d 17068 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17069 break;
099e5b4d 17070 default:
9c708c7f 17071 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17072 break;
17073 }
17074 break;
f7685877
YK
17075 case OPC_DLSA:
17076 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17077 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17078 decode_opc_special_r6(env, ctx);
17079 }
17080 break;
099e5b4d 17081#endif
10dc65db
LA
17082 default:
17083 if (ctx->insn_flags & ISA_MIPS32R6) {
17084 decode_opc_special_r6(env, ctx);
17085 } else {
17086 decode_opc_special_legacy(env, ctx);
17087 }
17088 }
17089}
17090
10dc65db 17091static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17092{
17093 int rs, rt, rd;
17094 uint32_t op1;
6c5c1e20 17095
4267d3e6
LA
17096 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17097
099e5b4d
LA
17098 rs = (ctx->opcode >> 21) & 0x1f;
17099 rt = (ctx->opcode >> 16) & 0x1f;
17100 rd = (ctx->opcode >> 11) & 0x1f;
17101
17102 op1 = MASK_SPECIAL2(ctx->opcode);
17103 switch (op1) {
17104 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17105 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17106 check_insn(ctx, ISA_MIPS32);
17107 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17108 break;
17109 case OPC_MUL:
099e5b4d
LA
17110 gen_arith(ctx, op1, rd, rs, rt);
17111 break;
fac5a073
LA
17112 case OPC_DIV_G_2F:
17113 case OPC_DIVU_G_2F:
17114 case OPC_MULT_G_2F:
17115 case OPC_MULTU_G_2F:
17116 case OPC_MOD_G_2F:
17117 case OPC_MODU_G_2F:
17118 check_insn(ctx, INSN_LOONGSON2F);
17119 gen_loongson_integer(ctx, op1, rd, rs, rt);
17120 break;
099e5b4d
LA
17121 case OPC_CLO:
17122 case OPC_CLZ:
17123 check_insn(ctx, ISA_MIPS32);
17124 gen_cl(ctx, op1, rd, rs);
17125 break;
17126 case OPC_SDBBP:
3b3c1694
LA
17127 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17128 gen_helper_do_semihosting(cpu_env);
17129 } else {
17130 /* XXX: not clear which exception should be raised
17131 * when in debug mode...
17132 */
17133 check_insn(ctx, ISA_MIPS32);
9c708c7f 17134 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17135 }
099e5b4d 17136 break;
9b1a1d68 17137#if defined(TARGET_MIPS64)
099e5b4d
LA
17138 case OPC_DCLO:
17139 case OPC_DCLZ:
17140 check_insn(ctx, ISA_MIPS64);
17141 check_mips_64(ctx);
17142 gen_cl(ctx, op1, rd, rs);
17143 break;
4267d3e6
LA
17144 case OPC_DMULT_G_2F:
17145 case OPC_DMULTU_G_2F:
17146 case OPC_DDIV_G_2F:
17147 case OPC_DDIVU_G_2F:
17148 case OPC_DMOD_G_2F:
17149 case OPC_DMODU_G_2F:
17150 check_insn(ctx, INSN_LOONGSON2F);
17151 gen_loongson_integer(ctx, op1, rd, rs, rt);
17152 break;
10dc65db 17153#endif
4267d3e6
LA
17154 default: /* Invalid */
17155 MIPS_INVAL("special2_legacy");
9c708c7f 17156 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17157 break;
10dc65db
LA
17158 }
17159}
17160
17161static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17162{
15eacb9b
YK
17163 int rs, rt, rd, sa;
17164 uint32_t op1, op2;
10dc65db
LA
17165 int16_t imm;
17166
17167 rs = (ctx->opcode >> 21) & 0x1f;
17168 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17169 rd = (ctx->opcode >> 11) & 0x1f;
17170 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17171 imm = (int16_t)ctx->opcode >> 7;
17172
17173 op1 = MASK_SPECIAL3(ctx->opcode);
17174 switch (op1) {
bf7910c6
LA
17175 case R6_OPC_PREF:
17176 if (rt >= 24) {
17177 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17178 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17179 }
17180 /* Treat as NOP. */
17181 break;
17182 case R6_OPC_CACHE:
17183 /* Treat as NOP. */
17184 break;
10dc65db
LA
17185 case R6_OPC_SC:
17186 gen_st_cond(ctx, op1, rt, rs, imm);
17187 break;
17188 case R6_OPC_LL:
17189 gen_ld(ctx, op1, rt, rs, imm);
17190 break;
15eacb9b
YK
17191 case OPC_BSHFL:
17192 {
17193 if (rd == 0) {
17194 /* Treat as NOP. */
17195 break;
17196 }
15eacb9b
YK
17197 op2 = MASK_BSHFL(ctx->opcode);
17198 switch (op2) {
17199 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17200 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17201 break;
17202 case OPC_BITSWAP:
1f1b4c00 17203 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17204 break;
17205 }
15eacb9b
YK
17206 }
17207 break;
bf7910c6
LA
17208#if defined(TARGET_MIPS64)
17209 case R6_OPC_SCD:
17210 gen_st_cond(ctx, op1, rt, rs, imm);
17211 break;
17212 case R6_OPC_LLD:
17213 gen_ld(ctx, op1, rt, rs, imm);
17214 break;
15eacb9b
YK
17215 case OPC_DBSHFL:
17216 check_mips_64(ctx);
17217 {
17218 if (rd == 0) {
17219 /* Treat as NOP. */
17220 break;
17221 }
15eacb9b
YK
17222 op2 = MASK_DBSHFL(ctx->opcode);
17223 switch (op2) {
17224 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17225 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17226 break;
17227 case OPC_DBITSWAP:
1f1b4c00 17228 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17229 break;
17230 }
1f1b4c00 17231
15eacb9b
YK
17232 }
17233 break;
bf7910c6 17234#endif
10dc65db
LA
17235 default: /* Invalid */
17236 MIPS_INVAL("special3_r6");
9c708c7f 17237 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17238 break;
17239 }
17240}
17241
17242static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17243{
fac5a073 17244 int rs, rt, rd;
099e5b4d 17245 uint32_t op1, op2;
099e5b4d
LA
17246
17247 rs = (ctx->opcode >> 21) & 0x1f;
17248 rt = (ctx->opcode >> 16) & 0x1f;
17249 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17250
17251 op1 = MASK_SPECIAL3(ctx->opcode);
17252 switch (op1) {
099e5b4d
LA
17253 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17254 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17255 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17256 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17257 * the same mask and op1. */
17258 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17259 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17260 switch (op2) {
099e5b4d
LA
17261 case OPC_ADDUH_QB:
17262 case OPC_ADDUH_R_QB:
17263 case OPC_ADDQH_PH:
17264 case OPC_ADDQH_R_PH:
17265 case OPC_ADDQH_W:
17266 case OPC_ADDQH_R_W:
17267 case OPC_SUBUH_QB:
17268 case OPC_SUBUH_R_QB:
17269 case OPC_SUBQH_PH:
17270 case OPC_SUBQH_R_PH:
17271 case OPC_SUBQH_W:
17272 case OPC_SUBQH_R_W:
461c08df
JL
17273 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17274 break;
099e5b4d
LA
17275 case OPC_MUL_PH:
17276 case OPC_MUL_S_PH:
17277 case OPC_MULQ_S_W:
17278 case OPC_MULQ_RS_W:
17279 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17280 break;
461c08df 17281 default:
099e5b4d 17282 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17283 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17284 break;
17285 }
099e5b4d
LA
17286 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17287 gen_loongson_integer(ctx, op1, rd, rs, rt);
17288 } else {
9c708c7f 17289 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17290 }
17291 break;
17292 case OPC_LX_DSP:
17293 op2 = MASK_LX(ctx->opcode);
17294 switch (op2) {
17295#if defined(TARGET_MIPS64)
17296 case OPC_LDX:
17297#endif
17298 case OPC_LBUX:
17299 case OPC_LHX:
17300 case OPC_LWX:
17301 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17302 break;
17303 default: /* Invalid */
17304 MIPS_INVAL("MASK LX");
9c708c7f 17305 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17306 break;
17307 }
17308 break;
17309 case OPC_ABSQ_S_PH_DSP:
17310 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17311 switch (op2) {
17312 case OPC_ABSQ_S_QB:
17313 case OPC_ABSQ_S_PH:
17314 case OPC_ABSQ_S_W:
17315 case OPC_PRECEQ_W_PHL:
17316 case OPC_PRECEQ_W_PHR:
17317 case OPC_PRECEQU_PH_QBL:
17318 case OPC_PRECEQU_PH_QBR:
17319 case OPC_PRECEQU_PH_QBLA:
17320 case OPC_PRECEQU_PH_QBRA:
17321 case OPC_PRECEU_PH_QBL:
17322 case OPC_PRECEU_PH_QBR:
17323 case OPC_PRECEU_PH_QBLA:
17324 case OPC_PRECEU_PH_QBRA:
17325 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17326 break;
17327 case OPC_BITREV:
17328 case OPC_REPL_QB:
17329 case OPC_REPLV_QB:
17330 case OPC_REPL_PH:
17331 case OPC_REPLV_PH:
17332 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17333 break;
17334 default:
17335 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17336 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17337 break;
17338 }
17339 break;
17340 case OPC_ADDU_QB_DSP:
17341 op2 = MASK_ADDU_QB(ctx->opcode);
17342 switch (op2) {
17343 case OPC_ADDQ_PH:
17344 case OPC_ADDQ_S_PH:
17345 case OPC_ADDQ_S_W:
17346 case OPC_ADDU_QB:
17347 case OPC_ADDU_S_QB:
17348 case OPC_ADDU_PH:
17349 case OPC_ADDU_S_PH:
17350 case OPC_SUBQ_PH:
17351 case OPC_SUBQ_S_PH:
17352 case OPC_SUBQ_S_W:
17353 case OPC_SUBU_QB:
17354 case OPC_SUBU_S_QB:
17355 case OPC_SUBU_PH:
17356 case OPC_SUBU_S_PH:
17357 case OPC_ADDSC:
17358 case OPC_ADDWC:
17359 case OPC_MODSUB:
17360 case OPC_RADDU_W_QB:
17361 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17362 break;
17363 case OPC_MULEU_S_PH_QBL:
17364 case OPC_MULEU_S_PH_QBR:
17365 case OPC_MULQ_RS_PH:
17366 case OPC_MULEQ_S_W_PHL:
17367 case OPC_MULEQ_S_W_PHR:
17368 case OPC_MULQ_S_PH:
17369 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17370 break;
17371 default: /* Invalid */
17372 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17373 generate_exception_end(ctx, EXCP_RI);
461c08df 17374 break;
461c08df 17375
099e5b4d
LA
17376 }
17377 break;
17378 case OPC_CMPU_EQ_QB_DSP:
17379 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17380 switch (op2) {
17381 case OPC_PRECR_SRA_PH_W:
17382 case OPC_PRECR_SRA_R_PH_W:
17383 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17384 break;
099e5b4d
LA
17385 case OPC_PRECR_QB_PH:
17386 case OPC_PRECRQ_QB_PH:
17387 case OPC_PRECRQ_PH_W:
17388 case OPC_PRECRQ_RS_PH_W:
17389 case OPC_PRECRQU_S_QB_PH:
17390 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17391 break;
099e5b4d
LA
17392 case OPC_CMPU_EQ_QB:
17393 case OPC_CMPU_LT_QB:
17394 case OPC_CMPU_LE_QB:
17395 case OPC_CMP_EQ_PH:
17396 case OPC_CMP_LT_PH:
17397 case OPC_CMP_LE_PH:
17398 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17399 break;
099e5b4d
LA
17400 case OPC_CMPGU_EQ_QB:
17401 case OPC_CMPGU_LT_QB:
17402 case OPC_CMPGU_LE_QB:
17403 case OPC_CMPGDU_EQ_QB:
17404 case OPC_CMPGDU_LT_QB:
17405 case OPC_CMPGDU_LE_QB:
17406 case OPC_PICK_QB:
17407 case OPC_PICK_PH:
17408 case OPC_PACKRL_PH:
17409 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17410 break;
17411 default: /* Invalid */
17412 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17413 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17414 break;
17415 }
17416 break;
17417 case OPC_SHLL_QB_DSP:
17418 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17419 break;
17420 case OPC_DPA_W_PH_DSP:
17421 op2 = MASK_DPA_W_PH(ctx->opcode);
17422 switch (op2) {
17423 case OPC_DPAU_H_QBL:
17424 case OPC_DPAU_H_QBR:
17425 case OPC_DPSU_H_QBL:
17426 case OPC_DPSU_H_QBR:
17427 case OPC_DPA_W_PH:
17428 case OPC_DPAX_W_PH:
17429 case OPC_DPAQ_S_W_PH:
17430 case OPC_DPAQX_S_W_PH:
17431 case OPC_DPAQX_SA_W_PH:
17432 case OPC_DPS_W_PH:
17433 case OPC_DPSX_W_PH:
17434 case OPC_DPSQ_S_W_PH:
17435 case OPC_DPSQX_S_W_PH:
17436 case OPC_DPSQX_SA_W_PH:
17437 case OPC_MULSAQ_S_W_PH:
17438 case OPC_DPAQ_SA_L_W:
17439 case OPC_DPSQ_SA_L_W:
17440 case OPC_MAQ_S_W_PHL:
17441 case OPC_MAQ_S_W_PHR:
17442 case OPC_MAQ_SA_W_PHL:
17443 case OPC_MAQ_SA_W_PHR:
17444 case OPC_MULSA_W_PH:
17445 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17446 break;
17447 default: /* Invalid */
17448 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17449 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17450 break;
17451 }
17452 break;
17453 case OPC_INSV_DSP:
17454 op2 = MASK_INSV(ctx->opcode);
17455 switch (op2) {
17456 case OPC_INSV:
17457 check_dsp(ctx);
17458 {
17459 TCGv t0, t1;
17460
17461 if (rt == 0) {
099e5b4d
LA
17462 break;
17463 }
17464
17465 t0 = tcg_temp_new();
17466 t1 = tcg_temp_new();
17467
17468 gen_load_gpr(t0, rt);
17469 gen_load_gpr(t1, rs);
17470
17471 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17472
17473 tcg_temp_free(t0);
17474 tcg_temp_free(t1);
a22260ae
JL
17475 break;
17476 }
099e5b4d
LA
17477 default: /* Invalid */
17478 MIPS_INVAL("MASK INSV");
9c708c7f 17479 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17480 break;
17481 }
17482 break;
17483 case OPC_APPEND_DSP:
17484 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17485 break;
17486 case OPC_EXTR_W_DSP:
17487 op2 = MASK_EXTR_W(ctx->opcode);
17488 switch (op2) {
17489 case OPC_EXTR_W:
17490 case OPC_EXTR_R_W:
17491 case OPC_EXTR_RS_W:
17492 case OPC_EXTR_S_H:
17493 case OPC_EXTRV_S_H:
17494 case OPC_EXTRV_W:
17495 case OPC_EXTRV_R_W:
17496 case OPC_EXTRV_RS_W:
17497 case OPC_EXTP:
17498 case OPC_EXTPV:
17499 case OPC_EXTPDP:
17500 case OPC_EXTPDPV:
17501 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17502 break;
17503 case OPC_RDDSP:
17504 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17505 break;
17506 case OPC_SHILO:
17507 case OPC_SHILOV:
17508 case OPC_MTHLIP:
17509 case OPC_WRDSP:
17510 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17511 break;
17512 default: /* Invalid */
17513 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17514 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17515 break;
17516 }
17517 break;
099e5b4d 17518#if defined(TARGET_MIPS64)
fac5a073
LA
17519 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17520 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17521 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17522 check_insn(ctx, INSN_LOONGSON2E);
17523 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17524 break;
099e5b4d
LA
17525 case OPC_ABSQ_S_QH_DSP:
17526 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17527 switch (op2) {
17528 case OPC_PRECEQ_L_PWL:
17529 case OPC_PRECEQ_L_PWR:
17530 case OPC_PRECEQ_PW_QHL:
17531 case OPC_PRECEQ_PW_QHR:
17532 case OPC_PRECEQ_PW_QHLA:
17533 case OPC_PRECEQ_PW_QHRA:
17534 case OPC_PRECEQU_QH_OBL:
17535 case OPC_PRECEQU_QH_OBR:
17536 case OPC_PRECEQU_QH_OBLA:
17537 case OPC_PRECEQU_QH_OBRA:
17538 case OPC_PRECEU_QH_OBL:
17539 case OPC_PRECEU_QH_OBR:
17540 case OPC_PRECEU_QH_OBLA:
17541 case OPC_PRECEU_QH_OBRA:
17542 case OPC_ABSQ_S_OB:
17543 case OPC_ABSQ_S_PW:
17544 case OPC_ABSQ_S_QH:
17545 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17546 break;
17547 case OPC_REPL_OB:
17548 case OPC_REPL_PW:
17549 case OPC_REPL_QH:
17550 case OPC_REPLV_OB:
17551 case OPC_REPLV_PW:
17552 case OPC_REPLV_QH:
17553 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17554 break;
17555 default: /* Invalid */
17556 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 17557 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17558 break;
17559 }
17560 break;
17561 case OPC_ADDU_OB_DSP:
17562 op2 = MASK_ADDU_OB(ctx->opcode);
17563 switch (op2) {
17564 case OPC_RADDU_L_OB:
17565 case OPC_SUBQ_PW:
17566 case OPC_SUBQ_S_PW:
17567 case OPC_SUBQ_QH:
17568 case OPC_SUBQ_S_QH:
17569 case OPC_SUBU_OB:
17570 case OPC_SUBU_S_OB:
17571 case OPC_SUBU_QH:
17572 case OPC_SUBU_S_QH:
17573 case OPC_SUBUH_OB:
17574 case OPC_SUBUH_R_OB:
17575 case OPC_ADDQ_PW:
17576 case OPC_ADDQ_S_PW:
17577 case OPC_ADDQ_QH:
17578 case OPC_ADDQ_S_QH:
17579 case OPC_ADDU_OB:
17580 case OPC_ADDU_S_OB:
17581 case OPC_ADDU_QH:
17582 case OPC_ADDU_S_QH:
17583 case OPC_ADDUH_OB:
17584 case OPC_ADDUH_R_OB:
17585 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17586 break;
099e5b4d
LA
17587 case OPC_MULEQ_S_PW_QHL:
17588 case OPC_MULEQ_S_PW_QHR:
17589 case OPC_MULEU_S_QH_OBL:
17590 case OPC_MULEU_S_QH_OBR:
17591 case OPC_MULQ_RS_QH:
17592 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17593 break;
099e5b4d
LA
17594 default: /* Invalid */
17595 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 17596 generate_exception_end(ctx, EXCP_RI);
26690560 17597 break;
099e5b4d
LA
17598 }
17599 break;
17600 case OPC_CMPU_EQ_OB_DSP:
17601 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17602 switch (op2) {
17603 case OPC_PRECR_SRA_QH_PW:
17604 case OPC_PRECR_SRA_R_QH_PW:
17605 /* Return value is rt. */
17606 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17607 break;
099e5b4d
LA
17608 case OPC_PRECR_OB_QH:
17609 case OPC_PRECRQ_OB_QH:
17610 case OPC_PRECRQ_PW_L:
17611 case OPC_PRECRQ_QH_PW:
17612 case OPC_PRECRQ_RS_QH_PW:
17613 case OPC_PRECRQU_S_OB_QH:
17614 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17615 break;
099e5b4d
LA
17616 case OPC_CMPU_EQ_OB:
17617 case OPC_CMPU_LT_OB:
17618 case OPC_CMPU_LE_OB:
17619 case OPC_CMP_EQ_QH:
17620 case OPC_CMP_LT_QH:
17621 case OPC_CMP_LE_QH:
17622 case OPC_CMP_EQ_PW:
17623 case OPC_CMP_LT_PW:
17624 case OPC_CMP_LE_PW:
17625 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17626 break;
099e5b4d
LA
17627 case OPC_CMPGDU_EQ_OB:
17628 case OPC_CMPGDU_LT_OB:
17629 case OPC_CMPGDU_LE_OB:
17630 case OPC_CMPGU_EQ_OB:
17631 case OPC_CMPGU_LT_OB:
17632 case OPC_CMPGU_LE_OB:
17633 case OPC_PACKRL_PW:
17634 case OPC_PICK_OB:
17635 case OPC_PICK_PW:
17636 case OPC_PICK_QH:
17637 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17638 break;
099e5b4d
LA
17639 default: /* Invalid */
17640 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 17641 generate_exception_end(ctx, EXCP_RI);
161f85e6 17642 break;
099e5b4d
LA
17643 }
17644 break;
17645 case OPC_DAPPEND_DSP:
17646 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17647 break;
17648 case OPC_DEXTR_W_DSP:
17649 op2 = MASK_DEXTR_W(ctx->opcode);
17650 switch (op2) {
17651 case OPC_DEXTP:
17652 case OPC_DEXTPDP:
17653 case OPC_DEXTPDPV:
17654 case OPC_DEXTPV:
17655 case OPC_DEXTR_L:
17656 case OPC_DEXTR_R_L:
17657 case OPC_DEXTR_RS_L:
17658 case OPC_DEXTR_W:
17659 case OPC_DEXTR_R_W:
17660 case OPC_DEXTR_RS_W:
17661 case OPC_DEXTR_S_H:
17662 case OPC_DEXTRV_L:
17663 case OPC_DEXTRV_R_L:
17664 case OPC_DEXTRV_RS_L:
17665 case OPC_DEXTRV_S_H:
17666 case OPC_DEXTRV_W:
17667 case OPC_DEXTRV_R_W:
17668 case OPC_DEXTRV_RS_W:
17669 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17670 break;
099e5b4d
LA
17671 case OPC_DMTHLIP:
17672 case OPC_DSHILO:
17673 case OPC_DSHILOV:
17674 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17675 break;
099e5b4d
LA
17676 default: /* Invalid */
17677 MIPS_INVAL("MASK EXTR.W");
9c708c7f 17678 generate_exception_end(ctx, EXCP_RI);
461c08df 17679 break;
099e5b4d
LA
17680 }
17681 break;
17682 case OPC_DPAQ_W_QH_DSP:
17683 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17684 switch (op2) {
17685 case OPC_DPAU_H_OBL:
17686 case OPC_DPAU_H_OBR:
17687 case OPC_DPSU_H_OBL:
17688 case OPC_DPSU_H_OBR:
17689 case OPC_DPA_W_QH:
17690 case OPC_DPAQ_S_W_QH:
17691 case OPC_DPS_W_QH:
17692 case OPC_DPSQ_S_W_QH:
17693 case OPC_MULSAQ_S_W_QH:
17694 case OPC_DPAQ_SA_L_PW:
17695 case OPC_DPSQ_SA_L_PW:
17696 case OPC_MULSAQ_S_L_PW:
17697 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17698 break;
17699 case OPC_MAQ_S_W_QHLL:
17700 case OPC_MAQ_S_W_QHLR:
17701 case OPC_MAQ_S_W_QHRL:
17702 case OPC_MAQ_S_W_QHRR:
17703 case OPC_MAQ_SA_W_QHLL:
17704 case OPC_MAQ_SA_W_QHLR:
17705 case OPC_MAQ_SA_W_QHRL:
17706 case OPC_MAQ_SA_W_QHRR:
17707 case OPC_MAQ_S_L_PWL:
17708 case OPC_MAQ_S_L_PWR:
17709 case OPC_DMADD:
17710 case OPC_DMADDU:
17711 case OPC_DMSUB:
17712 case OPC_DMSUBU:
17713 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17714 break;
099e5b4d
LA
17715 default: /* Invalid */
17716 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 17717 generate_exception_end(ctx, EXCP_RI);
b53371ed 17718 break;
099e5b4d
LA
17719 }
17720 break;
17721 case OPC_DINSV_DSP:
17722 op2 = MASK_INSV(ctx->opcode);
17723 switch (op2) {
17724 case OPC_DINSV:
17725 {
17726 TCGv t0, t1;
17727
17728 if (rt == 0) {
a22260ae
JL
17729 break;
17730 }
099e5b4d 17731 check_dsp(ctx);
1cb6686c 17732
099e5b4d
LA
17733 t0 = tcg_temp_new();
17734 t1 = tcg_temp_new();
1cb6686c 17735
099e5b4d
LA
17736 gen_load_gpr(t0, rt);
17737 gen_load_gpr(t1, rs);
1cb6686c 17738
099e5b4d 17739 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17740
099e5b4d
LA
17741 tcg_temp_free(t0);
17742 tcg_temp_free(t1);
77c5fa8b 17743 break;
099e5b4d 17744 }
7a387fff 17745 default: /* Invalid */
099e5b4d 17746 MIPS_INVAL("MASK DINSV");
9c708c7f 17747 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
17748 break;
17749 }
17750 break;
099e5b4d
LA
17751 case OPC_SHLL_OB_DSP:
17752 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17753 break;
17754#endif
fac5a073
LA
17755 default: /* Invalid */
17756 MIPS_INVAL("special3_legacy");
9c708c7f 17757 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
17758 break;
17759 }
17760}
17761
17762static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17763{
17764 int rs, rt, rd, sa;
17765 uint32_t op1, op2;
17766
17767 rs = (ctx->opcode >> 21) & 0x1f;
17768 rt = (ctx->opcode >> 16) & 0x1f;
17769 rd = (ctx->opcode >> 11) & 0x1f;
17770 sa = (ctx->opcode >> 6) & 0x1f;
17771
17772 op1 = MASK_SPECIAL3(ctx->opcode);
17773 switch (op1) {
17774 case OPC_EXT:
17775 case OPC_INS:
17776 check_insn(ctx, ISA_MIPS32R2);
17777 gen_bitops(ctx, op1, rt, rs, sa, rd);
17778 break;
17779 case OPC_BSHFL:
fac5a073 17780 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17781 switch (op2) {
17782 case OPC_ALIGN ... OPC_ALIGN_END:
17783 case OPC_BITSWAP:
17784 check_insn(ctx, ISA_MIPS32R6);
17785 decode_opc_special3_r6(env, ctx);
17786 break;
17787 default:
17788 check_insn(ctx, ISA_MIPS32R2);
17789 gen_bshfl(ctx, op2, rt, rd);
17790 break;
17791 }
fac5a073
LA
17792 break;
17793#if defined(TARGET_MIPS64)
17794 case OPC_DEXTM ... OPC_DEXT:
17795 case OPC_DINSM ... OPC_DINS:
17796 check_insn(ctx, ISA_MIPS64R2);
17797 check_mips_64(ctx);
17798 gen_bitops(ctx, op1, rt, rs, sa, rd);
17799 break;
17800 case OPC_DBSHFL:
fac5a073 17801 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17802 switch (op2) {
17803 case OPC_DALIGN ... OPC_DALIGN_END:
17804 case OPC_DBITSWAP:
17805 check_insn(ctx, ISA_MIPS32R6);
17806 decode_opc_special3_r6(env, ctx);
17807 break;
17808 default:
17809 check_insn(ctx, ISA_MIPS64R2);
17810 check_mips_64(ctx);
17811 op2 = MASK_DBSHFL(ctx->opcode);
17812 gen_bshfl(ctx, op2, rt, rd);
17813 break;
17814 }
fac5a073
LA
17815 break;
17816#endif
17817 case OPC_RDHWR:
b00c7218 17818 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
17819 break;
17820 case OPC_FORK:
17821 check_insn(ctx, ASE_MT);
17822 {
17823 TCGv t0 = tcg_temp_new();
17824 TCGv t1 = tcg_temp_new();
17825
17826 gen_load_gpr(t0, rt);
17827 gen_load_gpr(t1, rs);
17828 gen_helper_fork(t0, t1);
17829 tcg_temp_free(t0);
17830 tcg_temp_free(t1);
17831 }
17832 break;
17833 case OPC_YIELD:
17834 check_insn(ctx, ASE_MT);
17835 {
17836 TCGv t0 = tcg_temp_new();
17837
fac5a073
LA
17838 gen_load_gpr(t0, rs);
17839 gen_helper_yield(t0, cpu_env, t0);
17840 gen_store_gpr(t0, rd);
17841 tcg_temp_free(t0);
17842 }
17843 break;
10dc65db
LA
17844 default:
17845 if (ctx->insn_flags & ISA_MIPS32R6) {
17846 decode_opc_special3_r6(env, ctx);
17847 } else {
17848 decode_opc_special3_legacy(env, ctx);
17849 }
099e5b4d
LA
17850 }
17851}
17852
863f264d
YK
17853/* MIPS SIMD Architecture (MSA) */
17854static inline int check_msa_access(DisasContext *ctx)
17855{
17856 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17857 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 17858 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
17859 return 0;
17860 }
17861
17862 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17863 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 17864 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
17865 return 0;
17866 } else {
9c708c7f 17867 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
17868 return 0;
17869 }
17870 }
17871 return 1;
17872}
17873
5692c6e1
YK
17874static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17875{
17876 /* generates tcg ops to check if any element is 0 */
17877 /* Note this function only works with MSA_WRLEN = 128 */
17878 uint64_t eval_zero_or_big = 0;
17879 uint64_t eval_big = 0;
17880 TCGv_i64 t0 = tcg_temp_new_i64();
17881 TCGv_i64 t1 = tcg_temp_new_i64();
17882 switch (df) {
17883 case DF_BYTE:
17884 eval_zero_or_big = 0x0101010101010101ULL;
17885 eval_big = 0x8080808080808080ULL;
17886 break;
17887 case DF_HALF:
17888 eval_zero_or_big = 0x0001000100010001ULL;
17889 eval_big = 0x8000800080008000ULL;
17890 break;
17891 case DF_WORD:
17892 eval_zero_or_big = 0x0000000100000001ULL;
17893 eval_big = 0x8000000080000000ULL;
17894 break;
17895 case DF_DOUBLE:
17896 eval_zero_or_big = 0x0000000000000001ULL;
17897 eval_big = 0x8000000000000000ULL;
17898 break;
17899 }
17900 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17901 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17902 tcg_gen_andi_i64(t0, t0, eval_big);
17903 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17904 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17905 tcg_gen_andi_i64(t1, t1, eval_big);
17906 tcg_gen_or_i64(t0, t0, t1);
17907 /* if all bits are zero then all elements are not zero */
17908 /* if some bit is non-zero then some element is zero */
17909 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17910 tcg_gen_trunc_i64_tl(tresult, t0);
17911 tcg_temp_free_i64(t0);
17912 tcg_temp_free_i64(t1);
17913}
17914
17915static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17916{
17917 uint8_t df = (ctx->opcode >> 21) & 0x3;
17918 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17919 int64_t s16 = (int16_t)ctx->opcode;
17920
17921 check_msa_access(ctx);
17922
17923 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 17924 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
17925 return;
17926 }
17927 switch (op1) {
17928 case OPC_BZ_V:
17929 case OPC_BNZ_V:
17930 {
17931 TCGv_i64 t0 = tcg_temp_new_i64();
17932 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17933 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17934 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17935 tcg_gen_trunc_i64_tl(bcond, t0);
17936 tcg_temp_free_i64(t0);
17937 }
17938 break;
17939 case OPC_BZ_B:
17940 case OPC_BZ_H:
17941 case OPC_BZ_W:
17942 case OPC_BZ_D:
17943 gen_check_zero_element(bcond, df, wt);
17944 break;
17945 case OPC_BNZ_B:
17946 case OPC_BNZ_H:
17947 case OPC_BNZ_W:
17948 case OPC_BNZ_D:
17949 gen_check_zero_element(bcond, df, wt);
17950 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17951 break;
17952 }
17953
17954 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17955
17956 ctx->hflags |= MIPS_HFLAG_BC;
17957 ctx->hflags |= MIPS_HFLAG_BDS32;
17958}
17959
4c789546
YK
17960static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17961{
17962#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17963 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17964 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17965 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17966
17967 TCGv_i32 twd = tcg_const_i32(wd);
17968 TCGv_i32 tws = tcg_const_i32(ws);
17969 TCGv_i32 ti8 = tcg_const_i32(i8);
17970
17971 switch (MASK_MSA_I8(ctx->opcode)) {
17972 case OPC_ANDI_B:
17973 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17974 break;
17975 case OPC_ORI_B:
17976 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17977 break;
17978 case OPC_NORI_B:
17979 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17980 break;
17981 case OPC_XORI_B:
17982 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17983 break;
17984 case OPC_BMNZI_B:
17985 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17986 break;
17987 case OPC_BMZI_B:
17988 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17989 break;
17990 case OPC_BSELI_B:
17991 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17992 break;
17993 case OPC_SHF_B:
17994 case OPC_SHF_H:
17995 case OPC_SHF_W:
17996 {
17997 uint8_t df = (ctx->opcode >> 24) & 0x3;
17998 if (df == DF_DOUBLE) {
9c708c7f 17999 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18000 } else {
18001 TCGv_i32 tdf = tcg_const_i32(df);
18002 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18003 tcg_temp_free_i32(tdf);
18004 }
18005 }
18006 break;
18007 default:
18008 MIPS_INVAL("MSA instruction");
9c708c7f 18009 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18010 break;
18011 }
18012
18013 tcg_temp_free_i32(twd);
18014 tcg_temp_free_i32(tws);
18015 tcg_temp_free_i32(ti8);
18016}
18017
80e71591
YK
18018static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18019{
18020#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18021 uint8_t df = (ctx->opcode >> 21) & 0x3;
18022 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18023 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18024 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18025 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18026
18027 TCGv_i32 tdf = tcg_const_i32(df);
18028 TCGv_i32 twd = tcg_const_i32(wd);
18029 TCGv_i32 tws = tcg_const_i32(ws);
18030 TCGv_i32 timm = tcg_temp_new_i32();
18031 tcg_gen_movi_i32(timm, u5);
18032
18033 switch (MASK_MSA_I5(ctx->opcode)) {
18034 case OPC_ADDVI_df:
18035 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18036 break;
18037 case OPC_SUBVI_df:
18038 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18039 break;
18040 case OPC_MAXI_S_df:
18041 tcg_gen_movi_i32(timm, s5);
18042 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18043 break;
18044 case OPC_MAXI_U_df:
18045 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18046 break;
18047 case OPC_MINI_S_df:
18048 tcg_gen_movi_i32(timm, s5);
18049 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18050 break;
18051 case OPC_MINI_U_df:
18052 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18053 break;
18054 case OPC_CEQI_df:
18055 tcg_gen_movi_i32(timm, s5);
18056 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18057 break;
18058 case OPC_CLTI_S_df:
18059 tcg_gen_movi_i32(timm, s5);
18060 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18061 break;
18062 case OPC_CLTI_U_df:
18063 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18064 break;
18065 case OPC_CLEI_S_df:
18066 tcg_gen_movi_i32(timm, s5);
18067 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18068 break;
18069 case OPC_CLEI_U_df:
18070 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18071 break;
18072 case OPC_LDI_df:
18073 {
18074 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18075 tcg_gen_movi_i32(timm, s10);
18076 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18077 }
18078 break;
18079 default:
18080 MIPS_INVAL("MSA instruction");
9c708c7f 18081 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18082 break;
18083 }
18084
18085 tcg_temp_free_i32(tdf);
18086 tcg_temp_free_i32(twd);
18087 tcg_temp_free_i32(tws);
18088 tcg_temp_free_i32(timm);
18089}
18090
d4cf28de
YK
18091static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18092{
18093#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18094 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18095 uint32_t df = 0, m = 0;
18096 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18097 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18098
18099 TCGv_i32 tdf;
18100 TCGv_i32 tm;
18101 TCGv_i32 twd;
18102 TCGv_i32 tws;
18103
18104 if ((dfm & 0x40) == 0x00) {
18105 m = dfm & 0x3f;
18106 df = DF_DOUBLE;
18107 } else if ((dfm & 0x60) == 0x40) {
18108 m = dfm & 0x1f;
18109 df = DF_WORD;
18110 } else if ((dfm & 0x70) == 0x60) {
18111 m = dfm & 0x0f;
18112 df = DF_HALF;
18113 } else if ((dfm & 0x78) == 0x70) {
18114 m = dfm & 0x7;
18115 df = DF_BYTE;
18116 } else {
9c708c7f 18117 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18118 return;
18119 }
18120
18121 tdf = tcg_const_i32(df);
18122 tm = tcg_const_i32(m);
18123 twd = tcg_const_i32(wd);
18124 tws = tcg_const_i32(ws);
18125
18126 switch (MASK_MSA_BIT(ctx->opcode)) {
18127 case OPC_SLLI_df:
18128 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18129 break;
18130 case OPC_SRAI_df:
18131 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18132 break;
18133 case OPC_SRLI_df:
18134 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18135 break;
18136 case OPC_BCLRI_df:
18137 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18138 break;
18139 case OPC_BSETI_df:
18140 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18141 break;
18142 case OPC_BNEGI_df:
18143 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18144 break;
18145 case OPC_BINSLI_df:
18146 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18147 break;
18148 case OPC_BINSRI_df:
18149 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18150 break;
18151 case OPC_SAT_S_df:
18152 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18153 break;
18154 case OPC_SAT_U_df:
18155 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18156 break;
18157 case OPC_SRARI_df:
18158 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18159 break;
18160 case OPC_SRLRI_df:
18161 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18162 break;
18163 default:
18164 MIPS_INVAL("MSA instruction");
9c708c7f 18165 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18166 break;
18167 }
18168
18169 tcg_temp_free_i32(tdf);
18170 tcg_temp_free_i32(tm);
18171 tcg_temp_free_i32(twd);
18172 tcg_temp_free_i32(tws);
18173}
18174
28f99f08
YK
18175static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18176{
18177#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18178 uint8_t df = (ctx->opcode >> 21) & 0x3;
18179 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18180 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18181 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18182
18183 TCGv_i32 tdf = tcg_const_i32(df);
18184 TCGv_i32 twd = tcg_const_i32(wd);
18185 TCGv_i32 tws = tcg_const_i32(ws);
18186 TCGv_i32 twt = tcg_const_i32(wt);
18187
18188 switch (MASK_MSA_3R(ctx->opcode)) {
18189 case OPC_SLL_df:
18190 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18191 break;
18192 case OPC_ADDV_df:
18193 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18194 break;
18195 case OPC_CEQ_df:
18196 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18197 break;
18198 case OPC_ADD_A_df:
18199 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18200 break;
18201 case OPC_SUBS_S_df:
18202 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18203 break;
18204 case OPC_MULV_df:
18205 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18206 break;
18207 case OPC_SLD_df:
18208 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18209 break;
18210 case OPC_VSHF_df:
18211 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18212 break;
18213 case OPC_SRA_df:
18214 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18215 break;
18216 case OPC_SUBV_df:
18217 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18218 break;
18219 case OPC_ADDS_A_df:
18220 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18221 break;
18222 case OPC_SUBS_U_df:
18223 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18224 break;
18225 case OPC_MADDV_df:
18226 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18227 break;
18228 case OPC_SPLAT_df:
18229 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18230 break;
18231 case OPC_SRAR_df:
18232 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18233 break;
18234 case OPC_SRL_df:
18235 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18236 break;
18237 case OPC_MAX_S_df:
18238 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18239 break;
18240 case OPC_CLT_S_df:
18241 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18242 break;
18243 case OPC_ADDS_S_df:
18244 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18245 break;
18246 case OPC_SUBSUS_U_df:
18247 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18248 break;
18249 case OPC_MSUBV_df:
18250 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18251 break;
18252 case OPC_PCKEV_df:
18253 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18254 break;
18255 case OPC_SRLR_df:
18256 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18257 break;
18258 case OPC_BCLR_df:
18259 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18260 break;
18261 case OPC_MAX_U_df:
18262 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18263 break;
18264 case OPC_CLT_U_df:
18265 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18266 break;
18267 case OPC_ADDS_U_df:
18268 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18269 break;
18270 case OPC_SUBSUU_S_df:
18271 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18272 break;
18273 case OPC_PCKOD_df:
18274 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18275 break;
18276 case OPC_BSET_df:
18277 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18278 break;
18279 case OPC_MIN_S_df:
18280 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18281 break;
18282 case OPC_CLE_S_df:
18283 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18284 break;
18285 case OPC_AVE_S_df:
18286 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18287 break;
18288 case OPC_ASUB_S_df:
18289 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18290 break;
18291 case OPC_DIV_S_df:
18292 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18293 break;
18294 case OPC_ILVL_df:
18295 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18296 break;
18297 case OPC_BNEG_df:
18298 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18299 break;
18300 case OPC_MIN_U_df:
18301 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18302 break;
18303 case OPC_CLE_U_df:
18304 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18305 break;
18306 case OPC_AVE_U_df:
18307 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18308 break;
18309 case OPC_ASUB_U_df:
18310 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18311 break;
18312 case OPC_DIV_U_df:
18313 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18314 break;
18315 case OPC_ILVR_df:
18316 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18317 break;
18318 case OPC_BINSL_df:
18319 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18320 break;
18321 case OPC_MAX_A_df:
18322 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18323 break;
18324 case OPC_AVER_S_df:
18325 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18326 break;
18327 case OPC_MOD_S_df:
18328 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18329 break;
18330 case OPC_ILVEV_df:
18331 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18332 break;
18333 case OPC_BINSR_df:
18334 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18335 break;
18336 case OPC_MIN_A_df:
18337 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18338 break;
18339 case OPC_AVER_U_df:
18340 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18341 break;
18342 case OPC_MOD_U_df:
18343 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18344 break;
18345 case OPC_ILVOD_df:
18346 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18347 break;
18348
18349 case OPC_DOTP_S_df:
18350 case OPC_DOTP_U_df:
18351 case OPC_DPADD_S_df:
18352 case OPC_DPADD_U_df:
18353 case OPC_DPSUB_S_df:
18354 case OPC_HADD_S_df:
18355 case OPC_DPSUB_U_df:
18356 case OPC_HADD_U_df:
18357 case OPC_HSUB_S_df:
18358 case OPC_HSUB_U_df:
18359 if (df == DF_BYTE) {
9c708c7f
PD
18360 generate_exception_end(ctx, EXCP_RI);
18361 break;
28f99f08
YK
18362 }
18363 switch (MASK_MSA_3R(ctx->opcode)) {
18364 case OPC_DOTP_S_df:
18365 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18366 break;
18367 case OPC_DOTP_U_df:
18368 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18369 break;
18370 case OPC_DPADD_S_df:
18371 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18372 break;
18373 case OPC_DPADD_U_df:
18374 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18375 break;
18376 case OPC_DPSUB_S_df:
18377 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18378 break;
18379 case OPC_HADD_S_df:
18380 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18381 break;
18382 case OPC_DPSUB_U_df:
18383 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18384 break;
18385 case OPC_HADD_U_df:
18386 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18387 break;
18388 case OPC_HSUB_S_df:
18389 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18390 break;
18391 case OPC_HSUB_U_df:
18392 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18393 break;
18394 }
18395 break;
18396 default:
18397 MIPS_INVAL("MSA instruction");
9c708c7f 18398 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18399 break;
18400 }
18401 tcg_temp_free_i32(twd);
18402 tcg_temp_free_i32(tws);
18403 tcg_temp_free_i32(twt);
18404 tcg_temp_free_i32(tdf);
18405}
18406
1e608ec1
YK
18407static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18408{
18409#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18410 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18411 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18412 TCGv telm = tcg_temp_new();
18413 TCGv_i32 tsr = tcg_const_i32(source);
18414 TCGv_i32 tdt = tcg_const_i32(dest);
18415
18416 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18417 case OPC_CTCMSA:
18418 gen_load_gpr(telm, source);
18419 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18420 break;
18421 case OPC_CFCMSA:
18422 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18423 gen_store_gpr(telm, dest);
18424 break;
18425 case OPC_MOVE_V:
18426 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18427 break;
18428 default:
18429 MIPS_INVAL("MSA instruction");
9c708c7f 18430 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18431 break;
18432 }
18433
18434 tcg_temp_free(telm);
18435 tcg_temp_free_i32(tdt);
18436 tcg_temp_free_i32(tsr);
18437}
18438
18439static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18440 uint32_t n)
18441{
18442#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18443 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18444 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18445
18446 TCGv_i32 tws = tcg_const_i32(ws);
18447 TCGv_i32 twd = tcg_const_i32(wd);
18448 TCGv_i32 tn = tcg_const_i32(n);
18449 TCGv_i32 tdf = tcg_const_i32(df);
18450
18451 switch (MASK_MSA_ELM(ctx->opcode)) {
18452 case OPC_SLDI_df:
18453 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18454 break;
18455 case OPC_SPLATI_df:
18456 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18457 break;
18458 case OPC_INSVE_df:
18459 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18460 break;
18461 case OPC_COPY_S_df:
18462 case OPC_COPY_U_df:
18463 case OPC_INSERT_df:
18464#if !defined(TARGET_MIPS64)
18465 /* Double format valid only for MIPS64 */
18466 if (df == DF_DOUBLE) {
9c708c7f 18467 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18468 break;
18469 }
18470#endif
18471 switch (MASK_MSA_ELM(ctx->opcode)) {
18472 case OPC_COPY_S_df:
18473 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18474 break;
18475 case OPC_COPY_U_df:
18476 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18477 break;
18478 case OPC_INSERT_df:
18479 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18480 break;
18481 }
18482 break;
18483 default:
18484 MIPS_INVAL("MSA instruction");
9c708c7f 18485 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18486 }
18487 tcg_temp_free_i32(twd);
18488 tcg_temp_free_i32(tws);
18489 tcg_temp_free_i32(tn);
18490 tcg_temp_free_i32(tdf);
18491}
18492
18493static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18494{
18495 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18496 uint32_t df = 0, n = 0;
18497
18498 if ((dfn & 0x30) == 0x00) {
18499 n = dfn & 0x0f;
18500 df = DF_BYTE;
18501 } else if ((dfn & 0x38) == 0x20) {
18502 n = dfn & 0x07;
18503 df = DF_HALF;
18504 } else if ((dfn & 0x3c) == 0x30) {
18505 n = dfn & 0x03;
18506 df = DF_WORD;
18507 } else if ((dfn & 0x3e) == 0x38) {
18508 n = dfn & 0x01;
18509 df = DF_DOUBLE;
18510 } else if (dfn == 0x3E) {
18511 /* CTCMSA, CFCMSA, MOVE.V */
18512 gen_msa_elm_3e(env, ctx);
18513 return;
18514 } else {
9c708c7f 18515 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18516 return;
18517 }
18518
18519 gen_msa_elm_df(env, ctx, df, n);
18520}
18521
7d05b9c8
YK
18522static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18523{
18524#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18525 uint8_t df = (ctx->opcode >> 21) & 0x1;
18526 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18527 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18528 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18529
18530 TCGv_i32 twd = tcg_const_i32(wd);
18531 TCGv_i32 tws = tcg_const_i32(ws);
18532 TCGv_i32 twt = tcg_const_i32(wt);
18533 TCGv_i32 tdf = tcg_temp_new_i32();
18534
18535 /* adjust df value for floating-point instruction */
18536 tcg_gen_movi_i32(tdf, df + 2);
18537
18538 switch (MASK_MSA_3RF(ctx->opcode)) {
18539 case OPC_FCAF_df:
18540 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18541 break;
18542 case OPC_FADD_df:
18543 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18544 break;
18545 case OPC_FCUN_df:
18546 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18547 break;
18548 case OPC_FSUB_df:
18549 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18550 break;
18551 case OPC_FCOR_df:
18552 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18553 break;
18554 case OPC_FCEQ_df:
18555 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18556 break;
18557 case OPC_FMUL_df:
18558 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18559 break;
18560 case OPC_FCUNE_df:
18561 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18562 break;
18563 case OPC_FCUEQ_df:
18564 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18565 break;
18566 case OPC_FDIV_df:
18567 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18568 break;
18569 case OPC_FCNE_df:
18570 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_FCLT_df:
18573 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_FMADD_df:
18576 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_MUL_Q_df:
18579 tcg_gen_movi_i32(tdf, df + 1);
18580 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18581 break;
18582 case OPC_FCULT_df:
18583 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18584 break;
18585 case OPC_FMSUB_df:
18586 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18587 break;
18588 case OPC_MADD_Q_df:
18589 tcg_gen_movi_i32(tdf, df + 1);
18590 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18591 break;
18592 case OPC_FCLE_df:
18593 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18594 break;
18595 case OPC_MSUB_Q_df:
18596 tcg_gen_movi_i32(tdf, df + 1);
18597 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18598 break;
18599 case OPC_FCULE_df:
18600 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18601 break;
18602 case OPC_FEXP2_df:
18603 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18604 break;
18605 case OPC_FSAF_df:
18606 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18607 break;
18608 case OPC_FEXDO_df:
18609 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18610 break;
18611 case OPC_FSUN_df:
18612 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18613 break;
18614 case OPC_FSOR_df:
18615 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18616 break;
18617 case OPC_FSEQ_df:
18618 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18619 break;
18620 case OPC_FTQ_df:
18621 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18622 break;
18623 case OPC_FSUNE_df:
18624 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18625 break;
18626 case OPC_FSUEQ_df:
18627 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18628 break;
18629 case OPC_FSNE_df:
18630 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18631 break;
18632 case OPC_FSLT_df:
18633 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18634 break;
18635 case OPC_FMIN_df:
18636 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18637 break;
18638 case OPC_MULR_Q_df:
18639 tcg_gen_movi_i32(tdf, df + 1);
18640 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18641 break;
18642 case OPC_FSULT_df:
18643 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18644 break;
18645 case OPC_FMIN_A_df:
18646 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18647 break;
18648 case OPC_MADDR_Q_df:
18649 tcg_gen_movi_i32(tdf, df + 1);
18650 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18651 break;
18652 case OPC_FSLE_df:
18653 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18654 break;
18655 case OPC_FMAX_df:
18656 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18657 break;
18658 case OPC_MSUBR_Q_df:
18659 tcg_gen_movi_i32(tdf, df + 1);
18660 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18661 break;
18662 case OPC_FSULE_df:
18663 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18664 break;
18665 case OPC_FMAX_A_df:
18666 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18667 break;
18668 default:
18669 MIPS_INVAL("MSA instruction");
9c708c7f 18670 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
18671 break;
18672 }
18673
18674 tcg_temp_free_i32(twd);
18675 tcg_temp_free_i32(tws);
18676 tcg_temp_free_i32(twt);
18677 tcg_temp_free_i32(tdf);
18678}
18679
cbe50b9a
YK
18680static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18681{
18682#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18683 (op & (0x7 << 18)))
18684 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18685 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18686 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18687 uint8_t df = (ctx->opcode >> 16) & 0x3;
18688 TCGv_i32 twd = tcg_const_i32(wd);
18689 TCGv_i32 tws = tcg_const_i32(ws);
18690 TCGv_i32 twt = tcg_const_i32(wt);
18691 TCGv_i32 tdf = tcg_const_i32(df);
18692
18693 switch (MASK_MSA_2R(ctx->opcode)) {
18694 case OPC_FILL_df:
18695#if !defined(TARGET_MIPS64)
18696 /* Double format valid only for MIPS64 */
18697 if (df == DF_DOUBLE) {
9c708c7f 18698 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18699 break;
18700 }
18701#endif
18702 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18703 break;
18704 case OPC_PCNT_df:
18705 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18706 break;
18707 case OPC_NLOC_df:
18708 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18709 break;
18710 case OPC_NLZC_df:
18711 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18712 break;
18713 default:
18714 MIPS_INVAL("MSA instruction");
9c708c7f 18715 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18716 break;
18717 }
18718
18719 tcg_temp_free_i32(twd);
18720 tcg_temp_free_i32(tws);
18721 tcg_temp_free_i32(twt);
18722 tcg_temp_free_i32(tdf);
18723}
18724
3bdeb688
YK
18725static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18726{
18727#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18728 (op & (0xf << 17)))
18729 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18730 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18731 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18732 uint8_t df = (ctx->opcode >> 16) & 0x1;
18733 TCGv_i32 twd = tcg_const_i32(wd);
18734 TCGv_i32 tws = tcg_const_i32(ws);
18735 TCGv_i32 twt = tcg_const_i32(wt);
18736 /* adjust df value for floating-point instruction */
18737 TCGv_i32 tdf = tcg_const_i32(df + 2);
18738
18739 switch (MASK_MSA_2RF(ctx->opcode)) {
18740 case OPC_FCLASS_df:
18741 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18742 break;
18743 case OPC_FTRUNC_S_df:
18744 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18745 break;
18746 case OPC_FTRUNC_U_df:
18747 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18748 break;
18749 case OPC_FSQRT_df:
18750 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18751 break;
18752 case OPC_FRSQRT_df:
18753 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18754 break;
18755 case OPC_FRCP_df:
18756 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18757 break;
18758 case OPC_FRINT_df:
18759 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18760 break;
18761 case OPC_FLOG2_df:
18762 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18763 break;
18764 case OPC_FEXUPL_df:
18765 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18766 break;
18767 case OPC_FEXUPR_df:
18768 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18769 break;
18770 case OPC_FFQL_df:
18771 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18772 break;
18773 case OPC_FFQR_df:
18774 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18775 break;
18776 case OPC_FTINT_S_df:
18777 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18778 break;
18779 case OPC_FTINT_U_df:
18780 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18781 break;
18782 case OPC_FFINT_S_df:
18783 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18784 break;
18785 case OPC_FFINT_U_df:
18786 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18787 break;
18788 }
18789
18790 tcg_temp_free_i32(twd);
18791 tcg_temp_free_i32(tws);
18792 tcg_temp_free_i32(twt);
18793 tcg_temp_free_i32(tdf);
18794}
18795
cbe50b9a
YK
18796static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18797{
18798#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18799 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18800 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18801 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18802 TCGv_i32 twd = tcg_const_i32(wd);
18803 TCGv_i32 tws = tcg_const_i32(ws);
18804 TCGv_i32 twt = tcg_const_i32(wt);
18805
18806 switch (MASK_MSA_VEC(ctx->opcode)) {
18807 case OPC_AND_V:
18808 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18809 break;
18810 case OPC_OR_V:
18811 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18812 break;
18813 case OPC_NOR_V:
18814 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18815 break;
18816 case OPC_XOR_V:
18817 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18818 break;
18819 case OPC_BMNZ_V:
18820 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18821 break;
18822 case OPC_BMZ_V:
18823 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18824 break;
18825 case OPC_BSEL_V:
18826 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18827 break;
18828 default:
18829 MIPS_INVAL("MSA instruction");
9c708c7f 18830 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18831 break;
18832 }
18833
18834 tcg_temp_free_i32(twd);
18835 tcg_temp_free_i32(tws);
18836 tcg_temp_free_i32(twt);
18837}
18838
18839static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18840{
18841 switch (MASK_MSA_VEC(ctx->opcode)) {
18842 case OPC_AND_V:
18843 case OPC_OR_V:
18844 case OPC_NOR_V:
18845 case OPC_XOR_V:
18846 case OPC_BMNZ_V:
18847 case OPC_BMZ_V:
18848 case OPC_BSEL_V:
18849 gen_msa_vec_v(env, ctx);
18850 break;
18851 case OPC_MSA_2R:
18852 gen_msa_2r(env, ctx);
18853 break;
3bdeb688
YK
18854 case OPC_MSA_2RF:
18855 gen_msa_2rf(env, ctx);
18856 break;
cbe50b9a
YK
18857 default:
18858 MIPS_INVAL("MSA instruction");
9c708c7f 18859 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
18860 break;
18861 }
18862}
18863
4c789546
YK
18864static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18865{
18866 uint32_t opcode = ctx->opcode;
18867 check_insn(ctx, ASE_MSA);
18868 check_msa_access(ctx);
18869
18870 switch (MASK_MSA_MINOR(opcode)) {
18871 case OPC_MSA_I8_00:
18872 case OPC_MSA_I8_01:
18873 case OPC_MSA_I8_02:
18874 gen_msa_i8(env, ctx);
18875 break;
80e71591
YK
18876 case OPC_MSA_I5_06:
18877 case OPC_MSA_I5_07:
18878 gen_msa_i5(env, ctx);
18879 break;
d4cf28de
YK
18880 case OPC_MSA_BIT_09:
18881 case OPC_MSA_BIT_0A:
18882 gen_msa_bit(env, ctx);
18883 break;
28f99f08
YK
18884 case OPC_MSA_3R_0D:
18885 case OPC_MSA_3R_0E:
18886 case OPC_MSA_3R_0F:
18887 case OPC_MSA_3R_10:
18888 case OPC_MSA_3R_11:
18889 case OPC_MSA_3R_12:
18890 case OPC_MSA_3R_13:
18891 case OPC_MSA_3R_14:
18892 case OPC_MSA_3R_15:
18893 gen_msa_3r(env, ctx);
18894 break;
1e608ec1
YK
18895 case OPC_MSA_ELM:
18896 gen_msa_elm(env, ctx);
18897 break;
7d05b9c8
YK
18898 case OPC_MSA_3RF_1A:
18899 case OPC_MSA_3RF_1B:
18900 case OPC_MSA_3RF_1C:
18901 gen_msa_3rf(env, ctx);
18902 break;
cbe50b9a
YK
18903 case OPC_MSA_VEC:
18904 gen_msa_vec(env, ctx);
18905 break;
f7685877
YK
18906 case OPC_LD_B:
18907 case OPC_LD_H:
18908 case OPC_LD_W:
18909 case OPC_LD_D:
18910 case OPC_ST_B:
18911 case OPC_ST_H:
18912 case OPC_ST_W:
18913 case OPC_ST_D:
18914 {
18915 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18916 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18917 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18918 uint8_t df = (ctx->opcode >> 0) & 0x3;
18919
f7685877 18920 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
18921 TCGv taddr = tcg_temp_new();
18922 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
18923
18924 switch (MASK_MSA_MINOR(opcode)) {
18925 case OPC_LD_B:
adc370a4
YK
18926 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18927 break;
f7685877 18928 case OPC_LD_H:
adc370a4
YK
18929 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18930 break;
f7685877 18931 case OPC_LD_W:
adc370a4
YK
18932 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18933 break;
f7685877 18934 case OPC_LD_D:
adc370a4 18935 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
18936 break;
18937 case OPC_ST_B:
adc370a4
YK
18938 gen_helper_msa_st_b(cpu_env, twd, taddr);
18939 break;
f7685877 18940 case OPC_ST_H:
adc370a4
YK
18941 gen_helper_msa_st_h(cpu_env, twd, taddr);
18942 break;
f7685877 18943 case OPC_ST_W:
adc370a4
YK
18944 gen_helper_msa_st_w(cpu_env, twd, taddr);
18945 break;
f7685877 18946 case OPC_ST_D:
adc370a4 18947 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
18948 break;
18949 }
18950
18951 tcg_temp_free_i32(twd);
adc370a4 18952 tcg_temp_free(taddr);
f7685877
YK
18953 }
18954 break;
4c789546
YK
18955 default:
18956 MIPS_INVAL("MSA instruction");
9c708c7f 18957 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18958 break;
18959 }
18960
18961}
18962
d2bfa6e6 18963static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18964{
18965 int32_t offset;
18966 int rs, rt, rd, sa;
18967 uint32_t op, op1;
18968 int16_t imm;
18969
18970 /* make sure instructions are on a word boundary */
18971 if (ctx->pc & 0x3) {
18972 env->CP0_BadVAddr = ctx->pc;
aea14095 18973 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
18974 return;
18975 }
18976
18977 /* Handle blikely not taken case */
18978 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 18979 TCGLabel *l1 = gen_new_label();
099e5b4d 18980
099e5b4d
LA
18981 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18982 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18983 gen_goto_tb(ctx, 1, ctx->pc + 4);
18984 gen_set_label(l1);
18985 }
18986
099e5b4d
LA
18987 op = MASK_OP_MAJOR(ctx->opcode);
18988 rs = (ctx->opcode >> 21) & 0x1f;
18989 rt = (ctx->opcode >> 16) & 0x1f;
18990 rd = (ctx->opcode >> 11) & 0x1f;
18991 sa = (ctx->opcode >> 6) & 0x1f;
18992 imm = (int16_t)ctx->opcode;
18993 switch (op) {
18994 case OPC_SPECIAL:
18995 decode_opc_special(env, ctx);
18996 break;
18997 case OPC_SPECIAL2:
4267d3e6 18998 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18999 break;
19000 case OPC_SPECIAL3:
19001 decode_opc_special3(env, ctx);
19002 break;
7a387fff
TS
19003 case OPC_REGIMM:
19004 op1 = MASK_REGIMM(ctx->opcode);
19005 switch (op1) {
fecd2646
LA
19006 case OPC_BLTZL: /* REGIMM branches */
19007 case OPC_BGEZL:
19008 case OPC_BLTZALL:
19009 case OPC_BGEZALL:
d9224450 19010 check_insn(ctx, ISA_MIPS2);
fecd2646 19011 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19012 /* Fallthrough */
fecd2646
LA
19013 case OPC_BLTZ:
19014 case OPC_BGEZ:
b231c103 19015 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19016 break;
fecd2646
LA
19017 case OPC_BLTZAL:
19018 case OPC_BGEZAL:
0aefa333
YK
19019 if (ctx->insn_flags & ISA_MIPS32R6) {
19020 if (rs == 0) {
19021 /* OPC_NAL, OPC_BAL */
b231c103 19022 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19023 } else {
9c708c7f 19024 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19025 }
19026 } else {
b231c103 19027 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19028 }
c9602061 19029 break;
7a387fff
TS
19030 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19031 case OPC_TNEI:
d9224450 19032 check_insn(ctx, ISA_MIPS2);
fecd2646 19033 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19034 gen_trap(ctx, op1, rs, -1, imm);
19035 break;
bb238210
YK
19036 case OPC_SIGRIE:
19037 check_insn(ctx, ISA_MIPS32R6);
19038 generate_exception_end(ctx, EXCP_RI);
19039 break;
7a387fff 19040 case OPC_SYNCI:
d75c135e 19041 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19042 /* Break the TB to be able to sync copied instructions
19043 immediately */
19044 ctx->bstate = BS_STOP;
6af0bf9c 19045 break;
e45a93e2
JL
19046 case OPC_BPOSGE32: /* MIPS DSP branch */
19047#if defined(TARGET_MIPS64)
19048 case OPC_BPOSGE64:
19049#endif
19050 check_dsp(ctx);
b231c103 19051 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19052 break;
d4ea6acd
LA
19053#if defined(TARGET_MIPS64)
19054 case OPC_DAHI:
19055 check_insn(ctx, ISA_MIPS32R6);
19056 check_mips_64(ctx);
19057 if (rs != 0) {
19058 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19059 }
d4ea6acd
LA
19060 break;
19061 case OPC_DATI:
19062 check_insn(ctx, ISA_MIPS32R6);
19063 check_mips_64(ctx);
19064 if (rs != 0) {
19065 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19066 }
d4ea6acd
LA
19067 break;
19068#endif
6af0bf9c 19069 default: /* Invalid */
923617a3 19070 MIPS_INVAL("regimm");
9c708c7f 19071 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19072 break;
19073 }
19074 break;
7a387fff 19075 case OPC_CP0:
387a8fe5 19076 check_cp0_enabled(ctx);
7a387fff 19077 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19078 switch (op1) {
7a387fff
TS
19079 case OPC_MFC0:
19080 case OPC_MTC0:
ead9360e
TS
19081 case OPC_MFTR:
19082 case OPC_MTTR:
5204ea79
LA
19083 case OPC_MFHC0:
19084 case OPC_MTHC0:
d26bc211 19085#if defined(TARGET_MIPS64)
7a387fff
TS
19086 case OPC_DMFC0:
19087 case OPC_DMTC0:
19088#endif
f1aa6320 19089#ifndef CONFIG_USER_ONLY
932e71cd 19090 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19091#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19092 break;
19093 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19094#ifndef CONFIG_USER_ONLY
932e71cd 19095 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19096#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19097 break;
19098 case OPC_MFMC0:
8706c382 19099#ifndef CONFIG_USER_ONLY
932e71cd 19100 {
099e5b4d 19101 uint32_t op2;
35fbce2c 19102 TCGv t0 = tcg_temp_new();
6c5c1e20 19103
0eaef5aa 19104 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19105 switch (op2) {
19106 case OPC_DMT:
d75c135e 19107 check_insn(ctx, ASE_MT);
9ed5726c 19108 gen_helper_dmt(t0);
35fbce2c 19109 gen_store_gpr(t0, rt);
6c5c1e20
TS
19110 break;
19111 case OPC_EMT:
d75c135e 19112 check_insn(ctx, ASE_MT);
9ed5726c 19113 gen_helper_emt(t0);
35fbce2c 19114 gen_store_gpr(t0, rt);
da80682b 19115 break;
6c5c1e20 19116 case OPC_DVPE:
d75c135e 19117 check_insn(ctx, ASE_MT);
895c2d04 19118 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19119 gen_store_gpr(t0, rt);
6c5c1e20
TS
19120 break;
19121 case OPC_EVPE:
d75c135e 19122 check_insn(ctx, ASE_MT);
895c2d04 19123 gen_helper_evpe(t0, cpu_env);
35fbce2c 19124 gen_store_gpr(t0, rt);
6c5c1e20 19125 break;
01bc435b
YK
19126 case OPC_DVP:
19127 check_insn(ctx, ISA_MIPS32R6);
19128 if (ctx->vp) {
19129 gen_helper_dvp(t0, cpu_env);
19130 gen_store_gpr(t0, rt);
19131 }
19132 break;
19133 case OPC_EVP:
19134 check_insn(ctx, ISA_MIPS32R6);
19135 if (ctx->vp) {
19136 gen_helper_evp(t0, cpu_env);
19137 gen_store_gpr(t0, rt);
19138 }
19139 break;
6c5c1e20 19140 case OPC_DI:
d75c135e 19141 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19142 save_cpu_state(ctx, 1);
895c2d04 19143 gen_helper_di(t0, cpu_env);
35fbce2c 19144 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19145 /* Stop translation as we may have switched
19146 the execution mode. */
6c5c1e20
TS
19147 ctx->bstate = BS_STOP;
19148 break;
19149 case OPC_EI:
d75c135e 19150 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19151 save_cpu_state(ctx, 1);
895c2d04 19152 gen_helper_ei(t0, cpu_env);
35fbce2c 19153 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19154 /* Stop translation as we may have switched
19155 the execution mode. */
6c5c1e20
TS
19156 ctx->bstate = BS_STOP;
19157 break;
19158 default: /* Invalid */
19159 MIPS_INVAL("mfmc0");
9c708c7f 19160 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19161 break;
19162 }
6c5c1e20 19163 tcg_temp_free(t0);
7a387fff 19164 }
0eaef5aa 19165#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19166 break;
7a387fff 19167 case OPC_RDPGPR:
d75c135e 19168 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19169 gen_load_srsgpr(rt, rd);
ead9360e 19170 break;
7a387fff 19171 case OPC_WRPGPR:
d75c135e 19172 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19173 gen_store_srsgpr(rt, rd);
38121543 19174 break;
6af0bf9c 19175 default:
923617a3 19176 MIPS_INVAL("cp0");
9c708c7f 19177 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19178 break;
19179 }
19180 break;
31837be3
YK
19181 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19182 if (ctx->insn_flags & ISA_MIPS32R6) {
19183 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19184 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19185 } else {
19186 /* OPC_ADDI */
19187 /* Arithmetic with immediate opcode */
19188 gen_arith_imm(ctx, op, rt, rs, imm);
19189 }
19190 break;
324d9e32 19191 case OPC_ADDIU:
d75c135e 19192 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19193 break;
324d9e32
AJ
19194 case OPC_SLTI: /* Set on less than with immediate opcode */
19195 case OPC_SLTIU:
d75c135e 19196 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19197 break;
19198 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19199 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19200 case OPC_ORI:
19201 case OPC_XORI:
d75c135e 19202 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19203 break;
7a387fff
TS
19204 case OPC_J ... OPC_JAL: /* Jump */
19205 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19206 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19207 break;
31837be3
YK
19208 /* Branch */
19209 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19210 if (ctx->insn_flags & ISA_MIPS32R6) {
19211 if (rt == 0) {
9c708c7f 19212 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19213 break;
19214 }
19215 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19216 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19217 } else {
19218 /* OPC_BLEZL */
b231c103 19219 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19220 }
19221 break;
19222 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19223 if (ctx->insn_flags & ISA_MIPS32R6) {
19224 if (rt == 0) {
9c708c7f 19225 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19226 break;
19227 }
19228 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19229 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19230 } else {
19231 /* OPC_BGTZL */
b231c103 19232 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19233 }
19234 break;
19235 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19236 if (rt == 0) {
19237 /* OPC_BLEZ */
b231c103 19238 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19239 } else {
19240 check_insn(ctx, ISA_MIPS32R6);
19241 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19242 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19243 }
19244 break;
19245 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19246 if (rt == 0) {
19247 /* OPC_BGTZ */
b231c103 19248 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19249 } else {
19250 check_insn(ctx, ISA_MIPS32R6);
19251 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19252 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19253 }
19254 break;
19255 case OPC_BEQL:
19256 case OPC_BNEL:
d9224450 19257 check_insn(ctx, ISA_MIPS2);
fecd2646 19258 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19259 /* Fallthrough */
31837be3
YK
19260 case OPC_BEQ:
19261 case OPC_BNE:
b231c103 19262 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19263 break;
d9224450
MR
19264 case OPC_LL: /* Load and stores */
19265 check_insn(ctx, ISA_MIPS2);
19266 /* Fallthrough */
19267 case OPC_LWL:
fecd2646
LA
19268 case OPC_LWR:
19269 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19270 /* Fallthrough */
fecd2646
LA
19271 case OPC_LB ... OPC_LH:
19272 case OPC_LW ... OPC_LHU:
d75c135e 19273 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19274 break;
fecd2646 19275 case OPC_SWL:
7a387fff 19276 case OPC_SWR:
fecd2646 19277 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19278 /* fall through */
fecd2646
LA
19279 case OPC_SB ... OPC_SH:
19280 case OPC_SW:
5c13fdfd 19281 gen_st(ctx, op, rt, rs, imm);
7a387fff 19282 break;
d66c7132 19283 case OPC_SC:
d9224450 19284 check_insn(ctx, ISA_MIPS2);
4368b29a 19285 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19286 gen_st_cond(ctx, op, rt, rs, imm);
19287 break;
7a387fff 19288 case OPC_CACHE:
bf7910c6 19289 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19290 check_cp0_enabled(ctx);
d75c135e 19291 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 19292 /* Treat as NOP. */
34ae7b51 19293 break;
7a387fff 19294 case OPC_PREF:
bf7910c6 19295 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19296 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19297 /* Treat as NOP. */
6af0bf9c 19298 break;
4ad40f36 19299
923617a3 19300 /* Floating point (COP1). */
7a387fff
TS
19301 case OPC_LWC1:
19302 case OPC_LDC1:
19303 case OPC_SWC1:
19304 case OPC_SDC1:
5ab5c041 19305 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19306 break;
19307
7a387fff 19308 case OPC_CP1:
5692c6e1
YK
19309 op1 = MASK_CP1(ctx->opcode);
19310
19311 switch (op1) {
19312 case OPC_MFHC1:
19313 case OPC_MTHC1:
5e755519 19314 check_cp1_enabled(ctx);
5692c6e1
YK
19315 check_insn(ctx, ISA_MIPS32R2);
19316 case OPC_MFC1:
19317 case OPC_CFC1:
19318 case OPC_MTC1:
19319 case OPC_CTC1:
19320 check_cp1_enabled(ctx);
19321 gen_cp1(ctx, op1, rt, rd);
19322 break;
d26bc211 19323#if defined(TARGET_MIPS64)
5692c6e1
YK
19324 case OPC_DMFC1:
19325 case OPC_DMTC1:
19326 check_cp1_enabled(ctx);
19327 check_insn(ctx, ISA_MIPS3);
d9224450 19328 check_mips_64(ctx);
5692c6e1
YK
19329 gen_cp1(ctx, op1, rt, rd);
19330 break;
e189e748 19331#endif
5692c6e1
YK
19332 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19333 check_cp1_enabled(ctx);
19334 if (ctx->insn_flags & ISA_MIPS32R6) {
19335 /* OPC_BC1EQZ */
31837be3 19336 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19337 rt, imm << 2, 4);
5692c6e1
YK
19338 } else {
19339 /* OPC_BC1ANY2 */
b8aa4598 19340 check_cop1x(ctx);
d75c135e 19341 check_insn(ctx, ASE_MIPS3D);
d75c135e 19342 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19343 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19344 }
19345 break;
19346 case OPC_BC1NEZ:
19347 check_cp1_enabled(ctx);
19348 check_insn(ctx, ISA_MIPS32R6);
19349 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19350 rt, imm << 2, 4);
5692c6e1
YK
19351 break;
19352 case OPC_BC1ANY4:
19353 check_cp1_enabled(ctx);
19354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19355 check_cop1x(ctx);
19356 check_insn(ctx, ASE_MIPS3D);
19357 /* fall through */
19358 case OPC_BC1:
19359 check_cp1_enabled(ctx);
19360 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19361 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19362 (rt >> 2) & 0x7, imm << 2);
19363 break;
19364 case OPC_PS_FMT:
e29c9628 19365 check_ps(ctx);
b6f3b233 19366 /* fall through */
5692c6e1
YK
19367 case OPC_S_FMT:
19368 case OPC_D_FMT:
19369 check_cp1_enabled(ctx);
19370 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19371 (imm >> 8) & 0x7);
19372 break;
19373 case OPC_W_FMT:
19374 case OPC_L_FMT:
19375 {
19376 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19377 check_cp1_enabled(ctx);
19378 if (ctx->insn_flags & ISA_MIPS32R6) {
19379 switch (r6_op) {
19380 case R6_OPC_CMP_AF_S:
19381 case R6_OPC_CMP_UN_S:
19382 case R6_OPC_CMP_EQ_S:
19383 case R6_OPC_CMP_UEQ_S:
19384 case R6_OPC_CMP_LT_S:
19385 case R6_OPC_CMP_ULT_S:
19386 case R6_OPC_CMP_LE_S:
19387 case R6_OPC_CMP_ULE_S:
19388 case R6_OPC_CMP_SAF_S:
19389 case R6_OPC_CMP_SUN_S:
19390 case R6_OPC_CMP_SEQ_S:
19391 case R6_OPC_CMP_SEUQ_S:
19392 case R6_OPC_CMP_SLT_S:
19393 case R6_OPC_CMP_SULT_S:
19394 case R6_OPC_CMP_SLE_S:
19395 case R6_OPC_CMP_SULE_S:
19396 case R6_OPC_CMP_OR_S:
19397 case R6_OPC_CMP_UNE_S:
19398 case R6_OPC_CMP_NE_S:
19399 case R6_OPC_CMP_SOR_S:
19400 case R6_OPC_CMP_SUNE_S:
19401 case R6_OPC_CMP_SNE_S:
19402 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19403 break;
19404 case R6_OPC_CMP_AF_D:
19405 case R6_OPC_CMP_UN_D:
19406 case R6_OPC_CMP_EQ_D:
19407 case R6_OPC_CMP_UEQ_D:
19408 case R6_OPC_CMP_LT_D:
19409 case R6_OPC_CMP_ULT_D:
19410 case R6_OPC_CMP_LE_D:
19411 case R6_OPC_CMP_ULE_D:
19412 case R6_OPC_CMP_SAF_D:
19413 case R6_OPC_CMP_SUN_D:
19414 case R6_OPC_CMP_SEQ_D:
19415 case R6_OPC_CMP_SEUQ_D:
19416 case R6_OPC_CMP_SLT_D:
19417 case R6_OPC_CMP_SULT_D:
19418 case R6_OPC_CMP_SLE_D:
19419 case R6_OPC_CMP_SULE_D:
19420 case R6_OPC_CMP_OR_D:
19421 case R6_OPC_CMP_UNE_D:
19422 case R6_OPC_CMP_NE_D:
19423 case R6_OPC_CMP_SOR_D:
19424 case R6_OPC_CMP_SUNE_D:
19425 case R6_OPC_CMP_SNE_D:
19426 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19427 break;
19428 default:
d2bfa6e6
MR
19429 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19430 rt, rd, sa, (imm >> 8) & 0x7);
19431
5692c6e1 19432 break;
3f493883 19433 }
5692c6e1
YK
19434 } else {
19435 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19436 (imm >> 8) & 0x7);
36d23958 19437 }
5692c6e1
YK
19438 break;
19439 }
19440 case OPC_BZ_V:
19441 case OPC_BNZ_V:
19442 case OPC_BZ_B:
19443 case OPC_BZ_H:
19444 case OPC_BZ_W:
19445 case OPC_BZ_D:
19446 case OPC_BNZ_B:
19447 case OPC_BNZ_H:
19448 case OPC_BNZ_W:
19449 case OPC_BNZ_D:
19450 check_insn(ctx, ASE_MSA);
19451 gen_msa_branch(env, ctx, op1);
19452 break;
19453 default:
19454 MIPS_INVAL("cp1");
9c708c7f 19455 generate_exception_end(ctx, EXCP_RI);
5692c6e1 19456 break;
6ea83fed 19457 }
4ad40f36
FB
19458 break;
19459
31837be3
YK
19460 /* Compact branches [R6] and COP2 [non-R6] */
19461 case OPC_BC: /* OPC_LWC2 */
19462 case OPC_BALC: /* OPC_SWC2 */
19463 if (ctx->insn_flags & ISA_MIPS32R6) {
19464 /* OPC_BC, OPC_BALC */
19465 gen_compute_compact_branch(ctx, op, 0, 0,
19466 sextract32(ctx->opcode << 2, 0, 28));
19467 } else {
19468 /* OPC_LWC2, OPC_SWC2 */
19469 /* COP2: Not implemented. */
19470 generate_exception_err(ctx, EXCP_CpU, 2);
19471 }
19472 break;
19473 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19474 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19475 if (ctx->insn_flags & ISA_MIPS32R6) {
19476 if (rs != 0) {
19477 /* OPC_BEQZC, OPC_BNEZC */
19478 gen_compute_compact_branch(ctx, op, rs, 0,
19479 sextract32(ctx->opcode << 2, 0, 23));
19480 } else {
19481 /* OPC_JIC, OPC_JIALC */
19482 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19483 }
19484 } else {
19485 /* OPC_LWC2, OPC_SWC2 */
19486 /* COP2: Not implemented. */
19487 generate_exception_err(ctx, EXCP_CpU, 2);
19488 }
4ad40f36 19489 break;
bd277fa1 19490 case OPC_CP2:
d75c135e 19491 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19492 /* Note that these instructions use different fields. */
19493 gen_loongson_multimedia(ctx, sa, rd, rt);
19494 break;
4ad40f36 19495
7a387fff 19496 case OPC_CP3:
fecd2646 19497 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19498 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19499 check_cp1_enabled(ctx);
36d23958
TS
19500 op1 = MASK_CP3(ctx->opcode);
19501 switch (op1) {
d9224450
MR
19502 case OPC_LUXC1:
19503 case OPC_SUXC1:
19504 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19505 /* Fallthrough */
5a5012ec
TS
19506 case OPC_LWXC1:
19507 case OPC_LDXC1:
5a5012ec
TS
19508 case OPC_SWXC1:
19509 case OPC_SDXC1:
d9224450 19510 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19511 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19512 break;
e0c84da7 19513 case OPC_PREFX:
d9224450 19514 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19515 /* Treat as NOP. */
e0c84da7 19516 break;
5a5012ec 19517 case OPC_ALNV_PS:
d9224450
MR
19518 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19519 /* Fallthrough */
5a5012ec
TS
19520 case OPC_MADD_S:
19521 case OPC_MADD_D:
19522 case OPC_MADD_PS:
19523 case OPC_MSUB_S:
19524 case OPC_MSUB_D:
19525 case OPC_MSUB_PS:
19526 case OPC_NMADD_S:
19527 case OPC_NMADD_D:
19528 case OPC_NMADD_PS:
19529 case OPC_NMSUB_S:
19530 case OPC_NMSUB_D:
19531 case OPC_NMSUB_PS:
d9224450 19532 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19533 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19534 break;
36d23958 19535 default:
923617a3 19536 MIPS_INVAL("cp3");
9c708c7f 19537 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
19538 break;
19539 }
19540 } else {
e397ee33 19541 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19542 }
4ad40f36
FB
19543 break;
19544
d26bc211 19545#if defined(TARGET_MIPS64)
7a387fff 19546 /* MIPS64 opcodes */
7a387fff 19547 case OPC_LDL ... OPC_LDR:
bf7910c6 19548 case OPC_LLD:
fecd2646 19549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19550 /* fall through */
fecd2646 19551 case OPC_LWU:
7a387fff 19552 case OPC_LD:
d75c135e 19553 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19554 check_mips_64(ctx);
d75c135e 19555 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19556 break;
19557 case OPC_SDL ... OPC_SDR:
fecd2646 19558 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19559 /* fall through */
7a387fff 19560 case OPC_SD:
d75c135e 19561 check_insn(ctx, ISA_MIPS3);
e189e748 19562 check_mips_64(ctx);
5c13fdfd 19563 gen_st(ctx, op, rt, rs, imm);
7a387fff 19564 break;
d66c7132 19565 case OPC_SCD:
bf7910c6 19566 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19567 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19568 check_mips_64(ctx);
19569 gen_st_cond(ctx, op, rt, rs, imm);
19570 break;
31837be3
YK
19571 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19572 if (ctx->insn_flags & ISA_MIPS32R6) {
19573 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19574 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19575 } else {
19576 /* OPC_DADDI */
19577 check_insn(ctx, ISA_MIPS3);
19578 check_mips_64(ctx);
19579 gen_arith_imm(ctx, op, rt, rs, imm);
19580 }
19581 break;
324d9e32 19582 case OPC_DADDIU:
d75c135e 19583 check_insn(ctx, ISA_MIPS3);
e189e748 19584 check_mips_64(ctx);
d75c135e 19585 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19586 break;
31837be3
YK
19587#else
19588 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19589 if (ctx->insn_flags & ISA_MIPS32R6) {
19590 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19591 } else {
19592 MIPS_INVAL("major opcode");
9c708c7f 19593 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19594 }
19595 break;
6af0bf9c 19596#endif
d4ea6acd
LA
19597 case OPC_DAUI: /* OPC_JALX */
19598 if (ctx->insn_flags & ISA_MIPS32R6) {
19599#if defined(TARGET_MIPS64)
19600 /* OPC_DAUI */
19601 check_mips_64(ctx);
db77d852
LA
19602 if (rs == 0) {
19603 generate_exception(ctx, EXCP_RI);
19604 } else if (rt != 0) {
d4ea6acd
LA
19605 TCGv t0 = tcg_temp_new();
19606 gen_load_gpr(t0, rs);
19607 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19608 tcg_temp_free(t0);
19609 }
d4ea6acd 19610#else
9c708c7f 19611 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
19612 MIPS_INVAL("major opcode");
19613#endif
19614 } else {
19615 /* OPC_JALX */
19616 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19617 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19618 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19619 }
364d4831 19620 break;
4c789546 19621 case OPC_MSA: /* OPC_MDMX */
7a387fff 19622 /* MDMX: Not implemented. */
4c789546 19623 gen_msa(env, ctx);
d4ea6acd
LA
19624 break;
19625 case OPC_PCREL:
19626 check_insn(ctx, ISA_MIPS32R6);
ab39ee45 19627 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
d4ea6acd 19628 break;
6af0bf9c 19629 default: /* Invalid */
923617a3 19630 MIPS_INVAL("major opcode");
9c708c7f 19631 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19632 break;
19633 }
6af0bf9c
FB
19634}
19635
4e5e1215 19636void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19637{
4e5e1215 19638 MIPSCPU *cpu = mips_env_get_cpu(env);
ed2803da 19639 CPUState *cs = CPU(cpu);
278d0702 19640 DisasContext ctx;
6af0bf9c 19641 target_ulong pc_start;
fe237291 19642 target_ulong next_page_start;
2e70f6ef
PB
19643 int num_insns;
19644 int max_insns;
c9602061 19645 int insn_bytes;
339cd2a8 19646 int is_slot;
6af0bf9c
FB
19647
19648 pc_start = tb->pc;
fe237291 19649 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 19650 ctx.pc = pc_start;
4ad40f36 19651 ctx.saved_pc = -1;
ed2803da 19652 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19653 ctx.insn_flags = env->insn_flags;
5ab5c041 19654 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19655 ctx.tb = tb;
19656 ctx.bstate = BS_NONE;
c20d594e 19657 ctx.btarget = 0;
e98c0d17 19658 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19659 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19660 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19661 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19662 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
19663 ctx.PAMask = env->PAMask;
19664 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19665 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
4ad40f36 19666 /* Restore delay slot state from the tb context. */
c068688b 19667 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 19668 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
19669 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19670 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
01bc435b 19671 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
fd4a04eb 19672 restore_cpu_state(env, &ctx);
932e71cd 19673#ifdef CONFIG_USER_ONLY
0eaef5aa 19674 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19675#else
0eaef5aa 19676 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19677#endif
be3a8c53
YK
19678 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19679 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
19680 num_insns = 0;
19681 max_insns = tb->cflags & CF_COUNT_MASK;
190ce7fb 19682 if (max_insns == 0) {
2e70f6ef 19683 max_insns = CF_COUNT_MASK;
190ce7fb
RH
19684 }
19685 if (max_insns > TCG_MAX_INSNS) {
19686 max_insns = TCG_MAX_INSNS;
19687 }
19688
d12d51d5 19689 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 19690 gen_tb_start(tb);
faf7aaa9 19691 while (ctx.bstate == BS_NONE) {
c20d594e 19692 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
959082fc 19693 num_insns++;
667b8e29 19694
b933066a
RH
19695 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19696 save_cpu_state(&ctx, 1);
19697 ctx.bstate = BS_BRANCH;
19698 gen_helper_raise_exception_debug(cpu_env);
522a0d4e
RH
19699 /* The address covered by the breakpoint must be included in
19700 [tb->pc, tb->pc + tb->size) in order to for it to be
19701 properly cleared -- thus we increment the PC here so that
19702 the logic setting tb->size below does the right thing. */
b933066a
RH
19703 ctx.pc += 4;
19704 goto done_generating;
19705 }
19706
959082fc 19707 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
2e70f6ef 19708 gen_io_start();
667b8e29 19709 }
c9602061 19710
339cd2a8 19711 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19712 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19713 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19714 insn_bytes = 4;
240ce26a 19715 decode_opc(env, &ctx);
d75c135e 19716 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19717 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19718 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19719 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19720 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19721 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 19722 } else {
9c708c7f 19723 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
19724 break;
19725 }
31837be3 19726
b231c103 19727 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19728 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19729 MIPS_HFLAG_FBNSLOT))) {
19730 /* force to generate branch as there is neither delay nor
19731 forbidden slot */
19732 is_slot = 1;
b231c103 19733 }
65935f07
YK
19734 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19735 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19736 /* Force to generate branch as microMIPS R6 doesn't restrict
19737 branches in the forbidden slot. */
19738 is_slot = 1;
19739 }
b231c103 19740 }
339cd2a8 19741 if (is_slot) {
31837be3 19742 gen_branch(&ctx, insn_bytes);
c9602061
NF
19743 }
19744 ctx.pc += insn_bytes;
19745
7b270ef2
NF
19746 /* Execute a branch and its delay slot as a single instruction.
19747 This is what GDB expects and is consistent with what the
19748 hardware does (e.g. if a delay slot instruction faults, the
19749 reported PC is the PC of the branch). */
ed2803da 19750 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19751 break;
ed2803da 19752 }
4ad40f36 19753
fe237291 19754 if (ctx.pc >= next_page_start) {
6af0bf9c 19755 break;
fe237291 19756 }
4ad40f36 19757
fe700adb 19758 if (tcg_op_buf_full()) {
faf7aaa9 19759 break;
efd7f486 19760 }
faf7aaa9 19761
2e70f6ef
PB
19762 if (num_insns >= max_insns)
19763 break;
1b530a6d
AJ
19764
19765 if (singlestep)
19766 break;
6af0bf9c 19767 }
ed2803da 19768 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19769 gen_io_end();
ed2803da
AF
19770 }
19771 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19772 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
9c708c7f 19773 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 19774 } else {
6958549d 19775 switch (ctx.bstate) {
16c00cb2 19776 case BS_STOP:
df1561e2
TS
19777 gen_goto_tb(&ctx, 0, ctx.pc);
19778 break;
16c00cb2 19779 case BS_NONE:
278d0702 19780 save_cpu_state(&ctx, 0);
16c00cb2
TS
19781 gen_goto_tb(&ctx, 0, ctx.pc);
19782 break;
5a5012ec 19783 case BS_EXCP:
57fec1fe 19784 tcg_gen_exit_tb(0);
16c00cb2 19785 break;
5a5012ec
TS
19786 case BS_BRANCH:
19787 default:
19788 break;
6958549d 19789 }
6af0bf9c 19790 }
4ad40f36 19791done_generating:
806f352d 19792 gen_tb_end(tb, num_insns);
0a7df5da 19793
4e5e1215
RH
19794 tb->size = ctx.pc - pc_start;
19795 tb->icount = num_insns;
19796
6af0bf9c 19797#ifdef DEBUG_DISAS
d12d51d5 19798 LOG_DISAS("\n");
8fec2b8c 19799 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19800 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 19801 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19802 qemu_log("\n");
6af0bf9c
FB
19803 }
19804#endif
6af0bf9c
FB
19805}
19806
7db13fae 19807static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19808 int flags)
6ea83fed
FB
19809{
19810 int i;
5e755519 19811 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19812
2a5612e6
SW
19813#define printfpr(fp) \
19814 do { \
19815 if (is_fpu64) \
19816 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19817 " fd:%13g fs:%13g psu: %13g\n", \
19818 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19819 (double)(fp)->fd, \
19820 (double)(fp)->fs[FP_ENDIAN_IDX], \
19821 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19822 else { \
19823 fpr_t tmp; \
19824 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19825 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19826 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19827 " fd:%13g fs:%13g psu:%13g\n", \
19828 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19829 (double)tmp.fd, \
19830 (double)tmp.fs[FP_ENDIAN_IDX], \
19831 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19832 } \
6ea83fed
FB
19833 } while(0)
19834
5a5012ec 19835
9a78eead
SW
19836 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19837 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19838 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19839 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19840 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19841 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19842 }
19843
19844#undef printfpr
19845}
19846
878096ee
AF
19847void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19848 int flags)
6af0bf9c 19849{
878096ee
AF
19850 MIPSCPU *cpu = MIPS_CPU(cs);
19851 CPUMIPSState *env = &cpu->env;
6af0bf9c 19852 int i;
3b46e624 19853
a7200c9f
SW
19854 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19855 " LO=0x" TARGET_FMT_lx " ds %04x "
19856 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19857 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19858 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19859 for (i = 0; i < 32; i++) {
19860 if ((i & 3) == 0)
19861 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19862 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19863 if ((i & 3) == 3)
19864 cpu_fprintf(f, "\n");
19865 }
568b600d 19866
3594c774 19867 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19868 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
19869 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19870 PRIx64 "\n",
5499b6ff 19871 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19872 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19873 env->CP0_Config2, env->CP0_Config3);
19874 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19875 env->CP0_Config4, env->CP0_Config5);
5e755519 19876 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19877 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
19878}
19879
78ce64f4 19880void mips_tcg_init(void)
39454628 19881{
f01be154 19882 int i;
39454628
TS
19883 static int inited;
19884
19885 /* Initialize various static tables. */
19886 if (inited)
6958549d 19887 return;
39454628 19888
a7812ae4 19889 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
e1ccc054 19890
f2c94b92 19891 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19892 for (i = 1; i < 32; i++)
e1ccc054 19893 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 19894 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19895 regnames[i]);
d73ee8a2 19896
863f264d
YK
19897 for (i = 0; i < 32; i++) {
19898 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19899 msa_wr_d[i * 2] =
e1ccc054 19900 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
19901 /* The scalar floating-point unit (FPU) registers are mapped on
19902 * the MSA vector registers. */
19903 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19904 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19905 msa_wr_d[i * 2 + 1] =
e1ccc054 19906 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
19907 }
19908
e1ccc054 19909 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 19910 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19911 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 19912 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 19913 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19914 regnames_HI[i]);
e1ccc054 19915 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 19916 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19917 regnames_LO[i]);
4b2eb8d2 19918 }
e1ccc054 19919 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 19920 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19921 "DSPControl");
e1ccc054 19922 bcond = tcg_global_mem_new(cpu_env,
7db13fae 19923 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 19924 btarget = tcg_global_mem_new(cpu_env,
7db13fae 19925 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 19926 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 19927 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19928
e1ccc054 19929 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 19930 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 19931 "fcr0");
e1ccc054 19932 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 19933 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19934 "fcr31");
39454628
TS
19935
19936 inited = 1;
19937}
19938
aaed909a
FB
19939#include "translate_init.c"
19940
30bf942d 19941MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19942{
0f71a709 19943 MIPSCPU *cpu;
6af0bf9c 19944 CPUMIPSState *env;
c227f099 19945 const mips_def_t *def;
6af0bf9c 19946
aaed909a
FB
19947 def = cpu_mips_find_by_name(cpu_model);
19948 if (!def)
19949 return NULL;
0f71a709
AF
19950 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19951 env = &cpu->env;
aaed909a
FB
19952 env->cpu_model = def;
19953
51cc2e78
BS
19954#ifndef CONFIG_USER_ONLY
19955 mmu_init(env, def);
19956#endif
19957 fpu_init(env, def);
19958 mvp_init(env, def);
c1caf1d9
AF
19959
19960 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19961
30bf942d 19962 return cpu;
6ae81775
TS
19963}
19964
1bba0dc9 19965void cpu_state_reset(CPUMIPSState *env)
6ae81775 19966{
55e5c285
AF
19967 MIPSCPU *cpu = mips_env_get_cpu(env);
19968 CPUState *cs = CPU(cpu);
6ae81775 19969
51cc2e78
BS
19970 /* Reset registers to their default values */
19971 env->CP0_PRid = env->cpu_model->CP0_PRid;
19972 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19973#ifdef TARGET_WORDS_BIGENDIAN
19974 env->CP0_Config0 |= (1 << CP0C0_BE);
19975#endif
19976 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19977 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19978 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19979 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19980 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19981 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19982 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19983 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19984 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19985 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19986 << env->cpu_model->CP0_LLAddr_shift;
19987 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19988 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19989 env->CCRes = env->cpu_model->CCRes;
19990 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19991 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19992 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19993 env->current_tc = 0;
19994 env->SEGBITS = env->cpu_model->SEGBITS;
19995 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19996#if defined(TARGET_MIPS64)
19997 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19998 env->SEGMask |= 3ULL << 62;
19999 }
20000#endif
20001 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20002 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20003 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20004 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20005 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20006 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20007 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20008 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20009 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20010 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20011 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20012 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20013 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 20014 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
ba5c79f2 20015 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20016 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20017 env->insn_flags = env->cpu_model->insn_flags;
20018
0eaef5aa 20019#if defined(CONFIG_USER_ONLY)
03e6e501 20020 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20021# ifdef TARGET_MIPS64
20022 /* Enable 64-bit register mode. */
20023 env->CP0_Status |= (1 << CP0St_PX);
20024# endif
20025# ifdef TARGET_ABI_MIPSN64
20026 /* Enable 64-bit address mode. */
20027 env->CP0_Status |= (1 << CP0St_UX);
20028# endif
94159135
MI
20029 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20030 hardware registers. */
20031 env->CP0_HWREna |= 0x0000000F;
91a75935 20032 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20033 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20034 }
6f0af304
PJ
20035 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20036 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20037 }
4d66261f
PJ
20038# if defined(TARGET_MIPS64)
20039 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20040 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20041 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20042 env->CP0_Status |= (1 << CP0St_FR);
20043 }
4d66261f 20044# endif
932e71cd
AJ
20045#else
20046 if (env->hflags & MIPS_HFLAG_BMASK) {
20047 /* If the exception was raised from a delay slot,
20048 come back to the jump. */
c3577479
MR
20049 env->CP0_ErrorEPC = (env->active_tc.PC
20050 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20051 } else {
932e71cd
AJ
20052 env->CP0_ErrorEPC = env->active_tc.PC;
20053 }
20054 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
20055 env->CP0_Random = env->tlb->nb_tlb - 1;
20056 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20057 env->CP0_Wired = 0;
01bc435b 20058 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7
JH
20059 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20060 if (kvm_enabled()) {
20061 env->CP0_EBase |= 0x40000000;
20062 } else {
20063 env->CP0_EBase |= 0x80000000;
20064 }
932e71cd
AJ
20065 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20066 /* vectored interrupts not implemented, timer on int 7,
20067 no performance counters. */
20068 env->CP0_IntCtl = 0xe0000000;
20069 {
20070 int i;
20071
20072 for (i = 0; i < 7; i++) {
20073 env->CP0_WatchLo[i] = 0;
20074 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20075 }
932e71cd
AJ
20076 env->CP0_WatchLo[7] = 0;
20077 env->CP0_WatchHi[7] = 0;
fd88b6ab 20078 }
932e71cd
AJ
20079 /* Count register increments in debug mode, EJTAG version 1 */
20080 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20081
4b69c7e2
JH
20082 cpu_mips_store_count(env, 1);
20083
9e56e756
EI
20084 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20085 int i;
20086
20087 /* Only TC0 on VPE 0 starts as active. */
20088 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20089 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20090 env->tcs[i].CP0_TCHalt = 1;
20091 }
20092 env->active_tc.CP0_TCHalt = 1;
259186a7 20093 cs->halted = 1;
9e56e756 20094
55e5c285 20095 if (cs->cpu_index == 0) {
9e56e756
EI
20096 /* VPE0 starts up enabled. */
20097 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20098 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20099
20100 /* TC0 starts up unhalted. */
259186a7 20101 cs->halted = 0;
9e56e756
EI
20102 env->active_tc.CP0_TCHalt = 0;
20103 env->tcs[0].CP0_TCHalt = 0;
20104 /* With thread 0 active. */
20105 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20106 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20107 }
20108 }
51cc2e78 20109#endif
ddc584bd
LA
20110 if ((env->insn_flags & ISA_MIPS32R6) &&
20111 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20112 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20113 env->CP0_Status |= (1 << CP0St_FR);
20114 }
20115
863f264d
YK
20116 /* MSA */
20117 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20118 msa_reset(env);
20119 }
20120
03e6e501 20121 compute_hflags(env);
bb962386
MR
20122 restore_rounding_mode(env);
20123 restore_flush_mode(env);
e117f526 20124 restore_pamask(env);
27103424 20125 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20126
20127 if (semihosting_get_argc()) {
20128 /* UHI interface can be used to obtain argc and argv */
20129 env->active_tc.gpr[4] = -1;
20130 }
6af0bf9c 20131}
d2856f1a 20132
bad729e2
RH
20133void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20134 target_ulong *data)
d2856f1a 20135{
bad729e2 20136 env->active_tc.PC = data[0];
d2856f1a 20137 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20138 env->hflags |= data[1];
4636401d
AJ
20139 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20140 case MIPS_HFLAG_BR:
20141 break;
20142 case MIPS_HFLAG_BC:
20143 case MIPS_HFLAG_BL:
20144 case MIPS_HFLAG_B:
bad729e2 20145 env->btarget = data[2];
4636401d
AJ
20146 break;
20147 }
d2856f1a 20148}