]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: microMIPS32 R6 POOL32{I, C} instructions
[mirror_qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
0a2672b7 31#include "sysemu/kvm.h"
3b3c1694 32#include "exec/semihost.h"
a7812ae4 33
a7e30d84
LV
34#include "trace-tcg.h"
35
36
fb7729e2 37#define MIPS_DEBUG_DISAS 0
c570fd16 38//#define MIPS_DEBUG_SIGN_EXTENSIONS
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,
328 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
329
330 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
331 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
332};
333
7a387fff
TS
334/* Special2 opcodes */
335#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
336
e37e863f 337enum {
7a387fff
TS
338 /* Multiply & xxx operations */
339 OPC_MADD = 0x00 | OPC_SPECIAL2,
340 OPC_MADDU = 0x01 | OPC_SPECIAL2,
341 OPC_MUL = 0x02 | OPC_SPECIAL2,
342 OPC_MSUB = 0x04 | OPC_SPECIAL2,
343 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
344 /* Loongson 2F */
345 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
346 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
347 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
348 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
349 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
350 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
351 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
352 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
353 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
354 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
355 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
356 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 357 /* Misc */
7a387fff
TS
358 OPC_CLZ = 0x20 | OPC_SPECIAL2,
359 OPC_CLO = 0x21 | OPC_SPECIAL2,
360 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
361 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 362 /* Special */
7a387fff
TS
363 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
364};
365
366/* Special3 opcodes */
367#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
368
369enum {
370 OPC_EXT = 0x00 | OPC_SPECIAL3,
371 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
372 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
373 OPC_DEXT = 0x03 | OPC_SPECIAL3,
374 OPC_INS = 0x04 | OPC_SPECIAL3,
375 OPC_DINSM = 0x05 | OPC_SPECIAL3,
376 OPC_DINSU = 0x06 | OPC_SPECIAL3,
377 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
378 OPC_FORK = 0x08 | OPC_SPECIAL3,
379 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
380 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
381 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
382 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
383
384 /* Loongson 2E */
385 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
386 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
387 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
388 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
389 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
390 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
391 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
392 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
393 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
394 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
395 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
396 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
397
398 /* MIPS DSP Load */
399 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
400 /* MIPS DSP Arithmetic */
401 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 402 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 403 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 404 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
405 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
406 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
407 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 408 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
409 /* MIPS DSP GPR-Based Shift Sub-class */
410 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 411 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
412 /* MIPS DSP Multiply Sub-class insns */
413 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
414 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
415 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 416 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
417 /* DSP Bit/Manipulation Sub-class */
418 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 419 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 420 /* MIPS DSP Append Sub-class */
26690560 421 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 422 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
423 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
424 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 425 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
426
427 /* R6 */
bf7910c6
LA
428 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
429 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
430 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
431 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
432 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
433 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
434};
435
7a387fff
TS
436/* BSHFL opcodes */
437#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
438
e37e863f 439enum {
15eacb9b
YK
440 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
441 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
442 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
443 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
444 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
445 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
446};
447
7a387fff
TS
448/* DBSHFL opcodes */
449#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
450
e37e863f 451enum {
15eacb9b
YK
452 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
453 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
454 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
455 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
456 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
457};
458
e45a93e2
JL
459/* MIPS DSP REGIMM opcodes */
460enum {
461 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 462 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
463};
464
9b1a1d68
JL
465#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
466/* MIPS DSP Load */
467enum {
468 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
469 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
470 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 471 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
472};
473
461c08df
JL
474#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
475enum {
476 /* MIPS DSP Arithmetic Sub-class */
477 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
491 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
492 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
493 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
494 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
495 /* MIPS DSP Multiply Sub-class insns */
496 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
502};
503
504#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
505#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506enum {
507 /* MIPS DSP Arithmetic Sub-class */
508 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
520 /* MIPS DSP Multiply Sub-class insns */
521 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
525};
526
527#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
528enum {
529 /* MIPS DSP Arithmetic Sub-class */
530 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
543 /* DSP Bit/Manipulation Sub-class */
544 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
549};
550
551#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552enum {
553 /* MIPS DSP Arithmetic Sub-class */
554 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
561 /* DSP Compare-Pick Sub-class */
562 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 577};
a22260ae 578
77c5fa8b
JL
579#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
580enum {
581 /* MIPS DSP GPR-Based Shift Sub-class */
582 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
604};
461c08df 605
a22260ae
JL
606#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
607enum {
608 /* MIPS DSP Multiply Sub-class insns */
609 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
623 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
631};
632
1cb6686c
JL
633#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
634enum {
635 /* DSP Bit/Manipulation Sub-class */
636 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
637};
638
26690560
JL
639#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
640enum {
df6126a7 641 /* MIPS DSP Append Sub-class */
26690560
JL
642 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
643 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
644 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
645};
646
b53371ed
JL
647#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
648enum {
649 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
650 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
662 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
663 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
664 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
665 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
666 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
667};
668
461c08df
JL
669#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670enum {
671 /* MIPS DSP Arithmetic Sub-class */
672 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
689 /* DSP Bit/Manipulation Sub-class */
690 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 696};
461c08df 697
461c08df
JL
698#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
699enum {
a22260ae
JL
700 /* MIPS DSP Multiply Sub-class insns */
701 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
706 /* MIPS DSP Arithmetic Sub-class */
707 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
728};
461c08df 729
461c08df
JL
730#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
731enum {
26690560
JL
732 /* DSP Compare-Pick Sub-class */
733 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
752 /* MIPS DSP Arithmetic Sub-class */
753 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
761};
461c08df 762
26690560
JL
763#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
764enum {
df6126a7 765 /* DSP Append Sub-class */
26690560
JL
766 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
767 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
768 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
769 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
770};
26690560 771
b53371ed
JL
772#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
773enum {
774 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
775 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
776 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
796};
797
1cb6686c
JL
798#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
799enum {
800 /* DSP Bit/Manipulation Sub-class */
801 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
802};
1cb6686c 803
a22260ae
JL
804#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805enum {
806 /* MIPS DSP Multiply Sub-class insns */
807 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
833};
a22260ae 834
77c5fa8b
JL
835#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836enum {
837 /* MIPS DSP GPR-Based Shift Sub-class */
838 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
864};
77c5fa8b 865
7a387fff
TS
866/* Coprocessor 0 (rs field) */
867#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
868
6ea83fed 869enum {
7a387fff
TS
870 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
871 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 872 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
873 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
874 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 875 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 876 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
877 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
878 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 879 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
880 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
881 OPC_C0 = (0x10 << 21) | OPC_CP0,
882 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
883 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 884};
7a387fff
TS
885
886/* MFMC0 opcodes */
b48cfdff 887#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
888
889enum {
ead9360e
TS
890 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
891 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
893 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
894 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
895 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
896};
897
898/* Coprocessor 0 (with rs == C0) */
899#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
900
901enum {
902 OPC_TLBR = 0x01 | OPC_C0,
903 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
904 OPC_TLBINV = 0x03 | OPC_C0,
905 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
906 OPC_TLBWR = 0x06 | OPC_C0,
907 OPC_TLBP = 0x08 | OPC_C0,
908 OPC_RFE = 0x10 | OPC_C0,
909 OPC_ERET = 0x18 | OPC_C0,
910 OPC_DERET = 0x1F | OPC_C0,
911 OPC_WAIT = 0x20 | OPC_C0,
912};
913
914/* Coprocessor 1 (rs field) */
915#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
916
bf4120ad
NF
917/* Values for the fmt field in FP instructions */
918enum {
919 /* 0 - 15 are reserved */
e459440a
AJ
920 FMT_S = 16, /* single fp */
921 FMT_D = 17, /* double fp */
922 FMT_E = 18, /* extended fp */
923 FMT_Q = 19, /* quad fp */
924 FMT_W = 20, /* 32-bit fixed */
925 FMT_L = 21, /* 64-bit fixed */
926 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
927 /* 23 - 31 are reserved */
928};
929
7a387fff
TS
930enum {
931 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
932 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
933 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 934 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
935 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
936 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
937 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 938 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 939 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
940 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
941 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
942 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
943 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
944 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
945 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
946 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
947 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
948 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
949 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
950 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
951 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
952 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
953 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
954 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
955 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
956 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
957 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
958 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
959 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
960 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
961};
962
5a5012ec
TS
963#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
964#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
965
7a387fff
TS
966enum {
967 OPC_BC1F = (0x00 << 16) | OPC_BC1,
968 OPC_BC1T = (0x01 << 16) | OPC_BC1,
969 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
970 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
971};
972
5a5012ec
TS
973enum {
974 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
975 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
976};
977
978enum {
979 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
980 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
981};
7a387fff
TS
982
983#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
984
985enum {
986 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
987 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
988 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
989 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
990 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
991 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
992 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
993 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
994 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
995 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
996 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
997};
998
bd277fa1
RH
999#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1000
1001enum {
1002 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1010
1011 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1019
1020 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1021 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1022 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1023 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1024 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1025 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1026 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1027 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1028
1029 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1030 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1031 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1032 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1034 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1035 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1037
1038 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1039 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1041 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1042 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1044
1045 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1048 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1051
1052 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1055 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1058
1059 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1062 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1065
1066 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1067 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1068 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1069 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1070 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1071 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1072
1073 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1074 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1076 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1077 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1079
1080 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1081 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1082 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1083 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1084 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1085 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1086
1087 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1088 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1089 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1090 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1091 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1092 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1093};
1094
1095
e0c84da7
TS
1096#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1097
1098enum {
1099 OPC_LWXC1 = 0x00 | OPC_CP3,
1100 OPC_LDXC1 = 0x01 | OPC_CP3,
1101 OPC_LUXC1 = 0x05 | OPC_CP3,
1102 OPC_SWXC1 = 0x08 | OPC_CP3,
1103 OPC_SDXC1 = 0x09 | OPC_CP3,
1104 OPC_SUXC1 = 0x0D | OPC_CP3,
1105 OPC_PREFX = 0x0F | OPC_CP3,
1106 OPC_ALNV_PS = 0x1E | OPC_CP3,
1107 OPC_MADD_S = 0x20 | OPC_CP3,
1108 OPC_MADD_D = 0x21 | OPC_CP3,
1109 OPC_MADD_PS = 0x26 | OPC_CP3,
1110 OPC_MSUB_S = 0x28 | OPC_CP3,
1111 OPC_MSUB_D = 0x29 | OPC_CP3,
1112 OPC_MSUB_PS = 0x2E | OPC_CP3,
1113 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1114 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1115 OPC_NMADD_PS= 0x36 | OPC_CP3,
1116 OPC_NMSUB_S = 0x38 | OPC_CP3,
1117 OPC_NMSUB_D = 0x39 | OPC_CP3,
1118 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1119};
1120
239dfebe
YK
1121/* MSA Opcodes */
1122#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1123enum {
1124 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1125 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1126 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1127 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1128 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1129 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1130 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1131 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1132 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1133 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1134 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1135 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1136 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1137 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1138 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1139 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1140 OPC_MSA_ELM = 0x19 | OPC_MSA,
1141 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1142 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1143 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1144 OPC_MSA_VEC = 0x1E | OPC_MSA,
1145
1146 /* MI10 instruction */
1147 OPC_LD_B = (0x20) | OPC_MSA,
1148 OPC_LD_H = (0x21) | OPC_MSA,
1149 OPC_LD_W = (0x22) | OPC_MSA,
1150 OPC_LD_D = (0x23) | OPC_MSA,
1151 OPC_ST_B = (0x24) | OPC_MSA,
1152 OPC_ST_H = (0x25) | OPC_MSA,
1153 OPC_ST_W = (0x26) | OPC_MSA,
1154 OPC_ST_D = (0x27) | OPC_MSA,
1155};
1156
1157enum {
1158 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1159 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1160 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1161 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1162 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1163 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1164 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1165 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1166 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1167 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1168 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1169 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1170 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1171
1172 /* I8 instruction */
1173 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1174 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1175 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1176 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1177 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1179 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1180 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1181 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1182 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1183
1184 /* VEC/2R/2RF instruction */
1185 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1186 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1187 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1188 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1189 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1190 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1191 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1192
1193 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1194 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1195
1196 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1197 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1198 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1199 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1200 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1201
1202 /* 2RF instruction df(bit 16) = _w, _d */
1203 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1204 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1205 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1206 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1207 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1208 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1209 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1210 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1211 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1212 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1213 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1214 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1215 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1216 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1217 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1218 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1219
1220 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1221 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1222 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1223 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1224 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1225 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1226 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1227 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1228 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1229 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1230 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1231 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1232 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1233 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1234 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1235 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1236 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1237 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1238 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1239 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1240 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1241 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1242 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1243 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1244 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1245 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1246 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1247 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1248 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1249 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1250 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1251 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1252 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1253 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1254 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1255 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1256 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1257 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1258 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1259 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1260 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1261 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1262 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1263 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1264 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1265 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1266 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1267 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1268 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1269 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1270 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1271 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1272 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1273 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1274 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1275 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1276 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1277 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1278 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1279 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1280 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1281 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1282 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1283 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1284
1285 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1286 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1287 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1288 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1289 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1290 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1292 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1295
1296 /* 3RF instruction _df(bit 21) = _w, _d */
1297 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1298 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1299 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1300 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1301 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1302 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1307 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1310 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1312 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1313 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1315 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1316 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1317 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1318 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1319 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1320 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1321 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1322 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1323 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1324 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1326 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1327 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1328 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1329 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1332 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1335 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1336 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1337 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1338
1339 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1340 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1341 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1342 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1343 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1344 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1345 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1346 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1347 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1348 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1349 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1350 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1351 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1352};
1353
39454628 1354/* global register indices */
a7812ae4
PB
1355static TCGv_ptr cpu_env;
1356static TCGv cpu_gpr[32], cpu_PC;
340fff72 1357static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1358static TCGv cpu_dspctrl, btarget, bcond;
1359static TCGv_i32 hflags;
a7812ae4 1360static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1361static TCGv_i64 fpu_f64[32];
863f264d 1362static TCGv_i64 msa_wr_d[64];
aa0bf00b 1363
1a7ff922 1364static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1365static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 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;
8e9ade68
TS
1434} DisasContext;
1435
1436enum {
1437 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1438 * exception condition */
8e9ade68
TS
1439 BS_STOP = 1, /* We want to stop translation for any reason */
1440 BS_BRANCH = 2, /* We reached a branch condition */
1441 BS_EXCP = 3, /* We reached an exception condition */
1442};
1443
d73ee8a2
RH
1444static const char * const regnames[] = {
1445 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1446 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1447 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1448 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1449};
6af0bf9c 1450
d73ee8a2
RH
1451static const char * const regnames_HI[] = {
1452 "HI0", "HI1", "HI2", "HI3",
1453};
4b2eb8d2 1454
d73ee8a2
RH
1455static const char * const regnames_LO[] = {
1456 "LO0", "LO1", "LO2", "LO3",
1457};
4b2eb8d2 1458
d73ee8a2
RH
1459static const char * const fregnames[] = {
1460 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1461 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1462 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1463 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1464};
958fb4a9 1465
863f264d
YK
1466static const char * const msaregnames[] = {
1467 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1468 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1469 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1470 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1471 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1472 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1473 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1474 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1475 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1476 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1477 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1478 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1479 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1480 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1481 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1482 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1483};
1484
fb7729e2
RH
1485#define MIPS_DEBUG(fmt, ...) \
1486 do { \
1487 if (MIPS_DEBUG_DISAS) { \
1488 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1489 TARGET_FMT_lx ": %08x " fmt "\n", \
1490 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1491 } \
1492 } while (0)
1493
1494#define LOG_DISAS(...) \
1495 do { \
1496 if (MIPS_DEBUG_DISAS) { \
1497 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1498 } \
1499 } while (0)
958fb4a9 1500
8e9ade68 1501#define MIPS_INVAL(op) \
8e9ade68 1502 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1503 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1504
8e9ade68
TS
1505/* General purpose registers moves. */
1506static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1507{
8e9ade68
TS
1508 if (reg == 0)
1509 tcg_gen_movi_tl(t, 0);
1510 else
4b2eb8d2 1511 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1512}
1513
8e9ade68 1514static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1515{
8e9ade68 1516 if (reg != 0)
4b2eb8d2 1517 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1518}
1519
8e9ade68 1520/* Moves to/from shadow registers. */
be24bb4f 1521static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1522{
d9bea114 1523 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1524
1525 if (from == 0)
d9bea114 1526 tcg_gen_movi_tl(t0, 0);
8e9ade68 1527 else {
d9bea114 1528 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1529 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1530
7db13fae 1531 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1532 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1533 tcg_gen_andi_i32(t2, t2, 0xf);
1534 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1535 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1536 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1537
d9bea114 1538 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1539 tcg_temp_free_ptr(addr);
d9bea114 1540 tcg_temp_free_i32(t2);
8e9ade68 1541 }
d9bea114
AJ
1542 gen_store_gpr(t0, to);
1543 tcg_temp_free(t0);
aaa9128a
TS
1544}
1545
be24bb4f 1546static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1547{
be24bb4f 1548 if (to != 0) {
d9bea114
AJ
1549 TCGv t0 = tcg_temp_new();
1550 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1551 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1552
d9bea114 1553 gen_load_gpr(t0, from);
7db13fae 1554 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1555 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1556 tcg_gen_andi_i32(t2, t2, 0xf);
1557 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1558 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1559 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1560
d9bea114 1561 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1562 tcg_temp_free_ptr(addr);
d9bea114
AJ
1563 tcg_temp_free_i32(t2);
1564 tcg_temp_free(t0);
8e9ade68 1565 }
aaa9128a
TS
1566}
1567
eab9944c
LA
1568/* Tests */
1569static inline void gen_save_pc(target_ulong pc)
1570{
1571 tcg_gen_movi_tl(cpu_PC, pc);
1572}
1573
1574static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1575{
1576 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1577 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1578 gen_save_pc(ctx->pc);
1579 ctx->saved_pc = ctx->pc;
1580 }
1581 if (ctx->hflags != ctx->saved_hflags) {
1582 tcg_gen_movi_i32(hflags, ctx->hflags);
1583 ctx->saved_hflags = ctx->hflags;
1584 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1585 case MIPS_HFLAG_BR:
1586 break;
1587 case MIPS_HFLAG_BC:
1588 case MIPS_HFLAG_BL:
1589 case MIPS_HFLAG_B:
1590 tcg_gen_movi_tl(btarget, ctx->btarget);
1591 break;
1592 }
1593 }
1594}
1595
1596static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1597{
1598 ctx->saved_hflags = ctx->hflags;
1599 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1600 case MIPS_HFLAG_BR:
1601 break;
1602 case MIPS_HFLAG_BC:
1603 case MIPS_HFLAG_BL:
1604 case MIPS_HFLAG_B:
1605 ctx->btarget = env->btarget;
1606 break;
1607 }
1608}
1609
1610static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1611{
1612 TCGv_i32 texcp = tcg_const_i32(excp);
1613 TCGv_i32 terr = tcg_const_i32(err);
1614 save_cpu_state(ctx, 1);
1615 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1616 tcg_temp_free_i32(terr);
1617 tcg_temp_free_i32(texcp);
1618}
1619
1620static inline void generate_exception(DisasContext *ctx, int excp)
1621{
1622 save_cpu_state(ctx, 1);
1623 gen_helper_0e0i(raise_exception, excp);
1624}
1625
aaa9128a 1626/* Floating point register moves. */
7c979afd 1627static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1628{
7c979afd
LA
1629 if (ctx->hflags & MIPS_HFLAG_FRE) {
1630 generate_exception(ctx, EXCP_RI);
1631 }
d73ee8a2 1632 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1633}
1634
7c979afd 1635static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1636{
7c979afd
LA
1637 TCGv_i64 t64;
1638 if (ctx->hflags & MIPS_HFLAG_FRE) {
1639 generate_exception(ctx, EXCP_RI);
1640 }
1641 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1642 tcg_gen_extu_i32_i64(t64, t);
1643 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1644 tcg_temp_free_i64(t64);
6d066274
AJ
1645}
1646
7f6613ce 1647static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1648{
7f6613ce
PJ
1649 if (ctx->hflags & MIPS_HFLAG_F64) {
1650 TCGv_i64 t64 = tcg_temp_new_i64();
1651 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1652 tcg_gen_trunc_i64_i32(t, t64);
1653 tcg_temp_free_i64(t64);
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
1f1b4c00
YK
1728static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1729{
1730#if defined(TARGET_MIPS64)
1731 tcg_gen_ext32s_tl(ret, arg);
1732#else
1733 tcg_gen_trunc_i64_tl(ret, arg);
1734#endif
1735}
1736
356265ae 1737static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1738{
fe253235 1739 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1740 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1741}
1742
356265ae 1743static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1744{
fe253235 1745 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1746 generate_exception_err(ctx, EXCP_CpU, 1);
1747}
1748
b8aa4598
TS
1749/* Verify that the processor is running with COP1X instructions enabled.
1750 This is associated with the nabla symbol in the MIPS32 and MIPS64
1751 opcode tables. */
1752
356265ae 1753static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1754{
1755 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1756 generate_exception(ctx, EXCP_RI);
1757}
1758
1759/* Verify that the processor is running with 64-bit floating-point
1760 operations enabled. */
1761
356265ae 1762static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1763{
b8aa4598 1764 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1765 generate_exception(ctx, EXCP_RI);
1766}
1767
1768/*
1769 * Verify if floating point register is valid; an operation is not defined
1770 * if bit 0 of any register specification is set and the FR bit in the
1771 * Status register equals zero, since the register numbers specify an
1772 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1773 * in the Status register equals one, both even and odd register numbers
1774 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1775 *
1776 * Multiple 64 bit wide registers can be checked by calling
1777 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1778 */
356265ae 1779static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1780{
fe253235 1781 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1782 generate_exception(ctx, EXCP_RI);
1783}
1784
853c3240
JL
1785/* Verify that the processor is running with DSP instructions enabled.
1786 This is enabled by CP0 Status register MX(24) bit.
1787 */
1788
1789static inline void check_dsp(DisasContext *ctx)
1790{
1791 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1792 if (ctx->insn_flags & ASE_DSP) {
1793 generate_exception(ctx, EXCP_DSPDIS);
1794 } else {
1795 generate_exception(ctx, EXCP_RI);
1796 }
853c3240
JL
1797 }
1798}
1799
1800static inline void check_dspr2(DisasContext *ctx)
1801{
1802 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1803 if (ctx->insn_flags & ASE_DSP) {
1804 generate_exception(ctx, EXCP_DSPDIS);
1805 } else {
1806 generate_exception(ctx, EXCP_RI);
1807 }
853c3240
JL
1808 }
1809}
1810
3a95e3a7 1811/* This code generates a "reserved instruction" exception if the
e189e748 1812 CPU does not support the instruction set corresponding to flags. */
d75c135e 1813static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1814{
d75c135e 1815 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1816 generate_exception(ctx, EXCP_RI);
d75c135e 1817 }
3a95e3a7
TS
1818}
1819
fecd2646
LA
1820/* This code generates a "reserved instruction" exception if the
1821 CPU has corresponding flag set which indicates that the instruction
1822 has been removed. */
1823static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1824{
1825 if (unlikely(ctx->insn_flags & flags)) {
1826 generate_exception(ctx, EXCP_RI);
1827 }
1828}
1829
e29c9628
YK
1830/* This code generates a "reserved instruction" exception if the
1831 CPU does not support 64-bit paired-single (PS) floating point data type */
1832static inline void check_ps(DisasContext *ctx)
1833{
1834 if (unlikely(!ctx->ps)) {
1835 generate_exception(ctx, EXCP_RI);
1836 }
1837 check_cp1_64bitmode(ctx);
1838}
1839
c7986fd6 1840#ifdef TARGET_MIPS64
e189e748
TS
1841/* This code generates a "reserved instruction" exception if 64-bit
1842 instructions are not enabled. */
356265ae 1843static inline void check_mips_64(DisasContext *ctx)
e189e748 1844{
fe253235 1845 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1846 generate_exception(ctx, EXCP_RI);
1847}
c7986fd6 1848#endif
e189e748 1849
5204ea79
LA
1850#ifndef CONFIG_USER_ONLY
1851static inline void check_mvh(DisasContext *ctx)
1852{
1853 if (unlikely(!ctx->mvh)) {
1854 generate_exception(ctx, EXCP_RI);
1855 }
1856}
1857#endif
1858
8153667c
NF
1859/* Define small wrappers for gen_load_fpr* so that we have a uniform
1860 calling interface for 32 and 64-bit FPRs. No sense in changing
1861 all callers for gen_load_fpr32 when we need the CTX parameter for
1862 this one use. */
7c979afd 1863#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1864#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1865#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1866static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1867 int ft, int fs, int cc) \
1868{ \
1869 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1870 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1871 switch (ifmt) { \
1872 case FMT_PS: \
e29c9628 1873 check_ps(ctx); \
8153667c
NF
1874 break; \
1875 case FMT_D: \
1876 if (abs) { \
1877 check_cop1x(ctx); \
1878 } \
1879 check_cp1_registers(ctx, fs | ft); \
1880 break; \
1881 case FMT_S: \
1882 if (abs) { \
1883 check_cop1x(ctx); \
1884 } \
1885 break; \
1886 } \
1887 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1888 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1889 switch (n) { \
895c2d04
BS
1890 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1891 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1892 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1893 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1894 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1895 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1896 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1897 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1898 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1899 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1900 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1901 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1902 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1903 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1904 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1905 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1906 default: abort(); \
1907 } \
1908 tcg_temp_free_i##bits (fp0); \
1909 tcg_temp_free_i##bits (fp1); \
1910}
1911
1912FOP_CONDS(, 0, d, FMT_D, 64)
1913FOP_CONDS(abs, 1, d, FMT_D, 64)
1914FOP_CONDS(, 0, s, FMT_S, 32)
1915FOP_CONDS(abs, 1, s, FMT_S, 32)
1916FOP_CONDS(, 0, ps, FMT_PS, 64)
1917FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1918#undef FOP_CONDS
3f493883
YK
1919
1920#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1921static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1922 int ft, int fs, int fd) \
1923{ \
1924 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1925 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1926 if (ifmt == FMT_D) { \
3f493883 1927 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1928 } \
1929 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1930 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1931 switch (n) { \
1932 case 0: \
1933 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1934 break; \
1935 case 1: \
1936 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1937 break; \
1938 case 2: \
1939 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1940 break; \
1941 case 3: \
1942 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1943 break; \
1944 case 4: \
1945 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 5: \
1948 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 6: \
1951 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 7: \
1954 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 8: \
1957 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 case 9: \
1960 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1961 break; \
1962 case 10: \
1963 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1964 break; \
1965 case 11: \
1966 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1967 break; \
1968 case 12: \
1969 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1970 break; \
1971 case 13: \
1972 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1973 break; \
1974 case 14: \
1975 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1976 break; \
1977 case 15: \
1978 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1979 break; \
1980 case 17: \
1981 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1982 break; \
1983 case 18: \
1984 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1985 break; \
1986 case 19: \
1987 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1988 break; \
1989 case 25: \
1990 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1991 break; \
1992 case 26: \
1993 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1994 break; \
1995 case 27: \
1996 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1997 break; \
1998 default: \
1999 abort(); \
2000 } \
2001 STORE; \
2002 tcg_temp_free_i ## bits (fp0); \
2003 tcg_temp_free_i ## bits (fp1); \
2004}
2005
2006FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2007FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2008#undef FOP_CONDNS
8153667c
NF
2009#undef gen_ldcmp_fpr32
2010#undef gen_ldcmp_fpr64
2011
958fb4a9 2012/* load/store instructions. */
e7139c44 2013#ifdef CONFIG_USER_ONLY
d9bea114 2014#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2015static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
2016{ \
2017 TCGv t0 = tcg_temp_new(); \
2018 tcg_gen_mov_tl(t0, arg1); \
2019 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2020 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2021 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2022 tcg_temp_free(t0); \
aaa9128a 2023}
e7139c44
AJ
2024#else
2025#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 2026static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 2027{ \
895c2d04 2028 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
2029}
2030#endif
aaa9128a
TS
2031OP_LD_ATOMIC(ll,ld32s);
2032#if defined(TARGET_MIPS64)
2033OP_LD_ATOMIC(lld,ld64);
2034#endif
2035#undef OP_LD_ATOMIC
2036
590bc601
PB
2037#ifdef CONFIG_USER_ONLY
2038#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2039static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2040{ \
2041 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2042 TCGLabel *l1 = gen_new_label(); \
2043 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2044 \
2045 tcg_gen_andi_tl(t0, arg2, almask); \
2046 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2047 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2048 generate_exception(ctx, EXCP_AdES); \
2049 gen_set_label(l1); \
7db13fae 2050 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2051 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2052 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2053 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2054 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2055 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2056 gen_set_label(l2); \
2057 tcg_gen_movi_tl(t0, 0); \
2058 gen_store_gpr(t0, rt); \
2059 tcg_temp_free(t0); \
2060}
2061#else
2062#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2063static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2064{ \
2065 TCGv t0 = tcg_temp_new(); \
895c2d04 2066 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2067 gen_store_gpr(t0, rt); \
590bc601
PB
2068 tcg_temp_free(t0); \
2069}
2070#endif
590bc601 2071OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2072#if defined(TARGET_MIPS64)
590bc601 2073OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2074#endif
2075#undef OP_ST_ATOMIC
2076
662d7485
NF
2077static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2078 int base, int16_t offset)
2079{
2080 if (base == 0) {
2081 tcg_gen_movi_tl(addr, offset);
2082 } else if (offset == 0) {
2083 gen_load_gpr(addr, base);
2084 } else {
2085 tcg_gen_movi_tl(addr, offset);
2086 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2087 }
2088}
2089
364d4831
NF
2090static target_ulong pc_relative_pc (DisasContext *ctx)
2091{
2092 target_ulong pc = ctx->pc;
2093
2094 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2095 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2096
2097 pc -= branch_bytes;
2098 }
2099
2100 pc &= ~(target_ulong)3;
2101 return pc;
2102}
2103
5c13fdfd 2104/* Load */
d75c135e
AJ
2105static void gen_ld(DisasContext *ctx, uint32_t opc,
2106 int rt, int base, int16_t offset)
6af0bf9c 2107{
5c13fdfd 2108 const char *opn = "ld";
fc40787a 2109 TCGv t0, t1, t2;
afa88c3a 2110
d75c135e 2111 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2112 /* Loongson CPU uses a load to zero register for prefetch.
2113 We emulate it as a NOP. On other CPU we must perform the
2114 actual memory access. */
2115 MIPS_DEBUG("NOP");
2116 return;
2117 }
6af0bf9c 2118
afa88c3a 2119 t0 = tcg_temp_new();
662d7485 2120 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2121
6af0bf9c 2122 switch (opc) {
d26bc211 2123#if defined(TARGET_MIPS64)
6e473128 2124 case OPC_LWU:
be3a8c53
YK
2125 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2126 ctx->default_tcg_memop_mask);
78723684 2127 gen_store_gpr(t0, rt);
6e473128
TS
2128 opn = "lwu";
2129 break;
6af0bf9c 2130 case OPC_LD:
be3a8c53
YK
2131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2132 ctx->default_tcg_memop_mask);
78723684 2133 gen_store_gpr(t0, rt);
6af0bf9c
FB
2134 opn = "ld";
2135 break;
7a387fff 2136 case OPC_LLD:
bf7910c6 2137 case R6_OPC_LLD:
b835e919 2138 save_cpu_state(ctx, 1);
5c13fdfd 2139 op_ld_lld(t0, t0, ctx);
78723684 2140 gen_store_gpr(t0, rt);
7a387fff
TS
2141 opn = "lld";
2142 break;
6af0bf9c 2143 case OPC_LDL:
3cee3050 2144 t1 = tcg_temp_new();
fc40787a
AJ
2145 tcg_gen_andi_tl(t1, t0, 7);
2146#ifndef TARGET_WORDS_BIGENDIAN
2147 tcg_gen_xori_tl(t1, t1, 7);
2148#endif
2149 tcg_gen_shli_tl(t1, t1, 3);
2150 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2151 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2152 tcg_gen_shl_tl(t0, t0, t1);
2153 tcg_gen_xori_tl(t1, t1, 63);
2154 t2 = tcg_const_tl(0x7fffffffffffffffull);
2155 tcg_gen_shr_tl(t2, t2, t1);
78723684 2156 gen_load_gpr(t1, rt);
fc40787a
AJ
2157 tcg_gen_and_tl(t1, t1, t2);
2158 tcg_temp_free(t2);
2159 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2160 tcg_temp_free(t1);
fc40787a 2161 gen_store_gpr(t0, rt);
6af0bf9c
FB
2162 opn = "ldl";
2163 break;
6af0bf9c 2164 case OPC_LDR:
3cee3050 2165 t1 = tcg_temp_new();
fc40787a
AJ
2166 tcg_gen_andi_tl(t1, t0, 7);
2167#ifdef TARGET_WORDS_BIGENDIAN
2168 tcg_gen_xori_tl(t1, t1, 7);
2169#endif
2170 tcg_gen_shli_tl(t1, t1, 3);
2171 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2172 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2173 tcg_gen_shr_tl(t0, t0, t1);
2174 tcg_gen_xori_tl(t1, t1, 63);
2175 t2 = tcg_const_tl(0xfffffffffffffffeull);
2176 tcg_gen_shl_tl(t2, t2, t1);
78723684 2177 gen_load_gpr(t1, rt);
fc40787a
AJ
2178 tcg_gen_and_tl(t1, t1, t2);
2179 tcg_temp_free(t2);
2180 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2181 tcg_temp_free(t1);
fc40787a 2182 gen_store_gpr(t0, rt);
6af0bf9c
FB
2183 opn = "ldr";
2184 break;
364d4831 2185 case OPC_LDPC:
3cee3050 2186 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2187 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2188 tcg_temp_free(t1);
5f68f5ae 2189 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2190 gen_store_gpr(t0, rt);
5c13fdfd 2191 opn = "ldpc";
364d4831 2192 break;
6af0bf9c 2193#endif
364d4831 2194 case OPC_LWPC:
3cee3050 2195 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2196 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2197 tcg_temp_free(t1);
5f68f5ae 2198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2199 gen_store_gpr(t0, rt);
5c13fdfd 2200 opn = "lwpc";
364d4831 2201 break;
6af0bf9c 2202 case OPC_LW:
be3a8c53
YK
2203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2204 ctx->default_tcg_memop_mask);
78723684 2205 gen_store_gpr(t0, rt);
6af0bf9c
FB
2206 opn = "lw";
2207 break;
6af0bf9c 2208 case OPC_LH:
be3a8c53
YK
2209 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2210 ctx->default_tcg_memop_mask);
78723684 2211 gen_store_gpr(t0, rt);
6af0bf9c
FB
2212 opn = "lh";
2213 break;
6af0bf9c 2214 case OPC_LHU:
be3a8c53
YK
2215 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2216 ctx->default_tcg_memop_mask);
78723684 2217 gen_store_gpr(t0, rt);
6af0bf9c
FB
2218 opn = "lhu";
2219 break;
2220 case OPC_LB:
5f68f5ae 2221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2222 gen_store_gpr(t0, rt);
6af0bf9c
FB
2223 opn = "lb";
2224 break;
6af0bf9c 2225 case OPC_LBU:
5f68f5ae 2226 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2227 gen_store_gpr(t0, rt);
6af0bf9c
FB
2228 opn = "lbu";
2229 break;
2230 case OPC_LWL:
3cee3050 2231 t1 = tcg_temp_new();
fc40787a
AJ
2232 tcg_gen_andi_tl(t1, t0, 3);
2233#ifndef TARGET_WORDS_BIGENDIAN
2234 tcg_gen_xori_tl(t1, t1, 3);
2235#endif
2236 tcg_gen_shli_tl(t1, t1, 3);
2237 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2238 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2239 tcg_gen_shl_tl(t0, t0, t1);
2240 tcg_gen_xori_tl(t1, t1, 31);
2241 t2 = tcg_const_tl(0x7fffffffull);
2242 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2243 gen_load_gpr(t1, rt);
fc40787a
AJ
2244 tcg_gen_and_tl(t1, t1, t2);
2245 tcg_temp_free(t2);
2246 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2247 tcg_temp_free(t1);
fc40787a
AJ
2248 tcg_gen_ext32s_tl(t0, t0);
2249 gen_store_gpr(t0, rt);
6af0bf9c
FB
2250 opn = "lwl";
2251 break;
6af0bf9c 2252 case OPC_LWR:
3cee3050 2253 t1 = tcg_temp_new();
fc40787a
AJ
2254 tcg_gen_andi_tl(t1, t0, 3);
2255#ifdef TARGET_WORDS_BIGENDIAN
2256 tcg_gen_xori_tl(t1, t1, 3);
2257#endif
2258 tcg_gen_shli_tl(t1, t1, 3);
2259 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2260 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2261 tcg_gen_shr_tl(t0, t0, t1);
2262 tcg_gen_xori_tl(t1, t1, 31);
2263 t2 = tcg_const_tl(0xfffffffeull);
2264 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2265 gen_load_gpr(t1, rt);
fc40787a
AJ
2266 tcg_gen_and_tl(t1, t1, t2);
2267 tcg_temp_free(t2);
2268 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2269 tcg_temp_free(t1);
c728154b 2270 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2271 gen_store_gpr(t0, rt);
6af0bf9c
FB
2272 opn = "lwr";
2273 break;
6af0bf9c 2274 case OPC_LL:
4368b29a 2275 case R6_OPC_LL:
e7139c44 2276 save_cpu_state(ctx, 1);
5c13fdfd 2277 op_ld_ll(t0, t0, ctx);
78723684 2278 gen_store_gpr(t0, rt);
6af0bf9c
FB
2279 opn = "ll";
2280 break;
d66c7132 2281 }
2abf314d 2282 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2283 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
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{
2291 const char *opn = "st";
2292 TCGv t0 = tcg_temp_new();
2293 TCGv t1 = tcg_temp_new();
2294
2295 gen_base_offset_addr(ctx, t0, base, offset);
2296 gen_load_gpr(t1, rt);
2297 switch (opc) {
2298#if defined(TARGET_MIPS64)
2299 case OPC_SD:
be3a8c53
YK
2300 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2301 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2302 opn = "sd";
2303 break;
2304 case OPC_SDL:
2305 save_cpu_state(ctx, 1);
895c2d04 2306 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2307 opn = "sdl";
2308 break;
2309 case OPC_SDR:
2310 save_cpu_state(ctx, 1);
895c2d04 2311 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2312 opn = "sdr";
2313 break;
2314#endif
2315 case OPC_SW:
be3a8c53
YK
2316 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2317 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2318 opn = "sw";
2319 break;
2320 case OPC_SH:
be3a8c53
YK
2321 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2322 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2323 opn = "sh";
2324 break;
2325 case OPC_SB:
5f68f5ae 2326 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2327 opn = "sb";
2328 break;
2329 case OPC_SWL:
2330 save_cpu_state(ctx, 1);
895c2d04 2331 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2332 opn = "swl";
2333 break;
2334 case OPC_SWR:
2335 save_cpu_state(ctx, 1);
895c2d04 2336 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2337 opn = "swr";
2338 break;
2339 }
2abf314d 2340 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2341 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2342 tcg_temp_free(t0);
2343 tcg_temp_free(t1);
2344}
2345
2346
d66c7132
AJ
2347/* Store conditional */
2348static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2349 int base, int16_t offset)
2350{
2351 const char *opn = "st_cond";
2352 TCGv t0, t1;
2353
2d2826b9 2354#ifdef CONFIG_USER_ONLY
d66c7132 2355 t0 = tcg_temp_local_new();
d66c7132 2356 t1 = tcg_temp_local_new();
2d2826b9
AJ
2357#else
2358 t0 = tcg_temp_new();
2359 t1 = tcg_temp_new();
2360#endif
2361 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2362 gen_load_gpr(t1, rt);
2363 switch (opc) {
2364#if defined(TARGET_MIPS64)
2365 case OPC_SCD:
bf7910c6 2366 case R6_OPC_SCD:
b835e919 2367 save_cpu_state(ctx, 1);
5c13fdfd 2368 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2369 opn = "scd";
2370 break;
2371#endif
6af0bf9c 2372 case OPC_SC:
4368b29a 2373 case R6_OPC_SC:
e7139c44 2374 save_cpu_state(ctx, 1);
5c13fdfd 2375 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2376 opn = "sc";
2377 break;
6af0bf9c 2378 }
2abf314d 2379 (void)opn; /* avoid a compiler warning */
6af0bf9c 2380 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2381 tcg_temp_free(t1);
d66c7132 2382 tcg_temp_free(t0);
6af0bf9c
FB
2383}
2384
6ea83fed 2385/* Load and store */
7a387fff 2386static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2387 int base, int16_t offset)
6ea83fed 2388{
923617a3 2389 const char *opn = "flt_ldst";
4e2474d6 2390 TCGv t0 = tcg_temp_new();
6ea83fed 2391
662d7485 2392 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2393 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2394 memory access. */
6ea83fed
FB
2395 switch (opc) {
2396 case OPC_LWC1:
b6d96bed 2397 {
a7812ae4 2398 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2399 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2400 ctx->default_tcg_memop_mask);
7c979afd 2401 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2402 tcg_temp_free_i32(fp0);
b6d96bed 2403 }
6ea83fed
FB
2404 opn = "lwc1";
2405 break;
2406 case OPC_SWC1:
b6d96bed 2407 {
a7812ae4 2408 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2409 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2410 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2411 ctx->default_tcg_memop_mask);
a7812ae4 2412 tcg_temp_free_i32(fp0);
b6d96bed 2413 }
6ea83fed
FB
2414 opn = "swc1";
2415 break;
2416 case OPC_LDC1:
b6d96bed 2417 {
a7812ae4 2418 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2419 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2420 ctx->default_tcg_memop_mask);
b6d96bed 2421 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2422 tcg_temp_free_i64(fp0);
b6d96bed 2423 }
6ea83fed
FB
2424 opn = "ldc1";
2425 break;
2426 case OPC_SDC1:
b6d96bed 2427 {
a7812ae4 2428 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2429 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2430 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2431 ctx->default_tcg_memop_mask);
a7812ae4 2432 tcg_temp_free_i64(fp0);
b6d96bed 2433 }
6ea83fed
FB
2434 opn = "sdc1";
2435 break;
2436 default:
923617a3 2437 MIPS_INVAL(opn);
e397ee33 2438 generate_exception(ctx, EXCP_RI);
78723684 2439 goto out;
6ea83fed 2440 }
2abf314d 2441 (void)opn; /* avoid a compiler warning */
6ea83fed 2442 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2443 out:
2444 tcg_temp_free(t0);
6ea83fed 2445}
6ea83fed 2446
5ab5c041
AJ
2447static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2448 int rs, int16_t imm)
26ebe468 2449{
5ab5c041 2450 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2451 check_cp1_enabled(ctx);
d9224450
MR
2452 switch (op) {
2453 case OPC_LDC1:
2454 case OPC_SDC1:
2455 check_insn(ctx, ISA_MIPS2);
2456 /* Fallthrough */
2457 default:
2458 gen_flt_ldst(ctx, op, rt, rs, imm);
2459 }
26ebe468
NF
2460 } else {
2461 generate_exception_err(ctx, EXCP_CpU, 1);
2462 }
2463}
2464
6af0bf9c 2465/* Arithmetic with immediate operand */
d75c135e
AJ
2466static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2467 int rt, int rs, int16_t imm)
6af0bf9c 2468{
324d9e32 2469 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2470 const char *opn = "imm arith";
6af0bf9c 2471
7a387fff 2472 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2473 /* If no destination, treat it as a NOP.
2474 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2475 MIPS_DEBUG("NOP");
324d9e32 2476 return;
6af0bf9c
FB
2477 }
2478 switch (opc) {
2479 case OPC_ADDI:
48d38ca5 2480 {
324d9e32
AJ
2481 TCGv t0 = tcg_temp_local_new();
2482 TCGv t1 = tcg_temp_new();
2483 TCGv t2 = tcg_temp_new();
42a268c2 2484 TCGLabel *l1 = gen_new_label();
48d38ca5 2485
324d9e32
AJ
2486 gen_load_gpr(t1, rs);
2487 tcg_gen_addi_tl(t0, t1, uimm);
2488 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2489
324d9e32
AJ
2490 tcg_gen_xori_tl(t1, t1, ~uimm);
2491 tcg_gen_xori_tl(t2, t0, uimm);
2492 tcg_gen_and_tl(t1, t1, t2);
2493 tcg_temp_free(t2);
2494 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2495 tcg_temp_free(t1);
48d38ca5
TS
2496 /* operands of same sign, result different sign */
2497 generate_exception(ctx, EXCP_OVERFLOW);
2498 gen_set_label(l1);
78723684 2499 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2500 gen_store_gpr(t0, rt);
2501 tcg_temp_free(t0);
48d38ca5 2502 }
6af0bf9c
FB
2503 opn = "addi";
2504 break;
2505 case OPC_ADDIU:
324d9e32
AJ
2506 if (rs != 0) {
2507 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2508 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2509 } else {
2510 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2511 }
6af0bf9c
FB
2512 opn = "addiu";
2513 break;
d26bc211 2514#if defined(TARGET_MIPS64)
7a387fff 2515 case OPC_DADDI:
48d38ca5 2516 {
324d9e32
AJ
2517 TCGv t0 = tcg_temp_local_new();
2518 TCGv t1 = tcg_temp_new();
2519 TCGv t2 = tcg_temp_new();
42a268c2 2520 TCGLabel *l1 = gen_new_label();
48d38ca5 2521
324d9e32
AJ
2522 gen_load_gpr(t1, rs);
2523 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2524
324d9e32
AJ
2525 tcg_gen_xori_tl(t1, t1, ~uimm);
2526 tcg_gen_xori_tl(t2, t0, uimm);
2527 tcg_gen_and_tl(t1, t1, t2);
2528 tcg_temp_free(t2);
2529 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2530 tcg_temp_free(t1);
48d38ca5
TS
2531 /* operands of same sign, result different sign */
2532 generate_exception(ctx, EXCP_OVERFLOW);
2533 gen_set_label(l1);
324d9e32
AJ
2534 gen_store_gpr(t0, rt);
2535 tcg_temp_free(t0);
48d38ca5 2536 }
7a387fff
TS
2537 opn = "daddi";
2538 break;
2539 case OPC_DADDIU:
324d9e32
AJ
2540 if (rs != 0) {
2541 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2542 } else {
2543 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2544 }
7a387fff
TS
2545 opn = "daddiu";
2546 break;
2547#endif
324d9e32 2548 }
2abf314d 2549 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2550 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2551}
2552
2553/* Logic with immediate operand */
d75c135e 2554static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2555 int rt, int rs, int16_t imm)
324d9e32
AJ
2556{
2557 target_ulong uimm;
324d9e32
AJ
2558
2559 if (rt == 0) {
2560 /* If no destination, treat it as a NOP. */
2561 MIPS_DEBUG("NOP");
2562 return;
2563 }
2564 uimm = (uint16_t)imm;
2565 switch (opc) {
6af0bf9c 2566 case OPC_ANDI:
324d9e32
AJ
2567 if (likely(rs != 0))
2568 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2569 else
2570 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2571 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2572 regnames[rs], uimm);
6af0bf9c
FB
2573 break;
2574 case OPC_ORI:
324d9e32
AJ
2575 if (rs != 0)
2576 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2577 else
2578 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2579 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2580 regnames[rs], uimm);
6af0bf9c
FB
2581 break;
2582 case OPC_XORI:
324d9e32
AJ
2583 if (likely(rs != 0))
2584 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2585 else
2586 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2587 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2588 regnames[rs], uimm);
6af0bf9c
FB
2589 break;
2590 case OPC_LUI:
d4ea6acd
LA
2591 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2592 /* OPC_AUI */
2593 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2594 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2595 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2596 } else {
2597 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2598 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2599 }
7c2c3ea3
EJ
2600 break;
2601
2602 default:
2603 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2604 break;
324d9e32 2605 }
324d9e32
AJ
2606}
2607
2608/* Set on less than with immediate operand */
d75c135e 2609static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2610 int rt, int rs, int16_t imm)
324d9e32
AJ
2611{
2612 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2613 const char *opn = "imm arith";
2614 TCGv t0;
2615
2616 if (rt == 0) {
2617 /* If no destination, treat it as a NOP. */
2618 MIPS_DEBUG("NOP");
2619 return;
2620 }
2621 t0 = tcg_temp_new();
2622 gen_load_gpr(t0, rs);
2623 switch (opc) {
2624 case OPC_SLTI:
e68dd28f 2625 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2626 opn = "slti";
2627 break;
2628 case OPC_SLTIU:
e68dd28f 2629 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2630 opn = "sltiu";
2631 break;
2632 }
2abf314d 2633 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2634 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2635 tcg_temp_free(t0);
2636}
2637
2638/* Shifts with immediate operand */
d75c135e 2639static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2640 int rt, int rs, int16_t imm)
2641{
2642 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2643 const char *opn = "imm shift";
2644 TCGv t0;
2645
2646 if (rt == 0) {
2647 /* If no destination, treat it as a NOP. */
2648 MIPS_DEBUG("NOP");
2649 return;
2650 }
2651
2652 t0 = tcg_temp_new();
2653 gen_load_gpr(t0, rs);
2654 switch (opc) {
6af0bf9c 2655 case OPC_SLL:
78723684 2656 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2657 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2658 opn = "sll";
2659 break;
2660 case OPC_SRA:
324d9e32 2661 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2662 opn = "sra";
2663 break;
2664 case OPC_SRL:
ea63e2c3
NF
2665 if (uimm != 0) {
2666 tcg_gen_ext32u_tl(t0, t0);
2667 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2668 } else {
2669 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2670 }
ea63e2c3
NF
2671 opn = "srl";
2672 break;
2673 case OPC_ROTR:
2674 if (uimm != 0) {
2675 TCGv_i32 t1 = tcg_temp_new_i32();
2676
2677 tcg_gen_trunc_tl_i32(t1, t0);
2678 tcg_gen_rotri_i32(t1, t1, uimm);
2679 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2680 tcg_temp_free_i32(t1);
3399e30f
NF
2681 } else {
2682 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2683 }
2684 opn = "rotr";
7a387fff 2685 break;
d26bc211 2686#if defined(TARGET_MIPS64)
7a387fff 2687 case OPC_DSLL:
324d9e32 2688 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2689 opn = "dsll";
2690 break;
2691 case OPC_DSRA:
324d9e32 2692 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2693 opn = "dsra";
2694 break;
2695 case OPC_DSRL:
ea63e2c3
NF
2696 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2697 opn = "dsrl";
2698 break;
2699 case OPC_DROTR:
2700 if (uimm != 0) {
2701 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2702 } else {
2703 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2704 }
ea63e2c3 2705 opn = "drotr";
7a387fff
TS
2706 break;
2707 case OPC_DSLL32:
324d9e32 2708 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2709 opn = "dsll32";
2710 break;
2711 case OPC_DSRA32:
324d9e32 2712 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2713 opn = "dsra32";
2714 break;
2715 case OPC_DSRL32:
ea63e2c3
NF
2716 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2717 opn = "dsrl32";
2718 break;
2719 case OPC_DROTR32:
2720 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2721 opn = "drotr32";
6af0bf9c 2722 break;
7a387fff 2723#endif
6af0bf9c 2724 }
2abf314d 2725 (void)opn; /* avoid a compiler warning */
93b12ccc 2726 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2727 tcg_temp_free(t0);
6af0bf9c
FB
2728}
2729
2730/* Arithmetic */
d75c135e
AJ
2731static void gen_arith(DisasContext *ctx, uint32_t opc,
2732 int rd, int rs, int rt)
6af0bf9c 2733{
923617a3 2734 const char *opn = "arith";
6af0bf9c 2735
7a387fff
TS
2736 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2737 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2738 /* If no destination, treat it as a NOP.
2739 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2740 MIPS_DEBUG("NOP");
460f00c4 2741 return;
185f0762 2742 }
460f00c4 2743
6af0bf9c
FB
2744 switch (opc) {
2745 case OPC_ADD:
48d38ca5 2746 {
460f00c4
AJ
2747 TCGv t0 = tcg_temp_local_new();
2748 TCGv t1 = tcg_temp_new();
2749 TCGv t2 = tcg_temp_new();
42a268c2 2750 TCGLabel *l1 = gen_new_label();
48d38ca5 2751
460f00c4
AJ
2752 gen_load_gpr(t1, rs);
2753 gen_load_gpr(t2, rt);
2754 tcg_gen_add_tl(t0, t1, t2);
2755 tcg_gen_ext32s_tl(t0, t0);
2756 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2757 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2758 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2759 tcg_temp_free(t2);
2760 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2761 tcg_temp_free(t1);
48d38ca5
TS
2762 /* operands of same sign, result different sign */
2763 generate_exception(ctx, EXCP_OVERFLOW);
2764 gen_set_label(l1);
460f00c4
AJ
2765 gen_store_gpr(t0, rd);
2766 tcg_temp_free(t0);
48d38ca5 2767 }
6af0bf9c
FB
2768 opn = "add";
2769 break;
2770 case OPC_ADDU:
460f00c4
AJ
2771 if (rs != 0 && rt != 0) {
2772 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2773 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2774 } else if (rs == 0 && rt != 0) {
2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2776 } else if (rs != 0 && rt == 0) {
2777 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2778 } else {
2779 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780 }
6af0bf9c
FB
2781 opn = "addu";
2782 break;
2783 case OPC_SUB:
48d38ca5 2784 {
460f00c4
AJ
2785 TCGv t0 = tcg_temp_local_new();
2786 TCGv t1 = tcg_temp_new();
2787 TCGv t2 = tcg_temp_new();
42a268c2 2788 TCGLabel *l1 = gen_new_label();
48d38ca5 2789
460f00c4
AJ
2790 gen_load_gpr(t1, rs);
2791 gen_load_gpr(t2, rt);
2792 tcg_gen_sub_tl(t0, t1, t2);
2793 tcg_gen_ext32s_tl(t0, t0);
2794 tcg_gen_xor_tl(t2, t1, t2);
2795 tcg_gen_xor_tl(t1, t0, t1);
2796 tcg_gen_and_tl(t1, t1, t2);
2797 tcg_temp_free(t2);
2798 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2799 tcg_temp_free(t1);
31e3104f 2800 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2801 generate_exception(ctx, EXCP_OVERFLOW);
2802 gen_set_label(l1);
460f00c4
AJ
2803 gen_store_gpr(t0, rd);
2804 tcg_temp_free(t0);
48d38ca5 2805 }
6af0bf9c
FB
2806 opn = "sub";
2807 break;
2808 case OPC_SUBU:
460f00c4
AJ
2809 if (rs != 0 && rt != 0) {
2810 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2811 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2812 } else if (rs == 0 && rt != 0) {
2813 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2814 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2815 } else if (rs != 0 && rt == 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2817 } else {
2818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2819 }
6af0bf9c
FB
2820 opn = "subu";
2821 break;
d26bc211 2822#if defined(TARGET_MIPS64)
7a387fff 2823 case OPC_DADD:
48d38ca5 2824 {
460f00c4
AJ
2825 TCGv t0 = tcg_temp_local_new();
2826 TCGv t1 = tcg_temp_new();
2827 TCGv t2 = tcg_temp_new();
42a268c2 2828 TCGLabel *l1 = gen_new_label();
48d38ca5 2829
460f00c4
AJ
2830 gen_load_gpr(t1, rs);
2831 gen_load_gpr(t2, rt);
2832 tcg_gen_add_tl(t0, t1, t2);
2833 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2834 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2835 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2836 tcg_temp_free(t2);
2837 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2838 tcg_temp_free(t1);
48d38ca5
TS
2839 /* operands of same sign, result different sign */
2840 generate_exception(ctx, EXCP_OVERFLOW);
2841 gen_set_label(l1);
460f00c4
AJ
2842 gen_store_gpr(t0, rd);
2843 tcg_temp_free(t0);
48d38ca5 2844 }
7a387fff
TS
2845 opn = "dadd";
2846 break;
2847 case OPC_DADDU:
460f00c4
AJ
2848 if (rs != 0 && rt != 0) {
2849 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2850 } else if (rs == 0 && rt != 0) {
2851 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2852 } else if (rs != 0 && rt == 0) {
2853 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2854 } else {
2855 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2856 }
7a387fff
TS
2857 opn = "daddu";
2858 break;
2859 case OPC_DSUB:
48d38ca5 2860 {
460f00c4
AJ
2861 TCGv t0 = tcg_temp_local_new();
2862 TCGv t1 = tcg_temp_new();
2863 TCGv t2 = tcg_temp_new();
42a268c2 2864 TCGLabel *l1 = gen_new_label();
48d38ca5 2865
460f00c4
AJ
2866 gen_load_gpr(t1, rs);
2867 gen_load_gpr(t2, rt);
2868 tcg_gen_sub_tl(t0, t1, t2);
2869 tcg_gen_xor_tl(t2, t1, t2);
2870 tcg_gen_xor_tl(t1, t0, t1);
2871 tcg_gen_and_tl(t1, t1, t2);
2872 tcg_temp_free(t2);
2873 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2874 tcg_temp_free(t1);
31e3104f 2875 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2876 generate_exception(ctx, EXCP_OVERFLOW);
2877 gen_set_label(l1);
460f00c4
AJ
2878 gen_store_gpr(t0, rd);
2879 tcg_temp_free(t0);
48d38ca5 2880 }
7a387fff
TS
2881 opn = "dsub";
2882 break;
2883 case OPC_DSUBU:
460f00c4
AJ
2884 if (rs != 0 && rt != 0) {
2885 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2886 } else if (rs == 0 && rt != 0) {
2887 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2888 } else if (rs != 0 && rt == 0) {
2889 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2890 } else {
2891 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2892 }
7a387fff
TS
2893 opn = "dsubu";
2894 break;
2895#endif
460f00c4
AJ
2896 case OPC_MUL:
2897 if (likely(rs != 0 && rt != 0)) {
2898 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2899 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2900 } else {
2901 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2902 }
2903 opn = "mul";
6af0bf9c 2904 break;
460f00c4 2905 }
2abf314d 2906 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2907 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2908}
2909
2910/* Conditional move */
d75c135e 2911static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2912 int rd, int rs, int rt)
460f00c4
AJ
2913{
2914 const char *opn = "cond move";
acf12465 2915 TCGv t0, t1, t2;
460f00c4
AJ
2916
2917 if (rd == 0) {
acf12465 2918 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2919 MIPS_DEBUG("NOP");
2920 return;
2921 }
2922
acf12465
AJ
2923 t0 = tcg_temp_new();
2924 gen_load_gpr(t0, rt);
2925 t1 = tcg_const_tl(0);
2926 t2 = tcg_temp_new();
2927 gen_load_gpr(t2, rs);
460f00c4
AJ
2928 switch (opc) {
2929 case OPC_MOVN:
acf12465 2930 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2931 opn = "movn";
6af0bf9c 2932 break;
460f00c4 2933 case OPC_MOVZ:
acf12465 2934 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2935 opn = "movz";
2936 break;
b691d9d2
LA
2937 case OPC_SELNEZ:
2938 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2939 opn = "selnez";
2940 break;
2941 case OPC_SELEQZ:
2942 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2943 opn = "seleqz";
2944 break;
460f00c4 2945 }
acf12465
AJ
2946 tcg_temp_free(t2);
2947 tcg_temp_free(t1);
2948 tcg_temp_free(t0);
460f00c4 2949
2abf314d 2950 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2951 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2952}
2953
2954/* Logic */
d75c135e 2955static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2956 int rd, int rs, int rt)
460f00c4
AJ
2957{
2958 const char *opn = "logic";
2959
2960 if (rd == 0) {
2961 /* If no destination, treat it as a NOP. */
2962 MIPS_DEBUG("NOP");
2963 return;
2964 }
2965
2966 switch (opc) {
6af0bf9c 2967 case OPC_AND:
460f00c4
AJ
2968 if (likely(rs != 0 && rt != 0)) {
2969 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2970 } else {
2971 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2972 }
6af0bf9c
FB
2973 opn = "and";
2974 break;
2975 case OPC_NOR:
460f00c4
AJ
2976 if (rs != 0 && rt != 0) {
2977 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2978 } else if (rs == 0 && rt != 0) {
2979 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2980 } else if (rs != 0 && rt == 0) {
2981 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2982 } else {
2983 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2984 }
6af0bf9c
FB
2985 opn = "nor";
2986 break;
2987 case OPC_OR:
460f00c4
AJ
2988 if (likely(rs != 0 && rt != 0)) {
2989 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2990 } else if (rs == 0 && rt != 0) {
2991 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2992 } else if (rs != 0 && rt == 0) {
2993 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2994 } else {
2995 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2996 }
6af0bf9c
FB
2997 opn = "or";
2998 break;
2999 case OPC_XOR:
460f00c4
AJ
3000 if (likely(rs != 0 && rt != 0)) {
3001 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3002 } else if (rs == 0 && rt != 0) {
3003 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3004 } else if (rs != 0 && rt == 0) {
3005 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3006 } else {
3007 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3008 }
6af0bf9c
FB
3009 opn = "xor";
3010 break;
460f00c4 3011 }
2abf314d 3012 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
3013 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3014}
3015
3016/* Set on lower than */
d75c135e 3017static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 3018 int rd, int rs, int rt)
460f00c4
AJ
3019{
3020 const char *opn = "slt";
3021 TCGv t0, t1;
3022
3023 if (rd == 0) {
3024 /* If no destination, treat it as a NOP. */
3025 MIPS_DEBUG("NOP");
3026 return;
3027 }
3028
3029 t0 = tcg_temp_new();
3030 t1 = tcg_temp_new();
3031 gen_load_gpr(t0, rs);
3032 gen_load_gpr(t1, rt);
3033 switch (opc) {
3034 case OPC_SLT:
e68dd28f 3035 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 3036 opn = "slt";
6af0bf9c 3037 break;
460f00c4 3038 case OPC_SLTU:
e68dd28f 3039 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3040 opn = "sltu";
3041 break;
3042 }
2abf314d 3043 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
3044 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3045 tcg_temp_free(t0);
3046 tcg_temp_free(t1);
3047}
20c4c97c 3048
460f00c4 3049/* Shifts */
d75c135e
AJ
3050static void gen_shift(DisasContext *ctx, uint32_t opc,
3051 int rd, int rs, int rt)
460f00c4
AJ
3052{
3053 const char *opn = "shifts";
3054 TCGv t0, t1;
20c4c97c 3055
460f00c4
AJ
3056 if (rd == 0) {
3057 /* If no destination, treat it as a NOP.
3058 For add & sub, we must generate the overflow exception when needed. */
3059 MIPS_DEBUG("NOP");
3060 return;
3061 }
3062
3063 t0 = tcg_temp_new();
3064 t1 = tcg_temp_new();
3065 gen_load_gpr(t0, rs);
3066 gen_load_gpr(t1, rt);
3067 switch (opc) {
6af0bf9c 3068 case OPC_SLLV:
78723684
TS
3069 tcg_gen_andi_tl(t0, t0, 0x1f);
3070 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3071 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3072 opn = "sllv";
3073 break;
3074 case OPC_SRAV:
78723684 3075 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3076 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3077 opn = "srav";
3078 break;
3079 case OPC_SRLV:
ea63e2c3
NF
3080 tcg_gen_ext32u_tl(t1, t1);
3081 tcg_gen_andi_tl(t0, t0, 0x1f);
3082 tcg_gen_shr_tl(t0, t1, t0);
3083 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3084 opn = "srlv";
3085 break;
3086 case OPC_ROTRV:
3087 {
3088 TCGv_i32 t2 = tcg_temp_new_i32();
3089 TCGv_i32 t3 = tcg_temp_new_i32();
3090
3091 tcg_gen_trunc_tl_i32(t2, t0);
3092 tcg_gen_trunc_tl_i32(t3, t1);
3093 tcg_gen_andi_i32(t2, t2, 0x1f);
3094 tcg_gen_rotr_i32(t2, t3, t2);
3095 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3096 tcg_temp_free_i32(t2);
3097 tcg_temp_free_i32(t3);
3098 opn = "rotrv";
5a63bcb2 3099 }
7a387fff 3100 break;
d26bc211 3101#if defined(TARGET_MIPS64)
7a387fff 3102 case OPC_DSLLV:
78723684 3103 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3104 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3105 opn = "dsllv";
3106 break;
3107 case OPC_DSRAV:
78723684 3108 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3109 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3110 opn = "dsrav";
3111 break;
3112 case OPC_DSRLV:
ea63e2c3
NF
3113 tcg_gen_andi_tl(t0, t0, 0x3f);
3114 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3115 opn = "dsrlv";
3116 break;
3117 case OPC_DROTRV:
3118 tcg_gen_andi_tl(t0, t0, 0x3f);
3119 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3120 opn = "drotrv";
6af0bf9c 3121 break;
7a387fff 3122#endif
6af0bf9c 3123 }
2abf314d 3124 (void)opn; /* avoid a compiler warning */
6af0bf9c 3125 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3126 tcg_temp_free(t0);
3127 tcg_temp_free(t1);
6af0bf9c
FB
3128}
3129
3130/* Arithmetic on HI/LO registers */
26135ead 3131static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3132{
923617a3 3133 const char *opn = "hilo";
6af0bf9c
FB
3134
3135 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3136 /* Treat as NOP. */
6af0bf9c 3137 MIPS_DEBUG("NOP");
a1f6684d 3138 return;
6af0bf9c 3139 }
4133498f 3140
4133498f
JL
3141 if (acc != 0) {
3142 check_dsp(ctx);
3143 }
3144
6af0bf9c
FB
3145 switch (opc) {
3146 case OPC_MFHI:
4133498f
JL
3147#if defined(TARGET_MIPS64)
3148 if (acc != 0) {
3149 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3150 } else
3151#endif
3152 {
3153 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3154 }
6af0bf9c
FB
3155 opn = "mfhi";
3156 break;
3157 case OPC_MFLO:
4133498f
JL
3158#if defined(TARGET_MIPS64)
3159 if (acc != 0) {
3160 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3161 } else
3162#endif
3163 {
3164 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3165 }
6af0bf9c
FB
3166 opn = "mflo";
3167 break;
3168 case OPC_MTHI:
4133498f
JL
3169 if (reg != 0) {
3170#if defined(TARGET_MIPS64)
3171 if (acc != 0) {
3172 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3173 } else
3174#endif
3175 {
3176 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3177 }
3178 } else {
3179 tcg_gen_movi_tl(cpu_HI[acc], 0);
3180 }
6af0bf9c
FB
3181 opn = "mthi";
3182 break;
3183 case OPC_MTLO:
4133498f
JL
3184 if (reg != 0) {
3185#if defined(TARGET_MIPS64)
3186 if (acc != 0) {
3187 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3188 } else
3189#endif
3190 {
3191 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3192 }
3193 } else {
3194 tcg_gen_movi_tl(cpu_LO[acc], 0);
3195 }
6af0bf9c
FB
3196 opn = "mtlo";
3197 break;
6af0bf9c 3198 }
2abf314d 3199 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3200 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3201}
3202
d4ea6acd
LA
3203static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3204 TCGMemOp memop)
3205{
3206 TCGv t0 = tcg_const_tl(addr);
3207 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3208 gen_store_gpr(t0, reg);
3209 tcg_temp_free(t0);
3210}
3211
3212static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3213{
3214 target_long offset;
3215 target_long addr;
3216
3217 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3218 case OPC_ADDIUPC:
3219 if (rs != 0) {
3220 offset = sextract32(ctx->opcode << 2, 0, 21);
3221 addr = addr_add(ctx, ctx->pc, offset);
3222 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3223 }
3224 break;
3225 case R6_OPC_LWPC:
3226 offset = sextract32(ctx->opcode << 2, 0, 21);
3227 addr = addr_add(ctx, ctx->pc, offset);
3228 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3229 break;
3230#if defined(TARGET_MIPS64)
3231 case OPC_LWUPC:
3232 check_mips_64(ctx);
3233 offset = sextract32(ctx->opcode << 2, 0, 21);
3234 addr = addr_add(ctx, ctx->pc, offset);
3235 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3236 break;
3237#endif
3238 default:
3239 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3240 case OPC_AUIPC:
3241 if (rs != 0) {
3242 offset = imm << 16;
3243 addr = addr_add(ctx, ctx->pc, offset);
3244 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3245 }
3246 break;
3247 case OPC_ALUIPC:
3248 if (rs != 0) {
3249 offset = imm << 16;
3250 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3251 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3252 }
3253 break;
3254#if defined(TARGET_MIPS64)
3255 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3256 case R6_OPC_LDPC + (1 << 16):
3257 case R6_OPC_LDPC + (2 << 16):
3258 case R6_OPC_LDPC + (3 << 16):
3259 check_mips_64(ctx);
3260 offset = sextract32(ctx->opcode << 3, 0, 21);
3261 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3262 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3263 break;
3264#endif
3265 default:
3266 MIPS_INVAL("OPC_PCREL");
3267 generate_exception(ctx, EXCP_RI);
3268 break;
3269 }
3270 break;
3271 }
3272}
3273
b42ee5e1
LA
3274static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3275{
3276 const char *opn = "r6 mul/div";
3277 TCGv t0, t1;
3278
3279 if (rd == 0) {
3280 /* Treat as NOP. */
3281 MIPS_DEBUG("NOP");
3282 return;
3283 }
3284
3285 t0 = tcg_temp_new();
3286 t1 = tcg_temp_new();
3287
3288 gen_load_gpr(t0, rs);
3289 gen_load_gpr(t1, rt);
3290
3291 switch (opc) {
3292 case R6_OPC_DIV:
3293 {
3294 TCGv t2 = tcg_temp_new();
3295 TCGv t3 = tcg_temp_new();
3296 tcg_gen_ext32s_tl(t0, t0);
3297 tcg_gen_ext32s_tl(t1, t1);
3298 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3299 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3300 tcg_gen_and_tl(t2, t2, t3);
3301 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3302 tcg_gen_or_tl(t2, t2, t3);
3303 tcg_gen_movi_tl(t3, 0);
3304 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3305 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3306 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3307 tcg_temp_free(t3);
3308 tcg_temp_free(t2);
3309 }
3310 opn = "div";
3311 break;
3312 case R6_OPC_MOD:
3313 {
3314 TCGv t2 = tcg_temp_new();
3315 TCGv t3 = tcg_temp_new();
3316 tcg_gen_ext32s_tl(t0, t0);
3317 tcg_gen_ext32s_tl(t1, t1);
3318 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3319 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3320 tcg_gen_and_tl(t2, t2, t3);
3321 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3322 tcg_gen_or_tl(t2, t2, t3);
3323 tcg_gen_movi_tl(t3, 0);
3324 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3325 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3326 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3327 tcg_temp_free(t3);
3328 tcg_temp_free(t2);
3329 }
3330 opn = "mod";
3331 break;
3332 case R6_OPC_DIVU:
3333 {
3334 TCGv t2 = tcg_const_tl(0);
3335 TCGv t3 = tcg_const_tl(1);
3336 tcg_gen_ext32u_tl(t0, t0);
3337 tcg_gen_ext32u_tl(t1, t1);
3338 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3339 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3340 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3341 tcg_temp_free(t3);
3342 tcg_temp_free(t2);
3343 }
3344 opn = "divu";
3345 break;
3346 case R6_OPC_MODU:
3347 {
3348 TCGv t2 = tcg_const_tl(0);
3349 TCGv t3 = tcg_const_tl(1);
3350 tcg_gen_ext32u_tl(t0, t0);
3351 tcg_gen_ext32u_tl(t1, t1);
3352 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3353 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3354 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3355 tcg_temp_free(t3);
3356 tcg_temp_free(t2);
3357 }
3358 opn = "modu";
3359 break;
3360 case R6_OPC_MUL:
3361 {
3362 TCGv_i32 t2 = tcg_temp_new_i32();
3363 TCGv_i32 t3 = tcg_temp_new_i32();
3364 tcg_gen_trunc_tl_i32(t2, t0);
3365 tcg_gen_trunc_tl_i32(t3, t1);
3366 tcg_gen_mul_i32(t2, t2, t3);
3367 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3368 tcg_temp_free_i32(t2);
3369 tcg_temp_free_i32(t3);
3370 }
3371 opn = "mul";
3372 break;
3373 case R6_OPC_MUH:
3374 {
3375 TCGv_i32 t2 = tcg_temp_new_i32();
3376 TCGv_i32 t3 = tcg_temp_new_i32();
3377 tcg_gen_trunc_tl_i32(t2, t0);
3378 tcg_gen_trunc_tl_i32(t3, t1);
3379 tcg_gen_muls2_i32(t2, t3, t2, t3);
3380 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3381 tcg_temp_free_i32(t2);
3382 tcg_temp_free_i32(t3);
3383 }
3384 opn = "muh";
3385 break;
3386 case R6_OPC_MULU:
3387 {
3388 TCGv_i32 t2 = tcg_temp_new_i32();
3389 TCGv_i32 t3 = tcg_temp_new_i32();
3390 tcg_gen_trunc_tl_i32(t2, t0);
3391 tcg_gen_trunc_tl_i32(t3, t1);
3392 tcg_gen_mul_i32(t2, t2, t3);
3393 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3394 tcg_temp_free_i32(t2);
3395 tcg_temp_free_i32(t3);
3396 }
3397 opn = "mulu";
3398 break;
3399 case R6_OPC_MUHU:
3400 {
3401 TCGv_i32 t2 = tcg_temp_new_i32();
3402 TCGv_i32 t3 = tcg_temp_new_i32();
3403 tcg_gen_trunc_tl_i32(t2, t0);
3404 tcg_gen_trunc_tl_i32(t3, t1);
3405 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3406 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3407 tcg_temp_free_i32(t2);
3408 tcg_temp_free_i32(t3);
3409 }
3410 opn = "muhu";
3411 break;
3412#if defined(TARGET_MIPS64)
3413 case R6_OPC_DDIV:
3414 {
3415 TCGv t2 = tcg_temp_new();
3416 TCGv t3 = tcg_temp_new();
3417 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3418 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3419 tcg_gen_and_tl(t2, t2, t3);
3420 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3421 tcg_gen_or_tl(t2, t2, t3);
3422 tcg_gen_movi_tl(t3, 0);
3423 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3424 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3425 tcg_temp_free(t3);
3426 tcg_temp_free(t2);
3427 }
3428 opn = "ddiv";
3429 break;
3430 case R6_OPC_DMOD:
3431 {
3432 TCGv t2 = tcg_temp_new();
3433 TCGv t3 = tcg_temp_new();
3434 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3435 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3436 tcg_gen_and_tl(t2, t2, t3);
3437 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3438 tcg_gen_or_tl(t2, t2, t3);
3439 tcg_gen_movi_tl(t3, 0);
3440 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3441 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3442 tcg_temp_free(t3);
3443 tcg_temp_free(t2);
3444 }
3445 opn = "dmod";
3446 break;
3447 case R6_OPC_DDIVU:
3448 {
3449 TCGv t2 = tcg_const_tl(0);
3450 TCGv t3 = tcg_const_tl(1);
3451 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3452 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3453 tcg_temp_free(t3);
3454 tcg_temp_free(t2);
3455 }
3456 opn = "ddivu";
3457 break;
3458 case R6_OPC_DMODU:
3459 {
3460 TCGv t2 = tcg_const_tl(0);
3461 TCGv t3 = tcg_const_tl(1);
3462 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3463 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3464 tcg_temp_free(t3);
3465 tcg_temp_free(t2);
3466 }
3467 opn = "dmodu";
3468 break;
3469 case R6_OPC_DMUL:
3470 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3471 opn = "dmul";
3472 break;
3473 case R6_OPC_DMUH:
3474 {
3475 TCGv t2 = tcg_temp_new();
3476 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3477 tcg_temp_free(t2);
3478 }
3479 opn = "dmuh";
3480 break;
3481 case R6_OPC_DMULU:
3482 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3483 opn = "dmulu";
3484 break;
3485 case R6_OPC_DMUHU:
3486 {
3487 TCGv t2 = tcg_temp_new();
3488 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3489 tcg_temp_free(t2);
3490 }
3491 opn = "dmuhu";
3492 break;
3493#endif
3494 default:
3495 MIPS_INVAL(opn);
3496 generate_exception(ctx, EXCP_RI);
3497 goto out;
3498 }
3499 (void)opn; /* avoid a compiler warning */
3500 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3501 out:
3502 tcg_temp_free(t0);
3503 tcg_temp_free(t1);
3504}
3505
26135ead
RS
3506static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3507 int acc, int rs, int rt)
6af0bf9c 3508{
923617a3 3509 const char *opn = "mul/div";
d45f89f4
AJ
3510 TCGv t0, t1;
3511
51127181
AJ
3512 t0 = tcg_temp_new();
3513 t1 = tcg_temp_new();
6af0bf9c 3514
78723684
TS
3515 gen_load_gpr(t0, rs);
3516 gen_load_gpr(t1, rt);
51127181 3517
26135ead
RS
3518 if (acc != 0) {
3519 check_dsp(ctx);
3520 }
3521
6af0bf9c
FB
3522 switch (opc) {
3523 case OPC_DIV:
48d38ca5 3524 {
51127181
AJ
3525 TCGv t2 = tcg_temp_new();
3526 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3527 tcg_gen_ext32s_tl(t0, t0);
3528 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3529 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3530 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3531 tcg_gen_and_tl(t2, t2, t3);
3532 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3533 tcg_gen_or_tl(t2, t2, t3);
3534 tcg_gen_movi_tl(t3, 0);
3535 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3536 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3537 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3538 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3539 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3540 tcg_temp_free(t3);
3541 tcg_temp_free(t2);
48d38ca5 3542 }
6af0bf9c
FB
3543 opn = "div";
3544 break;
3545 case OPC_DIVU:
48d38ca5 3546 {
51127181
AJ
3547 TCGv t2 = tcg_const_tl(0);
3548 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3549 tcg_gen_ext32u_tl(t0, t0);
3550 tcg_gen_ext32u_tl(t1, t1);
51127181 3551 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3552 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3553 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3554 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3555 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3556 tcg_temp_free(t3);
3557 tcg_temp_free(t2);
48d38ca5 3558 }
6af0bf9c
FB
3559 opn = "divu";
3560 break;
3561 case OPC_MULT:
214c465f 3562 {
ce1dd5d1
RH
3563 TCGv_i32 t2 = tcg_temp_new_i32();
3564 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3565 tcg_gen_trunc_tl_i32(t2, t0);
3566 tcg_gen_trunc_tl_i32(t3, t1);
3567 tcg_gen_muls2_i32(t2, t3, t2, t3);
3568 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3569 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3570 tcg_temp_free_i32(t2);
3571 tcg_temp_free_i32(t3);
214c465f 3572 }
6af0bf9c
FB
3573 opn = "mult";
3574 break;
3575 case OPC_MULTU:
214c465f 3576 {
ce1dd5d1
RH
3577 TCGv_i32 t2 = tcg_temp_new_i32();
3578 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3579 tcg_gen_trunc_tl_i32(t2, t0);
3580 tcg_gen_trunc_tl_i32(t3, t1);
3581 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3582 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3583 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3584 tcg_temp_free_i32(t2);
3585 tcg_temp_free_i32(t3);
214c465f 3586 }
6af0bf9c
FB
3587 opn = "multu";
3588 break;
d26bc211 3589#if defined(TARGET_MIPS64)
7a387fff 3590 case OPC_DDIV:
48d38ca5 3591 {
51127181
AJ
3592 TCGv t2 = tcg_temp_new();
3593 TCGv t3 = tcg_temp_new();
3594 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3595 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3596 tcg_gen_and_tl(t2, t2, t3);
3597 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3598 tcg_gen_or_tl(t2, t2, t3);
3599 tcg_gen_movi_tl(t3, 0);
3600 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3601 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3602 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3603 tcg_temp_free(t3);
3604 tcg_temp_free(t2);
48d38ca5 3605 }
7a387fff
TS
3606 opn = "ddiv";
3607 break;
3608 case OPC_DDIVU:
48d38ca5 3609 {
51127181
AJ
3610 TCGv t2 = tcg_const_tl(0);
3611 TCGv t3 = tcg_const_tl(1);
3612 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3613 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3614 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3615 tcg_temp_free(t3);
3616 tcg_temp_free(t2);
48d38ca5 3617 }
7a387fff
TS
3618 opn = "ddivu";
3619 break;
3620 case OPC_DMULT:
26135ead 3621 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3622 opn = "dmult";
3623 break;
3624 case OPC_DMULTU:
26135ead 3625 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3626 opn = "dmultu";
3627 break;
3628#endif
6af0bf9c 3629 case OPC_MADD:
214c465f 3630 {
d45f89f4
AJ
3631 TCGv_i64 t2 = tcg_temp_new_i64();
3632 TCGv_i64 t3 = tcg_temp_new_i64();
3633
3634 tcg_gen_ext_tl_i64(t2, t0);
3635 tcg_gen_ext_tl_i64(t3, t1);
3636 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3637 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3638 tcg_gen_add_i64(t2, t2, t3);
3639 tcg_temp_free_i64(t3);
3640 tcg_gen_trunc_i64_tl(t0, t2);
3641 tcg_gen_shri_i64(t2, t2, 32);
3642 tcg_gen_trunc_i64_tl(t1, t2);
3643 tcg_temp_free_i64(t2);
4133498f
JL
3644 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3645 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3646 }
6af0bf9c
FB
3647 opn = "madd";
3648 break;
3649 case OPC_MADDU:
4133498f 3650 {
d45f89f4
AJ
3651 TCGv_i64 t2 = tcg_temp_new_i64();
3652 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3653
78723684
TS
3654 tcg_gen_ext32u_tl(t0, t0);
3655 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3656 tcg_gen_extu_tl_i64(t2, t0);
3657 tcg_gen_extu_tl_i64(t3, t1);
3658 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3659 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3660 tcg_gen_add_i64(t2, t2, t3);
3661 tcg_temp_free_i64(t3);
3662 tcg_gen_trunc_i64_tl(t0, t2);
3663 tcg_gen_shri_i64(t2, t2, 32);
3664 tcg_gen_trunc_i64_tl(t1, t2);
3665 tcg_temp_free_i64(t2);
4133498f
JL
3666 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3667 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3668 }
6af0bf9c
FB
3669 opn = "maddu";
3670 break;
3671 case OPC_MSUB:
214c465f 3672 {
d45f89f4
AJ
3673 TCGv_i64 t2 = tcg_temp_new_i64();
3674 TCGv_i64 t3 = tcg_temp_new_i64();
3675
3676 tcg_gen_ext_tl_i64(t2, t0);
3677 tcg_gen_ext_tl_i64(t3, t1);
3678 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3679 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3680 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3681 tcg_temp_free_i64(t3);
3682 tcg_gen_trunc_i64_tl(t0, t2);
3683 tcg_gen_shri_i64(t2, t2, 32);
3684 tcg_gen_trunc_i64_tl(t1, t2);
3685 tcg_temp_free_i64(t2);
4133498f
JL
3686 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3687 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3688 }
6af0bf9c
FB
3689 opn = "msub";
3690 break;
3691 case OPC_MSUBU:
214c465f 3692 {
d45f89f4
AJ
3693 TCGv_i64 t2 = tcg_temp_new_i64();
3694 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3695
78723684
TS
3696 tcg_gen_ext32u_tl(t0, t0);
3697 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3698 tcg_gen_extu_tl_i64(t2, t0);
3699 tcg_gen_extu_tl_i64(t3, t1);
3700 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3701 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3702 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3703 tcg_temp_free_i64(t3);
3704 tcg_gen_trunc_i64_tl(t0, t2);
3705 tcg_gen_shri_i64(t2, t2, 32);
3706 tcg_gen_trunc_i64_tl(t1, t2);
3707 tcg_temp_free_i64(t2);
4133498f
JL
3708 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3709 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3710 }
6af0bf9c
FB
3711 opn = "msubu";
3712 break;
3713 default:
923617a3 3714 MIPS_INVAL(opn);
6af0bf9c 3715 generate_exception(ctx, EXCP_RI);
78723684 3716 goto out;
6af0bf9c 3717 }
2abf314d 3718 (void)opn; /* avoid a compiler warning */
6af0bf9c 3719 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3720 out:
3721 tcg_temp_free(t0);
3722 tcg_temp_free(t1);
6af0bf9c
FB
3723}
3724
e9c71dd1
TS
3725static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3726 int rd, int rs, int rt)
3727{
3728 const char *opn = "mul vr54xx";
f157bfe1
AJ
3729 TCGv t0 = tcg_temp_new();
3730 TCGv t1 = tcg_temp_new();
e9c71dd1 3731
6c5c1e20
TS
3732 gen_load_gpr(t0, rs);
3733 gen_load_gpr(t1, rt);
e9c71dd1
TS
3734
3735 switch (opc) {
3736 case OPC_VR54XX_MULS:
895c2d04 3737 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3738 opn = "muls";
6958549d 3739 break;
e9c71dd1 3740 case OPC_VR54XX_MULSU:
895c2d04 3741 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3742 opn = "mulsu";
6958549d 3743 break;
e9c71dd1 3744 case OPC_VR54XX_MACC:
895c2d04 3745 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3746 opn = "macc";
6958549d 3747 break;
e9c71dd1 3748 case OPC_VR54XX_MACCU:
895c2d04 3749 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3750 opn = "maccu";
6958549d 3751 break;
e9c71dd1 3752 case OPC_VR54XX_MSAC:
895c2d04 3753 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3754 opn = "msac";
6958549d 3755 break;
e9c71dd1 3756 case OPC_VR54XX_MSACU:
895c2d04 3757 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3758 opn = "msacu";
6958549d 3759 break;
e9c71dd1 3760 case OPC_VR54XX_MULHI:
895c2d04 3761 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3762 opn = "mulhi";
6958549d 3763 break;
e9c71dd1 3764 case OPC_VR54XX_MULHIU:
895c2d04 3765 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3766 opn = "mulhiu";
6958549d 3767 break;
e9c71dd1 3768 case OPC_VR54XX_MULSHI:
895c2d04 3769 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3770 opn = "mulshi";
6958549d 3771 break;
e9c71dd1 3772 case OPC_VR54XX_MULSHIU:
895c2d04 3773 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3774 opn = "mulshiu";
6958549d 3775 break;
e9c71dd1 3776 case OPC_VR54XX_MACCHI:
895c2d04 3777 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3778 opn = "macchi";
6958549d 3779 break;
e9c71dd1 3780 case OPC_VR54XX_MACCHIU:
895c2d04 3781 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3782 opn = "macchiu";
6958549d 3783 break;
e9c71dd1 3784 case OPC_VR54XX_MSACHI:
895c2d04 3785 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3786 opn = "msachi";
6958549d 3787 break;
e9c71dd1 3788 case OPC_VR54XX_MSACHIU:
895c2d04 3789 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3790 opn = "msachiu";
6958549d 3791 break;
e9c71dd1
TS
3792 default:
3793 MIPS_INVAL("mul vr54xx");
3794 generate_exception(ctx, EXCP_RI);
6c5c1e20 3795 goto out;
e9c71dd1 3796 }
6c5c1e20 3797 gen_store_gpr(t0, rd);
2abf314d 3798 (void)opn; /* avoid a compiler warning */
e9c71dd1 3799 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3800
3801 out:
3802 tcg_temp_free(t0);
3803 tcg_temp_free(t1);
e9c71dd1
TS
3804}
3805
7a387fff 3806static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3807 int rd, int rs)
3808{
923617a3 3809 const char *opn = "CLx";
20e1fb52 3810 TCGv t0;
6c5c1e20 3811
6af0bf9c 3812 if (rd == 0) {
ead9360e 3813 /* Treat as NOP. */
6af0bf9c 3814 MIPS_DEBUG("NOP");
20e1fb52 3815 return;
6af0bf9c 3816 }
20e1fb52 3817 t0 = tcg_temp_new();
6c5c1e20 3818 gen_load_gpr(t0, rs);
6af0bf9c
FB
3819 switch (opc) {
3820 case OPC_CLO:
4267d3e6 3821 case R6_OPC_CLO:
20e1fb52 3822 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3823 opn = "clo";
3824 break;
3825 case OPC_CLZ:
4267d3e6 3826 case R6_OPC_CLZ:
20e1fb52 3827 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3828 opn = "clz";
3829 break;
d26bc211 3830#if defined(TARGET_MIPS64)
7a387fff 3831 case OPC_DCLO:
4267d3e6 3832 case R6_OPC_DCLO:
20e1fb52 3833 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3834 opn = "dclo";
3835 break;
3836 case OPC_DCLZ:
4267d3e6 3837 case R6_OPC_DCLZ:
20e1fb52 3838 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3839 opn = "dclz";
3840 break;
3841#endif
6af0bf9c 3842 }
2abf314d 3843 (void)opn; /* avoid a compiler warning */
6af0bf9c 3844 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3845 tcg_temp_free(t0);
6af0bf9c
FB
3846}
3847
161f85e6 3848/* Godson integer instructions */
bd277fa1
RH
3849static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3850 int rd, int rs, int rt)
161f85e6
AJ
3851{
3852 const char *opn = "loongson";
3853 TCGv t0, t1;
3854
3855 if (rd == 0) {
3856 /* Treat as NOP. */
3857 MIPS_DEBUG("NOP");
3858 return;
3859 }
3860
3861 switch (opc) {
3862 case OPC_MULT_G_2E:
3863 case OPC_MULT_G_2F:
3864 case OPC_MULTU_G_2E:
3865 case OPC_MULTU_G_2F:
3866#if defined(TARGET_MIPS64)
3867 case OPC_DMULT_G_2E:
3868 case OPC_DMULT_G_2F:
3869 case OPC_DMULTU_G_2E:
3870 case OPC_DMULTU_G_2F:
3871#endif
3872 t0 = tcg_temp_new();
3873 t1 = tcg_temp_new();
3874 break;
3875 default:
3876 t0 = tcg_temp_local_new();
3877 t1 = tcg_temp_local_new();
3878 break;
3879 }
3880
3881 gen_load_gpr(t0, rs);
3882 gen_load_gpr(t1, rt);
3883
3884 switch (opc) {
3885 case OPC_MULT_G_2E:
3886 case OPC_MULT_G_2F:
3887 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3888 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3889 opn = "mult.g";
3890 break;
3891 case OPC_MULTU_G_2E:
3892 case OPC_MULTU_G_2F:
3893 tcg_gen_ext32u_tl(t0, t0);
3894 tcg_gen_ext32u_tl(t1, t1);
3895 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3896 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3897 opn = "multu.g";
3898 break;
3899 case OPC_DIV_G_2E:
3900 case OPC_DIV_G_2F:
3901 {
42a268c2
RH
3902 TCGLabel *l1 = gen_new_label();
3903 TCGLabel *l2 = gen_new_label();
3904 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3905 tcg_gen_ext32s_tl(t0, t0);
3906 tcg_gen_ext32s_tl(t1, t1);
3907 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3908 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3909 tcg_gen_br(l3);
3910 gen_set_label(l1);
3911 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3912 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3913 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3914 tcg_gen_br(l3);
3915 gen_set_label(l2);
3916 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3917 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3918 gen_set_label(l3);
3919 }
3920 opn = "div.g";
3921 break;
3922 case OPC_DIVU_G_2E:
3923 case OPC_DIVU_G_2F:
3924 {
42a268c2
RH
3925 TCGLabel *l1 = gen_new_label();
3926 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3927 tcg_gen_ext32u_tl(t0, t0);
3928 tcg_gen_ext32u_tl(t1, t1);
3929 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3930 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3931 tcg_gen_br(l2);
3932 gen_set_label(l1);
3933 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3934 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3935 gen_set_label(l2);
3936 }
3937 opn = "divu.g";
3938 break;
3939 case OPC_MOD_G_2E:
3940 case OPC_MOD_G_2F:
3941 {
42a268c2
RH
3942 TCGLabel *l1 = gen_new_label();
3943 TCGLabel *l2 = gen_new_label();
3944 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3945 tcg_gen_ext32u_tl(t0, t0);
3946 tcg_gen_ext32u_tl(t1, t1);
3947 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3948 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3949 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3950 gen_set_label(l1);
3951 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3952 tcg_gen_br(l3);
3953 gen_set_label(l2);
3954 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3955 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3956 gen_set_label(l3);
3957 }
3958 opn = "mod.g";
3959 break;
3960 case OPC_MODU_G_2E:
3961 case OPC_MODU_G_2F:
3962 {
42a268c2
RH
3963 TCGLabel *l1 = gen_new_label();
3964 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3965 tcg_gen_ext32u_tl(t0, t0);
3966 tcg_gen_ext32u_tl(t1, t1);
3967 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3968 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3969 tcg_gen_br(l2);
3970 gen_set_label(l1);
3971 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3972 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3973 gen_set_label(l2);
3974 }
3975 opn = "modu.g";
3976 break;
3977#if defined(TARGET_MIPS64)
3978 case OPC_DMULT_G_2E:
3979 case OPC_DMULT_G_2F:
3980 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3981 opn = "dmult.g";
3982 break;
3983 case OPC_DMULTU_G_2E:
3984 case OPC_DMULTU_G_2F:
3985 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3986 opn = "dmultu.g";
3987 break;
3988 case OPC_DDIV_G_2E:
3989 case OPC_DDIV_G_2F:
3990 {
42a268c2
RH
3991 TCGLabel *l1 = gen_new_label();
3992 TCGLabel *l2 = gen_new_label();
3993 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3994 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3995 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3996 tcg_gen_br(l3);
3997 gen_set_label(l1);
3998 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3999 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4000 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4001 tcg_gen_br(l3);
4002 gen_set_label(l2);
4003 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4004 gen_set_label(l3);
4005 }
4006 opn = "ddiv.g";
4007 break;
4008 case OPC_DDIVU_G_2E:
4009 case OPC_DDIVU_G_2F:
4010 {
42a268c2
RH
4011 TCGLabel *l1 = gen_new_label();
4012 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4013 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4014 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4015 tcg_gen_br(l2);
4016 gen_set_label(l1);
4017 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4018 gen_set_label(l2);
4019 }
4020 opn = "ddivu.g";
4021 break;
4022 case OPC_DMOD_G_2E:
4023 case OPC_DMOD_G_2F:
4024 {
42a268c2
RH
4025 TCGLabel *l1 = gen_new_label();
4026 TCGLabel *l2 = gen_new_label();
4027 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
4028 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4029 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4030 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4031 gen_set_label(l1);
4032 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4033 tcg_gen_br(l3);
4034 gen_set_label(l2);
4035 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4036 gen_set_label(l3);
4037 }
4038 opn = "dmod.g";
4039 break;
4040 case OPC_DMODU_G_2E:
4041 case OPC_DMODU_G_2F:
4042 {
42a268c2
RH
4043 TCGLabel *l1 = gen_new_label();
4044 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
4045 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4046 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4047 tcg_gen_br(l2);
4048 gen_set_label(l1);
4049 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4050 gen_set_label(l2);
4051 }
4052 opn = "dmodu.g";
4053 break;
4054#endif
4055 }
4056
2abf314d 4057 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
4058 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4059 tcg_temp_free(t0);
4060 tcg_temp_free(t1);
4061}
4062
bd277fa1
RH
4063/* Loongson multimedia instructions */
4064static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4065{
4066 const char *opn = "loongson_cp2";
4067 uint32_t opc, shift_max;
4068 TCGv_i64 t0, t1;
4069
4070 opc = MASK_LMI(ctx->opcode);
4071 switch (opc) {
4072 case OPC_ADD_CP2:
4073 case OPC_SUB_CP2:
4074 case OPC_DADD_CP2:
4075 case OPC_DSUB_CP2:
4076 t0 = tcg_temp_local_new_i64();
4077 t1 = tcg_temp_local_new_i64();
4078 break;
4079 default:
4080 t0 = tcg_temp_new_i64();
4081 t1 = tcg_temp_new_i64();
4082 break;
4083 }
4084
4085 gen_load_fpr64(ctx, t0, rs);
4086 gen_load_fpr64(ctx, t1, rt);
4087
4088#define LMI_HELPER(UP, LO) \
4089 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4090#define LMI_HELPER_1(UP, LO) \
4091 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4092#define LMI_DIRECT(UP, LO, OP) \
4093 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4094
4095 switch (opc) {
4096 LMI_HELPER(PADDSH, paddsh);
4097 LMI_HELPER(PADDUSH, paddush);
4098 LMI_HELPER(PADDH, paddh);
4099 LMI_HELPER(PADDW, paddw);
4100 LMI_HELPER(PADDSB, paddsb);
4101 LMI_HELPER(PADDUSB, paddusb);
4102 LMI_HELPER(PADDB, paddb);
4103
4104 LMI_HELPER(PSUBSH, psubsh);
4105 LMI_HELPER(PSUBUSH, psubush);
4106 LMI_HELPER(PSUBH, psubh);
4107 LMI_HELPER(PSUBW, psubw);
4108 LMI_HELPER(PSUBSB, psubsb);
4109 LMI_HELPER(PSUBUSB, psubusb);
4110 LMI_HELPER(PSUBB, psubb);
4111
4112 LMI_HELPER(PSHUFH, pshufh);
4113 LMI_HELPER(PACKSSWH, packsswh);
4114 LMI_HELPER(PACKSSHB, packsshb);
4115 LMI_HELPER(PACKUSHB, packushb);
4116
4117 LMI_HELPER(PUNPCKLHW, punpcklhw);
4118 LMI_HELPER(PUNPCKHHW, punpckhhw);
4119 LMI_HELPER(PUNPCKLBH, punpcklbh);
4120 LMI_HELPER(PUNPCKHBH, punpckhbh);
4121 LMI_HELPER(PUNPCKLWD, punpcklwd);
4122 LMI_HELPER(PUNPCKHWD, punpckhwd);
4123
4124 LMI_HELPER(PAVGH, pavgh);
4125 LMI_HELPER(PAVGB, pavgb);
4126 LMI_HELPER(PMAXSH, pmaxsh);
4127 LMI_HELPER(PMINSH, pminsh);
4128 LMI_HELPER(PMAXUB, pmaxub);
4129 LMI_HELPER(PMINUB, pminub);
4130
4131 LMI_HELPER(PCMPEQW, pcmpeqw);
4132 LMI_HELPER(PCMPGTW, pcmpgtw);
4133 LMI_HELPER(PCMPEQH, pcmpeqh);
4134 LMI_HELPER(PCMPGTH, pcmpgth);
4135 LMI_HELPER(PCMPEQB, pcmpeqb);
4136 LMI_HELPER(PCMPGTB, pcmpgtb);
4137
4138 LMI_HELPER(PSLLW, psllw);
4139 LMI_HELPER(PSLLH, psllh);
4140 LMI_HELPER(PSRLW, psrlw);
4141 LMI_HELPER(PSRLH, psrlh);
4142 LMI_HELPER(PSRAW, psraw);
4143 LMI_HELPER(PSRAH, psrah);
4144
4145 LMI_HELPER(PMULLH, pmullh);
4146 LMI_HELPER(PMULHH, pmulhh);
4147 LMI_HELPER(PMULHUH, pmulhuh);
4148 LMI_HELPER(PMADDHW, pmaddhw);
4149
4150 LMI_HELPER(PASUBUB, pasubub);
4151 LMI_HELPER_1(BIADD, biadd);
4152 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4153
4154 LMI_DIRECT(PADDD, paddd, add);
4155 LMI_DIRECT(PSUBD, psubd, sub);
4156 LMI_DIRECT(XOR_CP2, xor, xor);
4157 LMI_DIRECT(NOR_CP2, nor, nor);
4158 LMI_DIRECT(AND_CP2, and, and);
4159 LMI_DIRECT(PANDN, pandn, andc);
4160 LMI_DIRECT(OR, or, or);
4161
4162 case OPC_PINSRH_0:
4163 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4164 opn = "pinsrh_0";
4165 break;
4166 case OPC_PINSRH_1:
4167 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4168 opn = "pinsrh_1";
4169 break;
4170 case OPC_PINSRH_2:
4171 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4172 opn = "pinsrh_2";
4173 break;
4174 case OPC_PINSRH_3:
4175 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4176 opn = "pinsrh_3";
4177 break;
4178
4179 case OPC_PEXTRH:
4180 tcg_gen_andi_i64(t1, t1, 3);
4181 tcg_gen_shli_i64(t1, t1, 4);
4182 tcg_gen_shr_i64(t0, t0, t1);
4183 tcg_gen_ext16u_i64(t0, t0);
4184 opn = "pextrh";
4185 break;
4186
4187 case OPC_ADDU_CP2:
4188 tcg_gen_add_i64(t0, t0, t1);
4189 tcg_gen_ext32s_i64(t0, t0);
4190 opn = "addu";
4191 break;
4192 case OPC_SUBU_CP2:
4193 tcg_gen_sub_i64(t0, t0, t1);
4194 tcg_gen_ext32s_i64(t0, t0);
4195 opn = "addu";
4196 break;
4197
4198 case OPC_SLL_CP2:
4199 opn = "sll";
4200 shift_max = 32;
4201 goto do_shift;
4202 case OPC_SRL_CP2:
4203 opn = "srl";
4204 shift_max = 32;
4205 goto do_shift;
4206 case OPC_SRA_CP2:
4207 opn = "sra";
4208 shift_max = 32;
4209 goto do_shift;
4210 case OPC_DSLL_CP2:
4211 opn = "dsll";
4212 shift_max = 64;
4213 goto do_shift;
4214 case OPC_DSRL_CP2:
4215 opn = "dsrl";
4216 shift_max = 64;
4217 goto do_shift;
4218 case OPC_DSRA_CP2:
4219 opn = "dsra";
4220 shift_max = 64;
4221 goto do_shift;
4222 do_shift:
4223 /* Make sure shift count isn't TCG undefined behaviour. */
4224 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4225
4226 switch (opc) {
4227 case OPC_SLL_CP2:
4228 case OPC_DSLL_CP2:
4229 tcg_gen_shl_i64(t0, t0, t1);
4230 break;
4231 case OPC_SRA_CP2:
4232 case OPC_DSRA_CP2:
4233 /* Since SRA is UndefinedResult without sign-extended inputs,
4234 we can treat SRA and DSRA the same. */
4235 tcg_gen_sar_i64(t0, t0, t1);
4236 break;
4237 case OPC_SRL_CP2:
4238 /* We want to shift in zeros for SRL; zero-extend first. */
4239 tcg_gen_ext32u_i64(t0, t0);
4240 /* FALLTHRU */
4241 case OPC_DSRL_CP2:
4242 tcg_gen_shr_i64(t0, t0, t1);
4243 break;
4244 }
4245
4246 if (shift_max == 32) {
4247 tcg_gen_ext32s_i64(t0, t0);
4248 }
4249
4250 /* Shifts larger than MAX produce zero. */
4251 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4252 tcg_gen_neg_i64(t1, t1);
4253 tcg_gen_and_i64(t0, t0, t1);
4254 break;
4255
4256 case OPC_ADD_CP2:
4257 case OPC_DADD_CP2:
4258 {
4259 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4260 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4261
4262 tcg_gen_mov_i64(t2, t0);
4263 tcg_gen_add_i64(t0, t1, t2);
4264 if (opc == OPC_ADD_CP2) {
4265 tcg_gen_ext32s_i64(t0, t0);
4266 }
4267 tcg_gen_xor_i64(t1, t1, t2);
4268 tcg_gen_xor_i64(t2, t2, t0);
4269 tcg_gen_andc_i64(t1, t2, t1);
4270 tcg_temp_free_i64(t2);
4271 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4272 generate_exception(ctx, EXCP_OVERFLOW);
4273 gen_set_label(lab);
4274
4275 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4276 break;
4277 }
4278
4279 case OPC_SUB_CP2:
4280 case OPC_DSUB_CP2:
4281 {
4282 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4283 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4284
4285 tcg_gen_mov_i64(t2, t0);
4286 tcg_gen_sub_i64(t0, t1, t2);
4287 if (opc == OPC_SUB_CP2) {
4288 tcg_gen_ext32s_i64(t0, t0);
4289 }
4290 tcg_gen_xor_i64(t1, t1, t2);
4291 tcg_gen_xor_i64(t2, t2, t0);
4292 tcg_gen_and_i64(t1, t1, t2);
4293 tcg_temp_free_i64(t2);
4294 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4295 generate_exception(ctx, EXCP_OVERFLOW);
4296 gen_set_label(lab);
4297
4298 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4299 break;
4300 }
4301
4302 case OPC_PMULUW:
4303 tcg_gen_ext32u_i64(t0, t0);
4304 tcg_gen_ext32u_i64(t1, t1);
4305 tcg_gen_mul_i64(t0, t0, t1);
4306 opn = "pmuluw";
4307 break;
4308
4309 case OPC_SEQU_CP2:
4310 case OPC_SEQ_CP2:
4311 case OPC_SLTU_CP2:
4312 case OPC_SLT_CP2:
4313 case OPC_SLEU_CP2:
4314 case OPC_SLE_CP2:
4315 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4316 FD field is the CC field? */
4317 default:
4318 MIPS_INVAL(opn);
4319 generate_exception(ctx, EXCP_RI);
4320 return;
4321 }
4322
4323#undef LMI_HELPER
4324#undef LMI_DIRECT
4325
4326 gen_store_fpr64(ctx, t0, rd);
4327
4328 (void)opn; /* avoid a compiler warning */
4329 MIPS_DEBUG("%s %s, %s, %s", opn,
4330 fregnames[rd], fregnames[rs], fregnames[rt]);
4331 tcg_temp_free_i64(t0);
4332 tcg_temp_free_i64(t1);
4333}
4334
6af0bf9c 4335/* Traps */
7a387fff 4336static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4337 int rs, int rt, int16_t imm)
4338{
4339 int cond;
cdc0faa6 4340 TCGv t0 = tcg_temp_new();
1ba74fb8 4341 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4342
4343 cond = 0;
4344 /* Load needed operands */
4345 switch (opc) {
4346 case OPC_TEQ:
4347 case OPC_TGE:
4348 case OPC_TGEU:
4349 case OPC_TLT:
4350 case OPC_TLTU:
4351 case OPC_TNE:
4352 /* Compare two registers */
4353 if (rs != rt) {
be24bb4f
TS
4354 gen_load_gpr(t0, rs);
4355 gen_load_gpr(t1, rt);
6af0bf9c
FB
4356 cond = 1;
4357 }
179e32bb 4358 break;
6af0bf9c
FB
4359 case OPC_TEQI:
4360 case OPC_TGEI:
4361 case OPC_TGEIU:
4362 case OPC_TLTI:
4363 case OPC_TLTIU:
4364 case OPC_TNEI:
4365 /* Compare register to immediate */
4366 if (rs != 0 || imm != 0) {
be24bb4f
TS
4367 gen_load_gpr(t0, rs);
4368 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4369 cond = 1;
4370 }
4371 break;
4372 }
4373 if (cond == 0) {
4374 switch (opc) {
4375 case OPC_TEQ: /* rs == rs */
4376 case OPC_TEQI: /* r0 == 0 */
4377 case OPC_TGE: /* rs >= rs */
4378 case OPC_TGEI: /* r0 >= 0 */
4379 case OPC_TGEU: /* rs >= rs unsigned */
4380 case OPC_TGEIU: /* r0 >= 0 unsigned */
4381 /* Always trap */
cdc0faa6 4382 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4383 break;
4384 case OPC_TLT: /* rs < rs */
4385 case OPC_TLTI: /* r0 < 0 */
4386 case OPC_TLTU: /* rs < rs unsigned */
4387 case OPC_TLTIU: /* r0 < 0 unsigned */
4388 case OPC_TNE: /* rs != rs */
4389 case OPC_TNEI: /* r0 != 0 */
ead9360e 4390 /* Never trap: treat as NOP. */
cdc0faa6 4391 break;
6af0bf9c
FB
4392 }
4393 } else {
42a268c2 4394 TCGLabel *l1 = gen_new_label();
cdc0faa6 4395
6af0bf9c
FB
4396 switch (opc) {
4397 case OPC_TEQ:
4398 case OPC_TEQI:
cdc0faa6 4399 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4400 break;
4401 case OPC_TGE:
4402 case OPC_TGEI:
cdc0faa6 4403 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4404 break;
4405 case OPC_TGEU:
4406 case OPC_TGEIU:
cdc0faa6 4407 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4408 break;
4409 case OPC_TLT:
4410 case OPC_TLTI:
cdc0faa6 4411 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4412 break;
4413 case OPC_TLTU:
4414 case OPC_TLTIU:
cdc0faa6 4415 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4416 break;
4417 case OPC_TNE:
4418 case OPC_TNEI:
cdc0faa6 4419 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4420 break;
6af0bf9c 4421 }
cdc0faa6 4422 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4423 gen_set_label(l1);
4424 }
be24bb4f
TS
4425 tcg_temp_free(t0);
4426 tcg_temp_free(t1);
6af0bf9c
FB
4427}
4428
356265ae 4429static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4430{
6e256c93
FB
4431 TranslationBlock *tb;
4432 tb = ctx->tb;
7b270ef2
NF
4433 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4434 likely(!ctx->singlestep_enabled)) {
57fec1fe 4435 tcg_gen_goto_tb(n);
9b9e4393 4436 gen_save_pc(dest);
8cfd0495 4437 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4438 } else {
9b9e4393 4439 gen_save_pc(dest);
7b270ef2
NF
4440 if (ctx->singlestep_enabled) {
4441 save_cpu_state(ctx, 0);
895c2d04 4442 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4443 }
57fec1fe 4444 tcg_gen_exit_tb(0);
6e256c93 4445 }
c53be334
FB
4446}
4447
6af0bf9c 4448/* Branches (before delay slot) */
7a387fff 4449static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4450 int insn_bytes,
b231c103
YK
4451 int rs, int rt, int32_t offset,
4452 int delayslot_size)
6af0bf9c 4453{
d077b6f7 4454 target_ulong btgt = -1;
3ad4bb2d 4455 int blink = 0;
2fdbad25 4456 int bcond_compute = 0;
1ba74fb8
AJ
4457 TCGv t0 = tcg_temp_new();
4458 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4459
4460 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4461#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4462 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4463 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4464#endif
3ad4bb2d 4465 generate_exception(ctx, EXCP_RI);
6c5c1e20 4466 goto out;
3ad4bb2d 4467 }
6af0bf9c 4468
6af0bf9c
FB
4469 /* Load needed operands */
4470 switch (opc) {
4471 case OPC_BEQ:
4472 case OPC_BEQL:
4473 case OPC_BNE:
4474 case OPC_BNEL:
4475 /* Compare two registers */
4476 if (rs != rt) {
6c5c1e20
TS
4477 gen_load_gpr(t0, rs);
4478 gen_load_gpr(t1, rt);
2fdbad25 4479 bcond_compute = 1;
6af0bf9c 4480 }
7dca4ad0 4481 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4482 break;
4483 case OPC_BGEZ:
4484 case OPC_BGEZAL:
4485 case OPC_BGEZALL:
4486 case OPC_BGEZL:
4487 case OPC_BGTZ:
4488 case OPC_BGTZL:
4489 case OPC_BLEZ:
4490 case OPC_BLEZL:
4491 case OPC_BLTZ:
4492 case OPC_BLTZAL:
4493 case OPC_BLTZALL:
4494 case OPC_BLTZL:
4495 /* Compare to zero */
4496 if (rs != 0) {
6c5c1e20 4497 gen_load_gpr(t0, rs);
2fdbad25 4498 bcond_compute = 1;
6af0bf9c 4499 }
7dca4ad0 4500 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4501 break;
e45a93e2
JL
4502 case OPC_BPOSGE32:
4503#if defined(TARGET_MIPS64)
4504 case OPC_BPOSGE64:
4505 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4506#else
4507 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4508#endif
4509 bcond_compute = 1;
4510 btgt = ctx->pc + insn_bytes + offset;
4511 break;
6af0bf9c
FB
4512 case OPC_J:
4513 case OPC_JAL:
364d4831 4514 case OPC_JALX:
6af0bf9c 4515 /* Jump to immediate */
7dca4ad0 4516 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4517 break;
4518 case OPC_JR:
4519 case OPC_JALR:
4520 /* Jump to register */
7a387fff
TS
4521 if (offset != 0 && offset != 16) {
4522 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4523 others are reserved. */
923617a3 4524 MIPS_INVAL("jump hint");
6af0bf9c 4525 generate_exception(ctx, EXCP_RI);
6c5c1e20 4526 goto out;
6af0bf9c 4527 }
d077b6f7 4528 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4529 break;
4530 default:
4531 MIPS_INVAL("branch/jump");
4532 generate_exception(ctx, EXCP_RI);
6c5c1e20 4533 goto out;
6af0bf9c 4534 }
2fdbad25 4535 if (bcond_compute == 0) {
6af0bf9c
FB
4536 /* No condition to be computed */
4537 switch (opc) {
4538 case OPC_BEQ: /* rx == rx */
4539 case OPC_BEQL: /* rx == rx likely */
4540 case OPC_BGEZ: /* 0 >= 0 */
4541 case OPC_BGEZL: /* 0 >= 0 likely */
4542 case OPC_BLEZ: /* 0 <= 0 */
4543 case OPC_BLEZL: /* 0 <= 0 likely */
4544 /* Always take */
4ad40f36 4545 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4546 MIPS_DEBUG("balways");
4547 break;
4548 case OPC_BGEZAL: /* 0 >= 0 */
4549 case OPC_BGEZALL: /* 0 >= 0 likely */
4550 /* Always take and link */
4551 blink = 31;
4ad40f36 4552 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4553 MIPS_DEBUG("balways and link");
4554 break;
4555 case OPC_BNE: /* rx != rx */
4556 case OPC_BGTZ: /* 0 > 0 */
4557 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4558 /* Treat as NOP. */
6af0bf9c 4559 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4560 goto out;
eeef26cd 4561 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4562 /* Handle as an unconditional branch to get correct delay
4563 slot checking. */
4564 blink = 31;
b231c103 4565 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4566 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4567 MIPS_DEBUG("bnever and link");
3c824109 4568 break;
eeef26cd 4569 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4570 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4571 /* Skip the instruction in the delay slot */
4572 MIPS_DEBUG("bnever, link and skip");
4573 ctx->pc += 4;
6c5c1e20 4574 goto out;
6af0bf9c
FB
4575 case OPC_BNEL: /* rx != rx likely */
4576 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4577 case OPC_BLTZL: /* 0 < 0 likely */
4578 /* Skip the instruction in the delay slot */
4579 MIPS_DEBUG("bnever and skip");
9898128f 4580 ctx->pc += 4;
6c5c1e20 4581 goto out;
6af0bf9c 4582 case OPC_J:
4ad40f36 4583 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4584 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4585 break;
364d4831
NF
4586 case OPC_JALX:
4587 ctx->hflags |= MIPS_HFLAG_BX;
4588 /* Fallthrough */
6af0bf9c
FB
4589 case OPC_JAL:
4590 blink = 31;
4ad40f36 4591 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4592 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4593 break;
4594 case OPC_JR:
4ad40f36 4595 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4596 MIPS_DEBUG("jr %s", regnames[rs]);
4597 break;
4598 case OPC_JALR:
4599 blink = rt;
4ad40f36 4600 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4601 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4602 break;
4603 default:
4604 MIPS_INVAL("branch/jump");
4605 generate_exception(ctx, EXCP_RI);
6c5c1e20 4606 goto out;
6af0bf9c
FB
4607 }
4608 } else {
4609 switch (opc) {
4610 case OPC_BEQ:
e68dd28f 4611 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4612 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4613 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4614 goto not_likely;
4615 case OPC_BEQL:
e68dd28f 4616 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4617 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4618 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4619 goto likely;
4620 case OPC_BNE:
e68dd28f 4621 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4622 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4623 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4624 goto not_likely;
4625 case OPC_BNEL:
e68dd28f 4626 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4627 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4628 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4629 goto likely;
4630 case OPC_BGEZ:
e68dd28f 4631 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4632 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4633 goto not_likely;
4634 case OPC_BGEZL:
e68dd28f 4635 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4636 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4637 goto likely;
4638 case OPC_BGEZAL:
e68dd28f 4639 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4640 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4641 blink = 31;
4642 goto not_likely;
4643 case OPC_BGEZALL:
e68dd28f 4644 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4645 blink = 31;
d077b6f7 4646 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4647 goto likely;
4648 case OPC_BGTZ:
e68dd28f 4649 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4650 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4651 goto not_likely;
4652 case OPC_BGTZL:
e68dd28f 4653 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4654 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4655 goto likely;
4656 case OPC_BLEZ:
e68dd28f 4657 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4658 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4659 goto not_likely;
4660 case OPC_BLEZL:
e68dd28f 4661 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4662 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4663 goto likely;
4664 case OPC_BLTZ:
e68dd28f 4665 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4666 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4667 goto not_likely;
4668 case OPC_BLTZL:
e68dd28f 4669 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4670 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4671 goto likely;
e45a93e2
JL
4672 case OPC_BPOSGE32:
4673 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4674 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4675 goto not_likely;
4676#if defined(TARGET_MIPS64)
4677 case OPC_BPOSGE64:
4678 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4679 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4680 goto not_likely;
4681#endif
6af0bf9c 4682 case OPC_BLTZAL:
e68dd28f 4683 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4684 blink = 31;
d077b6f7 4685 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4686 not_likely:
4ad40f36 4687 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4688 break;
4689 case OPC_BLTZALL:
e68dd28f 4690 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4691 blink = 31;
d077b6f7 4692 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4693 likely:
4ad40f36 4694 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4695 break;
c53f4a62
TS
4696 default:
4697 MIPS_INVAL("conditional branch/jump");
4698 generate_exception(ctx, EXCP_RI);
6c5c1e20 4699 goto out;
6af0bf9c 4700 }
6af0bf9c 4701 }
923617a3 4702 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4703 blink, ctx->hflags, btgt);
9b9e4393 4704
d077b6f7 4705 ctx->btarget = btgt;
b231c103
YK
4706
4707 switch (delayslot_size) {
4708 case 2:
4709 ctx->hflags |= MIPS_HFLAG_BDS16;
4710 break;
4711 case 4:
4712 ctx->hflags |= MIPS_HFLAG_BDS32;
4713 break;
4714 }
4715
6af0bf9c 4716 if (blink > 0) {
b231c103 4717 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4718 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4719
364d4831 4720 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4721 }
6c5c1e20
TS
4722
4723 out:
364d4831
NF
4724 if (insn_bytes == 2)
4725 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4726 tcg_temp_free(t0);
4727 tcg_temp_free(t1);
6af0bf9c
FB
4728}
4729
7a387fff
TS
4730/* special3 bitfield operations */
4731static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4732 int rs, int lsb, int msb)
7a387fff 4733{
a7812ae4
PB
4734 TCGv t0 = tcg_temp_new();
4735 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4736
4737 gen_load_gpr(t1, rs);
7a387fff
TS
4738 switch (opc) {
4739 case OPC_EXT:
4740 if (lsb + msb > 31)
4741 goto fail;
505ad7c2
AJ
4742 tcg_gen_shri_tl(t0, t1, lsb);
4743 if (msb != 31) {
4744 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4745 } else {
4746 tcg_gen_ext32s_tl(t0, t0);
4747 }
7a387fff 4748 break;
c6d6dd7c 4749#if defined(TARGET_MIPS64)
7a387fff 4750 case OPC_DEXTM:
505ad7c2
AJ
4751 tcg_gen_shri_tl(t0, t1, lsb);
4752 if (msb != 31) {
4753 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4754 }
7a387fff
TS
4755 break;
4756 case OPC_DEXTU:
505ad7c2
AJ
4757 tcg_gen_shri_tl(t0, t1, lsb + 32);
4758 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4759 break;
4760 case OPC_DEXT:
505ad7c2
AJ
4761 tcg_gen_shri_tl(t0, t1, lsb);
4762 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4763 break;
c6d6dd7c 4764#endif
7a387fff
TS
4765 case OPC_INS:
4766 if (lsb > msb)
4767 goto fail;
6c5c1e20 4768 gen_load_gpr(t0, rt);
e0d002f1 4769 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4770 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4771 break;
c6d6dd7c 4772#if defined(TARGET_MIPS64)
7a387fff 4773 case OPC_DINSM:
6c5c1e20 4774 gen_load_gpr(t0, rt);
e0d002f1 4775 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4776 break;
4777 case OPC_DINSU:
6c5c1e20 4778 gen_load_gpr(t0, rt);
e0d002f1 4779 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4780 break;
4781 case OPC_DINS:
6c5c1e20 4782 gen_load_gpr(t0, rt);
e0d002f1 4783 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4784 break;
c6d6dd7c 4785#endif
7a387fff
TS
4786 default:
4787fail:
4788 MIPS_INVAL("bitops");
4789 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4790 tcg_temp_free(t0);
4791 tcg_temp_free(t1);
7a387fff
TS
4792 return;
4793 }
6c5c1e20
TS
4794 gen_store_gpr(t0, rt);
4795 tcg_temp_free(t0);
4796 tcg_temp_free(t1);
7a387fff
TS
4797}
4798
49bcf33c
AJ
4799static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4800{
3a55fa47 4801 TCGv t0;
49bcf33c 4802
3a55fa47
AJ
4803 if (rd == 0) {
4804 /* If no destination, treat it as a NOP. */
4805 MIPS_DEBUG("NOP");
4806 return;
4807 }
4808
4809 t0 = tcg_temp_new();
4810 gen_load_gpr(t0, rt);
49bcf33c
AJ
4811 switch (op2) {
4812 case OPC_WSBH:
3a55fa47
AJ
4813 {
4814 TCGv t1 = tcg_temp_new();
4815
4816 tcg_gen_shri_tl(t1, t0, 8);
4817 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4818 tcg_gen_shli_tl(t0, t0, 8);
4819 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4820 tcg_gen_or_tl(t0, t0, t1);
4821 tcg_temp_free(t1);
4822 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4823 }
49bcf33c
AJ
4824 break;
4825 case OPC_SEB:
3a55fa47 4826 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4827 break;
4828 case OPC_SEH:
3a55fa47 4829 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4830 break;
4831#if defined(TARGET_MIPS64)
4832 case OPC_DSBH:
3a55fa47
AJ
4833 {
4834 TCGv t1 = tcg_temp_new();
4835
4836 tcg_gen_shri_tl(t1, t0, 8);
4837 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4838 tcg_gen_shli_tl(t0, t0, 8);
4839 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4840 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4841 tcg_temp_free(t1);
4842 }
49bcf33c
AJ
4843 break;
4844 case OPC_DSHD:
3a55fa47
AJ
4845 {
4846 TCGv t1 = tcg_temp_new();
4847
4848 tcg_gen_shri_tl(t1, t0, 16);
4849 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4850 tcg_gen_shli_tl(t0, t0, 16);
4851 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4852 tcg_gen_or_tl(t0, t0, t1);
4853 tcg_gen_shri_tl(t1, t0, 32);
4854 tcg_gen_shli_tl(t0, t0, 32);
4855 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4856 tcg_temp_free(t1);
4857 }
49bcf33c
AJ
4858 break;
4859#endif
4860 default:
4861 MIPS_INVAL("bsfhl");
4862 generate_exception(ctx, EXCP_RI);
4863 tcg_temp_free(t0);
49bcf33c
AJ
4864 return;
4865 }
49bcf33c 4866 tcg_temp_free(t0);
49bcf33c
AJ
4867}
4868
1f1b4c00
YK
4869static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4870 int imm2)
4871{
4872 TCGv t0;
4873 TCGv t1;
4874 if (rd == 0) {
4875 /* Treat as NOP. */
4876 return;
4877 }
4878 t0 = tcg_temp_new();
4879 t1 = tcg_temp_new();
4880 gen_load_gpr(t0, rs);
4881 gen_load_gpr(t1, rt);
4882 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4883 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4884 if (opc == OPC_LSA) {
4885 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4886 }
4887
4888 tcg_temp_free(t1);
4889 tcg_temp_free(t0);
4890
4891 return;
4892}
4893
4894static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4895 int bp)
284b731a 4896{
1f1b4c00
YK
4897 TCGv t0;
4898 if (rd == 0) {
4899 /* Treat as NOP. */
4900 return;
4901 }
4902 t0 = tcg_temp_new();
4903 gen_load_gpr(t0, rt);
4904 if (bp == 0) {
4905 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4906 } else {
4907 TCGv t1 = tcg_temp_new();
4908 gen_load_gpr(t1, rs);
4909 switch (opc) {
4910 case OPC_ALIGN:
4911 {
4912 TCGv_i64 t2 = tcg_temp_new_i64();
4913 tcg_gen_concat_tl_i64(t2, t1, t0);
4914 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4915 gen_move_low32(cpu_gpr[rd], t2);
4916 tcg_temp_free_i64(t2);
4917 }
4918 break;
284b731a 4919#if defined(TARGET_MIPS64)
1f1b4c00
YK
4920 case OPC_DALIGN:
4921 tcg_gen_shli_tl(t0, t0, 8 * bp);
4922 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4923 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4924 break;
284b731a 4925#endif
1f1b4c00
YK
4926 }
4927 tcg_temp_free(t1);
4928 }
4929
4930 tcg_temp_free(t0);
4931}
4932
4933static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4934{
4935 TCGv t0;
4936 if (rd == 0) {
4937 /* Treat as NOP. */
4938 return;
4939 }
4940 t0 = tcg_temp_new();
4941 gen_load_gpr(t0, rt);
4942 switch (opc) {
4943 case OPC_BITSWAP:
4944 gen_helper_bitswap(cpu_gpr[rd], t0);
4945 break;
4946#if defined(TARGET_MIPS64)
4947 case OPC_DBITSWAP:
4948 gen_helper_dbitswap(cpu_gpr[rd], t0);
4949 break;
4950#endif
4951 }
4952 tcg_temp_free(t0);
284b731a
LA
4953}
4954
1f1b4c00
YK
4955#ifndef CONFIG_USER_ONLY
4956/* CP0 (MMU and control) */
5204ea79
LA
4957static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4958{
4959 TCGv_i64 t0 = tcg_temp_new_i64();
4960 TCGv_i64 t1 = tcg_temp_new_i64();
4961
4962 tcg_gen_ext_tl_i64(t0, arg);
4963 tcg_gen_ld_i64(t1, cpu_env, off);
4964#if defined(TARGET_MIPS64)
4965 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4966#else
4967 tcg_gen_concat32_i64(t1, t1, t0);
4968#endif
4969 tcg_gen_st_i64(t1, cpu_env, off);
4970 tcg_temp_free_i64(t1);
4971 tcg_temp_free_i64(t0);
4972}
4973
4974static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4975{
4976 TCGv_i64 t0 = tcg_temp_new_i64();
4977 TCGv_i64 t1 = tcg_temp_new_i64();
4978
4979 tcg_gen_ext_tl_i64(t0, arg);
4980 tcg_gen_ld_i64(t1, cpu_env, off);
4981 tcg_gen_concat32_i64(t1, t1, t0);
4982 tcg_gen_st_i64(t1, cpu_env, off);
4983 tcg_temp_free_i64(t1);
4984 tcg_temp_free_i64(t0);
4985}
4986
4987static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4988{
4989 TCGv_i64 t0 = tcg_temp_new_i64();
4990
4991 tcg_gen_ld_i64(t0, cpu_env, off);
4992#if defined(TARGET_MIPS64)
4993 tcg_gen_shri_i64(t0, t0, 30);
4994#else
4995 tcg_gen_shri_i64(t0, t0, 32);
4996#endif
4997 gen_move_low32(arg, t0);
4998 tcg_temp_free_i64(t0);
4999}
5000
5001static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5002{
5003 TCGv_i64 t0 = tcg_temp_new_i64();
5004
5005 tcg_gen_ld_i64(t0, cpu_env, off);
5006 tcg_gen_shri_i64(t0, t0, 32 + shift);
5007 gen_move_low32(arg, t0);
5008 tcg_temp_free_i64(t0);
5009}
5010
d9bea114 5011static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 5012{
d9bea114 5013 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 5014
d9bea114
AJ
5015 tcg_gen_ld_i32(t0, cpu_env, off);
5016 tcg_gen_ext_i32_tl(arg, t0);
5017 tcg_temp_free_i32(t0);
4f57689a
TS
5018}
5019
d9bea114 5020static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 5021{
d9bea114
AJ
5022 tcg_gen_ld_tl(arg, cpu_env, off);
5023 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
5024}
5025
d9bea114 5026static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 5027{
d9bea114 5028 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 5029
d9bea114
AJ
5030 tcg_gen_trunc_tl_i32(t0, arg);
5031 tcg_gen_st_i32(t0, cpu_env, off);
5032 tcg_temp_free_i32(t0);
f1aa6320
TS
5033}
5034
d9bea114 5035static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 5036{
d9bea114
AJ
5037 tcg_gen_ext32s_tl(arg, arg);
5038 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
5039}
5040
5204ea79
LA
5041static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5042{
5043 const char *rn = "invalid";
5044
5045 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
5046 goto mfhc0_read_zero;
5047 }
5048
5049 switch (reg) {
5050 case 2:
5051 switch (sel) {
5052 case 0:
5053 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5054 rn = "EntryLo0";
5055 break;
5056 default:
5057 goto mfhc0_read_zero;
5058 }
5059 break;
5060 case 3:
5061 switch (sel) {
5062 case 0:
5063 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5064 rn = "EntryLo1";
5065 break;
5066 default:
5067 goto mfhc0_read_zero;
5068 }
5069 break;
5070 case 17:
5071 switch (sel) {
5072 case 0:
5073 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5074 ctx->CP0_LLAddr_shift);
5075 rn = "LLAddr";
5076 break;
5077 default:
5078 goto mfhc0_read_zero;
5079 }
5080 break;
5081 case 28:
5082 switch (sel) {
5083 case 0:
5084 case 2:
5085 case 4:
5086 case 6:
5087 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5088 rn = "TagLo";
5089 break;
5090 default:
5091 goto mfhc0_read_zero;
5092 }
5093 break;
5094 default:
5095 goto mfhc0_read_zero;
5096 }
5097
5098 (void)rn; /* avoid a compiler warning */
5099 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5100 return;
5101
5102mfhc0_read_zero:
5103 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5104 tcg_gen_movi_tl(arg, 0);
5105}
5106
5107static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5108{
5109 const char *rn = "invalid";
5110 uint64_t mask = ctx->PAMask >> 36;
5111
5112 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
5113 goto mthc0_nop;
5114 }
5115
5116 switch (reg) {
5117 case 2:
5118 switch (sel) {
5119 case 0:
5120 tcg_gen_andi_tl(arg, arg, mask);
5121 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5122 rn = "EntryLo0";
5123 break;
5124 default:
5125 goto mthc0_nop;
5126 }
5127 break;
5128 case 3:
5129 switch (sel) {
5130 case 0:
5131 tcg_gen_andi_tl(arg, arg, mask);
5132 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5133 rn = "EntryLo1";
5134 break;
5135 default:
5136 goto mthc0_nop;
5137 }
5138 break;
5139 case 17:
5140 switch (sel) {
5141 case 0:
5142 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5143 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5144 relevant for modern MIPS cores supporting MTHC0, therefore
5145 treating MTHC0 to LLAddr as NOP. */
5146 rn = "LLAddr";
5147 break;
5148 default:
5149 goto mthc0_nop;
5150 }
5151 break;
5152 case 28:
5153 switch (sel) {
5154 case 0:
5155 case 2:
5156 case 4:
5157 case 6:
5158 tcg_gen_andi_tl(arg, arg, mask);
5159 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5160 rn = "TagLo";
5161 break;
5162 default:
5163 goto mthc0_nop;
5164 }
5165 break;
5166 default:
5167 goto mthc0_nop;
5168 }
5169
5170 (void)rn; /* avoid a compiler warning */
5171mthc0_nop:
5172 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5173}
5174
e98c0d17
LA
5175static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5176{
5177 if (ctx->insn_flags & ISA_MIPS32R6) {
5178 tcg_gen_movi_tl(arg, 0);
5179 } else {
5180 tcg_gen_movi_tl(arg, ~0);
5181 }
5182}
5183
f31b035a
LA
5184#define CP0_CHECK(c) \
5185 do { \
5186 if (!(c)) { \
5187 goto cp0_unimplemented; \
5188 } \
5189 } while (0)
5190
d75c135e 5191static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5192{
7a387fff 5193 const char *rn = "invalid";
873eb012 5194
e189e748 5195 if (sel != 0)
d75c135e 5196 check_insn(ctx, ISA_MIPS32);
e189e748 5197
873eb012
TS
5198 switch (reg) {
5199 case 0:
7a387fff
TS
5200 switch (sel) {
5201 case 0:
7db13fae 5202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
5203 rn = "Index";
5204 break;
5205 case 1:
f31b035a 5206 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5207 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 5208 rn = "MVPControl";
ead9360e 5209 break;
7a387fff 5210 case 2:
f31b035a 5211 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5212 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 5213 rn = "MVPConf0";
ead9360e 5214 break;
7a387fff 5215 case 3:
f31b035a 5216 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5217 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 5218 rn = "MVPConf1";
ead9360e 5219 break;
7a387fff 5220 default:
f31b035a 5221 goto cp0_unimplemented;
7a387fff 5222 }
873eb012
TS
5223 break;
5224 case 1:
7a387fff
TS
5225 switch (sel) {
5226 case 0:
f31b035a 5227 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5228 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5229 rn = "Random";
2423f660 5230 break;
7a387fff 5231 case 1:
f31b035a 5232 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5233 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5234 rn = "VPEControl";
ead9360e 5235 break;
7a387fff 5236 case 2:
f31b035a 5237 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5239 rn = "VPEConf0";
ead9360e 5240 break;
7a387fff 5241 case 3:
f31b035a 5242 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5244 rn = "VPEConf1";
ead9360e 5245 break;
7a387fff 5246 case 4:
f31b035a 5247 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5248 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5249 rn = "YQMask";
ead9360e 5250 break;
7a387fff 5251 case 5:
f31b035a 5252 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5253 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5254 rn = "VPESchedule";
ead9360e 5255 break;
7a387fff 5256 case 6:
f31b035a 5257 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5258 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5259 rn = "VPEScheFBack";
ead9360e 5260 break;
7a387fff 5261 case 7:
f31b035a 5262 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5264 rn = "VPEOpt";
ead9360e 5265 break;
7a387fff 5266 default:
f31b035a 5267 goto cp0_unimplemented;
7a387fff 5268 }
873eb012
TS
5269 break;
5270 case 2:
7a387fff
TS
5271 switch (sel) {
5272 case 0:
284b731a
LA
5273 {
5274 TCGv_i64 tmp = tcg_temp_new_i64();
5275 tcg_gen_ld_i64(tmp, cpu_env,
5276 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5277#if defined(TARGET_MIPS64)
284b731a
LA
5278 if (ctx->rxi) {
5279 /* Move RI/XI fields to bits 31:30 */
5280 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5281 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5282 }
7207c7f9 5283#endif
284b731a
LA
5284 gen_move_low32(arg, tmp);
5285 tcg_temp_free_i64(tmp);
5286 }
2423f660
TS
5287 rn = "EntryLo0";
5288 break;
7a387fff 5289 case 1:
f31b035a 5290 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5291 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5292 rn = "TCStatus";
ead9360e 5293 break;
7a387fff 5294 case 2:
f31b035a 5295 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5296 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5297 rn = "TCBind";
ead9360e 5298 break;
7a387fff 5299 case 3:
f31b035a 5300 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5301 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5302 rn = "TCRestart";
ead9360e 5303 break;
7a387fff 5304 case 4:
f31b035a 5305 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5306 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5307 rn = "TCHalt";
ead9360e 5308 break;
7a387fff 5309 case 5:
f31b035a 5310 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5311 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5312 rn = "TCContext";
ead9360e 5313 break;
7a387fff 5314 case 6:
f31b035a 5315 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5316 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5317 rn = "TCSchedule";
ead9360e 5318 break;
7a387fff 5319 case 7:
f31b035a 5320 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5321 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5322 rn = "TCScheFBack";
ead9360e 5323 break;
7a387fff 5324 default:
f31b035a 5325 goto cp0_unimplemented;
7a387fff 5326 }
873eb012
TS
5327 break;
5328 case 3:
7a387fff
TS
5329 switch (sel) {
5330 case 0:
284b731a
LA
5331 {
5332 TCGv_i64 tmp = tcg_temp_new_i64();
5333 tcg_gen_ld_i64(tmp, cpu_env,
5334 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5335#if defined(TARGET_MIPS64)
284b731a
LA
5336 if (ctx->rxi) {
5337 /* Move RI/XI fields to bits 31:30 */
5338 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5339 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5340 }
7207c7f9 5341#endif
284b731a
LA
5342 gen_move_low32(arg, tmp);
5343 tcg_temp_free_i64(tmp);
5344 }
2423f660
TS
5345 rn = "EntryLo1";
5346 break;
7a387fff 5347 default:
f31b035a 5348 goto cp0_unimplemented;
1579a72e 5349 }
873eb012
TS
5350 break;
5351 case 4:
7a387fff
TS
5352 switch (sel) {
5353 case 0:
7db13fae 5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5355 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5356 rn = "Context";
5357 break;
7a387fff 5358 case 1:
d9bea114 5359// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5360 rn = "ContextConfig";
f31b035a 5361 goto cp0_unimplemented;
2423f660 5362// break;
d279279e 5363 case 2:
f31b035a
LA
5364 CP0_CHECK(ctx->ulri);
5365 tcg_gen_ld32s_tl(arg, cpu_env,
5366 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5367 rn = "UserLocal";
d279279e 5368 break;
7a387fff 5369 default:
f31b035a 5370 goto cp0_unimplemented;
1579a72e 5371 }
873eb012
TS
5372 break;
5373 case 5:
7a387fff
TS
5374 switch (sel) {
5375 case 0:
7db13fae 5376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5377 rn = "PageMask";
5378 break;
7a387fff 5379 case 1:
d75c135e 5380 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5382 rn = "PageGrain";
5383 break;
7a387fff 5384 default:
f31b035a 5385 goto cp0_unimplemented;
1579a72e 5386 }
873eb012
TS
5387 break;
5388 case 6:
7a387fff
TS
5389 switch (sel) {
5390 case 0:
7db13fae 5391 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5392 rn = "Wired";
5393 break;
7a387fff 5394 case 1:
d75c135e 5395 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5397 rn = "SRSConf0";
ead9360e 5398 break;
7a387fff 5399 case 2:
d75c135e 5400 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5402 rn = "SRSConf1";
ead9360e 5403 break;
7a387fff 5404 case 3:
d75c135e 5405 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5406 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5407 rn = "SRSConf2";
ead9360e 5408 break;
7a387fff 5409 case 4:
d75c135e 5410 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5412 rn = "SRSConf3";
ead9360e 5413 break;
7a387fff 5414 case 5:
d75c135e 5415 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5417 rn = "SRSConf4";
ead9360e 5418 break;
7a387fff 5419 default:
f31b035a 5420 goto cp0_unimplemented;
1579a72e 5421 }
873eb012 5422 break;
8c0fdd85 5423 case 7:
7a387fff
TS
5424 switch (sel) {
5425 case 0:
d75c135e 5426 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5428 rn = "HWREna";
5429 break;
7a387fff 5430 default:
f31b035a 5431 goto cp0_unimplemented;
1579a72e 5432 }
8c0fdd85 5433 break;
873eb012 5434 case 8:
7a387fff
TS
5435 switch (sel) {
5436 case 0:
7db13fae 5437 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5438 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5439 rn = "BadVAddr";
2423f660 5440 break;
aea14095 5441 case 1:
f31b035a
LA
5442 CP0_CHECK(ctx->bi);
5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5444 rn = "BadInstr";
aea14095
LA
5445 break;
5446 case 2:
f31b035a
LA
5447 CP0_CHECK(ctx->bp);
5448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5449 rn = "BadInstrP";
aea14095 5450 break;
7a387fff 5451 default:
f31b035a 5452 goto cp0_unimplemented;
aea14095 5453 }
873eb012
TS
5454 break;
5455 case 9:
7a387fff
TS
5456 switch (sel) {
5457 case 0:
2e70f6ef 5458 /* Mark as an IO operation because we read the time. */
bd79255d 5459 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5460 gen_io_start();
bd79255d 5461 }
895c2d04 5462 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 5463 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5464 gen_io_end();
2e70f6ef 5465 }
55807224
EI
5466 /* Break the TB to be able to take timer interrupts immediately
5467 after reading count. */
5468 ctx->bstate = BS_STOP;
2423f660
TS
5469 rn = "Count";
5470 break;
5471 /* 6,7 are implementation dependent */
7a387fff 5472 default:
f31b035a 5473 goto cp0_unimplemented;
2423f660 5474 }
873eb012
TS
5475 break;
5476 case 10:
7a387fff
TS
5477 switch (sel) {
5478 case 0:
7db13fae 5479 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5480 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5481 rn = "EntryHi";
5482 break;
7a387fff 5483 default:
f31b035a 5484 goto cp0_unimplemented;
1579a72e 5485 }
873eb012
TS
5486 break;
5487 case 11:
7a387fff
TS
5488 switch (sel) {
5489 case 0:
7db13fae 5490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5491 rn = "Compare";
5492 break;
5493 /* 6,7 are implementation dependent */
7a387fff 5494 default:
f31b035a 5495 goto cp0_unimplemented;
2423f660 5496 }
873eb012
TS
5497 break;
5498 case 12:
7a387fff
TS
5499 switch (sel) {
5500 case 0:
7db13fae 5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5502 rn = "Status";
5503 break;
7a387fff 5504 case 1:
d75c135e 5505 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5507 rn = "IntCtl";
5508 break;
7a387fff 5509 case 2:
d75c135e 5510 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5512 rn = "SRSCtl";
5513 break;
7a387fff 5514 case 3:
d75c135e 5515 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5516 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5517 rn = "SRSMap";
fd88b6ab 5518 break;
7a387fff 5519 default:
f31b035a 5520 goto cp0_unimplemented;
7a387fff 5521 }
873eb012
TS
5522 break;
5523 case 13:
7a387fff
TS
5524 switch (sel) {
5525 case 0:
7db13fae 5526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5527 rn = "Cause";
5528 break;
7a387fff 5529 default:
f31b035a 5530 goto cp0_unimplemented;
7a387fff 5531 }
873eb012
TS
5532 break;
5533 case 14:
7a387fff
TS
5534 switch (sel) {
5535 case 0:
7db13fae 5536 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5537 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5538 rn = "EPC";
5539 break;
7a387fff 5540 default:
f31b035a 5541 goto cp0_unimplemented;
1579a72e 5542 }
873eb012
TS
5543 break;
5544 case 15:
7a387fff
TS
5545 switch (sel) {
5546 case 0:
7db13fae 5547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5548 rn = "PRid";
5549 break;
7a387fff 5550 case 1:
d75c135e 5551 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5553 rn = "EBase";
5554 break;
7a387fff 5555 default:
f31b035a 5556 goto cp0_unimplemented;
7a387fff 5557 }
873eb012
TS
5558 break;
5559 case 16:
5560 switch (sel) {
5561 case 0:
7db13fae 5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5563 rn = "Config";
5564 break;
5565 case 1:
7db13fae 5566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5567 rn = "Config1";
5568 break;
7a387fff 5569 case 2:
7db13fae 5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5571 rn = "Config2";
5572 break;
5573 case 3:
7db13fae 5574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5575 rn = "Config3";
5576 break;
b4160af1
PJ
5577 case 4:
5578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5579 rn = "Config4";
5580 break;
b4dd99a3
PJ
5581 case 5:
5582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5583 rn = "Config5";
5584 break;
e397ee33
TS
5585 /* 6,7 are implementation dependent */
5586 case 6:
7db13fae 5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5588 rn = "Config6";
5589 break;
5590 case 7:
7db13fae 5591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5592 rn = "Config7";
5593 break;
873eb012 5594 default:
f31b035a 5595 goto cp0_unimplemented;
873eb012
TS
5596 }
5597 break;
5598 case 17:
7a387fff
TS
5599 switch (sel) {
5600 case 0:
895c2d04 5601 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5602 rn = "LLAddr";
5603 break;
7a387fff 5604 default:
f31b035a 5605 goto cp0_unimplemented;
7a387fff 5606 }
873eb012
TS
5607 break;
5608 case 18:
7a387fff 5609 switch (sel) {
fd88b6ab 5610 case 0 ... 7:
895c2d04 5611 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5612 rn = "WatchLo";
5613 break;
7a387fff 5614 default:
f31b035a 5615 goto cp0_unimplemented;
7a387fff 5616 }
873eb012
TS
5617 break;
5618 case 19:
7a387fff 5619 switch (sel) {
fd88b6ab 5620 case 0 ...7:
895c2d04 5621 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5622 rn = "WatchHi";
5623 break;
7a387fff 5624 default:
f31b035a 5625 goto cp0_unimplemented;
7a387fff 5626 }
873eb012 5627 break;
8c0fdd85 5628 case 20:
7a387fff
TS
5629 switch (sel) {
5630 case 0:
d26bc211 5631#if defined(TARGET_MIPS64)
d75c135e 5632 check_insn(ctx, ISA_MIPS3);
7db13fae 5633 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5634 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5635 rn = "XContext";
5636 break;
703eaf37 5637#endif
7a387fff 5638 default:
f31b035a 5639 goto cp0_unimplemented;
7a387fff 5640 }
8c0fdd85
TS
5641 break;
5642 case 21:
7a387fff 5643 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5644 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5645 switch (sel) {
5646 case 0:
7db13fae 5647 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5648 rn = "Framemask";
5649 break;
7a387fff 5650 default:
f31b035a 5651 goto cp0_unimplemented;
7a387fff 5652 }
8c0fdd85
TS
5653 break;
5654 case 22:
d9bea114 5655 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5656 rn = "'Diagnostic"; /* implementation dependent */
5657 break;
873eb012 5658 case 23:
7a387fff
TS
5659 switch (sel) {
5660 case 0:
895c2d04 5661 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5662 rn = "Debug";
5663 break;
7a387fff 5664 case 1:
d9bea114 5665// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5666 rn = "TraceControl";
5667// break;
7a387fff 5668 case 2:
d9bea114 5669// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5670 rn = "TraceControl2";
5671// break;
7a387fff 5672 case 3:
d9bea114 5673// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5674 rn = "UserTraceData";
5675// break;
7a387fff 5676 case 4:
d9bea114 5677// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5678 rn = "TraceBPC";
5679// break;
7a387fff 5680 default:
f31b035a 5681 goto cp0_unimplemented;
7a387fff 5682 }
873eb012
TS
5683 break;
5684 case 24:
7a387fff
TS
5685 switch (sel) {
5686 case 0:
f0b3f3ae 5687 /* EJTAG support */
7db13fae 5688 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5689 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5690 rn = "DEPC";
5691 break;
7a387fff 5692 default:
f31b035a 5693 goto cp0_unimplemented;
7a387fff 5694 }
873eb012 5695 break;
8c0fdd85 5696 case 25:
7a387fff
TS
5697 switch (sel) {
5698 case 0:
7db13fae 5699 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5700 rn = "Performance0";
7a387fff
TS
5701 break;
5702 case 1:
d9bea114 5703// gen_helper_mfc0_performance1(arg);
2423f660
TS
5704 rn = "Performance1";
5705// break;
7a387fff 5706 case 2:
d9bea114 5707// gen_helper_mfc0_performance2(arg);
2423f660
TS
5708 rn = "Performance2";
5709// break;
7a387fff 5710 case 3:
d9bea114 5711// gen_helper_mfc0_performance3(arg);
2423f660
TS
5712 rn = "Performance3";
5713// break;
7a387fff 5714 case 4:
d9bea114 5715// gen_helper_mfc0_performance4(arg);
2423f660
TS
5716 rn = "Performance4";
5717// break;
7a387fff 5718 case 5:
d9bea114 5719// gen_helper_mfc0_performance5(arg);
2423f660
TS
5720 rn = "Performance5";
5721// break;
7a387fff 5722 case 6:
d9bea114 5723// gen_helper_mfc0_performance6(arg);
2423f660
TS
5724 rn = "Performance6";
5725// break;
7a387fff 5726 case 7:
d9bea114 5727// gen_helper_mfc0_performance7(arg);
2423f660
TS
5728 rn = "Performance7";
5729// break;
7a387fff 5730 default:
f31b035a 5731 goto cp0_unimplemented;
7a387fff 5732 }
8c0fdd85
TS
5733 break;
5734 case 26:
d9bea114 5735 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5736 rn = "ECC";
5737 break;
8c0fdd85 5738 case 27:
7a387fff 5739 switch (sel) {
7a387fff 5740 case 0 ... 3:
d9bea114 5741 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5742 rn = "CacheErr";
5743 break;
7a387fff 5744 default:
f31b035a 5745 goto cp0_unimplemented;
7a387fff 5746 }
8c0fdd85 5747 break;
873eb012
TS
5748 case 28:
5749 switch (sel) {
5750 case 0:
7a387fff
TS
5751 case 2:
5752 case 4:
5753 case 6:
284b731a
LA
5754 {
5755 TCGv_i64 tmp = tcg_temp_new_i64();
5756 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5757 gen_move_low32(arg, tmp);
5758 tcg_temp_free_i64(tmp);
5759 }
873eb012
TS
5760 rn = "TagLo";
5761 break;
5762 case 1:
7a387fff
TS
5763 case 3:
5764 case 5:
5765 case 7:
7db13fae 5766 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5767 rn = "DataLo";
5768 break;
5769 default:
f31b035a 5770 goto cp0_unimplemented;
873eb012
TS
5771 }
5772 break;
8c0fdd85 5773 case 29:
7a387fff
TS
5774 switch (sel) {
5775 case 0:
5776 case 2:
5777 case 4:
5778 case 6:
7db13fae 5779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5780 rn = "TagHi";
5781 break;
5782 case 1:
5783 case 3:
5784 case 5:
5785 case 7:
7db13fae 5786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5787 rn = "DataHi";
5788 break;
5789 default:
f31b035a 5790 goto cp0_unimplemented;
7a387fff 5791 }
8c0fdd85 5792 break;
873eb012 5793 case 30:
7a387fff
TS
5794 switch (sel) {
5795 case 0:
7db13fae 5796 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5797 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5798 rn = "ErrorEPC";
5799 break;
7a387fff 5800 default:
f31b035a 5801 goto cp0_unimplemented;
7a387fff 5802 }
873eb012
TS
5803 break;
5804 case 31:
7a387fff
TS
5805 switch (sel) {
5806 case 0:
f0b3f3ae 5807 /* EJTAG support */
7db13fae 5808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5809 rn = "DESAVE";
5810 break;
e98c0d17 5811 case 2 ... 7:
f31b035a
LA
5812 CP0_CHECK(ctx->kscrexist & (1 << sel));
5813 tcg_gen_ld_tl(arg, cpu_env,
5814 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5815 tcg_gen_ext32s_tl(arg, arg);
5816 rn = "KScratch";
e98c0d17 5817 break;
7a387fff 5818 default:
f31b035a 5819 goto cp0_unimplemented;
7a387fff 5820 }
873eb012
TS
5821 break;
5822 default:
f31b035a 5823 goto cp0_unimplemented;
873eb012 5824 }
2abf314d 5825 (void)rn; /* avoid a compiler warning */
d12d51d5 5826 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5827 return;
5828
f31b035a 5829cp0_unimplemented:
d12d51d5 5830 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5831 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5832}
5833
d75c135e 5834static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5835{
7a387fff
TS
5836 const char *rn = "invalid";
5837
e189e748 5838 if (sel != 0)
d75c135e 5839 check_insn(ctx, ISA_MIPS32);
e189e748 5840
bd79255d 5841 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 5842 gen_io_start();
bd79255d 5843 }
2e70f6ef 5844
8c0fdd85
TS
5845 switch (reg) {
5846 case 0:
7a387fff
TS
5847 switch (sel) {
5848 case 0:
895c2d04 5849 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5850 rn = "Index";
5851 break;
5852 case 1:
f31b035a 5853 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5854 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5855 rn = "MVPControl";
ead9360e 5856 break;
7a387fff 5857 case 2:
f31b035a 5858 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5859 /* ignored */
7a387fff 5860 rn = "MVPConf0";
ead9360e 5861 break;
7a387fff 5862 case 3:
f31b035a 5863 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5864 /* ignored */
7a387fff 5865 rn = "MVPConf1";
ead9360e 5866 break;
7a387fff 5867 default:
f31b035a 5868 goto cp0_unimplemented;
7a387fff 5869 }
8c0fdd85
TS
5870 break;
5871 case 1:
7a387fff
TS
5872 switch (sel) {
5873 case 0:
2423f660 5874 /* ignored */
7a387fff 5875 rn = "Random";
2423f660 5876 break;
7a387fff 5877 case 1:
f31b035a 5878 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5879 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5880 rn = "VPEControl";
ead9360e 5881 break;
7a387fff 5882 case 2:
f31b035a 5883 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5884 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5885 rn = "VPEConf0";
ead9360e 5886 break;
7a387fff 5887 case 3:
f31b035a 5888 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5889 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5890 rn = "VPEConf1";
ead9360e 5891 break;
7a387fff 5892 case 4:
f31b035a 5893 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5894 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5895 rn = "YQMask";
ead9360e 5896 break;
7a387fff 5897 case 5:
f31b035a 5898 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5899 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5900 rn = "VPESchedule";
ead9360e 5901 break;
7a387fff 5902 case 6:
f31b035a 5903 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5904 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5905 rn = "VPEScheFBack";
ead9360e 5906 break;
7a387fff 5907 case 7:
f31b035a 5908 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5909 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5910 rn = "VPEOpt";
ead9360e 5911 break;
7a387fff 5912 default:
f31b035a 5913 goto cp0_unimplemented;
7a387fff 5914 }
8c0fdd85
TS
5915 break;
5916 case 2:
7a387fff
TS
5917 switch (sel) {
5918 case 0:
895c2d04 5919 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5920 rn = "EntryLo0";
5921 break;
7a387fff 5922 case 1:
f31b035a 5923 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5924 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5925 rn = "TCStatus";
ead9360e 5926 break;
7a387fff 5927 case 2:
f31b035a 5928 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5929 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5930 rn = "TCBind";
ead9360e 5931 break;
7a387fff 5932 case 3:
f31b035a 5933 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5934 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5935 rn = "TCRestart";
ead9360e 5936 break;
7a387fff 5937 case 4:
f31b035a 5938 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5939 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5940 rn = "TCHalt";
ead9360e 5941 break;
7a387fff 5942 case 5:
f31b035a 5943 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5944 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5945 rn = "TCContext";
ead9360e 5946 break;
7a387fff 5947 case 6:
f31b035a 5948 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5949 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5950 rn = "TCSchedule";
ead9360e 5951 break;
7a387fff 5952 case 7:
f31b035a 5953 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5954 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5955 rn = "TCScheFBack";
ead9360e 5956 break;
7a387fff 5957 default:
f31b035a 5958 goto cp0_unimplemented;
7a387fff 5959 }
8c0fdd85
TS
5960 break;
5961 case 3:
7a387fff
TS
5962 switch (sel) {
5963 case 0:
895c2d04 5964 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5965 rn = "EntryLo1";
5966 break;
7a387fff 5967 default:
f31b035a 5968 goto cp0_unimplemented;
876d4b07 5969 }
8c0fdd85
TS
5970 break;
5971 case 4:
7a387fff
TS
5972 switch (sel) {
5973 case 0:
895c2d04 5974 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5975 rn = "Context";
5976 break;
7a387fff 5977 case 1:
895c2d04 5978// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5979 rn = "ContextConfig";
f31b035a 5980 goto cp0_unimplemented;
2423f660 5981// break;
d279279e 5982 case 2:
f31b035a
LA
5983 CP0_CHECK(ctx->ulri);
5984 tcg_gen_st_tl(arg, cpu_env,
5985 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5986 rn = "UserLocal";
d279279e 5987 break;
7a387fff 5988 default:
f31b035a 5989 goto cp0_unimplemented;
876d4b07 5990 }
8c0fdd85
TS
5991 break;
5992 case 5:
7a387fff
TS
5993 switch (sel) {
5994 case 0:
895c2d04 5995 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5996 rn = "PageMask";
5997 break;
7a387fff 5998 case 1:
d75c135e 5999 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6000 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 6001 rn = "PageGrain";
e117f526 6002 ctx->bstate = BS_STOP;
2423f660 6003 break;
7a387fff 6004 default:
f31b035a 6005 goto cp0_unimplemented;
876d4b07 6006 }
8c0fdd85
TS
6007 break;
6008 case 6:
7a387fff
TS
6009 switch (sel) {
6010 case 0:
895c2d04 6011 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6012 rn = "Wired";
6013 break;
7a387fff 6014 case 1:
d75c135e 6015 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6016 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6017 rn = "SRSConf0";
ead9360e 6018 break;
7a387fff 6019 case 2:
d75c135e 6020 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6021 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6022 rn = "SRSConf1";
ead9360e 6023 break;
7a387fff 6024 case 3:
d75c135e 6025 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6026 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6027 rn = "SRSConf2";
ead9360e 6028 break;
7a387fff 6029 case 4:
d75c135e 6030 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6031 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6032 rn = "SRSConf3";
ead9360e 6033 break;
7a387fff 6034 case 5:
d75c135e 6035 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6036 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6037 rn = "SRSConf4";
ead9360e 6038 break;
7a387fff 6039 default:
f31b035a 6040 goto cp0_unimplemented;
876d4b07 6041 }
8c0fdd85
TS
6042 break;
6043 case 7:
7a387fff
TS
6044 switch (sel) {
6045 case 0:
d75c135e 6046 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6047 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6048 ctx->bstate = BS_STOP;
2423f660
TS
6049 rn = "HWREna";
6050 break;
7a387fff 6051 default:
f31b035a 6052 goto cp0_unimplemented;
876d4b07 6053 }
8c0fdd85
TS
6054 break;
6055 case 8:
aea14095
LA
6056 switch (sel) {
6057 case 0:
6058 /* ignored */
6059 rn = "BadVAddr";
6060 break;
6061 case 1:
6062 /* ignored */
6063 rn = "BadInstr";
6064 break;
6065 case 2:
6066 /* ignored */
6067 rn = "BadInstrP";
6068 break;
6069 default:
f31b035a 6070 goto cp0_unimplemented;
aea14095 6071 }
8c0fdd85
TS
6072 break;
6073 case 9:
7a387fff
TS
6074 switch (sel) {
6075 case 0:
895c2d04 6076 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6077 rn = "Count";
6078 break;
876d4b07 6079 /* 6,7 are implementation dependent */
7a387fff 6080 default:
f31b035a 6081 goto cp0_unimplemented;
876d4b07 6082 }
8c0fdd85
TS
6083 break;
6084 case 10:
7a387fff
TS
6085 switch (sel) {
6086 case 0:
895c2d04 6087 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6088 rn = "EntryHi";
6089 break;
7a387fff 6090 default:
f31b035a 6091 goto cp0_unimplemented;
876d4b07 6092 }
8c0fdd85
TS
6093 break;
6094 case 11:
7a387fff
TS
6095 switch (sel) {
6096 case 0:
895c2d04 6097 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6098 rn = "Compare";
6099 break;
6100 /* 6,7 are implementation dependent */
7a387fff 6101 default:
f31b035a 6102 goto cp0_unimplemented;
876d4b07 6103 }
8c0fdd85
TS
6104 break;
6105 case 12:
7a387fff
TS
6106 switch (sel) {
6107 case 0:
867abc7e 6108 save_cpu_state(ctx, 1);
895c2d04 6109 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6110 /* BS_STOP isn't good enough here, hflags may have changed. */
6111 gen_save_pc(ctx->pc + 4);
6112 ctx->bstate = BS_EXCP;
2423f660
TS
6113 rn = "Status";
6114 break;
7a387fff 6115 case 1:
d75c135e 6116 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6117 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6118 /* Stop translation as we may have switched the execution mode */
6119 ctx->bstate = BS_STOP;
2423f660
TS
6120 rn = "IntCtl";
6121 break;
7a387fff 6122 case 2:
d75c135e 6123 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6124 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6125 /* Stop translation as we may have switched the execution mode */
6126 ctx->bstate = BS_STOP;
2423f660
TS
6127 rn = "SRSCtl";
6128 break;
7a387fff 6129 case 3:
d75c135e 6130 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6131 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6132 /* Stop translation as we may have switched the execution mode */
6133 ctx->bstate = BS_STOP;
2423f660 6134 rn = "SRSMap";
fd88b6ab 6135 break;
7a387fff 6136 default:
f31b035a 6137 goto cp0_unimplemented;
876d4b07 6138 }
8c0fdd85
TS
6139 break;
6140 case 13:
7a387fff
TS
6141 switch (sel) {
6142 case 0:
867abc7e 6143 save_cpu_state(ctx, 1);
895c2d04 6144 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
6145 rn = "Cause";
6146 break;
7a387fff 6147 default:
f31b035a 6148 goto cp0_unimplemented;
876d4b07 6149 }
8c0fdd85
TS
6150 break;
6151 case 14:
7a387fff
TS
6152 switch (sel) {
6153 case 0:
7db13fae 6154 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6155 rn = "EPC";
6156 break;
7a387fff 6157 default:
f31b035a 6158 goto cp0_unimplemented;
876d4b07 6159 }
8c0fdd85
TS
6160 break;
6161 case 15:
7a387fff
TS
6162 switch (sel) {
6163 case 0:
2423f660
TS
6164 /* ignored */
6165 rn = "PRid";
6166 break;
7a387fff 6167 case 1:
d75c135e 6168 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6169 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6170 rn = "EBase";
6171 break;
7a387fff 6172 default:
f31b035a 6173 goto cp0_unimplemented;
1579a72e 6174 }
8c0fdd85
TS
6175 break;
6176 case 16:
6177 switch (sel) {
6178 case 0:
895c2d04 6179 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6180 rn = "Config";
2423f660
TS
6181 /* Stop translation as we may have switched the execution mode */
6182 ctx->bstate = BS_STOP;
7a387fff
TS
6183 break;
6184 case 1:
e397ee33 6185 /* ignored, read only */
7a387fff
TS
6186 rn = "Config1";
6187 break;
6188 case 2:
895c2d04 6189 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6190 rn = "Config2";
2423f660
TS
6191 /* Stop translation as we may have switched the execution mode */
6192 ctx->bstate = BS_STOP;
8c0fdd85 6193 break;
7a387fff 6194 case 3:
90f12d73 6195 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6196 rn = "Config3";
90f12d73
MR
6197 /* Stop translation as we may have switched the execution mode */
6198 ctx->bstate = BS_STOP;
7a387fff 6199 break;
b4160af1
PJ
6200 case 4:
6201 gen_helper_mtc0_config4(cpu_env, arg);
6202 rn = "Config4";
6203 ctx->bstate = BS_STOP;
6204 break;
b4dd99a3
PJ
6205 case 5:
6206 gen_helper_mtc0_config5(cpu_env, arg);
6207 rn = "Config5";
6208 /* Stop translation as we may have switched the execution mode */
6209 ctx->bstate = BS_STOP;
6210 break;
e397ee33
TS
6211 /* 6,7 are implementation dependent */
6212 case 6:
6213 /* ignored */
6214 rn = "Config6";
6215 break;
6216 case 7:
6217 /* ignored */
6218 rn = "Config7";
6219 break;
8c0fdd85
TS
6220 default:
6221 rn = "Invalid config selector";
f31b035a 6222 goto cp0_unimplemented;
8c0fdd85
TS
6223 }
6224 break;
6225 case 17:
7a387fff
TS
6226 switch (sel) {
6227 case 0:
895c2d04 6228 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6229 rn = "LLAddr";
6230 break;
7a387fff 6231 default:
f31b035a 6232 goto cp0_unimplemented;
7a387fff 6233 }
8c0fdd85
TS
6234 break;
6235 case 18:
7a387fff 6236 switch (sel) {
fd88b6ab 6237 case 0 ... 7:
895c2d04 6238 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6239 rn = "WatchLo";
6240 break;
7a387fff 6241 default:
f31b035a 6242 goto cp0_unimplemented;
7a387fff 6243 }
8c0fdd85
TS
6244 break;
6245 case 19:
7a387fff 6246 switch (sel) {
fd88b6ab 6247 case 0 ... 7:
895c2d04 6248 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6249 rn = "WatchHi";
6250 break;
7a387fff 6251 default:
f31b035a 6252 goto cp0_unimplemented;
7a387fff 6253 }
8c0fdd85
TS
6254 break;
6255 case 20:
7a387fff
TS
6256 switch (sel) {
6257 case 0:
d26bc211 6258#if defined(TARGET_MIPS64)
d75c135e 6259 check_insn(ctx, ISA_MIPS3);
895c2d04 6260 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6261 rn = "XContext";
6262 break;
703eaf37 6263#endif
7a387fff 6264 default:
f31b035a 6265 goto cp0_unimplemented;
7a387fff 6266 }
8c0fdd85
TS
6267 break;
6268 case 21:
7a387fff 6269 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6270 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6271 switch (sel) {
6272 case 0:
895c2d04 6273 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6274 rn = "Framemask";
6275 break;
7a387fff 6276 default:
f31b035a 6277 goto cp0_unimplemented;
7a387fff
TS
6278 }
6279 break;
8c0fdd85 6280 case 22:
7a387fff
TS
6281 /* ignored */
6282 rn = "Diagnostic"; /* implementation dependent */
2423f660 6283 break;
8c0fdd85 6284 case 23:
7a387fff
TS
6285 switch (sel) {
6286 case 0:
895c2d04 6287 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6288 /* BS_STOP isn't good enough here, hflags may have changed. */
6289 gen_save_pc(ctx->pc + 4);
6290 ctx->bstate = BS_EXCP;
2423f660
TS
6291 rn = "Debug";
6292 break;
7a387fff 6293 case 1:
895c2d04 6294// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6295 rn = "TraceControl";
8487327a
TS
6296 /* Stop translation as we may have switched the execution mode */
6297 ctx->bstate = BS_STOP;
2423f660 6298// break;
7a387fff 6299 case 2:
895c2d04 6300// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6301 rn = "TraceControl2";
8487327a
TS
6302 /* Stop translation as we may have switched the execution mode */
6303 ctx->bstate = BS_STOP;
2423f660 6304// break;
7a387fff 6305 case 3:
8487327a
TS
6306 /* Stop translation as we may have switched the execution mode */
6307 ctx->bstate = BS_STOP;
895c2d04 6308// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6309 rn = "UserTraceData";
8487327a
TS
6310 /* Stop translation as we may have switched the execution mode */
6311 ctx->bstate = BS_STOP;
2423f660 6312// break;
7a387fff 6313 case 4:
895c2d04 6314// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6315 /* Stop translation as we may have switched the execution mode */
6316 ctx->bstate = BS_STOP;
2423f660
TS
6317 rn = "TraceBPC";
6318// break;
7a387fff 6319 default:
f31b035a 6320 goto cp0_unimplemented;
7a387fff 6321 }
8c0fdd85
TS
6322 break;
6323 case 24:
7a387fff
TS
6324 switch (sel) {
6325 case 0:
f1aa6320 6326 /* EJTAG support */
7db13fae 6327 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6328 rn = "DEPC";
6329 break;
7a387fff 6330 default:
f31b035a 6331 goto cp0_unimplemented;
7a387fff 6332 }
8c0fdd85
TS
6333 break;
6334 case 25:
7a387fff
TS
6335 switch (sel) {
6336 case 0:
895c2d04 6337 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6338 rn = "Performance0";
6339 break;
7a387fff 6340 case 1:
d9bea114 6341// gen_helper_mtc0_performance1(arg);
2423f660
TS
6342 rn = "Performance1";
6343// break;
7a387fff 6344 case 2:
d9bea114 6345// gen_helper_mtc0_performance2(arg);
2423f660
TS
6346 rn = "Performance2";
6347// break;
7a387fff 6348 case 3:
d9bea114 6349// gen_helper_mtc0_performance3(arg);
2423f660
TS
6350 rn = "Performance3";
6351// break;
7a387fff 6352 case 4:
d9bea114 6353// gen_helper_mtc0_performance4(arg);
2423f660
TS
6354 rn = "Performance4";
6355// break;
7a387fff 6356 case 5:
d9bea114 6357// gen_helper_mtc0_performance5(arg);
2423f660
TS
6358 rn = "Performance5";
6359// break;
7a387fff 6360 case 6:
d9bea114 6361// gen_helper_mtc0_performance6(arg);
2423f660
TS
6362 rn = "Performance6";
6363// break;
7a387fff 6364 case 7:
d9bea114 6365// gen_helper_mtc0_performance7(arg);
2423f660
TS
6366 rn = "Performance7";
6367// break;
7a387fff 6368 default:
f31b035a 6369 goto cp0_unimplemented;
7a387fff 6370 }
8c0fdd85
TS
6371 break;
6372 case 26:
2423f660 6373 /* ignored */
8c0fdd85 6374 rn = "ECC";
2423f660 6375 break;
8c0fdd85 6376 case 27:
7a387fff
TS
6377 switch (sel) {
6378 case 0 ... 3:
2423f660
TS
6379 /* ignored */
6380 rn = "CacheErr";
6381 break;
7a387fff 6382 default:
f31b035a 6383 goto cp0_unimplemented;
7a387fff 6384 }
8c0fdd85
TS
6385 break;
6386 case 28:
6387 switch (sel) {
6388 case 0:
7a387fff
TS
6389 case 2:
6390 case 4:
6391 case 6:
895c2d04 6392 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6393 rn = "TagLo";
6394 break;
7a387fff
TS
6395 case 1:
6396 case 3:
6397 case 5:
6398 case 7:
895c2d04 6399 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6400 rn = "DataLo";
6401 break;
8c0fdd85 6402 default:
f31b035a 6403 goto cp0_unimplemented;
8c0fdd85
TS
6404 }
6405 break;
6406 case 29:
7a387fff
TS
6407 switch (sel) {
6408 case 0:
6409 case 2:
6410 case 4:
6411 case 6:
895c2d04 6412 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6413 rn = "TagHi";
6414 break;
6415 case 1:
6416 case 3:
6417 case 5:
6418 case 7:
895c2d04 6419 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6420 rn = "DataHi";
6421 break;
6422 default:
6423 rn = "invalid sel";
f31b035a 6424 goto cp0_unimplemented;
7a387fff 6425 }
8c0fdd85
TS
6426 break;
6427 case 30:
7a387fff
TS
6428 switch (sel) {
6429 case 0:
7db13fae 6430 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6431 rn = "ErrorEPC";
6432 break;
7a387fff 6433 default:
f31b035a 6434 goto cp0_unimplemented;
7a387fff 6435 }
8c0fdd85
TS
6436 break;
6437 case 31:
7a387fff
TS
6438 switch (sel) {
6439 case 0:
f1aa6320 6440 /* EJTAG support */
7db13fae 6441 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6442 rn = "DESAVE";
6443 break;
e98c0d17 6444 case 2 ... 7:
f31b035a
LA
6445 CP0_CHECK(ctx->kscrexist & (1 << sel));
6446 tcg_gen_st_tl(arg, cpu_env,
6447 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6448 rn = "KScratch";
e98c0d17 6449 break;
7a387fff 6450 default:
f31b035a 6451 goto cp0_unimplemented;
7a387fff 6452 }
2423f660
TS
6453 /* Stop translation as we may have switched the execution mode */
6454 ctx->bstate = BS_STOP;
8c0fdd85
TS
6455 break;
6456 default:
f31b035a 6457 goto cp0_unimplemented;
8c0fdd85 6458 }
2abf314d 6459 (void)rn; /* avoid a compiler warning */
d12d51d5 6460 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6461 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 6462 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
6463 gen_io_end();
6464 ctx->bstate = BS_STOP;
6465 }
8c0fdd85
TS
6466 return;
6467
f31b035a 6468cp0_unimplemented:
d12d51d5 6469 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6470}
6471
d26bc211 6472#if defined(TARGET_MIPS64)
d75c135e 6473static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6474{
6475 const char *rn = "invalid";
6476
e189e748 6477 if (sel != 0)
d75c135e 6478 check_insn(ctx, ISA_MIPS64);
e189e748 6479
9c2149c8
TS
6480 switch (reg) {
6481 case 0:
6482 switch (sel) {
6483 case 0:
7db13fae 6484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6485 rn = "Index";
6486 break;
6487 case 1:
f31b035a 6488 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6489 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6490 rn = "MVPControl";
ead9360e 6491 break;
9c2149c8 6492 case 2:
f31b035a 6493 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6494 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6495 rn = "MVPConf0";
ead9360e 6496 break;
9c2149c8 6497 case 3:
f31b035a 6498 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6499 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6500 rn = "MVPConf1";
ead9360e 6501 break;
9c2149c8 6502 default:
f31b035a 6503 goto cp0_unimplemented;
9c2149c8
TS
6504 }
6505 break;
6506 case 1:
6507 switch (sel) {
6508 case 0:
f31b035a 6509 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6510 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6511 rn = "Random";
2423f660 6512 break;
9c2149c8 6513 case 1:
f31b035a 6514 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6516 rn = "VPEControl";
ead9360e 6517 break;
9c2149c8 6518 case 2:
f31b035a 6519 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6521 rn = "VPEConf0";
ead9360e 6522 break;
9c2149c8 6523 case 3:
f31b035a 6524 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6526 rn = "VPEConf1";
ead9360e 6527 break;
9c2149c8 6528 case 4:
f31b035a 6529 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6530 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6531 rn = "YQMask";
ead9360e 6532 break;
9c2149c8 6533 case 5:
f31b035a 6534 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6535 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6536 rn = "VPESchedule";
ead9360e 6537 break;
9c2149c8 6538 case 6:
f31b035a 6539 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6540 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6541 rn = "VPEScheFBack";
ead9360e 6542 break;
9c2149c8 6543 case 7:
f31b035a 6544 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6546 rn = "VPEOpt";
ead9360e 6547 break;
9c2149c8 6548 default:
f31b035a 6549 goto cp0_unimplemented;
9c2149c8
TS
6550 }
6551 break;
6552 case 2:
6553 switch (sel) {
6554 case 0:
7db13fae 6555 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6556 rn = "EntryLo0";
6557 break;
9c2149c8 6558 case 1:
f31b035a 6559 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6560 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6561 rn = "TCStatus";
ead9360e 6562 break;
9c2149c8 6563 case 2:
f31b035a 6564 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6565 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6566 rn = "TCBind";
ead9360e 6567 break;
9c2149c8 6568 case 3:
f31b035a 6569 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6570 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6571 rn = "TCRestart";
ead9360e 6572 break;
9c2149c8 6573 case 4:
f31b035a 6574 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6575 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6576 rn = "TCHalt";
ead9360e 6577 break;
9c2149c8 6578 case 5:
f31b035a 6579 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6580 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6581 rn = "TCContext";
ead9360e 6582 break;
9c2149c8 6583 case 6:
f31b035a 6584 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6585 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6586 rn = "TCSchedule";
ead9360e 6587 break;
9c2149c8 6588 case 7:
f31b035a 6589 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6590 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6591 rn = "TCScheFBack";
ead9360e 6592 break;
9c2149c8 6593 default:
f31b035a 6594 goto cp0_unimplemented;
9c2149c8
TS
6595 }
6596 break;
6597 case 3:
6598 switch (sel) {
6599 case 0:
7db13fae 6600 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6601 rn = "EntryLo1";
6602 break;
9c2149c8 6603 default:
f31b035a 6604 goto cp0_unimplemented;
1579a72e 6605 }
9c2149c8
TS
6606 break;
6607 case 4:
6608 switch (sel) {
6609 case 0:
7db13fae 6610 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6611 rn = "Context";
6612 break;
9c2149c8 6613 case 1:
d9bea114 6614// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6615 rn = "ContextConfig";
f31b035a 6616 goto cp0_unimplemented;
2423f660 6617// break;
d279279e 6618 case 2:
f31b035a
LA
6619 CP0_CHECK(ctx->ulri);
6620 tcg_gen_ld_tl(arg, cpu_env,
6621 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6622 rn = "UserLocal";
d279279e 6623 break;
9c2149c8 6624 default:
f31b035a 6625 goto cp0_unimplemented;
876d4b07 6626 }
9c2149c8
TS
6627 break;
6628 case 5:
6629 switch (sel) {
6630 case 0:
7db13fae 6631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6632 rn = "PageMask";
6633 break;
9c2149c8 6634 case 1:
d75c135e 6635 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6637 rn = "PageGrain";
6638 break;
9c2149c8 6639 default:
f31b035a 6640 goto cp0_unimplemented;
876d4b07 6641 }
9c2149c8
TS
6642 break;
6643 case 6:
6644 switch (sel) {
6645 case 0:
7db13fae 6646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6647 rn = "Wired";
6648 break;
9c2149c8 6649 case 1:
d75c135e 6650 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6652 rn = "SRSConf0";
ead9360e 6653 break;
9c2149c8 6654 case 2:
d75c135e 6655 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6657 rn = "SRSConf1";
ead9360e 6658 break;
9c2149c8 6659 case 3:
d75c135e 6660 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6662 rn = "SRSConf2";
ead9360e 6663 break;
9c2149c8 6664 case 4:
d75c135e 6665 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6667 rn = "SRSConf3";
ead9360e 6668 break;
9c2149c8 6669 case 5:
d75c135e 6670 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6671 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6672 rn = "SRSConf4";
ead9360e 6673 break;
9c2149c8 6674 default:
f31b035a 6675 goto cp0_unimplemented;
876d4b07 6676 }
9c2149c8
TS
6677 break;
6678 case 7:
6679 switch (sel) {
6680 case 0:
d75c135e 6681 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6683 rn = "HWREna";
6684 break;
9c2149c8 6685 default:
f31b035a 6686 goto cp0_unimplemented;
876d4b07 6687 }
9c2149c8
TS
6688 break;
6689 case 8:
6690 switch (sel) {
6691 case 0:
7db13fae 6692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6693 rn = "BadVAddr";
2423f660 6694 break;
aea14095 6695 case 1:
f31b035a
LA
6696 CP0_CHECK(ctx->bi);
6697 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6698 rn = "BadInstr";
aea14095
LA
6699 break;
6700 case 2:
f31b035a
LA
6701 CP0_CHECK(ctx->bp);
6702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6703 rn = "BadInstrP";
aea14095 6704 break;
9c2149c8 6705 default:
f31b035a 6706 goto cp0_unimplemented;
876d4b07 6707 }
9c2149c8
TS
6708 break;
6709 case 9:
6710 switch (sel) {
6711 case 0:
2e70f6ef 6712 /* Mark as an IO operation because we read the time. */
bd79255d 6713 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6714 gen_io_start();
bd79255d 6715 }
895c2d04 6716 gen_helper_mfc0_count(arg, cpu_env);
bd79255d 6717 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 6718 gen_io_end();
2e70f6ef 6719 }
55807224
EI
6720 /* Break the TB to be able to take timer interrupts immediately
6721 after reading count. */
6722 ctx->bstate = BS_STOP;
2423f660
TS
6723 rn = "Count";
6724 break;
6725 /* 6,7 are implementation dependent */
9c2149c8 6726 default:
f31b035a 6727 goto cp0_unimplemented;
876d4b07 6728 }
9c2149c8
TS
6729 break;
6730 case 10:
6731 switch (sel) {
6732 case 0:
7db13fae 6733 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6734 rn = "EntryHi";
6735 break;
9c2149c8 6736 default:
f31b035a 6737 goto cp0_unimplemented;
876d4b07 6738 }
9c2149c8
TS
6739 break;
6740 case 11:
6741 switch (sel) {
6742 case 0:
7db13fae 6743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6744 rn = "Compare";
6745 break;
876d4b07 6746 /* 6,7 are implementation dependent */
9c2149c8 6747 default:
f31b035a 6748 goto cp0_unimplemented;
876d4b07 6749 }
9c2149c8
TS
6750 break;
6751 case 12:
6752 switch (sel) {
6753 case 0:
7db13fae 6754 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6755 rn = "Status";
6756 break;
9c2149c8 6757 case 1:
d75c135e 6758 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6760 rn = "IntCtl";
6761 break;
9c2149c8 6762 case 2:
d75c135e 6763 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6764 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6765 rn = "SRSCtl";
6766 break;
9c2149c8 6767 case 3:
d75c135e 6768 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6769 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6770 rn = "SRSMap";
6771 break;
9c2149c8 6772 default:
f31b035a 6773 goto cp0_unimplemented;
876d4b07 6774 }
9c2149c8
TS
6775 break;
6776 case 13:
6777 switch (sel) {
6778 case 0:
7db13fae 6779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6780 rn = "Cause";
6781 break;
9c2149c8 6782 default:
f31b035a 6783 goto cp0_unimplemented;
876d4b07 6784 }
9c2149c8
TS
6785 break;
6786 case 14:
6787 switch (sel) {
6788 case 0:
7db13fae 6789 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6790 rn = "EPC";
6791 break;
9c2149c8 6792 default:
f31b035a 6793 goto cp0_unimplemented;
876d4b07 6794 }
9c2149c8
TS
6795 break;
6796 case 15:
6797 switch (sel) {
6798 case 0:
7db13fae 6799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6800 rn = "PRid";
6801 break;
9c2149c8 6802 case 1:
d75c135e 6803 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6805 rn = "EBase";
6806 break;
9c2149c8 6807 default:
f31b035a 6808 goto cp0_unimplemented;
876d4b07 6809 }
9c2149c8
TS
6810 break;
6811 case 16:
6812 switch (sel) {
6813 case 0:
7db13fae 6814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6815 rn = "Config";
6816 break;
6817 case 1:
7db13fae 6818 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6819 rn = "Config1";
6820 break;
6821 case 2:
7db13fae 6822 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6823 rn = "Config2";
6824 break;
6825 case 3:
7db13fae 6826 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6827 rn = "Config3";
6828 break;
faf1f68b
LA
6829 case 4:
6830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6831 rn = "Config4";
6832 break;
6833 case 5:
6834 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6835 rn = "Config5";
6836 break;
9c2149c8 6837 /* 6,7 are implementation dependent */
f0b3f3ae 6838 case 6:
7db13fae 6839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6840 rn = "Config6";
6841 break;
6842 case 7:
7db13fae 6843 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6844 rn = "Config7";
6845 break;
9c2149c8 6846 default:
f31b035a 6847 goto cp0_unimplemented;
9c2149c8
TS
6848 }
6849 break;
6850 case 17:
6851 switch (sel) {
6852 case 0:
895c2d04 6853 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6854 rn = "LLAddr";
6855 break;
9c2149c8 6856 default:
f31b035a 6857 goto cp0_unimplemented;
9c2149c8
TS
6858 }
6859 break;
6860 case 18:
6861 switch (sel) {
fd88b6ab 6862 case 0 ... 7:
895c2d04 6863 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6864 rn = "WatchLo";
6865 break;
9c2149c8 6866 default:
f31b035a 6867 goto cp0_unimplemented;
9c2149c8
TS
6868 }
6869 break;
6870 case 19:
6871 switch (sel) {
fd88b6ab 6872 case 0 ... 7:
895c2d04 6873 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6874 rn = "WatchHi";
6875 break;
9c2149c8 6876 default:
f31b035a 6877 goto cp0_unimplemented;
9c2149c8
TS
6878 }
6879 break;
6880 case 20:
6881 switch (sel) {
6882 case 0:
d75c135e 6883 check_insn(ctx, ISA_MIPS3);
7db13fae 6884 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6885 rn = "XContext";
6886 break;
9c2149c8 6887 default:
f31b035a 6888 goto cp0_unimplemented;
9c2149c8
TS
6889 }
6890 break;
6891 case 21:
6892 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6893 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6894 switch (sel) {
6895 case 0:
7db13fae 6896 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6897 rn = "Framemask";
6898 break;
9c2149c8 6899 default:
f31b035a 6900 goto cp0_unimplemented;
9c2149c8
TS
6901 }
6902 break;
6903 case 22:
d9bea114 6904 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6905 rn = "'Diagnostic"; /* implementation dependent */
6906 break;
9c2149c8
TS
6907 case 23:
6908 switch (sel) {
6909 case 0:
895c2d04 6910 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6911 rn = "Debug";
6912 break;
9c2149c8 6913 case 1:
895c2d04 6914// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6915 rn = "TraceControl";
6916// break;
9c2149c8 6917 case 2:
895c2d04 6918// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6919 rn = "TraceControl2";
6920// break;
9c2149c8 6921 case 3:
895c2d04 6922// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6923 rn = "UserTraceData";
6924// break;
9c2149c8 6925 case 4:
895c2d04 6926// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6927 rn = "TraceBPC";
6928// break;
9c2149c8 6929 default:
f31b035a 6930 goto cp0_unimplemented;
9c2149c8
TS
6931 }
6932 break;
6933 case 24:
6934 switch (sel) {
6935 case 0:
f0b3f3ae 6936 /* EJTAG support */
7db13fae 6937 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6938 rn = "DEPC";
6939 break;
9c2149c8 6940 default:
f31b035a 6941 goto cp0_unimplemented;
9c2149c8
TS
6942 }
6943 break;
6944 case 25:
6945 switch (sel) {
6946 case 0:
7db13fae 6947 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6948 rn = "Performance0";
9c2149c8
TS
6949 break;
6950 case 1:
d9bea114 6951// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6952 rn = "Performance1";
6953// break;
9c2149c8 6954 case 2:
d9bea114 6955// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6956 rn = "Performance2";
6957// break;
9c2149c8 6958 case 3:
d9bea114 6959// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6960 rn = "Performance3";
6961// break;
9c2149c8 6962 case 4:
d9bea114 6963// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6964 rn = "Performance4";
6965// break;
9c2149c8 6966 case 5:
d9bea114 6967// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6968 rn = "Performance5";
6969// break;
9c2149c8 6970 case 6:
d9bea114 6971// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6972 rn = "Performance6";
6973// break;
9c2149c8 6974 case 7:
d9bea114 6975// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6976 rn = "Performance7";
6977// break;
9c2149c8 6978 default:
f31b035a 6979 goto cp0_unimplemented;
9c2149c8
TS
6980 }
6981 break;
6982 case 26:
d9bea114 6983 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6984 rn = "ECC";
6985 break;
9c2149c8
TS
6986 case 27:
6987 switch (sel) {
6988 /* ignored */
6989 case 0 ... 3:
d9bea114 6990 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6991 rn = "CacheErr";
6992 break;
9c2149c8 6993 default:
f31b035a 6994 goto cp0_unimplemented;
9c2149c8
TS
6995 }
6996 break;
6997 case 28:
6998 switch (sel) {
6999 case 0:
7000 case 2:
7001 case 4:
7002 case 6:
7db13fae 7003 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
7004 rn = "TagLo";
7005 break;
7006 case 1:
7007 case 3:
7008 case 5:
7009 case 7:
7db13fae 7010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7011 rn = "DataLo";
7012 break;
7013 default:
f31b035a 7014 goto cp0_unimplemented;
9c2149c8
TS
7015 }
7016 break;
7017 case 29:
7018 switch (sel) {
7019 case 0:
7020 case 2:
7021 case 4:
7022 case 6:
7db13fae 7023 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7024 rn = "TagHi";
7025 break;
7026 case 1:
7027 case 3:
7028 case 5:
7029 case 7:
7db13fae 7030 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7031 rn = "DataHi";
7032 break;
7033 default:
f31b035a 7034 goto cp0_unimplemented;
9c2149c8
TS
7035 }
7036 break;
7037 case 30:
7038 switch (sel) {
7039 case 0:
7db13fae 7040 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7041 rn = "ErrorEPC";
7042 break;
9c2149c8 7043 default:
f31b035a 7044 goto cp0_unimplemented;
9c2149c8
TS
7045 }
7046 break;
7047 case 31:
7048 switch (sel) {
7049 case 0:
f0b3f3ae 7050 /* EJTAG support */
7db13fae 7051 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7052 rn = "DESAVE";
7053 break;
e98c0d17 7054 case 2 ... 7:
f31b035a
LA
7055 CP0_CHECK(ctx->kscrexist & (1 << sel));
7056 tcg_gen_ld_tl(arg, cpu_env,
7057 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7058 rn = "KScratch";
e98c0d17 7059 break;
9c2149c8 7060 default:
f31b035a 7061 goto cp0_unimplemented;
9c2149c8
TS
7062 }
7063 break;
7064 default:
f31b035a 7065 goto cp0_unimplemented;
9c2149c8 7066 }
2abf314d 7067 (void)rn; /* avoid a compiler warning */
d12d51d5 7068 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
7069 return;
7070
f31b035a 7071cp0_unimplemented:
d12d51d5 7072 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7073 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7074}
7075
d75c135e 7076static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7077{
7078 const char *rn = "invalid";
7079
e189e748 7080 if (sel != 0)
d75c135e 7081 check_insn(ctx, ISA_MIPS64);
e189e748 7082
bd79255d 7083 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef 7084 gen_io_start();
bd79255d 7085 }
2e70f6ef 7086
9c2149c8
TS
7087 switch (reg) {
7088 case 0:
7089 switch (sel) {
7090 case 0:
895c2d04 7091 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7092 rn = "Index";
7093 break;
7094 case 1:
f31b035a 7095 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7096 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7097 rn = "MVPControl";
ead9360e 7098 break;
9c2149c8 7099 case 2:
f31b035a 7100 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7101 /* ignored */
9c2149c8 7102 rn = "MVPConf0";
ead9360e 7103 break;
9c2149c8 7104 case 3:
f31b035a 7105 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7106 /* ignored */
9c2149c8 7107 rn = "MVPConf1";
ead9360e 7108 break;
9c2149c8 7109 default:
f31b035a 7110 goto cp0_unimplemented;
9c2149c8
TS
7111 }
7112 break;
7113 case 1:
7114 switch (sel) {
7115 case 0:
2423f660 7116 /* ignored */
9c2149c8 7117 rn = "Random";
2423f660 7118 break;
9c2149c8 7119 case 1:
f31b035a 7120 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7121 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7122 rn = "VPEControl";
ead9360e 7123 break;
9c2149c8 7124 case 2:
f31b035a 7125 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7126 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7127 rn = "VPEConf0";
ead9360e 7128 break;
9c2149c8 7129 case 3:
f31b035a 7130 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7131 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7132 rn = "VPEConf1";
ead9360e 7133 break;
9c2149c8 7134 case 4:
f31b035a 7135 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7136 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7137 rn = "YQMask";
ead9360e 7138 break;
9c2149c8 7139 case 5:
f31b035a 7140 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7141 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7142 rn = "VPESchedule";
ead9360e 7143 break;
9c2149c8 7144 case 6:
f31b035a 7145 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7146 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7147 rn = "VPEScheFBack";
ead9360e 7148 break;
9c2149c8 7149 case 7:
f31b035a 7150 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7151 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7152 rn = "VPEOpt";
ead9360e 7153 break;
9c2149c8 7154 default:
f31b035a 7155 goto cp0_unimplemented;
9c2149c8
TS
7156 }
7157 break;
7158 case 2:
7159 switch (sel) {
7160 case 0:
7207c7f9 7161 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7162 rn = "EntryLo0";
7163 break;
9c2149c8 7164 case 1:
f31b035a 7165 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7166 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7167 rn = "TCStatus";
ead9360e 7168 break;
9c2149c8 7169 case 2:
f31b035a 7170 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7171 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7172 rn = "TCBind";
ead9360e 7173 break;
9c2149c8 7174 case 3:
f31b035a 7175 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7176 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7177 rn = "TCRestart";
ead9360e 7178 break;
9c2149c8 7179 case 4:
f31b035a 7180 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7181 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7182 rn = "TCHalt";
ead9360e 7183 break;
9c2149c8 7184 case 5:
f31b035a 7185 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7186 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7187 rn = "TCContext";
ead9360e 7188 break;
9c2149c8 7189 case 6:
f31b035a 7190 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7191 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7192 rn = "TCSchedule";
ead9360e 7193 break;
9c2149c8 7194 case 7:
f31b035a 7195 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7196 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7197 rn = "TCScheFBack";
ead9360e 7198 break;
9c2149c8 7199 default:
f31b035a 7200 goto cp0_unimplemented;
9c2149c8
TS
7201 }
7202 break;
7203 case 3:
7204 switch (sel) {
7205 case 0:
7207c7f9 7206 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7207 rn = "EntryLo1";
7208 break;
9c2149c8 7209 default:
f31b035a 7210 goto cp0_unimplemented;
876d4b07 7211 }
9c2149c8
TS
7212 break;
7213 case 4:
7214 switch (sel) {
7215 case 0:
895c2d04 7216 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7217 rn = "Context";
7218 break;
9c2149c8 7219 case 1:
895c2d04 7220// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7221 rn = "ContextConfig";
f31b035a 7222 goto cp0_unimplemented;
2423f660 7223// break;
d279279e 7224 case 2:
f31b035a
LA
7225 CP0_CHECK(ctx->ulri);
7226 tcg_gen_st_tl(arg, cpu_env,
7227 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7228 rn = "UserLocal";
d279279e 7229 break;
9c2149c8 7230 default:
f31b035a 7231 goto cp0_unimplemented;
876d4b07 7232 }
9c2149c8
TS
7233 break;
7234 case 5:
7235 switch (sel) {
7236 case 0:
895c2d04 7237 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7238 rn = "PageMask";
7239 break;
9c2149c8 7240 case 1:
d75c135e 7241 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7242 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7243 rn = "PageGrain";
7244 break;
9c2149c8 7245 default:
f31b035a 7246 goto cp0_unimplemented;
876d4b07 7247 }
9c2149c8
TS
7248 break;
7249 case 6:
7250 switch (sel) {
7251 case 0:
895c2d04 7252 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7253 rn = "Wired";
7254 break;
9c2149c8 7255 case 1:
d75c135e 7256 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7257 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7258 rn = "SRSConf0";
ead9360e 7259 break;
9c2149c8 7260 case 2:
d75c135e 7261 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7262 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7263 rn = "SRSConf1";
ead9360e 7264 break;
9c2149c8 7265 case 3:
d75c135e 7266 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7267 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7268 rn = "SRSConf2";
ead9360e 7269 break;
9c2149c8 7270 case 4:
d75c135e 7271 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7272 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7273 rn = "SRSConf3";
ead9360e 7274 break;
9c2149c8 7275 case 5:
d75c135e 7276 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7277 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7278 rn = "SRSConf4";
ead9360e 7279 break;
9c2149c8 7280 default:
f31b035a 7281 goto cp0_unimplemented;
876d4b07 7282 }
9c2149c8
TS
7283 break;
7284 case 7:
7285 switch (sel) {
7286 case 0:
d75c135e 7287 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7288 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 7289 ctx->bstate = BS_STOP;
2423f660
TS
7290 rn = "HWREna";
7291 break;
9c2149c8 7292 default:
f31b035a 7293 goto cp0_unimplemented;
876d4b07 7294 }
9c2149c8
TS
7295 break;
7296 case 8:
aea14095
LA
7297 switch (sel) {
7298 case 0:
7299 /* ignored */
7300 rn = "BadVAddr";
7301 break;
7302 case 1:
7303 /* ignored */
7304 rn = "BadInstr";
7305 break;
7306 case 2:
7307 /* ignored */
7308 rn = "BadInstrP";
7309 break;
7310 default:
f31b035a 7311 goto cp0_unimplemented;
aea14095 7312 }
9c2149c8
TS
7313 break;
7314 case 9:
7315 switch (sel) {
7316 case 0:
895c2d04 7317 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7318 rn = "Count";
7319 break;
876d4b07 7320 /* 6,7 are implementation dependent */
9c2149c8 7321 default:
f31b035a 7322 goto cp0_unimplemented;
876d4b07
TS
7323 }
7324 /* Stop translation as we may have switched the execution mode */
7325 ctx->bstate = BS_STOP;
9c2149c8
TS
7326 break;
7327 case 10:
7328 switch (sel) {
7329 case 0:
895c2d04 7330 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7331 rn = "EntryHi";
7332 break;
9c2149c8 7333 default:
f31b035a 7334 goto cp0_unimplemented;
876d4b07 7335 }
9c2149c8
TS
7336 break;
7337 case 11:
7338 switch (sel) {
7339 case 0:
895c2d04 7340 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7341 rn = "Compare";
7342 break;
876d4b07 7343 /* 6,7 are implementation dependent */
9c2149c8 7344 default:
f31b035a 7345 goto cp0_unimplemented;
876d4b07 7346 }
de9a95f0
AJ
7347 /* Stop translation as we may have switched the execution mode */
7348 ctx->bstate = BS_STOP;
9c2149c8
TS
7349 break;
7350 case 12:
7351 switch (sel) {
7352 case 0:
867abc7e 7353 save_cpu_state(ctx, 1);
895c2d04 7354 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7355 /* BS_STOP isn't good enough here, hflags may have changed. */
7356 gen_save_pc(ctx->pc + 4);
7357 ctx->bstate = BS_EXCP;
2423f660
TS
7358 rn = "Status";
7359 break;
9c2149c8 7360 case 1:
d75c135e 7361 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7362 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7363 /* Stop translation as we may have switched the execution mode */
7364 ctx->bstate = BS_STOP;
2423f660
TS
7365 rn = "IntCtl";
7366 break;
9c2149c8 7367 case 2:
d75c135e 7368 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7369 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7370 /* Stop translation as we may have switched the execution mode */
7371 ctx->bstate = BS_STOP;
2423f660
TS
7372 rn = "SRSCtl";
7373 break;
9c2149c8 7374 case 3:
d75c135e 7375 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7376 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7377 /* Stop translation as we may have switched the execution mode */
7378 ctx->bstate = BS_STOP;
2423f660
TS
7379 rn = "SRSMap";
7380 break;
7381 default:
f31b035a 7382 goto cp0_unimplemented;
876d4b07 7383 }
9c2149c8
TS
7384 break;
7385 case 13:
7386 switch (sel) {
7387 case 0:
867abc7e 7388 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7389 /* Mark as an IO operation because we may trigger a software
7390 interrupt. */
bd79255d 7391 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7392 gen_io_start();
7393 }
895c2d04 7394 gen_helper_mtc0_cause(cpu_env, arg);
bd79255d 7395 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5dc5d9f0
AJ
7396 gen_io_end();
7397 }
7398 /* Stop translation as we may have triggered an intetrupt */
7399 ctx->bstate = BS_STOP;
2423f660
TS
7400 rn = "Cause";
7401 break;
9c2149c8 7402 default:
f31b035a 7403 goto cp0_unimplemented;
876d4b07 7404 }
9c2149c8
TS
7405 break;
7406 case 14:
7407 switch (sel) {
7408 case 0:
7db13fae 7409 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7410 rn = "EPC";
7411 break;
9c2149c8 7412 default:
f31b035a 7413 goto cp0_unimplemented;
876d4b07 7414 }
9c2149c8
TS
7415 break;
7416 case 15:
7417 switch (sel) {
7418 case 0:
2423f660
TS
7419 /* ignored */
7420 rn = "PRid";
7421 break;
9c2149c8 7422 case 1:
d75c135e 7423 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7424 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7425 rn = "EBase";
7426 break;
9c2149c8 7427 default:
f31b035a 7428 goto cp0_unimplemented;
876d4b07 7429 }
9c2149c8
TS
7430 break;
7431 case 16:
7432 switch (sel) {
7433 case 0:
895c2d04 7434 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7435 rn = "Config";
2423f660
TS
7436 /* Stop translation as we may have switched the execution mode */
7437 ctx->bstate = BS_STOP;
9c2149c8
TS
7438 break;
7439 case 1:
1fc7bf6e 7440 /* ignored, read only */
9c2149c8
TS
7441 rn = "Config1";
7442 break;
7443 case 2:
895c2d04 7444 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7445 rn = "Config2";
2423f660
TS
7446 /* Stop translation as we may have switched the execution mode */
7447 ctx->bstate = BS_STOP;
9c2149c8
TS
7448 break;
7449 case 3:
90f12d73 7450 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7451 rn = "Config3";
90f12d73
MR
7452 /* Stop translation as we may have switched the execution mode */
7453 ctx->bstate = BS_STOP;
9c2149c8 7454 break;
faf1f68b
LA
7455 case 4:
7456 /* currently ignored */
7457 rn = "Config4";
7458 break;
7459 case 5:
7460 gen_helper_mtc0_config5(cpu_env, arg);
7461 rn = "Config5";
7462 /* Stop translation as we may have switched the execution mode */
7463 ctx->bstate = BS_STOP;
7464 break;
9c2149c8
TS
7465 /* 6,7 are implementation dependent */
7466 default:
7467 rn = "Invalid config selector";
f31b035a 7468 goto cp0_unimplemented;
9c2149c8 7469 }
9c2149c8
TS
7470 break;
7471 case 17:
7472 switch (sel) {
7473 case 0:
895c2d04 7474 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7475 rn = "LLAddr";
7476 break;
9c2149c8 7477 default:
f31b035a 7478 goto cp0_unimplemented;
9c2149c8
TS
7479 }
7480 break;
7481 case 18:
7482 switch (sel) {
fd88b6ab 7483 case 0 ... 7:
895c2d04 7484 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7485 rn = "WatchLo";
7486 break;
9c2149c8 7487 default:
f31b035a 7488 goto cp0_unimplemented;
9c2149c8
TS
7489 }
7490 break;
7491 case 19:
7492 switch (sel) {
fd88b6ab 7493 case 0 ... 7:
895c2d04 7494 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7495 rn = "WatchHi";
7496 break;
9c2149c8 7497 default:
f31b035a 7498 goto cp0_unimplemented;
9c2149c8
TS
7499 }
7500 break;
7501 case 20:
7502 switch (sel) {
7503 case 0:
d75c135e 7504 check_insn(ctx, ISA_MIPS3);
895c2d04 7505 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7506 rn = "XContext";
7507 break;
9c2149c8 7508 default:
f31b035a 7509 goto cp0_unimplemented;
9c2149c8
TS
7510 }
7511 break;
7512 case 21:
7513 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7514 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7515 switch (sel) {
7516 case 0:
895c2d04 7517 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7518 rn = "Framemask";
7519 break;
9c2149c8 7520 default:
f31b035a 7521 goto cp0_unimplemented;
9c2149c8
TS
7522 }
7523 break;
7524 case 22:
7525 /* ignored */
7526 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7527 break;
9c2149c8
TS
7528 case 23:
7529 switch (sel) {
7530 case 0:
895c2d04 7531 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7532 /* BS_STOP isn't good enough here, hflags may have changed. */
7533 gen_save_pc(ctx->pc + 4);
7534 ctx->bstate = BS_EXCP;
2423f660
TS
7535 rn = "Debug";
7536 break;
9c2149c8 7537 case 1:
895c2d04 7538// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7539 /* Stop translation as we may have switched the execution mode */
7540 ctx->bstate = BS_STOP;
2423f660
TS
7541 rn = "TraceControl";
7542// break;
9c2149c8 7543 case 2:
895c2d04 7544// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7545 /* Stop translation as we may have switched the execution mode */
7546 ctx->bstate = BS_STOP;
2423f660
TS
7547 rn = "TraceControl2";
7548// break;
9c2149c8 7549 case 3:
895c2d04 7550// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7551 /* Stop translation as we may have switched the execution mode */
7552 ctx->bstate = BS_STOP;
2423f660
TS
7553 rn = "UserTraceData";
7554// break;
9c2149c8 7555 case 4:
895c2d04 7556// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7557 /* Stop translation as we may have switched the execution mode */
7558 ctx->bstate = BS_STOP;
2423f660
TS
7559 rn = "TraceBPC";
7560// break;
9c2149c8 7561 default:
f31b035a 7562 goto cp0_unimplemented;
9c2149c8 7563 }
9c2149c8
TS
7564 break;
7565 case 24:
7566 switch (sel) {
7567 case 0:
f1aa6320 7568 /* EJTAG support */
7db13fae 7569 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7570 rn = "DEPC";
7571 break;
9c2149c8 7572 default:
f31b035a 7573 goto cp0_unimplemented;
9c2149c8
TS
7574 }
7575 break;
7576 case 25:
7577 switch (sel) {
7578 case 0:
895c2d04 7579 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7580 rn = "Performance0";
7581 break;
9c2149c8 7582 case 1:
895c2d04 7583// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7584 rn = "Performance1";
7585// break;
9c2149c8 7586 case 2:
895c2d04 7587// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7588 rn = "Performance2";
7589// break;
9c2149c8 7590 case 3:
895c2d04 7591// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7592 rn = "Performance3";
7593// break;
9c2149c8 7594 case 4:
895c2d04 7595// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7596 rn = "Performance4";
7597// break;
9c2149c8 7598 case 5:
895c2d04 7599// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7600 rn = "Performance5";
7601// break;
9c2149c8 7602 case 6:
895c2d04 7603// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7604 rn = "Performance6";
7605// break;
9c2149c8 7606 case 7:
895c2d04 7607// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7608 rn = "Performance7";
7609// break;
9c2149c8 7610 default:
f31b035a 7611 goto cp0_unimplemented;
9c2149c8 7612 }
876d4b07 7613 break;
9c2149c8 7614 case 26:
876d4b07 7615 /* ignored */
9c2149c8 7616 rn = "ECC";
876d4b07 7617 break;
9c2149c8
TS
7618 case 27:
7619 switch (sel) {
7620 case 0 ... 3:
2423f660
TS
7621 /* ignored */
7622 rn = "CacheErr";
7623 break;
9c2149c8 7624 default:
f31b035a 7625 goto cp0_unimplemented;
9c2149c8 7626 }
876d4b07 7627 break;
9c2149c8
TS
7628 case 28:
7629 switch (sel) {
7630 case 0:
7631 case 2:
7632 case 4:
7633 case 6:
895c2d04 7634 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7635 rn = "TagLo";
7636 break;
7637 case 1:
7638 case 3:
7639 case 5:
7640 case 7:
895c2d04 7641 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7642 rn = "DataLo";
7643 break;
7644 default:
f31b035a 7645 goto cp0_unimplemented;
9c2149c8
TS
7646 }
7647 break;
7648 case 29:
7649 switch (sel) {
7650 case 0:
7651 case 2:
7652 case 4:
7653 case 6:
895c2d04 7654 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7655 rn = "TagHi";
7656 break;
7657 case 1:
7658 case 3:
7659 case 5:
7660 case 7:
895c2d04 7661 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7662 rn = "DataHi";
7663 break;
7664 default:
7665 rn = "invalid sel";
f31b035a 7666 goto cp0_unimplemented;
9c2149c8 7667 }
876d4b07 7668 break;
9c2149c8
TS
7669 case 30:
7670 switch (sel) {
7671 case 0:
7db13fae 7672 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7673 rn = "ErrorEPC";
7674 break;
9c2149c8 7675 default:
f31b035a 7676 goto cp0_unimplemented;
9c2149c8
TS
7677 }
7678 break;
7679 case 31:
7680 switch (sel) {
7681 case 0:
f1aa6320 7682 /* EJTAG support */
7db13fae 7683 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7684 rn = "DESAVE";
7685 break;
e98c0d17 7686 case 2 ... 7:
f31b035a
LA
7687 CP0_CHECK(ctx->kscrexist & (1 << sel));
7688 tcg_gen_st_tl(arg, cpu_env,
7689 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7690 rn = "KScratch";
e98c0d17 7691 break;
9c2149c8 7692 default:
f31b035a 7693 goto cp0_unimplemented;
9c2149c8 7694 }
876d4b07
TS
7695 /* Stop translation as we may have switched the execution mode */
7696 ctx->bstate = BS_STOP;
9c2149c8
TS
7697 break;
7698 default:
f31b035a 7699 goto cp0_unimplemented;
9c2149c8 7700 }
2abf314d 7701 (void)rn; /* avoid a compiler warning */
d12d51d5 7702 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7703 /* For simplicity assume that all writes can cause interrupts. */
bd79255d 7704 if (ctx->tb->cflags & CF_USE_ICOUNT) {
2e70f6ef
PB
7705 gen_io_end();
7706 ctx->bstate = BS_STOP;
7707 }
9c2149c8
TS
7708 return;
7709
f31b035a 7710cp0_unimplemented:
d12d51d5 7711 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7712}
d26bc211 7713#endif /* TARGET_MIPS64 */
9c2149c8 7714
7db13fae 7715static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7716 int u, int sel, int h)
7717{
7718 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7719 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7720
7721 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7722 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7723 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7724 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7725 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7726 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7727 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7728 else if (u == 0) {
7729 switch (rt) {
5a25ce94
EI
7730 case 1:
7731 switch (sel) {
7732 case 1:
895c2d04 7733 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7734 break;
7735 case 2:
895c2d04 7736 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7737 break;
7738 default:
7739 goto die;
7740 break;
7741 }
7742 break;
ead9360e
TS
7743 case 2:
7744 switch (sel) {
7745 case 1:
895c2d04 7746 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7747 break;
7748 case 2:
895c2d04 7749 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7750 break;
7751 case 3:
895c2d04 7752 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7753 break;
7754 case 4:
895c2d04 7755 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7756 break;
7757 case 5:
895c2d04 7758 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7759 break;
7760 case 6:
895c2d04 7761 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7762 break;
7763 case 7:
895c2d04 7764 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7765 break;
7766 default:
d75c135e 7767 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7768 break;
7769 }
7770 break;
7771 case 10:
7772 switch (sel) {
7773 case 0:
895c2d04 7774 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7775 break;
7776 default:
d75c135e 7777 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7778 break;
7779 }
7780 case 12:
7781 switch (sel) {
7782 case 0:
895c2d04 7783 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7784 break;
7785 default:
d75c135e 7786 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7787 break;
7788 }
5a25ce94
EI
7789 case 13:
7790 switch (sel) {
7791 case 0:
895c2d04 7792 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7793 break;
7794 default:
7795 goto die;
7796 break;
7797 }
7798 break;
7799 case 14:
7800 switch (sel) {
7801 case 0:
895c2d04 7802 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7803 break;
7804 default:
7805 goto die;
7806 break;
7807 }
7808 break;
7809 case 15:
7810 switch (sel) {
7811 case 1:
895c2d04 7812 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7813 break;
7814 default:
7815 goto die;
7816 break;
7817 }
7818 break;
7819 case 16:
7820 switch (sel) {
7821 case 0 ... 7:
895c2d04 7822 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7823 break;
7824 default:
7825 goto die;
7826 break;
7827 }
7828 break;
ead9360e
TS
7829 case 23:
7830 switch (sel) {
7831 case 0:
895c2d04 7832 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7833 break;
7834 default:
d75c135e 7835 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7836 break;
7837 }
7838 break;
7839 default:
d75c135e 7840 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7841 }
7842 } else switch (sel) {
7843 /* GPR registers. */
7844 case 0:
895c2d04 7845 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7846 break;
7847 /* Auxiliary CPU registers */
7848 case 1:
7849 switch (rt) {
7850 case 0:
895c2d04 7851 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7852 break;
7853 case 1:
895c2d04 7854 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7855 break;
7856 case 2:
895c2d04 7857 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7858 break;
7859 case 4:
895c2d04 7860 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7861 break;
7862 case 5:
895c2d04 7863 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7864 break;
7865 case 6:
895c2d04 7866 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7867 break;
7868 case 8:
895c2d04 7869 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7870 break;
7871 case 9:
895c2d04 7872 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7873 break;
7874 case 10:
895c2d04 7875 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7876 break;
7877 case 12:
895c2d04 7878 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7879 break;
7880 case 13:
895c2d04 7881 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7882 break;
7883 case 14:
895c2d04 7884 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7885 break;
7886 case 16:
895c2d04 7887 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7888 break;
7889 default:
7890 goto die;
7891 }
7892 break;
7893 /* Floating point (COP1). */
7894 case 2:
7895 /* XXX: For now we support only a single FPU context. */
7896 if (h == 0) {
a7812ae4 7897 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7898
7c979afd 7899 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7900 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7901 tcg_temp_free_i32(fp0);
ead9360e 7902 } else {
a7812ae4 7903 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7904
7f6613ce 7905 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7906 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7907 tcg_temp_free_i32(fp0);
ead9360e
TS
7908 }
7909 break;
7910 case 3:
7911 /* XXX: For now we support only a single FPU context. */
895c2d04 7912 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7913 break;
7914 /* COP2: Not implemented. */
7915 case 4:
7916 case 5:
7917 /* fall through */
7918 default:
7919 goto die;
7920 }
d12d51d5 7921 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7922 gen_store_gpr(t0, rd);
7923 tcg_temp_free(t0);
ead9360e
TS
7924 return;
7925
7926die:
1a3fd9c3 7927 tcg_temp_free(t0);
d12d51d5 7928 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7929 generate_exception(ctx, EXCP_RI);
7930}
7931
7db13fae 7932static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7933 int u, int sel, int h)
7934{
7935 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7936 TCGv t0 = tcg_temp_local_new();
ead9360e 7937
1a3fd9c3 7938 gen_load_gpr(t0, rt);
ead9360e 7939 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7940 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7941 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7942 /* NOP */ ;
7943 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7944 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7945 /* NOP */ ;
7946 else if (u == 0) {
7947 switch (rd) {
5a25ce94
EI
7948 case 1:
7949 switch (sel) {
7950 case 1:
895c2d04 7951 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7952 break;
7953 case 2:
895c2d04 7954 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7955 break;
7956 default:
7957 goto die;
7958 break;
7959 }
7960 break;
ead9360e
TS
7961 case 2:
7962 switch (sel) {
7963 case 1:
895c2d04 7964 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7965 break;
7966 case 2:
895c2d04 7967 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7968 break;
7969 case 3:
895c2d04 7970 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7971 break;
7972 case 4:
895c2d04 7973 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7974 break;
7975 case 5:
895c2d04 7976 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7977 break;
7978 case 6:
895c2d04 7979 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7980 break;
7981 case 7:
895c2d04 7982 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7983 break;
7984 default:
d75c135e 7985 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7986 break;
7987 }
7988 break;
7989 case 10:
7990 switch (sel) {
7991 case 0:
895c2d04 7992 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7993 break;
7994 default:
d75c135e 7995 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7996 break;
7997 }
7998 case 12:
7999 switch (sel) {
8000 case 0:
895c2d04 8001 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8002 break;
8003 default:
d75c135e 8004 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8005 break;
8006 }
5a25ce94
EI
8007 case 13:
8008 switch (sel) {
8009 case 0:
895c2d04 8010 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8011 break;
8012 default:
8013 goto die;
8014 break;
8015 }
8016 break;
8017 case 15:
8018 switch (sel) {
8019 case 1:
895c2d04 8020 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8021 break;
8022 default:
8023 goto die;
8024 break;
8025 }
8026 break;
ead9360e
TS
8027 case 23:
8028 switch (sel) {
8029 case 0:
895c2d04 8030 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8031 break;
8032 default:
d75c135e 8033 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8034 break;
8035 }
8036 break;
8037 default:
d75c135e 8038 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8039 }
8040 } else switch (sel) {
8041 /* GPR registers. */
8042 case 0:
895c2d04 8043 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8044 break;
8045 /* Auxiliary CPU registers */
8046 case 1:
8047 switch (rd) {
8048 case 0:
895c2d04 8049 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8050 break;
8051 case 1:
895c2d04 8052 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8053 break;
8054 case 2:
895c2d04 8055 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8056 break;
8057 case 4:
895c2d04 8058 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8059 break;
8060 case 5:
895c2d04 8061 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8062 break;
8063 case 6:
895c2d04 8064 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8065 break;
8066 case 8:
895c2d04 8067 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8068 break;
8069 case 9:
895c2d04 8070 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8071 break;
8072 case 10:
895c2d04 8073 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8074 break;
8075 case 12:
895c2d04 8076 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8077 break;
8078 case 13:
895c2d04 8079 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8080 break;
8081 case 14:
895c2d04 8082 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8083 break;
8084 case 16:
895c2d04 8085 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8086 break;
8087 default:
8088 goto die;
8089 }
8090 break;
8091 /* Floating point (COP1). */
8092 case 2:
8093 /* XXX: For now we support only a single FPU context. */
8094 if (h == 0) {
a7812ae4 8095 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8096
8097 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8098 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8099 tcg_temp_free_i32(fp0);
ead9360e 8100 } else {
a7812ae4 8101 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8102
8103 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8104 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8105 tcg_temp_free_i32(fp0);
ead9360e
TS
8106 }
8107 break;
8108 case 3:
8109 /* XXX: For now we support only a single FPU context. */
4cf8a45f 8110 save_cpu_state(ctx, 1);
736d120a
PJ
8111 {
8112 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8113
8114 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8115 tcg_temp_free_i32(fs_tmp);
8116 }
4cf8a45f
YK
8117 /* Stop translation as we may have changed hflags */
8118 ctx->bstate = BS_STOP;
ead9360e
TS
8119 break;
8120 /* COP2: Not implemented. */
8121 case 4:
8122 case 5:
8123 /* fall through */
8124 default:
8125 goto die;
8126 }
d12d51d5 8127 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 8128 tcg_temp_free(t0);
ead9360e
TS
8129 return;
8130
8131die:
1a3fd9c3 8132 tcg_temp_free(t0);
d12d51d5 8133 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
8134 generate_exception(ctx, EXCP_RI);
8135}
8136
7db13fae 8137static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8138{
287c4b84 8139 const char *opn = "ldst";
6af0bf9c 8140
2e15497c 8141 check_cp0_enabled(ctx);
6af0bf9c
FB
8142 switch (opc) {
8143 case OPC_MFC0:
8144 if (rt == 0) {
ead9360e 8145 /* Treat as NOP. */
6af0bf9c
FB
8146 return;
8147 }
d75c135e 8148 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8149 opn = "mfc0";
8150 break;
8151 case OPC_MTC0:
1a3fd9c3 8152 {
1fc7bf6e 8153 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8154
8155 gen_load_gpr(t0, rt);
d75c135e 8156 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8157 tcg_temp_free(t0);
8158 }
6af0bf9c
FB
8159 opn = "mtc0";
8160 break;
d26bc211 8161#if defined(TARGET_MIPS64)
9c2149c8 8162 case OPC_DMFC0:
d75c135e 8163 check_insn(ctx, ISA_MIPS3);
9c2149c8 8164 if (rt == 0) {
ead9360e 8165 /* Treat as NOP. */
9c2149c8
TS
8166 return;
8167 }
d75c135e 8168 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8169 opn = "dmfc0";
8170 break;
8171 case OPC_DMTC0:
d75c135e 8172 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8173 {
1fc7bf6e 8174 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8175
8176 gen_load_gpr(t0, rt);
d75c135e 8177 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8178 tcg_temp_free(t0);
8179 }
9c2149c8
TS
8180 opn = "dmtc0";
8181 break;
534ce69f 8182#endif
5204ea79
LA
8183 case OPC_MFHC0:
8184 check_mvh(ctx);
8185 if (rt == 0) {
8186 /* Treat as NOP. */
8187 return;
8188 }
8189 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8190 opn = "mfhc0";
8191 break;
8192 case OPC_MTHC0:
8193 check_mvh(ctx);
8194 {
8195 TCGv t0 = tcg_temp_new();
8196 gen_load_gpr(t0, rt);
8197 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8198 tcg_temp_free(t0);
8199 }
8200 opn = "mthc0";
8201 break;
ead9360e 8202 case OPC_MFTR:
d75c135e 8203 check_insn(ctx, ASE_MT);
ead9360e
TS
8204 if (rd == 0) {
8205 /* Treat as NOP. */
8206 return;
8207 }
6c5c1e20 8208 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8209 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8210 opn = "mftr";
8211 break;
8212 case OPC_MTTR:
d75c135e 8213 check_insn(ctx, ASE_MT);
6c5c1e20 8214 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8215 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8216 opn = "mttr";
8217 break;
6af0bf9c 8218 case OPC_TLBWI:
6af0bf9c 8219 opn = "tlbwi";
c01fccd2 8220 if (!env->tlb->helper_tlbwi)
29929e34 8221 goto die;
895c2d04 8222 gen_helper_tlbwi(cpu_env);
6af0bf9c 8223 break;
9456c2fb
LA
8224 case OPC_TLBINV:
8225 opn = "tlbinv";
8226 if (ctx->ie >= 2) {
8227 if (!env->tlb->helper_tlbinv) {
8228 goto die;
8229 }
8230 gen_helper_tlbinv(cpu_env);
8231 } /* treat as nop if TLBINV not supported */
8232 break;
8233 case OPC_TLBINVF:
8234 opn = "tlbinvf";
8235 if (ctx->ie >= 2) {
8236 if (!env->tlb->helper_tlbinvf) {
8237 goto die;
8238 }
8239 gen_helper_tlbinvf(cpu_env);
8240 } /* treat as nop if TLBINV not supported */
8241 break;
6af0bf9c 8242 case OPC_TLBWR:
6af0bf9c 8243 opn = "tlbwr";
c01fccd2 8244 if (!env->tlb->helper_tlbwr)
29929e34 8245 goto die;
895c2d04 8246 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8247 break;
8248 case OPC_TLBP:
6af0bf9c 8249 opn = "tlbp";
c01fccd2 8250 if (!env->tlb->helper_tlbp)
29929e34 8251 goto die;
895c2d04 8252 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8253 break;
8254 case OPC_TLBR:
6af0bf9c 8255 opn = "tlbr";
c01fccd2 8256 if (!env->tlb->helper_tlbr)
29929e34 8257 goto die;
895c2d04 8258 gen_helper_tlbr(cpu_env);
6af0bf9c 8259 break;
ce9782f4 8260 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8261 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8262 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8263 MIPS_DEBUG("CTI in delay / forbidden slot");
8264 goto die;
ce9782f4
LA
8265 } else {
8266 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8267 if (ctx->opcode & (1 << bit_shift)) {
8268 /* OPC_ERETNC */
8269 opn = "eretnc";
8270 check_insn(ctx, ISA_MIPS32R5);
8271 gen_helper_eretnc(cpu_env);
8272 } else {
8273 /* OPC_ERET */
8274 opn = "eret";
8275 check_insn(ctx, ISA_MIPS2);
8276 gen_helper_eret(cpu_env);
8277 }
8278 ctx->bstate = BS_EXCP;
339cd2a8 8279 }
6af0bf9c
FB
8280 break;
8281 case OPC_DERET:
8282 opn = "deret";
d75c135e 8283 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8284 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8285 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8286 MIPS_DEBUG("CTI in delay / forbidden slot");
8287 goto die;
8288 }
6af0bf9c 8289 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8290 MIPS_INVAL(opn);
6af0bf9c
FB
8291 generate_exception(ctx, EXCP_RI);
8292 } else {
895c2d04 8293 gen_helper_deret(cpu_env);
6af0bf9c
FB
8294 ctx->bstate = BS_EXCP;
8295 }
8296 break;
4ad40f36
FB
8297 case OPC_WAIT:
8298 opn = "wait";
d75c135e 8299 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8300 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8301 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8302 MIPS_DEBUG("CTI in delay / forbidden slot");
8303 goto die;
8304 }
4ad40f36
FB
8305 /* If we get an exception, we want to restart at next instruction */
8306 ctx->pc += 4;
8307 save_cpu_state(ctx, 1);
8308 ctx->pc -= 4;
895c2d04 8309 gen_helper_wait(cpu_env);
4ad40f36
FB
8310 ctx->bstate = BS_EXCP;
8311 break;
6af0bf9c 8312 default:
29929e34 8313 die:
923617a3 8314 MIPS_INVAL(opn);
6af0bf9c
FB
8315 generate_exception(ctx, EXCP_RI);
8316 return;
8317 }
2abf314d 8318 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
8319 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
8320}
f1aa6320 8321#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8322
6ea83fed 8323/* CP1 Branches (before delay slot) */
d75c135e
AJ
8324static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8325 int32_t cc, int32_t offset)
6ea83fed
FB
8326{
8327 target_ulong btarget;
923617a3 8328 const char *opn = "cp1 cond branch";
a7812ae4 8329 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8330
339cd2a8
LA
8331 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8332 MIPS_DEBUG("CTI in delay / forbidden slot");
8333 generate_exception(ctx, EXCP_RI);
8334 goto out;
8335 }
8336
e189e748 8337 if (cc != 0)
d75c135e 8338 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8339
6ea83fed
FB
8340 btarget = ctx->pc + 4 + offset;
8341
7a387fff
TS
8342 switch (op) {
8343 case OPC_BC1F:
d94536f4
AJ
8344 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8345 tcg_gen_not_i32(t0, t0);
8346 tcg_gen_andi_i32(t0, t0, 1);
8347 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8348 opn = "bc1f";
6ea83fed 8349 goto not_likely;
7a387fff 8350 case OPC_BC1FL:
d94536f4
AJ
8351 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8352 tcg_gen_not_i32(t0, t0);
8353 tcg_gen_andi_i32(t0, t0, 1);
8354 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8355 opn = "bc1fl";
6ea83fed 8356 goto likely;
7a387fff 8357 case OPC_BC1T:
d94536f4
AJ
8358 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8359 tcg_gen_andi_i32(t0, t0, 1);
8360 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8361 opn = "bc1t";
5a5012ec 8362 goto not_likely;
7a387fff 8363 case OPC_BC1TL:
d94536f4
AJ
8364 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8365 tcg_gen_andi_i32(t0, t0, 1);
8366 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 8367 opn = "bc1tl";
6ea83fed
FB
8368 likely:
8369 ctx->hflags |= MIPS_HFLAG_BL;
8370 break;
5a5012ec 8371 case OPC_BC1FANY2:
a16336e4 8372 {
d94536f4
AJ
8373 TCGv_i32 t1 = tcg_temp_new_i32();
8374 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8375 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8376 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8377 tcg_temp_free_i32(t1);
d94536f4
AJ
8378 tcg_gen_andi_i32(t0, t0, 1);
8379 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8380 }
fd4a04eb 8381 opn = "bc1any2f";
5a5012ec
TS
8382 goto not_likely;
8383 case OPC_BC1TANY2:
a16336e4 8384 {
d94536f4
AJ
8385 TCGv_i32 t1 = tcg_temp_new_i32();
8386 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8387 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8388 tcg_gen_or_i32(t0, t0, t1);
8389 tcg_temp_free_i32(t1);
8390 tcg_gen_andi_i32(t0, t0, 1);
8391 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8392 }
fd4a04eb 8393 opn = "bc1any2t";
5a5012ec
TS
8394 goto not_likely;
8395 case OPC_BC1FANY4:
a16336e4 8396 {
d94536f4
AJ
8397 TCGv_i32 t1 = tcg_temp_new_i32();
8398 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8399 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8400 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8401 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8402 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8403 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8404 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8405 tcg_temp_free_i32(t1);
d94536f4
AJ
8406 tcg_gen_andi_i32(t0, t0, 1);
8407 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8408 }
fd4a04eb 8409 opn = "bc1any4f";
5a5012ec
TS
8410 goto not_likely;
8411 case OPC_BC1TANY4:
a16336e4 8412 {
d94536f4
AJ
8413 TCGv_i32 t1 = tcg_temp_new_i32();
8414 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8415 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8416 tcg_gen_or_i32(t0, t0, t1);
8417 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8418 tcg_gen_or_i32(t0, t0, t1);
8419 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8420 tcg_gen_or_i32(t0, t0, t1);
8421 tcg_temp_free_i32(t1);
8422 tcg_gen_andi_i32(t0, t0, 1);
8423 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8424 }
fd4a04eb 8425 opn = "bc1any4t";
5a5012ec
TS
8426 not_likely:
8427 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8428 break;
8429 default:
923617a3 8430 MIPS_INVAL(opn);
e397ee33 8431 generate_exception (ctx, EXCP_RI);
6c5c1e20 8432 goto out;
6ea83fed 8433 }
2abf314d 8434 (void)opn; /* avoid a compiler warning */
923617a3 8435 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8436 ctx->hflags, btarget);
8437 ctx->btarget = btarget;
b231c103 8438 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8439 out:
a7812ae4 8440 tcg_temp_free_i32(t0);
6ea83fed
FB
8441}
8442
31837be3
YK
8443/* R6 CP1 Branches */
8444static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8445 int32_t ft, int32_t offset,
8446 int delayslot_size)
31837be3
YK
8447{
8448 target_ulong btarget;
8449 const char *opn = "cp1 cond branch";
8450 TCGv_i64 t0 = tcg_temp_new_i64();
8451
8452 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8453#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8454 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8455 "\n", ctx->pc);
31837be3
YK
8456#endif
8457 generate_exception(ctx, EXCP_RI);
8458 goto out;
8459 }
8460
8461 gen_load_fpr64(ctx, t0, ft);
8462 tcg_gen_andi_i64(t0, t0, 1);
8463
8464 btarget = addr_add(ctx, ctx->pc + 4, offset);
8465
8466 switch (op) {
8467 case OPC_BC1EQZ:
8468 tcg_gen_xori_i64(t0, t0, 1);
8469 opn = "bc1eqz";
8470 ctx->hflags |= MIPS_HFLAG_BC;
8471 break;
8472 case OPC_BC1NEZ:
8473 /* t0 already set */
8474 opn = "bc1nez";
8475 ctx->hflags |= MIPS_HFLAG_BC;
8476 break;
8477 default:
8478 MIPS_INVAL(opn);
8479 generate_exception(ctx, EXCP_RI);
8480 goto out;
8481 }
8482
8483 tcg_gen_trunc_i64_tl(bcond, t0);
8484
8485 (void)opn; /* avoid a compiler warning */
8486 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8487 ctx->hflags, btarget);
8488 ctx->btarget = btarget;
65935f07
YK
8489
8490 switch (delayslot_size) {
8491 case 2:
8492 ctx->hflags |= MIPS_HFLAG_BDS16;
8493 break;
8494 case 4:
8495 ctx->hflags |= MIPS_HFLAG_BDS32;
8496 break;
8497 }
31837be3
YK
8498
8499out:
8500 tcg_temp_free_i64(t0);
8501}
8502
6af0bf9c 8503/* Coprocessor 1 (FPU) */
5a5012ec 8504
5a5012ec
TS
8505#define FOP(func, fmt) (((fmt) << 21) | (func))
8506
bf4120ad
NF
8507enum fopcode {
8508 OPC_ADD_S = FOP(0, FMT_S),
8509 OPC_SUB_S = FOP(1, FMT_S),
8510 OPC_MUL_S = FOP(2, FMT_S),
8511 OPC_DIV_S = FOP(3, FMT_S),
8512 OPC_SQRT_S = FOP(4, FMT_S),
8513 OPC_ABS_S = FOP(5, FMT_S),
8514 OPC_MOV_S = FOP(6, FMT_S),
8515 OPC_NEG_S = FOP(7, FMT_S),
8516 OPC_ROUND_L_S = FOP(8, FMT_S),
8517 OPC_TRUNC_L_S = FOP(9, FMT_S),
8518 OPC_CEIL_L_S = FOP(10, FMT_S),
8519 OPC_FLOOR_L_S = FOP(11, FMT_S),
8520 OPC_ROUND_W_S = FOP(12, FMT_S),
8521 OPC_TRUNC_W_S = FOP(13, FMT_S),
8522 OPC_CEIL_W_S = FOP(14, FMT_S),
8523 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8524 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8525 OPC_MOVCF_S = FOP(17, FMT_S),
8526 OPC_MOVZ_S = FOP(18, FMT_S),
8527 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8528 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8529 OPC_RECIP_S = FOP(21, FMT_S),
8530 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8531 OPC_SELNEZ_S = FOP(23, FMT_S),
8532 OPC_MADDF_S = FOP(24, FMT_S),
8533 OPC_MSUBF_S = FOP(25, FMT_S),
8534 OPC_RINT_S = FOP(26, FMT_S),
8535 OPC_CLASS_S = FOP(27, FMT_S),
8536 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8537 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8538 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8539 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8540 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8541 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8542 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8543 OPC_RSQRT2_S = FOP(31, FMT_S),
8544 OPC_CVT_D_S = FOP(33, FMT_S),
8545 OPC_CVT_W_S = FOP(36, FMT_S),
8546 OPC_CVT_L_S = FOP(37, FMT_S),
8547 OPC_CVT_PS_S = FOP(38, FMT_S),
8548 OPC_CMP_F_S = FOP (48, FMT_S),
8549 OPC_CMP_UN_S = FOP (49, FMT_S),
8550 OPC_CMP_EQ_S = FOP (50, FMT_S),
8551 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8552 OPC_CMP_OLT_S = FOP (52, FMT_S),
8553 OPC_CMP_ULT_S = FOP (53, FMT_S),
8554 OPC_CMP_OLE_S = FOP (54, FMT_S),
8555 OPC_CMP_ULE_S = FOP (55, FMT_S),
8556 OPC_CMP_SF_S = FOP (56, FMT_S),
8557 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8558 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8559 OPC_CMP_NGL_S = FOP (59, FMT_S),
8560 OPC_CMP_LT_S = FOP (60, FMT_S),
8561 OPC_CMP_NGE_S = FOP (61, FMT_S),
8562 OPC_CMP_LE_S = FOP (62, FMT_S),
8563 OPC_CMP_NGT_S = FOP (63, FMT_S),
8564
8565 OPC_ADD_D = FOP(0, FMT_D),
8566 OPC_SUB_D = FOP(1, FMT_D),
8567 OPC_MUL_D = FOP(2, FMT_D),
8568 OPC_DIV_D = FOP(3, FMT_D),
8569 OPC_SQRT_D = FOP(4, FMT_D),
8570 OPC_ABS_D = FOP(5, FMT_D),
8571 OPC_MOV_D = FOP(6, FMT_D),
8572 OPC_NEG_D = FOP(7, FMT_D),
8573 OPC_ROUND_L_D = FOP(8, FMT_D),
8574 OPC_TRUNC_L_D = FOP(9, FMT_D),
8575 OPC_CEIL_L_D = FOP(10, FMT_D),
8576 OPC_FLOOR_L_D = FOP(11, FMT_D),
8577 OPC_ROUND_W_D = FOP(12, FMT_D),
8578 OPC_TRUNC_W_D = FOP(13, FMT_D),
8579 OPC_CEIL_W_D = FOP(14, FMT_D),
8580 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8581 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8582 OPC_MOVCF_D = FOP(17, FMT_D),
8583 OPC_MOVZ_D = FOP(18, FMT_D),
8584 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8585 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8586 OPC_RECIP_D = FOP(21, FMT_D),
8587 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8588 OPC_SELNEZ_D = FOP(23, FMT_D),
8589 OPC_MADDF_D = FOP(24, FMT_D),
8590 OPC_MSUBF_D = FOP(25, FMT_D),
8591 OPC_RINT_D = FOP(26, FMT_D),
8592 OPC_CLASS_D = FOP(27, FMT_D),
8593 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8594 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8595 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8596 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8597 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8598 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8599 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8600 OPC_RSQRT2_D = FOP(31, FMT_D),
8601 OPC_CVT_S_D = FOP(32, FMT_D),
8602 OPC_CVT_W_D = FOP(36, FMT_D),
8603 OPC_CVT_L_D = FOP(37, FMT_D),
8604 OPC_CMP_F_D = FOP (48, FMT_D),
8605 OPC_CMP_UN_D = FOP (49, FMT_D),
8606 OPC_CMP_EQ_D = FOP (50, FMT_D),
8607 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8608 OPC_CMP_OLT_D = FOP (52, FMT_D),
8609 OPC_CMP_ULT_D = FOP (53, FMT_D),
8610 OPC_CMP_OLE_D = FOP (54, FMT_D),
8611 OPC_CMP_ULE_D = FOP (55, FMT_D),
8612 OPC_CMP_SF_D = FOP (56, FMT_D),
8613 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8614 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8615 OPC_CMP_NGL_D = FOP (59, FMT_D),
8616 OPC_CMP_LT_D = FOP (60, FMT_D),
8617 OPC_CMP_NGE_D = FOP (61, FMT_D),
8618 OPC_CMP_LE_D = FOP (62, FMT_D),
8619 OPC_CMP_NGT_D = FOP (63, FMT_D),
8620
8621 OPC_CVT_S_W = FOP(32, FMT_W),
8622 OPC_CVT_D_W = FOP(33, FMT_W),
8623 OPC_CVT_S_L = FOP(32, FMT_L),
8624 OPC_CVT_D_L = FOP(33, FMT_L),
8625 OPC_CVT_PS_PW = FOP(38, FMT_W),
8626
8627 OPC_ADD_PS = FOP(0, FMT_PS),
8628 OPC_SUB_PS = FOP(1, FMT_PS),
8629 OPC_MUL_PS = FOP(2, FMT_PS),
8630 OPC_DIV_PS = FOP(3, FMT_PS),
8631 OPC_ABS_PS = FOP(5, FMT_PS),
8632 OPC_MOV_PS = FOP(6, FMT_PS),
8633 OPC_NEG_PS = FOP(7, FMT_PS),
8634 OPC_MOVCF_PS = FOP(17, FMT_PS),
8635 OPC_MOVZ_PS = FOP(18, FMT_PS),
8636 OPC_MOVN_PS = FOP(19, FMT_PS),
8637 OPC_ADDR_PS = FOP(24, FMT_PS),
8638 OPC_MULR_PS = FOP(26, FMT_PS),
8639 OPC_RECIP2_PS = FOP(28, FMT_PS),
8640 OPC_RECIP1_PS = FOP(29, FMT_PS),
8641 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8642 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8643
8644 OPC_CVT_S_PU = FOP(32, FMT_PS),
8645 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8646 OPC_CVT_S_PL = FOP(40, FMT_PS),
8647 OPC_PLL_PS = FOP(44, FMT_PS),
8648 OPC_PLU_PS = FOP(45, FMT_PS),
8649 OPC_PUL_PS = FOP(46, FMT_PS),
8650 OPC_PUU_PS = FOP(47, FMT_PS),
8651 OPC_CMP_F_PS = FOP (48, FMT_PS),
8652 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8653 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8654 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8655 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8656 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8657 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8658 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8659 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8660 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8661 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8662 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8663 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8664 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8665 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8666 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8667};
8668
3f493883
YK
8669enum r6_f_cmp_op {
8670 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8671 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8672 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8673 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8674 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8675 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8676 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8677 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8678 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8679 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8680 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8681 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8682 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8683 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8684 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8685 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8686 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8687 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8688 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8689 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8690 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8691 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8692
8693 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8694 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8695 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8696 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8697 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8698 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8699 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8700 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8701 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8702 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8703 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8704 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8705 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8706 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8707 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8708 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8709 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8710 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8711 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8712 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8713 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8714 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8715};
7a387fff 8716static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8717{
923617a3 8718 const char *opn = "cp1 move";
72c3a3ee 8719 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8720
8721 switch (opc) {
8722 case OPC_MFC1:
b6d96bed 8723 {
a7812ae4 8724 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8725
7c979afd 8726 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8727 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8728 tcg_temp_free_i32(fp0);
6958549d 8729 }
6c5c1e20 8730 gen_store_gpr(t0, rt);
6ea83fed
FB
8731 opn = "mfc1";
8732 break;
8733 case OPC_MTC1:
6c5c1e20 8734 gen_load_gpr(t0, rt);
b6d96bed 8735 {
a7812ae4 8736 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8737
8738 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8739 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8740 tcg_temp_free_i32(fp0);
6958549d 8741 }
6ea83fed
FB
8742 opn = "mtc1";
8743 break;
8744 case OPC_CFC1:
895c2d04 8745 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8746 gen_store_gpr(t0, rt);
6ea83fed
FB
8747 opn = "cfc1";
8748 break;
8749 case OPC_CTC1:
6c5c1e20 8750 gen_load_gpr(t0, rt);
4cf8a45f 8751 save_cpu_state(ctx, 1);
736d120a
PJ
8752 {
8753 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8754
8755 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8756 tcg_temp_free_i32(fs_tmp);
8757 }
4cf8a45f
YK
8758 /* Stop translation as we may have changed hflags */
8759 ctx->bstate = BS_STOP;
6ea83fed
FB
8760 opn = "ctc1";
8761 break;
72c3a3ee 8762#if defined(TARGET_MIPS64)
9c2149c8 8763 case OPC_DMFC1:
72c3a3ee 8764 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8765 gen_store_gpr(t0, rt);
5a5012ec
TS
8766 opn = "dmfc1";
8767 break;
9c2149c8 8768 case OPC_DMTC1:
6c5c1e20 8769 gen_load_gpr(t0, rt);
72c3a3ee 8770 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8771 opn = "dmtc1";
8772 break;
72c3a3ee 8773#endif
5a5012ec 8774 case OPC_MFHC1:
b6d96bed 8775 {
a7812ae4 8776 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8777
7f6613ce 8778 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8779 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8780 tcg_temp_free_i32(fp0);
6958549d 8781 }
6c5c1e20 8782 gen_store_gpr(t0, rt);
5a5012ec
TS
8783 opn = "mfhc1";
8784 break;
8785 case OPC_MTHC1:
6c5c1e20 8786 gen_load_gpr(t0, rt);
b6d96bed 8787 {
a7812ae4 8788 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8789
8790 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8791 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8792 tcg_temp_free_i32(fp0);
6958549d 8793 }
5a5012ec
TS
8794 opn = "mthc1";
8795 break;
6ea83fed 8796 default:
923617a3 8797 MIPS_INVAL(opn);
e397ee33 8798 generate_exception (ctx, EXCP_RI);
6c5c1e20 8799 goto out;
6ea83fed 8800 }
2abf314d 8801 (void)opn; /* avoid a compiler warning */
6ea83fed 8802 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8803
8804 out:
8805 tcg_temp_free(t0);
6ea83fed
FB
8806}
8807
5a5012ec
TS
8808static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8809{
42a268c2 8810 TCGLabel *l1;
e214b9bb 8811 TCGCond cond;
af58f9ca
AJ
8812 TCGv_i32 t0;
8813
8814 if (rd == 0) {
8815 /* Treat as NOP. */
8816 return;
8817 }
6ea83fed 8818
e214b9bb 8819 if (tf)
e214b9bb 8820 cond = TCG_COND_EQ;
27848470
TS
8821 else
8822 cond = TCG_COND_NE;
8823
af58f9ca
AJ
8824 l1 = gen_new_label();
8825 t0 = tcg_temp_new_i32();
fa31af0e 8826 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8827 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8828 tcg_temp_free_i32(t0);
af58f9ca
AJ
8829 if (rs == 0) {
8830 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8831 } else {
8832 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8833 }
e214b9bb 8834 gen_set_label(l1);
5a5012ec
TS
8835}
8836
7c979afd
LA
8837static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8838 int tf)
a16336e4 8839{
a16336e4 8840 int cond;
cbc37b28 8841 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8842 TCGLabel *l1 = gen_new_label();
a16336e4 8843
a16336e4
TS
8844 if (tf)
8845 cond = TCG_COND_EQ;
8846 else
8847 cond = TCG_COND_NE;
8848
fa31af0e 8849 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8850 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8851 gen_load_fpr32(ctx, t0, fs);
8852 gen_store_fpr32(ctx, t0, fd);
a16336e4 8853 gen_set_label(l1);
cbc37b28 8854 tcg_temp_free_i32(t0);
5a5012ec 8855}
a16336e4 8856
b6d96bed 8857static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8858{
a16336e4 8859 int cond;
cbc37b28
AJ
8860 TCGv_i32 t0 = tcg_temp_new_i32();
8861 TCGv_i64 fp0;
42a268c2 8862 TCGLabel *l1 = gen_new_label();
a16336e4 8863
a16336e4
TS
8864 if (tf)
8865 cond = TCG_COND_EQ;
8866 else
8867 cond = TCG_COND_NE;
8868
fa31af0e 8869 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8870 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8871 tcg_temp_free_i32(t0);
11f94258 8872 fp0 = tcg_temp_new_i64();
9bf3eb2c 8873 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8874 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8875 tcg_temp_free_i64(fp0);
cbc37b28 8876 gen_set_label(l1);
a16336e4
TS
8877}
8878
7f6613ce
PJ
8879static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8880 int cc, int tf)
a16336e4
TS
8881{
8882 int cond;
cbc37b28 8883 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8884 TCGLabel *l1 = gen_new_label();
8885 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8886
8887 if (tf)
8888 cond = TCG_COND_EQ;
8889 else
8890 cond = TCG_COND_NE;
8891
fa31af0e 8892 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8893 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8894 gen_load_fpr32(ctx, t0, fs);
8895 gen_store_fpr32(ctx, t0, fd);
a16336e4 8896 gen_set_label(l1);
9bf3eb2c 8897
fa31af0e 8898 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8899 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8900 gen_load_fpr32h(ctx, t0, fs);
8901 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8902 tcg_temp_free_i32(t0);
a16336e4 8903 gen_set_label(l2);
a16336e4
TS
8904}
8905
e7f16abb
LA
8906static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8907 int fs)
8908{
8909 TCGv_i32 t1 = tcg_const_i32(0);
8910 TCGv_i32 fp0 = tcg_temp_new_i32();
8911 TCGv_i32 fp1 = tcg_temp_new_i32();
8912 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8913 gen_load_fpr32(ctx, fp0, fd);
8914 gen_load_fpr32(ctx, fp1, ft);
8915 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8916
8917 switch (op1) {
8918 case OPC_SEL_S:
8919 tcg_gen_andi_i32(fp0, fp0, 1);
8920 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8921 break;
8922 case OPC_SELEQZ_S:
8923 tcg_gen_andi_i32(fp1, fp1, 1);
8924 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8925 break;
8926 case OPC_SELNEZ_S:
8927 tcg_gen_andi_i32(fp1, fp1, 1);
8928 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8929 break;
8930 default:
8931 MIPS_INVAL("gen_sel_s");
8932 generate_exception (ctx, EXCP_RI);
8933 break;
8934 }
8935
7c979afd 8936 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8937 tcg_temp_free_i32(fp2);
8938 tcg_temp_free_i32(fp1);
8939 tcg_temp_free_i32(fp0);
8940 tcg_temp_free_i32(t1);
8941}
8942
8943static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8944 int fs)
8945{
8946 TCGv_i64 t1 = tcg_const_i64(0);
8947 TCGv_i64 fp0 = tcg_temp_new_i64();
8948 TCGv_i64 fp1 = tcg_temp_new_i64();
8949 TCGv_i64 fp2 = tcg_temp_new_i64();
8950 gen_load_fpr64(ctx, fp0, fd);
8951 gen_load_fpr64(ctx, fp1, ft);
8952 gen_load_fpr64(ctx, fp2, fs);
8953
8954 switch (op1) {
8955 case OPC_SEL_D:
8956 tcg_gen_andi_i64(fp0, fp0, 1);
8957 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8958 break;
8959 case OPC_SELEQZ_D:
8960 tcg_gen_andi_i64(fp1, fp1, 1);
8961 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8962 break;
8963 case OPC_SELNEZ_D:
8964 tcg_gen_andi_i64(fp1, fp1, 1);
8965 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8966 break;
8967 default:
8968 MIPS_INVAL("gen_sel_d");
8969 generate_exception (ctx, EXCP_RI);
8970 break;
8971 }
8972
8973 gen_store_fpr64(ctx, fp0, fd);
8974 tcg_temp_free_i64(fp2);
8975 tcg_temp_free_i64(fp1);
8976 tcg_temp_free_i64(fp0);
8977 tcg_temp_free_i64(t1);
8978}
6ea83fed 8979
bf4120ad 8980static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8981 int ft, int fs, int fd, int cc)
6ea83fed 8982{
923617a3 8983 const char *opn = "farith";
6ea83fed
FB
8984 const char *condnames[] = {
8985 "c.f",
8986 "c.un",
8987 "c.eq",
8988 "c.ueq",
8989 "c.olt",
8990 "c.ult",
8991 "c.ole",
8992 "c.ule",
8993 "c.sf",
8994 "c.ngle",
8995 "c.seq",
8996 "c.ngl",
8997 "c.lt",
8998 "c.nge",
8999 "c.le",
9000 "c.ngt",
9001 };
5a1e8ffb
TS
9002 const char *condnames_abs[] = {
9003 "cabs.f",
9004 "cabs.un",
9005 "cabs.eq",
9006 "cabs.ueq",
9007 "cabs.olt",
9008 "cabs.ult",
9009 "cabs.ole",
9010 "cabs.ule",
9011 "cabs.sf",
9012 "cabs.ngle",
9013 "cabs.seq",
9014 "cabs.ngl",
9015 "cabs.lt",
9016 "cabs.nge",
9017 "cabs.le",
9018 "cabs.ngt",
9019 };
9020 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff 9021 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9022 switch (op1) {
9023 case OPC_ADD_S:
b6d96bed 9024 {
a7812ae4
PB
9025 TCGv_i32 fp0 = tcg_temp_new_i32();
9026 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9027
7c979afd
LA
9028 gen_load_fpr32(ctx, fp0, fs);
9029 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9030 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9031 tcg_temp_free_i32(fp1);
7c979afd 9032 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9033 tcg_temp_free_i32(fp0);
b6d96bed 9034 }
5a5012ec 9035 opn = "add.s";
5a1e8ffb 9036 optype = BINOP;
5a5012ec 9037 break;
bf4120ad 9038 case OPC_SUB_S:
b6d96bed 9039 {
a7812ae4
PB
9040 TCGv_i32 fp0 = tcg_temp_new_i32();
9041 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9042
7c979afd
LA
9043 gen_load_fpr32(ctx, fp0, fs);
9044 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9045 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9046 tcg_temp_free_i32(fp1);
7c979afd 9047 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9048 tcg_temp_free_i32(fp0);
b6d96bed 9049 }
5a5012ec 9050 opn = "sub.s";
5a1e8ffb 9051 optype = BINOP;
5a5012ec 9052 break;
bf4120ad 9053 case OPC_MUL_S:
b6d96bed 9054 {
a7812ae4
PB
9055 TCGv_i32 fp0 = tcg_temp_new_i32();
9056 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9057
7c979afd
LA
9058 gen_load_fpr32(ctx, fp0, fs);
9059 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9060 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9061 tcg_temp_free_i32(fp1);
7c979afd 9062 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9063 tcg_temp_free_i32(fp0);
b6d96bed 9064 }
5a5012ec 9065 opn = "mul.s";
5a1e8ffb 9066 optype = BINOP;
5a5012ec 9067 break;
bf4120ad 9068 case OPC_DIV_S:
b6d96bed 9069 {
a7812ae4
PB
9070 TCGv_i32 fp0 = tcg_temp_new_i32();
9071 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9072
7c979afd
LA
9073 gen_load_fpr32(ctx, fp0, fs);
9074 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9075 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9076 tcg_temp_free_i32(fp1);
7c979afd 9077 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9078 tcg_temp_free_i32(fp0);
b6d96bed 9079 }
5a5012ec 9080 opn = "div.s";
5a1e8ffb 9081 optype = BINOP;
5a5012ec 9082 break;
bf4120ad 9083 case OPC_SQRT_S:
b6d96bed 9084 {
a7812ae4 9085 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9086
7c979afd 9087 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9088 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9089 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9090 tcg_temp_free_i32(fp0);
b6d96bed 9091 }
5a5012ec
TS
9092 opn = "sqrt.s";
9093 break;
bf4120ad 9094 case OPC_ABS_S:
b6d96bed 9095 {
a7812ae4 9096 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9097
7c979afd 9098 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 9099 gen_helper_float_abs_s(fp0, fp0);
7c979afd 9100 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9101 tcg_temp_free_i32(fp0);
b6d96bed 9102 }
5a5012ec
TS
9103 opn = "abs.s";
9104 break;
bf4120ad 9105 case OPC_MOV_S:
b6d96bed 9106 {
a7812ae4 9107 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9108
7c979afd
LA
9109 gen_load_fpr32(ctx, fp0, fs);
9110 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9111 tcg_temp_free_i32(fp0);
b6d96bed 9112 }
5a5012ec
TS
9113 opn = "mov.s";
9114 break;
bf4120ad 9115 case OPC_NEG_S:
b6d96bed 9116 {
a7812ae4 9117 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9118
7c979afd 9119 gen_load_fpr32(ctx, fp0, fs);
a7812ae4 9120 gen_helper_float_chs_s(fp0, fp0);
7c979afd 9121 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9122 tcg_temp_free_i32(fp0);
b6d96bed 9123 }
5a5012ec
TS
9124 opn = "neg.s";
9125 break;
bf4120ad 9126 case OPC_ROUND_L_S:
5e755519 9127 check_cp1_64bitmode(ctx);
b6d96bed 9128 {
a7812ae4
PB
9129 TCGv_i32 fp32 = tcg_temp_new_i32();
9130 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9131
7c979afd 9132 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9133 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 9134 tcg_temp_free_i32(fp32);
b6d96bed 9135 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9136 tcg_temp_free_i64(fp64);
b6d96bed 9137 }
5a5012ec
TS
9138 opn = "round.l.s";
9139 break;
bf4120ad 9140 case OPC_TRUNC_L_S:
5e755519 9141 check_cp1_64bitmode(ctx);
b6d96bed 9142 {
a7812ae4
PB
9143 TCGv_i32 fp32 = tcg_temp_new_i32();
9144 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9145
7c979afd 9146 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9147 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 9148 tcg_temp_free_i32(fp32);
b6d96bed 9149 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9150 tcg_temp_free_i64(fp64);
b6d96bed 9151 }
5a5012ec
TS
9152 opn = "trunc.l.s";
9153 break;
bf4120ad 9154 case OPC_CEIL_L_S:
5e755519 9155 check_cp1_64bitmode(ctx);
b6d96bed 9156 {
a7812ae4
PB
9157 TCGv_i32 fp32 = tcg_temp_new_i32();
9158 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9159
7c979afd 9160 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9161 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 9162 tcg_temp_free_i32(fp32);
b6d96bed 9163 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9164 tcg_temp_free_i64(fp64);
b6d96bed 9165 }
5a5012ec
TS
9166 opn = "ceil.l.s";
9167 break;
bf4120ad 9168 case OPC_FLOOR_L_S:
5e755519 9169 check_cp1_64bitmode(ctx);
b6d96bed 9170 {
a7812ae4
PB
9171 TCGv_i32 fp32 = tcg_temp_new_i32();
9172 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9173
7c979afd 9174 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9175 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 9176 tcg_temp_free_i32(fp32);
b6d96bed 9177 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9178 tcg_temp_free_i64(fp64);
b6d96bed 9179 }
5a5012ec
TS
9180 opn = "floor.l.s";
9181 break;
bf4120ad 9182 case OPC_ROUND_W_S:
b6d96bed 9183 {
a7812ae4 9184 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9185
7c979afd 9186 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9187 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7c979afd 9188 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9189 tcg_temp_free_i32(fp0);
b6d96bed 9190 }
5a5012ec
TS
9191 opn = "round.w.s";
9192 break;
bf4120ad 9193 case OPC_TRUNC_W_S:
b6d96bed 9194 {
a7812ae4 9195 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9196
7c979afd 9197 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9198 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7c979afd 9199 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9200 tcg_temp_free_i32(fp0);
b6d96bed 9201 }
5a5012ec
TS
9202 opn = "trunc.w.s";
9203 break;
bf4120ad 9204 case OPC_CEIL_W_S:
b6d96bed 9205 {
a7812ae4 9206 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9207
7c979afd 9208 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9209 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7c979afd 9210 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9211 tcg_temp_free_i32(fp0);
b6d96bed 9212 }
5a5012ec
TS
9213 opn = "ceil.w.s";
9214 break;
bf4120ad 9215 case OPC_FLOOR_W_S:
b6d96bed 9216 {
a7812ae4 9217 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9218
7c979afd 9219 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9220 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7c979afd 9221 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9222 tcg_temp_free_i32(fp0);
b6d96bed 9223 }
5a5012ec
TS
9224 opn = "floor.w.s";
9225 break;
e7f16abb
LA
9226 case OPC_SEL_S:
9227 check_insn(ctx, ISA_MIPS32R6);
9228 gen_sel_s(ctx, op1, fd, ft, fs);
9229 opn = "sel.s";
9230 break;
9231 case OPC_SELEQZ_S:
9232 check_insn(ctx, ISA_MIPS32R6);
9233 gen_sel_s(ctx, op1, fd, ft, fs);
9234 opn = "seleqz.s";
9235 break;
9236 case OPC_SELNEZ_S:
9237 check_insn(ctx, ISA_MIPS32R6);
9238 gen_sel_s(ctx, op1, fd, ft, fs);
9239 opn = "selnez.s";
9240 break;
bf4120ad 9241 case OPC_MOVCF_S:
fecd2646 9242 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9243 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
9244 opn = "movcf.s";
9245 break;
bf4120ad 9246 case OPC_MOVZ_S:
fecd2646 9247 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9248 {
42a268c2 9249 TCGLabel *l1 = gen_new_label();
c9297f4d 9250 TCGv_i32 fp0;
a16336e4 9251
c9297f4d
AJ
9252 if (ft != 0) {
9253 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9254 }
9255 fp0 = tcg_temp_new_i32();
7c979afd
LA
9256 gen_load_fpr32(ctx, fp0, fs);
9257 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9258 tcg_temp_free_i32(fp0);
a16336e4
TS
9259 gen_set_label(l1);
9260 }
5a5012ec
TS
9261 opn = "movz.s";
9262 break;
bf4120ad 9263 case OPC_MOVN_S:
fecd2646 9264 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9265 {
42a268c2 9266 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9267 TCGv_i32 fp0;
9268
9269 if (ft != 0) {
9270 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9271 fp0 = tcg_temp_new_i32();
7c979afd
LA
9272 gen_load_fpr32(ctx, fp0, fs);
9273 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9274 tcg_temp_free_i32(fp0);
9275 gen_set_label(l1);
9276 }
a16336e4 9277 }
5a5012ec
TS
9278 opn = "movn.s";
9279 break;
bf4120ad 9280 case OPC_RECIP_S:
b8aa4598 9281 check_cop1x(ctx);
b6d96bed 9282 {
a7812ae4 9283 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9284
7c979afd 9285 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9286 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9287 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9288 tcg_temp_free_i32(fp0);
b6d96bed 9289 }
57fa1fb3
TS
9290 opn = "recip.s";
9291 break;
bf4120ad 9292 case OPC_RSQRT_S:
b8aa4598 9293 check_cop1x(ctx);
b6d96bed 9294 {
a7812ae4 9295 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9296
7c979afd 9297 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9298 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9299 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9300 tcg_temp_free_i32(fp0);
b6d96bed 9301 }
57fa1fb3
TS
9302 opn = "rsqrt.s";
9303 break;
e7f16abb
LA
9304 case OPC_MADDF_S:
9305 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9306 {
a7812ae4
PB
9307 TCGv_i32 fp0 = tcg_temp_new_i32();
9308 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9309 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9310 gen_load_fpr32(ctx, fp0, fs);
9311 gen_load_fpr32(ctx, fp1, ft);
9312 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9313 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9314 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9315 tcg_temp_free_i32(fp2);
a7812ae4 9316 tcg_temp_free_i32(fp1);
a7812ae4 9317 tcg_temp_free_i32(fp0);
e7f16abb 9318 opn = "maddf.s";
b6d96bed 9319 }
57fa1fb3 9320 break;
e7f16abb
LA
9321 case OPC_MSUBF_S:
9322 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9323 {
a7812ae4 9324 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9325 TCGv_i32 fp1 = tcg_temp_new_i32();
9326 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9327 gen_load_fpr32(ctx, fp0, fs);
9328 gen_load_fpr32(ctx, fp1, ft);
9329 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9330 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9331 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9332 tcg_temp_free_i32(fp2);
9333 tcg_temp_free_i32(fp1);
a7812ae4 9334 tcg_temp_free_i32(fp0);
e7f16abb 9335 opn = "msubf.s";
b6d96bed 9336 }
57fa1fb3 9337 break;
e7f16abb
LA
9338 case OPC_RINT_S:
9339 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9340 {
a7812ae4 9341 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9342 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9343 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9344 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9345 tcg_temp_free_i32(fp0);
e7f16abb 9346 opn = "rint.s";
b6d96bed 9347 }
57fa1fb3 9348 break;
e7f16abb
LA
9349 case OPC_CLASS_S:
9350 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9351 {
e7f16abb 9352 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9353 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9354 gen_helper_float_class_s(fp0, fp0);
7c979afd 9355 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9356 tcg_temp_free_i32(fp0);
9357 opn = "class.s";
9358 }
9359 break;
9360 case OPC_MIN_S: /* OPC_RECIP2_S */
9361 if (ctx->insn_flags & ISA_MIPS32R6) {
9362 /* OPC_MIN_S */
a7812ae4
PB
9363 TCGv_i32 fp0 = tcg_temp_new_i32();
9364 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9365 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9366 gen_load_fpr32(ctx, fp0, fs);
9367 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9368 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9369 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9370 tcg_temp_free_i32(fp2);
9371 tcg_temp_free_i32(fp1);
9372 tcg_temp_free_i32(fp0);
9373 opn = "min.s";
9374 } else {
9375 /* OPC_RECIP2_S */
9376 check_cp1_64bitmode(ctx);
9377 {
9378 TCGv_i32 fp0 = tcg_temp_new_i32();
9379 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9380
7c979afd
LA
9381 gen_load_fpr32(ctx, fp0, fs);
9382 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9383 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9384 tcg_temp_free_i32(fp1);
7c979afd 9385 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9386 tcg_temp_free_i32(fp0);
9387 }
9388 opn = "recip2.s";
9389 }
9390 break;
9391 case OPC_MINA_S: /* OPC_RECIP1_S */
9392 if (ctx->insn_flags & ISA_MIPS32R6) {
9393 /* OPC_MINA_S */
9394 TCGv_i32 fp0 = tcg_temp_new_i32();
9395 TCGv_i32 fp1 = tcg_temp_new_i32();
9396 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9397 gen_load_fpr32(ctx, fp0, fs);
9398 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9399 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9400 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9401 tcg_temp_free_i32(fp2);
9402 tcg_temp_free_i32(fp1);
9403 tcg_temp_free_i32(fp0);
9404 opn = "mina.s";
9405 } else {
9406 /* OPC_RECIP1_S */
9407 check_cp1_64bitmode(ctx);
9408 {
9409 TCGv_i32 fp0 = tcg_temp_new_i32();
9410
7c979afd 9411 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9412 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9413 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9414 tcg_temp_free_i32(fp0);
9415 }
9416 opn = "recip1.s";
9417 }
9418 break;
9419 case OPC_MAX_S: /* OPC_RSQRT1_S */
9420 if (ctx->insn_flags & ISA_MIPS32R6) {
9421 /* OPC_MAX_S */
9422 TCGv_i32 fp0 = tcg_temp_new_i32();
9423 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9424 gen_load_fpr32(ctx, fp0, fs);
9425 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9426 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9427 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9428 tcg_temp_free_i32(fp1);
9429 tcg_temp_free_i32(fp0);
9430 opn = "max.s";
9431 } else {
9432 /* OPC_RSQRT1_S */
9433 check_cp1_64bitmode(ctx);
9434 {
9435 TCGv_i32 fp0 = tcg_temp_new_i32();
9436
7c979afd 9437 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9438 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9439 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9440 tcg_temp_free_i32(fp0);
9441 }
9442 opn = "rsqrt1.s";
9443 }
9444 break;
9445 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9446 if (ctx->insn_flags & ISA_MIPS32R6) {
9447 /* OPC_MAXA_S */
9448 TCGv_i32 fp0 = tcg_temp_new_i32();
9449 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9450 gen_load_fpr32(ctx, fp0, fs);
9451 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9452 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9453 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9454 tcg_temp_free_i32(fp1);
a7812ae4 9455 tcg_temp_free_i32(fp0);
e7f16abb
LA
9456 opn = "maxa.s";
9457 } else {
9458 /* OPC_RSQRT2_S */
9459 check_cp1_64bitmode(ctx);
9460 {
9461 TCGv_i32 fp0 = tcg_temp_new_i32();
9462 TCGv_i32 fp1 = tcg_temp_new_i32();
9463
7c979afd
LA
9464 gen_load_fpr32(ctx, fp0, fs);
9465 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9466 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9467 tcg_temp_free_i32(fp1);
7c979afd 9468 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9469 tcg_temp_free_i32(fp0);
9470 }
9471 opn = "rsqrt2.s";
b6d96bed 9472 }
57fa1fb3 9473 break;
bf4120ad 9474 case OPC_CVT_D_S:
5e755519 9475 check_cp1_registers(ctx, fd);
b6d96bed 9476 {
a7812ae4
PB
9477 TCGv_i32 fp32 = tcg_temp_new_i32();
9478 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9479
7c979afd 9480 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9481 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9482 tcg_temp_free_i32(fp32);
b6d96bed 9483 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9484 tcg_temp_free_i64(fp64);
b6d96bed 9485 }
5a5012ec
TS
9486 opn = "cvt.d.s";
9487 break;
bf4120ad 9488 case OPC_CVT_W_S:
b6d96bed 9489 {
a7812ae4 9490 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9491
7c979afd 9492 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9493 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7c979afd 9494 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9495 tcg_temp_free_i32(fp0);
b6d96bed 9496 }
5a5012ec
TS
9497 opn = "cvt.w.s";
9498 break;
bf4120ad 9499 case OPC_CVT_L_S:
5e755519 9500 check_cp1_64bitmode(ctx);
b6d96bed 9501 {
a7812ae4
PB
9502 TCGv_i32 fp32 = tcg_temp_new_i32();
9503 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9504
7c979afd 9505 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9506 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9507 tcg_temp_free_i32(fp32);
b6d96bed 9508 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9509 tcg_temp_free_i64(fp64);
b6d96bed 9510 }
5a5012ec
TS
9511 opn = "cvt.l.s";
9512 break;
bf4120ad 9513 case OPC_CVT_PS_S:
e29c9628 9514 check_ps(ctx);
b6d96bed 9515 {
a7812ae4
PB
9516 TCGv_i64 fp64 = tcg_temp_new_i64();
9517 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9518 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9519
7c979afd
LA
9520 gen_load_fpr32(ctx, fp32_0, fs);
9521 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9522 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9523 tcg_temp_free_i32(fp32_1);
9524 tcg_temp_free_i32(fp32_0);
36aa55dc 9525 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9526 tcg_temp_free_i64(fp64);
b6d96bed 9527 }
5a5012ec
TS
9528 opn = "cvt.ps.s";
9529 break;
bf4120ad
NF
9530 case OPC_CMP_F_S:
9531 case OPC_CMP_UN_S:
9532 case OPC_CMP_EQ_S:
9533 case OPC_CMP_UEQ_S:
9534 case OPC_CMP_OLT_S:
9535 case OPC_CMP_ULT_S:
9536 case OPC_CMP_OLE_S:
9537 case OPC_CMP_ULE_S:
9538 case OPC_CMP_SF_S:
9539 case OPC_CMP_NGLE_S:
9540 case OPC_CMP_SEQ_S:
9541 case OPC_CMP_NGL_S:
9542 case OPC_CMP_LT_S:
9543 case OPC_CMP_NGE_S:
9544 case OPC_CMP_LE_S:
9545 case OPC_CMP_NGT_S:
fecd2646 9546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9547 if (ctx->opcode & (1 << 6)) {
9548 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9549 opn = condnames_abs[func-48];
9550 } else {
9551 gen_cmp_s(ctx, func-48, ft, fs, cc);
9552 opn = condnames[func-48];
5a1e8ffb 9553 }
5a5012ec 9554 break;
bf4120ad 9555 case OPC_ADD_D:
5e755519 9556 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9557 {
a7812ae4
PB
9558 TCGv_i64 fp0 = tcg_temp_new_i64();
9559 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9560
9561 gen_load_fpr64(ctx, fp0, fs);
9562 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9563 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9564 tcg_temp_free_i64(fp1);
b6d96bed 9565 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9566 tcg_temp_free_i64(fp0);
b6d96bed 9567 }
6ea83fed 9568 opn = "add.d";
5a1e8ffb 9569 optype = BINOP;
6ea83fed 9570 break;
bf4120ad 9571 case OPC_SUB_D:
5e755519 9572 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9573 {
a7812ae4
PB
9574 TCGv_i64 fp0 = tcg_temp_new_i64();
9575 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9576
9577 gen_load_fpr64(ctx, fp0, fs);
9578 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9579 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9580 tcg_temp_free_i64(fp1);
b6d96bed 9581 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9582 tcg_temp_free_i64(fp0);
b6d96bed 9583 }
6ea83fed 9584 opn = "sub.d";
5a1e8ffb 9585 optype = BINOP;
6ea83fed 9586 break;
bf4120ad 9587 case OPC_MUL_D:
5e755519 9588 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9589 {
a7812ae4
PB
9590 TCGv_i64 fp0 = tcg_temp_new_i64();
9591 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9592
9593 gen_load_fpr64(ctx, fp0, fs);
9594 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9595 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9596 tcg_temp_free_i64(fp1);
b6d96bed 9597 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9598 tcg_temp_free_i64(fp0);
b6d96bed 9599 }
6ea83fed 9600 opn = "mul.d";
5a1e8ffb 9601 optype = BINOP;
6ea83fed 9602 break;
bf4120ad 9603 case OPC_DIV_D:
5e755519 9604 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9605 {
a7812ae4
PB
9606 TCGv_i64 fp0 = tcg_temp_new_i64();
9607 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9608
9609 gen_load_fpr64(ctx, fp0, fs);
9610 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9611 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9612 tcg_temp_free_i64(fp1);
b6d96bed 9613 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9614 tcg_temp_free_i64(fp0);
b6d96bed 9615 }
6ea83fed 9616 opn = "div.d";
5a1e8ffb 9617 optype = BINOP;
6ea83fed 9618 break;
bf4120ad 9619 case OPC_SQRT_D:
5e755519 9620 check_cp1_registers(ctx, fs | fd);
b6d96bed 9621 {
a7812ae4 9622 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9623
9624 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9625 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9626 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9627 tcg_temp_free_i64(fp0);
b6d96bed 9628 }
6ea83fed
FB
9629 opn = "sqrt.d";
9630 break;
bf4120ad 9631 case OPC_ABS_D:
5e755519 9632 check_cp1_registers(ctx, fs | fd);
b6d96bed 9633 {
a7812ae4 9634 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9635
9636 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9637 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9638 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9639 tcg_temp_free_i64(fp0);
b6d96bed 9640 }
6ea83fed
FB
9641 opn = "abs.d";
9642 break;
bf4120ad 9643 case OPC_MOV_D:
5e755519 9644 check_cp1_registers(ctx, fs | fd);
b6d96bed 9645 {
a7812ae4 9646 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9647
9648 gen_load_fpr64(ctx, fp0, fs);
9649 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9650 tcg_temp_free_i64(fp0);
b6d96bed 9651 }
6ea83fed
FB
9652 opn = "mov.d";
9653 break;
bf4120ad 9654 case OPC_NEG_D:
5e755519 9655 check_cp1_registers(ctx, fs | fd);
b6d96bed 9656 {
a7812ae4 9657 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9658
9659 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9660 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9661 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9662 tcg_temp_free_i64(fp0);
b6d96bed 9663 }
6ea83fed
FB
9664 opn = "neg.d";
9665 break;
bf4120ad 9666 case OPC_ROUND_L_D:
5e755519 9667 check_cp1_64bitmode(ctx);
b6d96bed 9668 {
a7812ae4 9669 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9670
9671 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9672 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9673 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9674 tcg_temp_free_i64(fp0);
b6d96bed 9675 }
5a5012ec
TS
9676 opn = "round.l.d";
9677 break;
bf4120ad 9678 case OPC_TRUNC_L_D:
5e755519 9679 check_cp1_64bitmode(ctx);
b6d96bed 9680 {
a7812ae4 9681 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9682
9683 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9684 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9685 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9686 tcg_temp_free_i64(fp0);
b6d96bed 9687 }
5a5012ec
TS
9688 opn = "trunc.l.d";
9689 break;
bf4120ad 9690 case OPC_CEIL_L_D:
5e755519 9691 check_cp1_64bitmode(ctx);
b6d96bed 9692 {
a7812ae4 9693 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9694
9695 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9696 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9697 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9698 tcg_temp_free_i64(fp0);
b6d96bed 9699 }
5a5012ec
TS
9700 opn = "ceil.l.d";
9701 break;
bf4120ad 9702 case OPC_FLOOR_L_D:
5e755519 9703 check_cp1_64bitmode(ctx);
b6d96bed 9704 {
a7812ae4 9705 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9706
9707 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9708 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9709 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9710 tcg_temp_free_i64(fp0);
b6d96bed 9711 }
5a5012ec
TS
9712 opn = "floor.l.d";
9713 break;
bf4120ad 9714 case OPC_ROUND_W_D:
5e755519 9715 check_cp1_registers(ctx, fs);
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_roundw_d(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 }
6ea83fed
FB
9726 opn = "round.w.d";
9727 break;
bf4120ad 9728 case OPC_TRUNC_W_D:
5e755519 9729 check_cp1_registers(ctx, fs);
b6d96bed 9730 {
a7812ae4
PB
9731 TCGv_i32 fp32 = tcg_temp_new_i32();
9732 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9733
9734 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9735 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9736 tcg_temp_free_i64(fp64);
7c979afd 9737 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9738 tcg_temp_free_i32(fp32);
b6d96bed 9739 }
6ea83fed
FB
9740 opn = "trunc.w.d";
9741 break;
bf4120ad 9742 case OPC_CEIL_W_D:
5e755519 9743 check_cp1_registers(ctx, fs);
b6d96bed 9744 {
a7812ae4
PB
9745 TCGv_i32 fp32 = tcg_temp_new_i32();
9746 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9747
9748 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9749 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9750 tcg_temp_free_i64(fp64);
7c979afd 9751 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9752 tcg_temp_free_i32(fp32);
b6d96bed 9753 }
6ea83fed
FB
9754 opn = "ceil.w.d";
9755 break;
bf4120ad 9756 case OPC_FLOOR_W_D:
5e755519 9757 check_cp1_registers(ctx, fs);
b6d96bed 9758 {
a7812ae4
PB
9759 TCGv_i32 fp32 = tcg_temp_new_i32();
9760 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9761
9762 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9763 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9764 tcg_temp_free_i64(fp64);
7c979afd 9765 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9766 tcg_temp_free_i32(fp32);
b6d96bed 9767 }
7a387fff 9768 opn = "floor.w.d";
6ea83fed 9769 break;
e7f16abb
LA
9770 case OPC_SEL_D:
9771 check_insn(ctx, ISA_MIPS32R6);
9772 gen_sel_d(ctx, op1, fd, ft, fs);
9773 opn = "sel.d";
9774 break;
9775 case OPC_SELEQZ_D:
9776 check_insn(ctx, ISA_MIPS32R6);
9777 gen_sel_d(ctx, op1, fd, ft, fs);
9778 opn = "seleqz.d";
9779 break;
9780 case OPC_SELNEZ_D:
9781 check_insn(ctx, ISA_MIPS32R6);
9782 gen_sel_d(ctx, op1, fd, ft, fs);
9783 opn = "selnez.d";
9784 break;
bf4120ad 9785 case OPC_MOVCF_D:
fecd2646 9786 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9787 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9788 opn = "movcf.d";
dd016883 9789 break;
bf4120ad 9790 case OPC_MOVZ_D:
fecd2646 9791 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9792 {
42a268c2 9793 TCGLabel *l1 = gen_new_label();
c9297f4d 9794 TCGv_i64 fp0;
a16336e4 9795
c9297f4d
AJ
9796 if (ft != 0) {
9797 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9798 }
9799 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9800 gen_load_fpr64(ctx, fp0, fs);
9801 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9802 tcg_temp_free_i64(fp0);
a16336e4
TS
9803 gen_set_label(l1);
9804 }
5a5012ec
TS
9805 opn = "movz.d";
9806 break;
bf4120ad 9807 case OPC_MOVN_D:
fecd2646 9808 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9809 {
42a268c2 9810 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9811 TCGv_i64 fp0;
9812
9813 if (ft != 0) {
9814 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9815 fp0 = tcg_temp_new_i64();
9816 gen_load_fpr64(ctx, fp0, fs);
9817 gen_store_fpr64(ctx, fp0, fd);
9818 tcg_temp_free_i64(fp0);
9819 gen_set_label(l1);
9820 }
a16336e4 9821 }
5a5012ec 9822 opn = "movn.d";
6ea83fed 9823 break;
bf4120ad 9824 case OPC_RECIP_D:
b8aa4598 9825 check_cp1_64bitmode(ctx);
b6d96bed 9826 {
a7812ae4 9827 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9828
9829 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9830 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9831 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9832 tcg_temp_free_i64(fp0);
b6d96bed 9833 }
57fa1fb3
TS
9834 opn = "recip.d";
9835 break;
bf4120ad 9836 case OPC_RSQRT_D:
b8aa4598 9837 check_cp1_64bitmode(ctx);
b6d96bed 9838 {
a7812ae4 9839 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9840
9841 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9842 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9843 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9844 tcg_temp_free_i64(fp0);
b6d96bed 9845 }
57fa1fb3
TS
9846 opn = "rsqrt.d";
9847 break;
e7f16abb
LA
9848 case OPC_MADDF_D:
9849 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9850 {
a7812ae4
PB
9851 TCGv_i64 fp0 = tcg_temp_new_i64();
9852 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9853 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9854 gen_load_fpr64(ctx, fp0, fs);
9855 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9856 gen_load_fpr64(ctx, fp2, fd);
9857 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9858 gen_store_fpr64(ctx, fp2, fd);
9859 tcg_temp_free_i64(fp2);
a7812ae4 9860 tcg_temp_free_i64(fp1);
a7812ae4 9861 tcg_temp_free_i64(fp0);
e7f16abb 9862 opn = "maddf.d";
b6d96bed 9863 }
57fa1fb3 9864 break;
e7f16abb
LA
9865 case OPC_MSUBF_D:
9866 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9867 {
a7812ae4 9868 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9869 TCGv_i64 fp1 = tcg_temp_new_i64();
9870 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9871 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9872 gen_load_fpr64(ctx, fp1, ft);
9873 gen_load_fpr64(ctx, fp2, fd);
9874 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9875 gen_store_fpr64(ctx, fp2, fd);
9876 tcg_temp_free_i64(fp2);
9877 tcg_temp_free_i64(fp1);
a7812ae4 9878 tcg_temp_free_i64(fp0);
e7f16abb 9879 opn = "msubf.d";
b6d96bed 9880 }
57fa1fb3 9881 break;
e7f16abb
LA
9882 case OPC_RINT_D:
9883 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9884 {
a7812ae4 9885 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9886 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9887 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9888 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9889 tcg_temp_free_i64(fp0);
e7f16abb 9890 opn = "rint.d";
b6d96bed 9891 }
57fa1fb3 9892 break;
e7f16abb
LA
9893 case OPC_CLASS_D:
9894 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9895 {
e7f16abb
LA
9896 TCGv_i64 fp0 = tcg_temp_new_i64();
9897 gen_load_fpr64(ctx, fp0, fs);
9898 gen_helper_float_class_d(fp0, fp0);
9899 gen_store_fpr64(ctx, fp0, fd);
9900 tcg_temp_free_i64(fp0);
9901 opn = "class.d";
9902 }
9903 break;
9904 case OPC_MIN_D: /* OPC_RECIP2_D */
9905 if (ctx->insn_flags & ISA_MIPS32R6) {
9906 /* OPC_MIN_D */
a7812ae4
PB
9907 TCGv_i64 fp0 = tcg_temp_new_i64();
9908 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9909 gen_load_fpr64(ctx, fp0, fs);
9910 gen_load_fpr64(ctx, fp1, ft);
9911 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9912 gen_store_fpr64(ctx, fp1, fd);
9913 tcg_temp_free_i64(fp1);
9914 tcg_temp_free_i64(fp0);
9915 opn = "min.d";
9916 } else {
9917 /* OPC_RECIP2_D */
9918 check_cp1_64bitmode(ctx);
9919 {
9920 TCGv_i64 fp0 = tcg_temp_new_i64();
9921 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9922
e7f16abb
LA
9923 gen_load_fpr64(ctx, fp0, fs);
9924 gen_load_fpr64(ctx, fp1, ft);
9925 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9926 tcg_temp_free_i64(fp1);
9927 gen_store_fpr64(ctx, fp0, fd);
9928 tcg_temp_free_i64(fp0);
9929 }
9930 opn = "recip2.d";
9931 }
9932 break;
9933 case OPC_MINA_D: /* OPC_RECIP1_D */
9934 if (ctx->insn_flags & ISA_MIPS32R6) {
9935 /* OPC_MINA_D */
9936 TCGv_i64 fp0 = tcg_temp_new_i64();
9937 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9938 gen_load_fpr64(ctx, fp0, fs);
9939 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9940 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9941 gen_store_fpr64(ctx, fp1, fd);
9942 tcg_temp_free_i64(fp1);
9943 tcg_temp_free_i64(fp0);
9944 opn = "mina.d";
9945 } else {
9946 /* OPC_RECIP1_D */
9947 check_cp1_64bitmode(ctx);
9948 {
9949 TCGv_i64 fp0 = tcg_temp_new_i64();
9950
9951 gen_load_fpr64(ctx, fp0, fs);
9952 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9953 gen_store_fpr64(ctx, fp0, fd);
9954 tcg_temp_free_i64(fp0);
9955 }
9956 opn = "recip1.d";
9957 }
9958 break;
9959 case OPC_MAX_D: /* OPC_RSQRT1_D */
9960 if (ctx->insn_flags & ISA_MIPS32R6) {
9961 /* OPC_MAX_D */
9962 TCGv_i64 fp0 = tcg_temp_new_i64();
9963 TCGv_i64 fp1 = tcg_temp_new_i64();
9964 gen_load_fpr64(ctx, fp0, fs);
9965 gen_load_fpr64(ctx, fp1, ft);
9966 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9967 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9968 tcg_temp_free_i64(fp1);
a7812ae4 9969 tcg_temp_free_i64(fp0);
e7f16abb
LA
9970 opn = "max.d";
9971 } else {
9972 /* OPC_RSQRT1_D */
9973 check_cp1_64bitmode(ctx);
9974 {
9975 TCGv_i64 fp0 = tcg_temp_new_i64();
9976
9977 gen_load_fpr64(ctx, fp0, fs);
9978 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9979 gen_store_fpr64(ctx, fp0, fd);
9980 tcg_temp_free_i64(fp0);
9981 }
9982 opn = "rsqrt1.d";
9983 }
9984 break;
9985 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9986 if (ctx->insn_flags & ISA_MIPS32R6) {
9987 /* OPC_MAXA_D */
9988 TCGv_i64 fp0 = tcg_temp_new_i64();
9989 TCGv_i64 fp1 = tcg_temp_new_i64();
9990 gen_load_fpr64(ctx, fp0, fs);
9991 gen_load_fpr64(ctx, fp1, ft);
9992 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9993 gen_store_fpr64(ctx, fp1, fd);
9994 tcg_temp_free_i64(fp1);
9995 tcg_temp_free_i64(fp0);
9996 opn = "maxa.d";
9997 } else {
9998 /* OPC_RSQRT2_D */
9999 check_cp1_64bitmode(ctx);
10000 {
10001 TCGv_i64 fp0 = tcg_temp_new_i64();
10002 TCGv_i64 fp1 = tcg_temp_new_i64();
10003
10004 gen_load_fpr64(ctx, fp0, fs);
10005 gen_load_fpr64(ctx, fp1, ft);
10006 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10007 tcg_temp_free_i64(fp1);
10008 gen_store_fpr64(ctx, fp0, fd);
10009 tcg_temp_free_i64(fp0);
10010 }
10011 opn = "rsqrt2.d";
b6d96bed 10012 }
57fa1fb3 10013 break;
bf4120ad
NF
10014 case OPC_CMP_F_D:
10015 case OPC_CMP_UN_D:
10016 case OPC_CMP_EQ_D:
10017 case OPC_CMP_UEQ_D:
10018 case OPC_CMP_OLT_D:
10019 case OPC_CMP_ULT_D:
10020 case OPC_CMP_OLE_D:
10021 case OPC_CMP_ULE_D:
10022 case OPC_CMP_SF_D:
10023 case OPC_CMP_NGLE_D:
10024 case OPC_CMP_SEQ_D:
10025 case OPC_CMP_NGL_D:
10026 case OPC_CMP_LT_D:
10027 case OPC_CMP_NGE_D:
10028 case OPC_CMP_LE_D:
10029 case OPC_CMP_NGT_D:
fecd2646 10030 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10031 if (ctx->opcode & (1 << 6)) {
10032 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
10033 opn = condnames_abs[func-48];
10034 } else {
10035 gen_cmp_d(ctx, func-48, ft, fs, cc);
10036 opn = condnames[func-48];
5a1e8ffb 10037 }
6ea83fed 10038 break;
bf4120ad 10039 case OPC_CVT_S_D:
5e755519 10040 check_cp1_registers(ctx, fs);
b6d96bed 10041 {
a7812ae4
PB
10042 TCGv_i32 fp32 = tcg_temp_new_i32();
10043 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10044
10045 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10046 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10047 tcg_temp_free_i64(fp64);
7c979afd 10048 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10049 tcg_temp_free_i32(fp32);
b6d96bed 10050 }
5a5012ec
TS
10051 opn = "cvt.s.d";
10052 break;
bf4120ad 10053 case OPC_CVT_W_D:
5e755519 10054 check_cp1_registers(ctx, fs);
b6d96bed 10055 {
a7812ae4
PB
10056 TCGv_i32 fp32 = tcg_temp_new_i32();
10057 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10058
10059 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10060 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 10061 tcg_temp_free_i64(fp64);
7c979afd 10062 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10063 tcg_temp_free_i32(fp32);
b6d96bed 10064 }
5a5012ec
TS
10065 opn = "cvt.w.d";
10066 break;
bf4120ad 10067 case OPC_CVT_L_D:
5e755519 10068 check_cp1_64bitmode(ctx);
b6d96bed 10069 {
a7812ae4 10070 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10071
10072 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10073 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 10074 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10075 tcg_temp_free_i64(fp0);
b6d96bed 10076 }
5a5012ec
TS
10077 opn = "cvt.l.d";
10078 break;
bf4120ad 10079 case OPC_CVT_S_W:
b6d96bed 10080 {
a7812ae4 10081 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10082
7c979afd 10083 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10084 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10085 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10086 tcg_temp_free_i32(fp0);
b6d96bed 10087 }
5a5012ec 10088 opn = "cvt.s.w";
6ea83fed 10089 break;
bf4120ad 10090 case OPC_CVT_D_W:
5e755519 10091 check_cp1_registers(ctx, fd);
b6d96bed 10092 {
a7812ae4
PB
10093 TCGv_i32 fp32 = tcg_temp_new_i32();
10094 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10095
7c979afd 10096 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10097 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10098 tcg_temp_free_i32(fp32);
b6d96bed 10099 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10100 tcg_temp_free_i64(fp64);
b6d96bed 10101 }
5a5012ec
TS
10102 opn = "cvt.d.w";
10103 break;
bf4120ad 10104 case OPC_CVT_S_L:
5e755519 10105 check_cp1_64bitmode(ctx);
b6d96bed 10106 {
a7812ae4
PB
10107 TCGv_i32 fp32 = tcg_temp_new_i32();
10108 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10109
10110 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10111 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10112 tcg_temp_free_i64(fp64);
7c979afd 10113 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10114 tcg_temp_free_i32(fp32);
b6d96bed 10115 }
5a5012ec
TS
10116 opn = "cvt.s.l";
10117 break;
bf4120ad 10118 case OPC_CVT_D_L:
5e755519 10119 check_cp1_64bitmode(ctx);
b6d96bed 10120 {
a7812ae4 10121 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10122
10123 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10124 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10125 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10126 tcg_temp_free_i64(fp0);
b6d96bed 10127 }
5a5012ec
TS
10128 opn = "cvt.d.l";
10129 break;
bf4120ad 10130 case OPC_CVT_PS_PW:
e29c9628 10131 check_ps(ctx);
b6d96bed 10132 {
a7812ae4 10133 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10134
10135 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10136 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10137 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10138 tcg_temp_free_i64(fp0);
b6d96bed 10139 }
5a5012ec
TS
10140 opn = "cvt.ps.pw";
10141 break;
bf4120ad 10142 case OPC_ADD_PS:
e29c9628 10143 check_ps(ctx);
b6d96bed 10144 {
a7812ae4
PB
10145 TCGv_i64 fp0 = tcg_temp_new_i64();
10146 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10147
10148 gen_load_fpr64(ctx, fp0, fs);
10149 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10150 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10151 tcg_temp_free_i64(fp1);
b6d96bed 10152 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10153 tcg_temp_free_i64(fp0);
b6d96bed 10154 }
5a5012ec 10155 opn = "add.ps";
6ea83fed 10156 break;
bf4120ad 10157 case OPC_SUB_PS:
e29c9628 10158 check_ps(ctx);
b6d96bed 10159 {
a7812ae4
PB
10160 TCGv_i64 fp0 = tcg_temp_new_i64();
10161 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10162
10163 gen_load_fpr64(ctx, fp0, fs);
10164 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10165 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10166 tcg_temp_free_i64(fp1);
b6d96bed 10167 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10168 tcg_temp_free_i64(fp0);
b6d96bed 10169 }
5a5012ec 10170 opn = "sub.ps";
6ea83fed 10171 break;
bf4120ad 10172 case OPC_MUL_PS:
e29c9628 10173 check_ps(ctx);
b6d96bed 10174 {
a7812ae4
PB
10175 TCGv_i64 fp0 = tcg_temp_new_i64();
10176 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10177
10178 gen_load_fpr64(ctx, fp0, fs);
10179 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10180 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10181 tcg_temp_free_i64(fp1);
b6d96bed 10182 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10183 tcg_temp_free_i64(fp0);
b6d96bed 10184 }
5a5012ec 10185 opn = "mul.ps";
6ea83fed 10186 break;
bf4120ad 10187 case OPC_ABS_PS:
e29c9628 10188 check_ps(ctx);
b6d96bed 10189 {
a7812ae4 10190 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10191
10192 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10193 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10194 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10195 tcg_temp_free_i64(fp0);
b6d96bed 10196 }
5a5012ec 10197 opn = "abs.ps";
6ea83fed 10198 break;
bf4120ad 10199 case OPC_MOV_PS:
e29c9628 10200 check_ps(ctx);
b6d96bed 10201 {
a7812ae4 10202 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10203
10204 gen_load_fpr64(ctx, fp0, fs);
10205 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10206 tcg_temp_free_i64(fp0);
b6d96bed 10207 }
5a5012ec 10208 opn = "mov.ps";
6ea83fed 10209 break;
bf4120ad 10210 case OPC_NEG_PS:
e29c9628 10211 check_ps(ctx);
b6d96bed 10212 {
a7812ae4 10213 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10214
10215 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10216 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10217 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10218 tcg_temp_free_i64(fp0);
b6d96bed 10219 }
5a5012ec 10220 opn = "neg.ps";
6ea83fed 10221 break;
bf4120ad 10222 case OPC_MOVCF_PS:
e29c9628 10223 check_ps(ctx);
7f6613ce 10224 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 10225 opn = "movcf.ps";
6ea83fed 10226 break;
bf4120ad 10227 case OPC_MOVZ_PS:
e29c9628 10228 check_ps(ctx);
a16336e4 10229 {
42a268c2 10230 TCGLabel *l1 = gen_new_label();
30a3848b 10231 TCGv_i64 fp0;
a16336e4 10232
c9297f4d
AJ
10233 if (ft != 0)
10234 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10235 fp0 = tcg_temp_new_i64();
10236 gen_load_fpr64(ctx, fp0, fs);
10237 gen_store_fpr64(ctx, fp0, fd);
10238 tcg_temp_free_i64(fp0);
a16336e4
TS
10239 gen_set_label(l1);
10240 }
5a5012ec 10241 opn = "movz.ps";
6ea83fed 10242 break;
bf4120ad 10243 case OPC_MOVN_PS:
e29c9628 10244 check_ps(ctx);
a16336e4 10245 {
42a268c2 10246 TCGLabel *l1 = gen_new_label();
30a3848b 10247 TCGv_i64 fp0;
c9297f4d
AJ
10248
10249 if (ft != 0) {
10250 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10251 fp0 = tcg_temp_new_i64();
10252 gen_load_fpr64(ctx, fp0, fs);
10253 gen_store_fpr64(ctx, fp0, fd);
10254 tcg_temp_free_i64(fp0);
10255 gen_set_label(l1);
10256 }
a16336e4 10257 }
5a5012ec 10258 opn = "movn.ps";
6ea83fed 10259 break;
bf4120ad 10260 case OPC_ADDR_PS:
e29c9628 10261 check_ps(ctx);
b6d96bed 10262 {
a7812ae4
PB
10263 TCGv_i64 fp0 = tcg_temp_new_i64();
10264 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10265
10266 gen_load_fpr64(ctx, fp0, ft);
10267 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10268 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10269 tcg_temp_free_i64(fp1);
b6d96bed 10270 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10271 tcg_temp_free_i64(fp0);
b6d96bed 10272 }
fbcc6828
TS
10273 opn = "addr.ps";
10274 break;
bf4120ad 10275 case OPC_MULR_PS:
e29c9628 10276 check_ps(ctx);
b6d96bed 10277 {
a7812ae4
PB
10278 TCGv_i64 fp0 = tcg_temp_new_i64();
10279 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10280
10281 gen_load_fpr64(ctx, fp0, ft);
10282 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10283 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10284 tcg_temp_free_i64(fp1);
b6d96bed 10285 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10286 tcg_temp_free_i64(fp0);
b6d96bed 10287 }
57fa1fb3
TS
10288 opn = "mulr.ps";
10289 break;
bf4120ad 10290 case OPC_RECIP2_PS:
e29c9628 10291 check_ps(ctx);
b6d96bed 10292 {
a7812ae4
PB
10293 TCGv_i64 fp0 = tcg_temp_new_i64();
10294 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10295
10296 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10297 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10298 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10299 tcg_temp_free_i64(fp1);
b6d96bed 10300 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10301 tcg_temp_free_i64(fp0);
b6d96bed 10302 }
57fa1fb3
TS
10303 opn = "recip2.ps";
10304 break;
bf4120ad 10305 case OPC_RECIP1_PS:
e29c9628 10306 check_ps(ctx);
b6d96bed 10307 {
a7812ae4 10308 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10309
10310 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10311 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10312 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10313 tcg_temp_free_i64(fp0);
b6d96bed 10314 }
57fa1fb3
TS
10315 opn = "recip1.ps";
10316 break;
bf4120ad 10317 case OPC_RSQRT1_PS:
e29c9628 10318 check_ps(ctx);
b6d96bed 10319 {
a7812ae4 10320 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10321
10322 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10323 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10324 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10325 tcg_temp_free_i64(fp0);
b6d96bed 10326 }
57fa1fb3
TS
10327 opn = "rsqrt1.ps";
10328 break;
bf4120ad 10329 case OPC_RSQRT2_PS:
e29c9628 10330 check_ps(ctx);
b6d96bed 10331 {
a7812ae4
PB
10332 TCGv_i64 fp0 = tcg_temp_new_i64();
10333 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10334
10335 gen_load_fpr64(ctx, fp0, fs);
10336 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10337 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10338 tcg_temp_free_i64(fp1);
b6d96bed 10339 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10340 tcg_temp_free_i64(fp0);
b6d96bed 10341 }
57fa1fb3
TS
10342 opn = "rsqrt2.ps";
10343 break;
bf4120ad 10344 case OPC_CVT_S_PU:
5e755519 10345 check_cp1_64bitmode(ctx);
b6d96bed 10346 {
a7812ae4 10347 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10348
7f6613ce 10349 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10350 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10351 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10352 tcg_temp_free_i32(fp0);
b6d96bed 10353 }
5a5012ec 10354 opn = "cvt.s.pu";
dd016883 10355 break;
bf4120ad 10356 case OPC_CVT_PW_PS:
e29c9628 10357 check_ps(ctx);
b6d96bed 10358 {
a7812ae4 10359 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10360
10361 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10362 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10363 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10364 tcg_temp_free_i64(fp0);
b6d96bed 10365 }
5a5012ec 10366 opn = "cvt.pw.ps";
6ea83fed 10367 break;
bf4120ad 10368 case OPC_CVT_S_PL:
5e755519 10369 check_cp1_64bitmode(ctx);
b6d96bed 10370 {
a7812ae4 10371 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10372
7c979afd 10373 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10374 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10375 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10376 tcg_temp_free_i32(fp0);
b6d96bed 10377 }
5a5012ec 10378 opn = "cvt.s.pl";
6ea83fed 10379 break;
bf4120ad 10380 case OPC_PLL_PS:
e29c9628 10381 check_ps(ctx);
b6d96bed 10382 {
a7812ae4
PB
10383 TCGv_i32 fp0 = tcg_temp_new_i32();
10384 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10385
7c979afd
LA
10386 gen_load_fpr32(ctx, fp0, fs);
10387 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10388 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10389 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10390 tcg_temp_free_i32(fp0);
10391 tcg_temp_free_i32(fp1);
b6d96bed 10392 }
5a5012ec 10393 opn = "pll.ps";
6ea83fed 10394 break;
bf4120ad 10395 case OPC_PLU_PS:
e29c9628 10396 check_ps(ctx);
b6d96bed 10397 {
a7812ae4
PB
10398 TCGv_i32 fp0 = tcg_temp_new_i32();
10399 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10400
7c979afd 10401 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10402 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10403 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10404 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10405 tcg_temp_free_i32(fp0);
10406 tcg_temp_free_i32(fp1);
b6d96bed 10407 }
5a5012ec
TS
10408 opn = "plu.ps";
10409 break;
bf4120ad 10410 case OPC_PUL_PS:
e29c9628 10411 check_ps(ctx);
b6d96bed 10412 {
a7812ae4
PB
10413 TCGv_i32 fp0 = tcg_temp_new_i32();
10414 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10415
7f6613ce 10416 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10417 gen_load_fpr32(ctx, fp1, ft);
10418 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10419 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10420 tcg_temp_free_i32(fp0);
10421 tcg_temp_free_i32(fp1);
b6d96bed 10422 }
5a5012ec
TS
10423 opn = "pul.ps";
10424 break;
bf4120ad 10425 case OPC_PUU_PS:
e29c9628 10426 check_ps(ctx);
b6d96bed 10427 {
a7812ae4
PB
10428 TCGv_i32 fp0 = tcg_temp_new_i32();
10429 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10430
7f6613ce
PJ
10431 gen_load_fpr32h(ctx, fp0, fs);
10432 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10433 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10434 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10435 tcg_temp_free_i32(fp0);
10436 tcg_temp_free_i32(fp1);
b6d96bed 10437 }
5a5012ec
TS
10438 opn = "puu.ps";
10439 break;
bf4120ad
NF
10440 case OPC_CMP_F_PS:
10441 case OPC_CMP_UN_PS:
10442 case OPC_CMP_EQ_PS:
10443 case OPC_CMP_UEQ_PS:
10444 case OPC_CMP_OLT_PS:
10445 case OPC_CMP_ULT_PS:
10446 case OPC_CMP_OLE_PS:
10447 case OPC_CMP_ULE_PS:
10448 case OPC_CMP_SF_PS:
10449 case OPC_CMP_NGLE_PS:
10450 case OPC_CMP_SEQ_PS:
10451 case OPC_CMP_NGL_PS:
10452 case OPC_CMP_LT_PS:
10453 case OPC_CMP_NGE_PS:
10454 case OPC_CMP_LE_PS:
10455 case OPC_CMP_NGT_PS:
8153667c
NF
10456 if (ctx->opcode & (1 << 6)) {
10457 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10458 opn = condnames_abs[func-48];
10459 } else {
10460 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10461 opn = condnames[func-48];
5a1e8ffb 10462 }
6ea83fed 10463 break;
5a5012ec 10464 default:
923617a3 10465 MIPS_INVAL(opn);
e397ee33 10466 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10467 return;
10468 }
2abf314d 10469 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10470 switch (optype) {
10471 case BINOP:
6ea83fed 10472 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10473 break;
10474 case CMPOP:
10475 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10476 break;
10477 default:
6ea83fed 10478 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10479 break;
10480 }
6ea83fed 10481}
6af0bf9c 10482
5a5012ec 10483/* Coprocessor 3 (FPU) */
5e755519
TS
10484static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10485 int fd, int fs, int base, int index)
7a387fff 10486{
923617a3 10487 const char *opn = "extended float load/store";
93b12ccc 10488 int store = 0;
4e2474d6 10489 TCGv t0 = tcg_temp_new();
7a387fff 10490
93b12ccc 10491 if (base == 0) {
6c5c1e20 10492 gen_load_gpr(t0, index);
93b12ccc 10493 } else if (index == 0) {
6c5c1e20 10494 gen_load_gpr(t0, base);
93b12ccc 10495 } else {
05168674 10496 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10497 }
5a5012ec 10498 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10499 memory access. */
5a5012ec
TS
10500 switch (opc) {
10501 case OPC_LWXC1:
8c0ab41f 10502 check_cop1x(ctx);
b6d96bed 10503 {
a7812ae4 10504 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10505
5f68f5ae 10506 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10507 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10508 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10509 tcg_temp_free_i32(fp0);
b6d96bed 10510 }
5a5012ec
TS
10511 opn = "lwxc1";
10512 break;
10513 case OPC_LDXC1:
8c0ab41f
AJ
10514 check_cop1x(ctx);
10515 check_cp1_registers(ctx, fd);
b6d96bed 10516 {
a7812ae4 10517 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10518 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10519 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10520 tcg_temp_free_i64(fp0);
b6d96bed 10521 }
5a5012ec
TS
10522 opn = "ldxc1";
10523 break;
10524 case OPC_LUXC1:
8c0ab41f 10525 check_cp1_64bitmode(ctx);
6c5c1e20 10526 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10527 {
a7812ae4 10528 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10529
5f68f5ae 10530 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10532 tcg_temp_free_i64(fp0);
b6d96bed 10533 }
5a5012ec
TS
10534 opn = "luxc1";
10535 break;
10536 case OPC_SWXC1:
8c0ab41f 10537 check_cop1x(ctx);
b6d96bed 10538 {
a7812ae4 10539 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10540 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10541 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10542 tcg_temp_free_i32(fp0);
b6d96bed 10543 }
5a5012ec 10544 opn = "swxc1";
93b12ccc 10545 store = 1;
5a5012ec
TS
10546 break;
10547 case OPC_SDXC1:
8c0ab41f
AJ
10548 check_cop1x(ctx);
10549 check_cp1_registers(ctx, fs);
b6d96bed 10550 {
a7812ae4 10551 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10552 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10553 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10554 tcg_temp_free_i64(fp0);
b6d96bed 10555 }
5a5012ec 10556 opn = "sdxc1";
93b12ccc 10557 store = 1;
5a5012ec
TS
10558 break;
10559 case OPC_SUXC1:
8c0ab41f 10560 check_cp1_64bitmode(ctx);
6c5c1e20 10561 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10562 {
a7812ae4 10563 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10564 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10565 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10566 tcg_temp_free_i64(fp0);
b6d96bed 10567 }
5a5012ec 10568 opn = "suxc1";
93b12ccc 10569 store = 1;
5a5012ec 10570 break;
5a5012ec 10571 }
6c5c1e20 10572 tcg_temp_free(t0);
2abf314d 10573 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10574 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10575 regnames[index], regnames[base]);
5a5012ec
TS
10576}
10577
5e755519
TS
10578static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10579 int fd, int fr, int fs, int ft)
5a5012ec 10580{
923617a3 10581 const char *opn = "flt3_arith";
5a5012ec 10582
5a5012ec
TS
10583 switch (opc) {
10584 case OPC_ALNV_PS:
e29c9628 10585 check_ps(ctx);
a16336e4 10586 {
a7812ae4 10587 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10588 TCGv_i32 fp = tcg_temp_new_i32();
10589 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10590 TCGLabel *l1 = gen_new_label();
10591 TCGLabel *l2 = gen_new_label();
a16336e4 10592
6c5c1e20
TS
10593 gen_load_gpr(t0, fr);
10594 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10595
10596 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10597 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10598 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10599 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10600 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10601 tcg_gen_br(l2);
10602 gen_set_label(l1);
6c5c1e20
TS
10603 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10604 tcg_temp_free(t0);
a16336e4 10605#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10606 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10607 gen_load_fpr32h(ctx, fph, ft);
10608 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10609 gen_store_fpr32(ctx, fph, fd);
a16336e4 10610#else
7f6613ce 10611 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10612 gen_load_fpr32(ctx, fp, ft);
10613 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10614 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10615#endif
10616 gen_set_label(l2);
c905fdac
AJ
10617 tcg_temp_free_i32(fp);
10618 tcg_temp_free_i32(fph);
a16336e4 10619 }
5a5012ec
TS
10620 opn = "alnv.ps";
10621 break;
10622 case OPC_MADD_S:
b8aa4598 10623 check_cop1x(ctx);
b6d96bed 10624 {
a7812ae4
PB
10625 TCGv_i32 fp0 = tcg_temp_new_i32();
10626 TCGv_i32 fp1 = tcg_temp_new_i32();
10627 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10628
7c979afd
LA
10629 gen_load_fpr32(ctx, fp0, fs);
10630 gen_load_fpr32(ctx, fp1, ft);
10631 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10632 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10633 tcg_temp_free_i32(fp0);
10634 tcg_temp_free_i32(fp1);
7c979afd 10635 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10636 tcg_temp_free_i32(fp2);
b6d96bed 10637 }
5a5012ec
TS
10638 opn = "madd.s";
10639 break;
10640 case OPC_MADD_D:
b8aa4598
TS
10641 check_cop1x(ctx);
10642 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10643 {
a7812ae4
PB
10644 TCGv_i64 fp0 = tcg_temp_new_i64();
10645 TCGv_i64 fp1 = tcg_temp_new_i64();
10646 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10647
10648 gen_load_fpr64(ctx, fp0, fs);
10649 gen_load_fpr64(ctx, fp1, ft);
10650 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10651 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10652 tcg_temp_free_i64(fp0);
10653 tcg_temp_free_i64(fp1);
b6d96bed 10654 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10655 tcg_temp_free_i64(fp2);
b6d96bed 10656 }
5a5012ec
TS
10657 opn = "madd.d";
10658 break;
10659 case OPC_MADD_PS:
e29c9628 10660 check_ps(ctx);
b6d96bed 10661 {
a7812ae4
PB
10662 TCGv_i64 fp0 = tcg_temp_new_i64();
10663 TCGv_i64 fp1 = tcg_temp_new_i64();
10664 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10665
10666 gen_load_fpr64(ctx, fp0, fs);
10667 gen_load_fpr64(ctx, fp1, ft);
10668 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10669 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10670 tcg_temp_free_i64(fp0);
10671 tcg_temp_free_i64(fp1);
b6d96bed 10672 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10673 tcg_temp_free_i64(fp2);
b6d96bed 10674 }
5a5012ec
TS
10675 opn = "madd.ps";
10676 break;
10677 case OPC_MSUB_S:
b8aa4598 10678 check_cop1x(ctx);
b6d96bed 10679 {
a7812ae4
PB
10680 TCGv_i32 fp0 = tcg_temp_new_i32();
10681 TCGv_i32 fp1 = tcg_temp_new_i32();
10682 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10683
7c979afd
LA
10684 gen_load_fpr32(ctx, fp0, fs);
10685 gen_load_fpr32(ctx, fp1, ft);
10686 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10687 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10688 tcg_temp_free_i32(fp0);
10689 tcg_temp_free_i32(fp1);
7c979afd 10690 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10691 tcg_temp_free_i32(fp2);
b6d96bed 10692 }
5a5012ec
TS
10693 opn = "msub.s";
10694 break;
10695 case OPC_MSUB_D:
b8aa4598
TS
10696 check_cop1x(ctx);
10697 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10698 {
a7812ae4
PB
10699 TCGv_i64 fp0 = tcg_temp_new_i64();
10700 TCGv_i64 fp1 = tcg_temp_new_i64();
10701 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10702
10703 gen_load_fpr64(ctx, fp0, fs);
10704 gen_load_fpr64(ctx, fp1, ft);
10705 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10706 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10707 tcg_temp_free_i64(fp0);
10708 tcg_temp_free_i64(fp1);
b6d96bed 10709 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10710 tcg_temp_free_i64(fp2);
b6d96bed 10711 }
5a5012ec
TS
10712 opn = "msub.d";
10713 break;
10714 case OPC_MSUB_PS:
e29c9628 10715 check_ps(ctx);
b6d96bed 10716 {
a7812ae4
PB
10717 TCGv_i64 fp0 = tcg_temp_new_i64();
10718 TCGv_i64 fp1 = tcg_temp_new_i64();
10719 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10720
10721 gen_load_fpr64(ctx, fp0, fs);
10722 gen_load_fpr64(ctx, fp1, ft);
10723 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10724 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10725 tcg_temp_free_i64(fp0);
10726 tcg_temp_free_i64(fp1);
b6d96bed 10727 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10728 tcg_temp_free_i64(fp2);
b6d96bed 10729 }
5a5012ec
TS
10730 opn = "msub.ps";
10731 break;
10732 case OPC_NMADD_S:
b8aa4598 10733 check_cop1x(ctx);
b6d96bed 10734 {
a7812ae4
PB
10735 TCGv_i32 fp0 = tcg_temp_new_i32();
10736 TCGv_i32 fp1 = tcg_temp_new_i32();
10737 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10738
7c979afd
LA
10739 gen_load_fpr32(ctx, fp0, fs);
10740 gen_load_fpr32(ctx, fp1, ft);
10741 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10742 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10743 tcg_temp_free_i32(fp0);
10744 tcg_temp_free_i32(fp1);
7c979afd 10745 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10746 tcg_temp_free_i32(fp2);
b6d96bed 10747 }
5a5012ec
TS
10748 opn = "nmadd.s";
10749 break;
10750 case OPC_NMADD_D:
b8aa4598
TS
10751 check_cop1x(ctx);
10752 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10753 {
a7812ae4
PB
10754 TCGv_i64 fp0 = tcg_temp_new_i64();
10755 TCGv_i64 fp1 = tcg_temp_new_i64();
10756 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10757
10758 gen_load_fpr64(ctx, fp0, fs);
10759 gen_load_fpr64(ctx, fp1, ft);
10760 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10761 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10762 tcg_temp_free_i64(fp0);
10763 tcg_temp_free_i64(fp1);
b6d96bed 10764 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10765 tcg_temp_free_i64(fp2);
b6d96bed 10766 }
5a5012ec
TS
10767 opn = "nmadd.d";
10768 break;
10769 case OPC_NMADD_PS:
e29c9628 10770 check_ps(ctx);
b6d96bed 10771 {
a7812ae4
PB
10772 TCGv_i64 fp0 = tcg_temp_new_i64();
10773 TCGv_i64 fp1 = tcg_temp_new_i64();
10774 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10775
10776 gen_load_fpr64(ctx, fp0, fs);
10777 gen_load_fpr64(ctx, fp1, ft);
10778 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10779 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10780 tcg_temp_free_i64(fp0);
10781 tcg_temp_free_i64(fp1);
b6d96bed 10782 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10783 tcg_temp_free_i64(fp2);
b6d96bed 10784 }
5a5012ec
TS
10785 opn = "nmadd.ps";
10786 break;
10787 case OPC_NMSUB_S:
b8aa4598 10788 check_cop1x(ctx);
b6d96bed 10789 {
a7812ae4
PB
10790 TCGv_i32 fp0 = tcg_temp_new_i32();
10791 TCGv_i32 fp1 = tcg_temp_new_i32();
10792 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10793
7c979afd
LA
10794 gen_load_fpr32(ctx, fp0, fs);
10795 gen_load_fpr32(ctx, fp1, ft);
10796 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10797 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10798 tcg_temp_free_i32(fp0);
10799 tcg_temp_free_i32(fp1);
7c979afd 10800 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10801 tcg_temp_free_i32(fp2);
b6d96bed 10802 }
5a5012ec
TS
10803 opn = "nmsub.s";
10804 break;
10805 case OPC_NMSUB_D:
b8aa4598
TS
10806 check_cop1x(ctx);
10807 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10808 {
a7812ae4
PB
10809 TCGv_i64 fp0 = tcg_temp_new_i64();
10810 TCGv_i64 fp1 = tcg_temp_new_i64();
10811 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10812
10813 gen_load_fpr64(ctx, fp0, fs);
10814 gen_load_fpr64(ctx, fp1, ft);
10815 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10816 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10817 tcg_temp_free_i64(fp0);
10818 tcg_temp_free_i64(fp1);
b6d96bed 10819 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10820 tcg_temp_free_i64(fp2);
b6d96bed 10821 }
5a5012ec
TS
10822 opn = "nmsub.d";
10823 break;
10824 case OPC_NMSUB_PS:
e29c9628 10825 check_ps(ctx);
b6d96bed 10826 {
a7812ae4
PB
10827 TCGv_i64 fp0 = tcg_temp_new_i64();
10828 TCGv_i64 fp1 = tcg_temp_new_i64();
10829 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10830
10831 gen_load_fpr64(ctx, fp0, fs);
10832 gen_load_fpr64(ctx, fp1, ft);
10833 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10834 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10835 tcg_temp_free_i64(fp0);
10836 tcg_temp_free_i64(fp1);
b6d96bed 10837 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10838 tcg_temp_free_i64(fp2);
b6d96bed 10839 }
5a5012ec
TS
10840 opn = "nmsub.ps";
10841 break;
923617a3
TS
10842 default:
10843 MIPS_INVAL(opn);
5a5012ec
TS
10844 generate_exception (ctx, EXCP_RI);
10845 return;
10846 }
2abf314d 10847 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10848 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10849 fregnames[fs], fregnames[ft]);
7a387fff
TS
10850}
10851
d75c135e 10852static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10853{
10854 TCGv t0;
10855
b3167288
RH
10856#if !defined(CONFIG_USER_ONLY)
10857 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10858 Therefore only check the ISA in system mode. */
d75c135e 10859 check_insn(ctx, ISA_MIPS32R2);
b3167288 10860#endif
26ebe468
NF
10861 t0 = tcg_temp_new();
10862
10863 switch (rd) {
10864 case 0:
10865 save_cpu_state(ctx, 1);
895c2d04 10866 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10867 gen_store_gpr(t0, rt);
10868 break;
10869 case 1:
10870 save_cpu_state(ctx, 1);
895c2d04 10871 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10872 gen_store_gpr(t0, rt);
10873 break;
10874 case 2:
10875 save_cpu_state(ctx, 1);
895c2d04 10876 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10877 gen_store_gpr(t0, rt);
10878 break;
10879 case 3:
10880 save_cpu_state(ctx, 1);
895c2d04 10881 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10882 gen_store_gpr(t0, rt);
10883 break;
10884 case 29:
10885#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10886 tcg_gen_ld_tl(t0, cpu_env,
10887 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10888 gen_store_gpr(t0, rt);
10889 break;
10890#else
d279279e
PJ
10891 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10892 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10893 tcg_gen_ld_tl(t0, cpu_env,
10894 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10895 gen_store_gpr(t0, rt);
10896 } else {
10897 generate_exception(ctx, EXCP_RI);
10898 }
10899 break;
26ebe468
NF
10900#endif
10901 default: /* Invalid */
10902 MIPS_INVAL("rdhwr");
10903 generate_exception(ctx, EXCP_RI);
10904 break;
10905 }
10906 tcg_temp_free(t0);
10907}
10908
a5f53390
LA
10909static inline void clear_branch_hflags(DisasContext *ctx)
10910{
10911 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10912 if (ctx->bstate == BS_NONE) {
10913 save_cpu_state(ctx, 0);
10914 } else {
10915 /* it is not safe to save ctx->hflags as hflags may be changed
10916 in execution time by the instruction in delay / forbidden slot. */
10917 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10918 }
10919}
10920
31837be3 10921static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10922{
10923 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10924 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10925 /* Branches completion */
a5f53390 10926 clear_branch_hflags(ctx);
c9602061 10927 ctx->bstate = BS_BRANCH;
c9602061 10928 /* FIXME: Need to clear can_do_io. */
364d4831 10929 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10930 case MIPS_HFLAG_FBNSLOT:
10931 MIPS_DEBUG("forbidden slot");
10932 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10933 break;
c9602061
NF
10934 case MIPS_HFLAG_B:
10935 /* unconditional branch */
10936 MIPS_DEBUG("unconditional branch");
364d4831
NF
10937 if (proc_hflags & MIPS_HFLAG_BX) {
10938 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10939 }
c9602061
NF
10940 gen_goto_tb(ctx, 0, ctx->btarget);
10941 break;
10942 case MIPS_HFLAG_BL:
10943 /* blikely taken case */
10944 MIPS_DEBUG("blikely branch taken");
10945 gen_goto_tb(ctx, 0, ctx->btarget);
10946 break;
10947 case MIPS_HFLAG_BC:
10948 /* Conditional branch */
10949 MIPS_DEBUG("conditional branch");
10950 {
42a268c2 10951 TCGLabel *l1 = gen_new_label();
c9602061
NF
10952
10953 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10954 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10955 gen_set_label(l1);
10956 gen_goto_tb(ctx, 0, ctx->btarget);
10957 }
10958 break;
10959 case MIPS_HFLAG_BR:
10960 /* unconditional branch to register */
10961 MIPS_DEBUG("branch to register");
d75c135e 10962 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10963 TCGv t0 = tcg_temp_new();
10964 TCGv_i32 t1 = tcg_temp_new_i32();
10965
10966 tcg_gen_andi_tl(t0, btarget, 0x1);
10967 tcg_gen_trunc_tl_i32(t1, t0);
10968 tcg_temp_free(t0);
10969 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10970 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10971 tcg_gen_or_i32(hflags, hflags, t1);
10972 tcg_temp_free_i32(t1);
10973
10974 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10975 } else {
10976 tcg_gen_mov_tl(cpu_PC, btarget);
10977 }
c9602061
NF
10978 if (ctx->singlestep_enabled) {
10979 save_cpu_state(ctx, 0);
895c2d04 10980 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10981 }
10982 tcg_gen_exit_tb(0);
10983 break;
10984 default:
a5f53390
LA
10985 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10986 abort();
c9602061
NF
10987 }
10988 }
10989}
10990
6893f074
YK
10991/* Compact Branches */
10992static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10993 int rs, int rt, int32_t offset)
10994{
10995 int bcond_compute = 0;
10996 TCGv t0 = tcg_temp_new();
10997 TCGv t1 = tcg_temp_new();
65935f07 10998 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10999
11000 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11001#ifdef MIPS_DEBUG_DISAS
11002 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11003 "\n", ctx->pc);
11004#endif
11005 generate_exception(ctx, EXCP_RI);
11006 goto out;
11007 }
11008
11009 /* Load needed operands and calculate btarget */
11010 switch (opc) {
11011 /* compact branch */
11012 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11013 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11014 gen_load_gpr(t0, rs);
11015 gen_load_gpr(t1, rt);
11016 bcond_compute = 1;
11017 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
11018 if (rs <= rt && rs == 0) {
11019 /* OPC_BEQZALC, OPC_BNEZALC */
65935f07 11020 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
11021 }
11022 break;
11023 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11024 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11025 gen_load_gpr(t0, rs);
11026 gen_load_gpr(t1, rt);
11027 bcond_compute = 1;
11028 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
11029 break;
11030 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11031 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11032 if (rs == 0 || rs == rt) {
11033 /* OPC_BLEZALC, OPC_BGEZALC */
11034 /* OPC_BGTZALC, OPC_BLTZALC */
65935f07 11035 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
11036 }
11037 gen_load_gpr(t0, rs);
11038 gen_load_gpr(t1, rt);
11039 bcond_compute = 1;
11040 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
11041 break;
11042 case OPC_BC:
11043 case OPC_BALC:
11044 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
11045 break;
11046 case OPC_BEQZC:
11047 case OPC_BNEZC:
11048 if (rs != 0) {
11049 /* OPC_BEQZC, OPC_BNEZC */
11050 gen_load_gpr(t0, rs);
11051 bcond_compute = 1;
11052 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
11053 } else {
11054 /* OPC_JIC, OPC_JIALC */
11055 TCGv tbase = tcg_temp_new();
11056 TCGv toffset = tcg_temp_new();
11057
11058 gen_load_gpr(tbase, rt);
11059 tcg_gen_movi_tl(toffset, offset);
11060 gen_op_addr_add(ctx, btarget, tbase, toffset);
11061 tcg_temp_free(tbase);
11062 tcg_temp_free(toffset);
11063 }
11064 break;
11065 default:
11066 MIPS_INVAL("Compact branch/jump");
11067 generate_exception(ctx, EXCP_RI);
11068 goto out;
11069 }
11070
11071 if (bcond_compute == 0) {
11072 /* Uncoditional compact branch */
11073 switch (opc) {
11074 case OPC_JIALC:
65935f07 11075 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
11076 /* Fallthrough */
11077 case OPC_JIC:
11078 ctx->hflags |= MIPS_HFLAG_BR;
11079 break;
11080 case OPC_BALC:
65935f07 11081 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
6893f074
YK
11082 /* Fallthrough */
11083 case OPC_BC:
11084 ctx->hflags |= MIPS_HFLAG_B;
11085 break;
11086 default:
11087 MIPS_INVAL("Compact branch/jump");
11088 generate_exception(ctx, EXCP_RI);
11089 goto out;
11090 }
11091
11092 /* Generating branch here as compact branches don't have delay slot */
11093 gen_branch(ctx, 4);
11094 } else {
11095 /* Conditional compact branch */
11096 TCGLabel *fs = gen_new_label();
11097 save_cpu_state(ctx, 0);
11098
11099 switch (opc) {
11100 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11101 if (rs == 0 && rt != 0) {
11102 /* OPC_BLEZALC */
11103 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11104 } else if (rs != 0 && rt != 0 && rs == rt) {
11105 /* OPC_BGEZALC */
11106 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11107 } else {
11108 /* OPC_BGEUC */
11109 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11110 }
11111 break;
11112 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11113 if (rs == 0 && rt != 0) {
11114 /* OPC_BGTZALC */
11115 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11116 } else if (rs != 0 && rt != 0 && rs == rt) {
11117 /* OPC_BLTZALC */
11118 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11119 } else {
11120 /* OPC_BLTUC */
11121 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11122 }
11123 break;
11124 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11125 if (rs == 0 && rt != 0) {
11126 /* OPC_BLEZC */
11127 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11128 } else if (rs != 0 && rt != 0 && rs == rt) {
11129 /* OPC_BGEZC */
11130 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11131 } else {
11132 /* OPC_BGEC */
11133 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11134 }
11135 break;
11136 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11137 if (rs == 0 && rt != 0) {
11138 /* OPC_BGTZC */
11139 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11140 } else if (rs != 0 && rt != 0 && rs == rt) {
11141 /* OPC_BLTZC */
11142 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11143 } else {
11144 /* OPC_BLTC */
11145 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11146 }
11147 break;
11148 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11149 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11150 if (rs >= rt) {
11151 /* OPC_BOVC, OPC_BNVC */
11152 TCGv t2 = tcg_temp_new();
11153 TCGv t3 = tcg_temp_new();
11154 TCGv t4 = tcg_temp_new();
11155 TCGv input_overflow = tcg_temp_new();
11156
11157 gen_load_gpr(t0, rs);
11158 gen_load_gpr(t1, rt);
11159 tcg_gen_ext32s_tl(t2, t0);
11160 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11161 tcg_gen_ext32s_tl(t3, t1);
11162 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11163 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11164
11165 tcg_gen_add_tl(t4, t2, t3);
11166 tcg_gen_ext32s_tl(t4, t4);
11167 tcg_gen_xor_tl(t2, t2, t3);
11168 tcg_gen_xor_tl(t3, t4, t3);
11169 tcg_gen_andc_tl(t2, t3, t2);
11170 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11171 tcg_gen_or_tl(t4, t4, input_overflow);
11172 if (opc == OPC_BOVC) {
11173 /* OPC_BOVC */
11174 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11175 } else {
11176 /* OPC_BNVC */
11177 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11178 }
11179 tcg_temp_free(input_overflow);
11180 tcg_temp_free(t4);
11181 tcg_temp_free(t3);
11182 tcg_temp_free(t2);
11183 } else if (rs < rt && rs == 0) {
11184 /* OPC_BEQZALC, OPC_BNEZALC */
11185 if (opc == OPC_BEQZALC) {
11186 /* OPC_BEQZALC */
11187 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11188 } else {
11189 /* OPC_BNEZALC */
11190 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11191 }
11192 } else {
11193 /* OPC_BEQC, OPC_BNEC */
11194 if (opc == OPC_BEQC) {
11195 /* OPC_BEQC */
11196 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11197 } else {
11198 /* OPC_BNEC */
11199 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11200 }
11201 }
11202 break;
11203 case OPC_BEQZC:
11204 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11205 break;
11206 case OPC_BNEZC:
11207 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11208 break;
11209 default:
11210 MIPS_INVAL("Compact conditional branch/jump");
11211 generate_exception(ctx, EXCP_RI);
11212 goto out;
11213 }
11214
11215 /* Generating branch here as compact branches don't have delay slot */
11216 gen_goto_tb(ctx, 1, ctx->btarget);
11217 gen_set_label(fs);
11218
11219 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11220 MIPS_DEBUG("Compact conditional branch");
11221 }
11222
11223out:
11224 tcg_temp_free(t0);
11225 tcg_temp_free(t1);
11226}
11227
7a387fff 11228/* ISA extensions (ASEs) */
6af0bf9c 11229/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11230
11231/* MIPS16 major opcodes */
11232enum {
11233 M16_OPC_ADDIUSP = 0x00,
11234 M16_OPC_ADDIUPC = 0x01,
11235 M16_OPC_B = 0x02,
11236 M16_OPC_JAL = 0x03,
11237 M16_OPC_BEQZ = 0x04,
11238 M16_OPC_BNEQZ = 0x05,
11239 M16_OPC_SHIFT = 0x06,
11240 M16_OPC_LD = 0x07,
11241 M16_OPC_RRIA = 0x08,
11242 M16_OPC_ADDIU8 = 0x09,
11243 M16_OPC_SLTI = 0x0a,
11244 M16_OPC_SLTIU = 0x0b,
11245 M16_OPC_I8 = 0x0c,
11246 M16_OPC_LI = 0x0d,
11247 M16_OPC_CMPI = 0x0e,
11248 M16_OPC_SD = 0x0f,
11249 M16_OPC_LB = 0x10,
11250 M16_OPC_LH = 0x11,
11251 M16_OPC_LWSP = 0x12,
11252 M16_OPC_LW = 0x13,
11253 M16_OPC_LBU = 0x14,
11254 M16_OPC_LHU = 0x15,
11255 M16_OPC_LWPC = 0x16,
11256 M16_OPC_LWU = 0x17,
11257 M16_OPC_SB = 0x18,
11258 M16_OPC_SH = 0x19,
11259 M16_OPC_SWSP = 0x1a,
11260 M16_OPC_SW = 0x1b,
11261 M16_OPC_RRR = 0x1c,
11262 M16_OPC_RR = 0x1d,
11263 M16_OPC_EXTEND = 0x1e,
11264 M16_OPC_I64 = 0x1f
11265};
11266
11267/* I8 funct field */
11268enum {
11269 I8_BTEQZ = 0x0,
11270 I8_BTNEZ = 0x1,
11271 I8_SWRASP = 0x2,
11272 I8_ADJSP = 0x3,
11273 I8_SVRS = 0x4,
11274 I8_MOV32R = 0x5,
11275 I8_MOVR32 = 0x7
11276};
11277
11278/* RRR f field */
11279enum {
11280 RRR_DADDU = 0x0,
11281 RRR_ADDU = 0x1,
11282 RRR_DSUBU = 0x2,
11283 RRR_SUBU = 0x3
11284};
11285
11286/* RR funct field */
11287enum {
11288 RR_JR = 0x00,
11289 RR_SDBBP = 0x01,
11290 RR_SLT = 0x02,
11291 RR_SLTU = 0x03,
11292 RR_SLLV = 0x04,
11293 RR_BREAK = 0x05,
11294 RR_SRLV = 0x06,
11295 RR_SRAV = 0x07,
11296 RR_DSRL = 0x08,
11297 RR_CMP = 0x0a,
11298 RR_NEG = 0x0b,
11299 RR_AND = 0x0c,
11300 RR_OR = 0x0d,
11301 RR_XOR = 0x0e,
11302 RR_NOT = 0x0f,
11303 RR_MFHI = 0x10,
11304 RR_CNVT = 0x11,
11305 RR_MFLO = 0x12,
11306 RR_DSRA = 0x13,
11307 RR_DSLLV = 0x14,
11308 RR_DSRLV = 0x16,
11309 RR_DSRAV = 0x17,
11310 RR_MULT = 0x18,
11311 RR_MULTU = 0x19,
11312 RR_DIV = 0x1a,
11313 RR_DIVU = 0x1b,
11314 RR_DMULT = 0x1c,
11315 RR_DMULTU = 0x1d,
11316 RR_DDIV = 0x1e,
11317 RR_DDIVU = 0x1f
11318};
11319
11320/* I64 funct field */
11321enum {
11322 I64_LDSP = 0x0,
11323 I64_SDSP = 0x1,
11324 I64_SDRASP = 0x2,
11325 I64_DADJSP = 0x3,
11326 I64_LDPC = 0x4,
364d4831 11327 I64_DADDIU5 = 0x5,
6ea219d0
NF
11328 I64_DADDIUPC = 0x6,
11329 I64_DADDIUSP = 0x7
11330};
11331
11332/* RR ry field for CNVT */
11333enum {
11334 RR_RY_CNVT_ZEB = 0x0,
11335 RR_RY_CNVT_ZEH = 0x1,
11336 RR_RY_CNVT_ZEW = 0x2,
11337 RR_RY_CNVT_SEB = 0x4,
11338 RR_RY_CNVT_SEH = 0x5,
11339 RR_RY_CNVT_SEW = 0x6,
11340};
11341
364d4831
NF
11342static int xlat (int r)
11343{
11344 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11345
11346 return map[r];
11347}
11348
11349static void gen_mips16_save (DisasContext *ctx,
11350 int xsregs, int aregs,
11351 int do_ra, int do_s0, int do_s1,
11352 int framesize)
11353{
11354 TCGv t0 = tcg_temp_new();
11355 TCGv t1 = tcg_temp_new();
c48245f0 11356 TCGv t2 = tcg_temp_new();
364d4831
NF
11357 int args, astatic;
11358
11359 switch (aregs) {
11360 case 0:
11361 case 1:
11362 case 2:
11363 case 3:
11364 case 11:
11365 args = 0;
11366 break;
11367 case 4:
11368 case 5:
11369 case 6:
11370 case 7:
11371 args = 1;
11372 break;
11373 case 8:
11374 case 9:
11375 case 10:
11376 args = 2;
11377 break;
11378 case 12:
11379 case 13:
11380 args = 3;
11381 break;
11382 case 14:
11383 args = 4;
11384 break;
11385 default:
11386 generate_exception(ctx, EXCP_RI);
11387 return;
11388 }
11389
11390 switch (args) {
11391 case 4:
11392 gen_base_offset_addr(ctx, t0, 29, 12);
11393 gen_load_gpr(t1, 7);
5f68f5ae 11394 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11395 /* Fall through */
11396 case 3:
11397 gen_base_offset_addr(ctx, t0, 29, 8);
11398 gen_load_gpr(t1, 6);
5f68f5ae 11399 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11400 /* Fall through */
11401 case 2:
11402 gen_base_offset_addr(ctx, t0, 29, 4);
11403 gen_load_gpr(t1, 5);
5f68f5ae 11404 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11405 /* Fall through */
11406 case 1:
11407 gen_base_offset_addr(ctx, t0, 29, 0);
11408 gen_load_gpr(t1, 4);
5f68f5ae 11409 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11410 }
11411
11412 gen_load_gpr(t0, 29);
11413
5f68f5ae 11414#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11415 tcg_gen_movi_tl(t2, -4); \
11416 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11417 gen_load_gpr(t1, reg); \
11418 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11419 } while (0)
11420
11421 if (do_ra) {
11422 DECR_AND_STORE(31);
11423 }
11424
11425 switch (xsregs) {
11426 case 7:
11427 DECR_AND_STORE(30);
11428 /* Fall through */
11429 case 6:
11430 DECR_AND_STORE(23);
11431 /* Fall through */
11432 case 5:
11433 DECR_AND_STORE(22);
11434 /* Fall through */
11435 case 4:
11436 DECR_AND_STORE(21);
11437 /* Fall through */
11438 case 3:
11439 DECR_AND_STORE(20);
11440 /* Fall through */
11441 case 2:
11442 DECR_AND_STORE(19);
11443 /* Fall through */
11444 case 1:
11445 DECR_AND_STORE(18);
11446 }
11447
11448 if (do_s1) {
11449 DECR_AND_STORE(17);
11450 }
11451 if (do_s0) {
11452 DECR_AND_STORE(16);
11453 }
11454
11455 switch (aregs) {
11456 case 0:
11457 case 4:
11458 case 8:
11459 case 12:
11460 case 14:
11461 astatic = 0;
11462 break;
11463 case 1:
11464 case 5:
11465 case 9:
11466 case 13:
11467 astatic = 1;
11468 break;
11469 case 2:
11470 case 6:
11471 case 10:
11472 astatic = 2;
11473 break;
11474 case 3:
11475 case 7:
11476 astatic = 3;
11477 break;
11478 case 11:
11479 astatic = 4;
11480 break;
11481 default:
11482 generate_exception(ctx, EXCP_RI);
11483 return;
11484 }
11485
11486 if (astatic > 0) {
11487 DECR_AND_STORE(7);
11488 if (astatic > 1) {
11489 DECR_AND_STORE(6);
11490 if (astatic > 2) {
11491 DECR_AND_STORE(5);
11492 if (astatic > 3) {
11493 DECR_AND_STORE(4);
11494 }
11495 }
11496 }
11497 }
11498#undef DECR_AND_STORE
11499
c48245f0
MR
11500 tcg_gen_movi_tl(t2, -framesize);
11501 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11502 tcg_temp_free(t0);
11503 tcg_temp_free(t1);
c48245f0 11504 tcg_temp_free(t2);
364d4831
NF
11505}
11506
11507static void gen_mips16_restore (DisasContext *ctx,
11508 int xsregs, int aregs,
11509 int do_ra, int do_s0, int do_s1,
11510 int framesize)
11511{
11512 int astatic;
11513 TCGv t0 = tcg_temp_new();
11514 TCGv t1 = tcg_temp_new();
c48245f0 11515 TCGv t2 = tcg_temp_new();
364d4831 11516
c48245f0
MR
11517 tcg_gen_movi_tl(t2, framesize);
11518 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11519
5f68f5ae 11520#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11521 tcg_gen_movi_tl(t2, -4); \
11522 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11523 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11524 gen_store_gpr(t1, reg); \
364d4831
NF
11525 } while (0)
11526
11527 if (do_ra) {
11528 DECR_AND_LOAD(31);
11529 }
11530
11531 switch (xsregs) {
11532 case 7:
11533 DECR_AND_LOAD(30);
11534 /* Fall through */
11535 case 6:
11536 DECR_AND_LOAD(23);
11537 /* Fall through */
11538 case 5:
11539 DECR_AND_LOAD(22);
11540 /* Fall through */
11541 case 4:
11542 DECR_AND_LOAD(21);
11543 /* Fall through */
11544 case 3:
11545 DECR_AND_LOAD(20);
11546 /* Fall through */
11547 case 2:
11548 DECR_AND_LOAD(19);
11549 /* Fall through */
11550 case 1:
11551 DECR_AND_LOAD(18);
11552 }
11553
11554 if (do_s1) {
11555 DECR_AND_LOAD(17);
11556 }
11557 if (do_s0) {
11558 DECR_AND_LOAD(16);
11559 }
11560
11561 switch (aregs) {
11562 case 0:
11563 case 4:
11564 case 8:
11565 case 12:
11566 case 14:
11567 astatic = 0;
11568 break;
11569 case 1:
11570 case 5:
11571 case 9:
11572 case 13:
11573 astatic = 1;
11574 break;
11575 case 2:
11576 case 6:
11577 case 10:
11578 astatic = 2;
11579 break;
11580 case 3:
11581 case 7:
11582 astatic = 3;
11583 break;
11584 case 11:
11585 astatic = 4;
11586 break;
11587 default:
11588 generate_exception(ctx, EXCP_RI);
11589 return;
11590 }
11591
11592 if (astatic > 0) {
11593 DECR_AND_LOAD(7);
11594 if (astatic > 1) {
11595 DECR_AND_LOAD(6);
11596 if (astatic > 2) {
11597 DECR_AND_LOAD(5);
11598 if (astatic > 3) {
11599 DECR_AND_LOAD(4);
11600 }
11601 }
11602 }
11603 }
11604#undef DECR_AND_LOAD
11605
c48245f0
MR
11606 tcg_gen_movi_tl(t2, framesize);
11607 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11608 tcg_temp_free(t0);
11609 tcg_temp_free(t1);
c48245f0 11610 tcg_temp_free(t2);
364d4831
NF
11611}
11612
11613static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11614 int is_64_bit, int extended)
11615{
11616 TCGv t0;
11617
11618 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11619 generate_exception(ctx, EXCP_RI);
11620 return;
11621 }
11622
11623 t0 = tcg_temp_new();
11624
11625 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11626 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11627 if (!is_64_bit) {
11628 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11629 }
11630
11631 tcg_temp_free(t0);
11632}
11633
11634#if defined(TARGET_MIPS64)
d75c135e 11635static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11636 int ry, int funct, int16_t offset,
11637 int extended)
11638{
11639 switch (funct) {
11640 case I64_LDSP:
d9224450 11641 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11642 check_mips_64(ctx);
11643 offset = extended ? offset : offset << 3;
d75c135e 11644 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11645 break;
11646 case I64_SDSP:
d9224450 11647 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11648 check_mips_64(ctx);
11649 offset = extended ? offset : offset << 3;
5c13fdfd 11650 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11651 break;
11652 case I64_SDRASP:
d9224450 11653 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11654 check_mips_64(ctx);
11655 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11656 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11657 break;
11658 case I64_DADJSP:
d9224450 11659 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11660 check_mips_64(ctx);
11661 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11662 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11663 break;
11664 case I64_LDPC:
d9224450
MR
11665 check_insn(ctx, ISA_MIPS3);
11666 check_mips_64(ctx);
364d4831
NF
11667 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11668 generate_exception(ctx, EXCP_RI);
11669 } else {
11670 offset = extended ? offset : offset << 3;
d75c135e 11671 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11672 }
11673 break;
11674 case I64_DADDIU5:
d9224450 11675 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11676 check_mips_64(ctx);
11677 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11678 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11679 break;
11680 case I64_DADDIUPC:
d9224450 11681 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11682 check_mips_64(ctx);
11683 offset = extended ? offset : offset << 2;
11684 gen_addiupc(ctx, ry, offset, 1, extended);
11685 break;
11686 case I64_DADDIUSP:
d9224450 11687 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11688 check_mips_64(ctx);
11689 offset = extended ? offset : offset << 2;
d75c135e 11690 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11691 break;
11692 }
11693}
11694#endif
11695
240ce26a 11696static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11697{
895c2d04 11698 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11699 int op, rx, ry, funct, sa;
11700 int16_t imm, offset;
11701
11702 ctx->opcode = (ctx->opcode << 16) | extend;
11703 op = (ctx->opcode >> 11) & 0x1f;
11704 sa = (ctx->opcode >> 22) & 0x1f;
11705 funct = (ctx->opcode >> 8) & 0x7;
11706 rx = xlat((ctx->opcode >> 8) & 0x7);
11707 ry = xlat((ctx->opcode >> 5) & 0x7);
11708 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11709 | ((ctx->opcode >> 21) & 0x3f) << 5
11710 | (ctx->opcode & 0x1f));
11711
11712 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11713 counterparts. */
11714 switch (op) {
11715 case M16_OPC_ADDIUSP:
d75c135e 11716 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11717 break;
11718 case M16_OPC_ADDIUPC:
11719 gen_addiupc(ctx, rx, imm, 0, 1);
11720 break;
11721 case M16_OPC_B:
b231c103 11722 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11723 /* No delay slot, so just process as a normal instruction */
11724 break;
11725 case M16_OPC_BEQZ:
b231c103 11726 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11727 /* No delay slot, so just process as a normal instruction */
11728 break;
11729 case M16_OPC_BNEQZ:
b231c103 11730 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11731 /* No delay slot, so just process as a normal instruction */
11732 break;
11733 case M16_OPC_SHIFT:
11734 switch (ctx->opcode & 0x3) {
11735 case 0x0:
d75c135e 11736 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11737 break;
11738 case 0x1:
11739#if defined(TARGET_MIPS64)
11740 check_mips_64(ctx);
d75c135e 11741 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11742#else
11743 generate_exception(ctx, EXCP_RI);
11744#endif
11745 break;
11746 case 0x2:
d75c135e 11747 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11748 break;
11749 case 0x3:
d75c135e 11750 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11751 break;
11752 }
11753 break;
11754#if defined(TARGET_MIPS64)
11755 case M16_OPC_LD:
d9224450 11756 check_insn(ctx, ISA_MIPS3);
d75de749 11757 check_mips_64(ctx);
d75c135e 11758 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11759 break;
11760#endif
11761 case M16_OPC_RRIA:
11762 imm = ctx->opcode & 0xf;
11763 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11764 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11765 imm = (int16_t) (imm << 1) >> 1;
11766 if ((ctx->opcode >> 4) & 0x1) {
11767#if defined(TARGET_MIPS64)
11768 check_mips_64(ctx);
d75c135e 11769 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11770#else
11771 generate_exception(ctx, EXCP_RI);
11772#endif
11773 } else {
d75c135e 11774 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11775 }
11776 break;
11777 case M16_OPC_ADDIU8:
d75c135e 11778 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11779 break;
11780 case M16_OPC_SLTI:
d75c135e 11781 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11782 break;
11783 case M16_OPC_SLTIU:
d75c135e 11784 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11785 break;
11786 case M16_OPC_I8:
11787 switch (funct) {
11788 case I8_BTEQZ:
b231c103 11789 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11790 break;
11791 case I8_BTNEZ:
b231c103 11792 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11793 break;
11794 case I8_SWRASP:
5c13fdfd 11795 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11796 break;
11797 case I8_ADJSP:
d75c135e 11798 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11799 break;
11800 case I8_SVRS:
d9224450 11801 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11802 {
11803 int xsregs = (ctx->opcode >> 24) & 0x7;
11804 int aregs = (ctx->opcode >> 16) & 0xf;
11805 int do_ra = (ctx->opcode >> 6) & 0x1;
11806 int do_s0 = (ctx->opcode >> 5) & 0x1;
11807 int do_s1 = (ctx->opcode >> 4) & 0x1;
11808 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11809 | (ctx->opcode & 0xf)) << 3;
11810
11811 if (ctx->opcode & (1 << 7)) {
11812 gen_mips16_save(ctx, xsregs, aregs,
11813 do_ra, do_s0, do_s1,
11814 framesize);
11815 } else {
11816 gen_mips16_restore(ctx, xsregs, aregs,
11817 do_ra, do_s0, do_s1,
11818 framesize);
11819 }
11820 }
11821 break;
11822 default:
11823 generate_exception(ctx, EXCP_RI);
11824 break;
11825 }
11826 break;
11827 case M16_OPC_LI:
11828 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11829 break;
11830 case M16_OPC_CMPI:
11831 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11832 break;
11833#if defined(TARGET_MIPS64)
11834 case M16_OPC_SD:
d9224450
MR
11835 check_insn(ctx, ISA_MIPS3);
11836 check_mips_64(ctx);
5c13fdfd 11837 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11838 break;
11839#endif
11840 case M16_OPC_LB:
d75c135e 11841 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11842 break;
11843 case M16_OPC_LH:
d75c135e 11844 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11845 break;
11846 case M16_OPC_LWSP:
d75c135e 11847 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11848 break;
11849 case M16_OPC_LW:
d75c135e 11850 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11851 break;
11852 case M16_OPC_LBU:
d75c135e 11853 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11854 break;
11855 case M16_OPC_LHU:
d75c135e 11856 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11857 break;
11858 case M16_OPC_LWPC:
d75c135e 11859 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11860 break;
11861#if defined(TARGET_MIPS64)
11862 case M16_OPC_LWU:
d9224450
MR
11863 check_insn(ctx, ISA_MIPS3);
11864 check_mips_64(ctx);
d75c135e 11865 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11866 break;
11867#endif
11868 case M16_OPC_SB:
5c13fdfd 11869 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11870 break;
11871 case M16_OPC_SH:
5c13fdfd 11872 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11873 break;
11874 case M16_OPC_SWSP:
5c13fdfd 11875 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11876 break;
11877 case M16_OPC_SW:
5c13fdfd 11878 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11879 break;
11880#if defined(TARGET_MIPS64)
11881 case M16_OPC_I64:
d75c135e 11882 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11883 break;
11884#endif
11885 default:
11886 generate_exception(ctx, EXCP_RI);
11887 break;
11888 }
11889
11890 return 4;
11891}
11892
3b3c1694
LA
11893static inline bool is_uhi(int sdbbp_code)
11894{
11895#ifdef CONFIG_USER_ONLY
11896 return false;
11897#else
11898 return semihosting_enabled() && sdbbp_code == 1;
11899#endif
11900}
11901
240ce26a 11902static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11903{
11904 int rx, ry;
11905 int sa;
11906 int op, cnvt_op, op1, offset;
11907 int funct;
11908 int n_bytes;
11909
11910 op = (ctx->opcode >> 11) & 0x1f;
11911 sa = (ctx->opcode >> 2) & 0x7;
11912 sa = sa == 0 ? 8 : sa;
11913 rx = xlat((ctx->opcode >> 8) & 0x7);
11914 cnvt_op = (ctx->opcode >> 5) & 0x7;
11915 ry = xlat((ctx->opcode >> 5) & 0x7);
11916 op1 = offset = ctx->opcode & 0x1f;
11917
11918 n_bytes = 2;
11919
11920 switch (op) {
11921 case M16_OPC_ADDIUSP:
11922 {
11923 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11924
d75c135e 11925 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11926 }
11927 break;
11928 case M16_OPC_ADDIUPC:
11929 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11930 break;
11931 case M16_OPC_B:
11932 offset = (ctx->opcode & 0x7ff) << 1;
11933 offset = (int16_t)(offset << 4) >> 4;
b231c103 11934 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11935 /* No delay slot, so just process as a normal instruction */
11936 break;
11937 case M16_OPC_JAL:
895c2d04 11938 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11939 offset = (((ctx->opcode & 0x1f) << 21)
11940 | ((ctx->opcode >> 5) & 0x1f) << 16
11941 | offset) << 2;
b231c103
YK
11942 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11943 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11944 n_bytes = 4;
364d4831
NF
11945 break;
11946 case M16_OPC_BEQZ:
b231c103
YK
11947 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11948 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11949 /* No delay slot, so just process as a normal instruction */
11950 break;
11951 case M16_OPC_BNEQZ:
b231c103
YK
11952 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11953 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11954 /* No delay slot, so just process as a normal instruction */
11955 break;
11956 case M16_OPC_SHIFT:
11957 switch (ctx->opcode & 0x3) {
11958 case 0x0:
d75c135e 11959 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11960 break;
11961 case 0x1:
11962#if defined(TARGET_MIPS64)
d9224450 11963 check_insn(ctx, ISA_MIPS3);
364d4831 11964 check_mips_64(ctx);
d75c135e 11965 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11966#else
11967 generate_exception(ctx, EXCP_RI);
11968#endif
11969 break;
11970 case 0x2:
d75c135e 11971 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11972 break;
11973 case 0x3:
d75c135e 11974 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11975 break;
11976 }
11977 break;
11978#if defined(TARGET_MIPS64)
11979 case M16_OPC_LD:
d9224450 11980 check_insn(ctx, ISA_MIPS3);
364d4831 11981 check_mips_64(ctx);
d75c135e 11982 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11983 break;
11984#endif
11985 case M16_OPC_RRIA:
11986 {
11987 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11988
11989 if ((ctx->opcode >> 4) & 1) {
11990#if defined(TARGET_MIPS64)
d9224450 11991 check_insn(ctx, ISA_MIPS3);
364d4831 11992 check_mips_64(ctx);
d75c135e 11993 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11994#else
11995 generate_exception(ctx, EXCP_RI);
11996#endif
11997 } else {
d75c135e 11998 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11999 }
12000 }
12001 break;
12002 case M16_OPC_ADDIU8:
12003 {
12004 int16_t imm = (int8_t) ctx->opcode;
12005
d75c135e 12006 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12007 }
12008 break;
12009 case M16_OPC_SLTI:
12010 {
12011 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12012 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12013 }
12014 break;
12015 case M16_OPC_SLTIU:
12016 {
12017 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12018 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12019 }
12020 break;
12021 case M16_OPC_I8:
12022 {
12023 int reg32;
12024
12025 funct = (ctx->opcode >> 8) & 0x7;
12026 switch (funct) {
12027 case I8_BTEQZ:
12028 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 12029 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12030 break;
12031 case I8_BTNEZ:
12032 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 12033 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12034 break;
12035 case I8_SWRASP:
5c13fdfd 12036 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
12037 break;
12038 case I8_ADJSP:
d75c135e 12039 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
12040 ((int8_t)ctx->opcode) << 3);
12041 break;
12042 case I8_SVRS:
d9224450 12043 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12044 {
12045 int do_ra = ctx->opcode & (1 << 6);
12046 int do_s0 = ctx->opcode & (1 << 5);
12047 int do_s1 = ctx->opcode & (1 << 4);
12048 int framesize = ctx->opcode & 0xf;
12049
12050 if (framesize == 0) {
12051 framesize = 128;
12052 } else {
12053 framesize = framesize << 3;
12054 }
12055
12056 if (ctx->opcode & (1 << 7)) {
12057 gen_mips16_save(ctx, 0, 0,
12058 do_ra, do_s0, do_s1, framesize);
12059 } else {
12060 gen_mips16_restore(ctx, 0, 0,
12061 do_ra, do_s0, do_s1, framesize);
12062 }
12063 }
12064 break;
12065 case I8_MOV32R:
12066 {
12067 int rz = xlat(ctx->opcode & 0x7);
12068
12069 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12070 ((ctx->opcode >> 5) & 0x7);
d75c135e 12071 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
12072 }
12073 break;
12074 case I8_MOVR32:
12075 reg32 = ctx->opcode & 0x1f;
d75c135e 12076 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
12077 break;
12078 default:
12079 generate_exception(ctx, EXCP_RI);
12080 break;
12081 }
12082 }
12083 break;
12084 case M16_OPC_LI:
12085 {
12086 int16_t imm = (uint8_t) ctx->opcode;
12087
d75c135e 12088 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12089 }
12090 break;
12091 case M16_OPC_CMPI:
12092 {
12093 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12094 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12095 }
12096 break;
12097#if defined(TARGET_MIPS64)
12098 case M16_OPC_SD:
d9224450 12099 check_insn(ctx, ISA_MIPS3);
364d4831 12100 check_mips_64(ctx);
5c13fdfd 12101 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12102 break;
12103#endif
12104 case M16_OPC_LB:
d75c135e 12105 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12106 break;
12107 case M16_OPC_LH:
d75c135e 12108 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12109 break;
12110 case M16_OPC_LWSP:
d75c135e 12111 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12112 break;
12113 case M16_OPC_LW:
d75c135e 12114 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12115 break;
12116 case M16_OPC_LBU:
d75c135e 12117 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12118 break;
12119 case M16_OPC_LHU:
d75c135e 12120 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12121 break;
12122 case M16_OPC_LWPC:
d75c135e 12123 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12124 break;
12125#if defined (TARGET_MIPS64)
12126 case M16_OPC_LWU:
d9224450 12127 check_insn(ctx, ISA_MIPS3);
364d4831 12128 check_mips_64(ctx);
d75c135e 12129 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12130 break;
12131#endif
12132 case M16_OPC_SB:
5c13fdfd 12133 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12134 break;
12135 case M16_OPC_SH:
5c13fdfd 12136 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12137 break;
12138 case M16_OPC_SWSP:
5c13fdfd 12139 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12140 break;
12141 case M16_OPC_SW:
5c13fdfd 12142 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12143 break;
12144 case M16_OPC_RRR:
12145 {
12146 int rz = xlat((ctx->opcode >> 2) & 0x7);
12147 int mips32_op;
12148
12149 switch (ctx->opcode & 0x3) {
12150 case RRR_ADDU:
12151 mips32_op = OPC_ADDU;
12152 break;
12153 case RRR_SUBU:
12154 mips32_op = OPC_SUBU;
12155 break;
12156#if defined(TARGET_MIPS64)
12157 case RRR_DADDU:
12158 mips32_op = OPC_DADDU;
d9224450 12159 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12160 check_mips_64(ctx);
12161 break;
12162 case RRR_DSUBU:
12163 mips32_op = OPC_DSUBU;
d9224450 12164 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12165 check_mips_64(ctx);
12166 break;
12167#endif
12168 default:
12169 generate_exception(ctx, EXCP_RI);
12170 goto done;
12171 }
12172
d75c135e 12173 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12174 done:
12175 ;
12176 }
12177 break;
12178 case M16_OPC_RR:
12179 switch (op1) {
12180 case RR_JR:
12181 {
12182 int nd = (ctx->opcode >> 7) & 0x1;
12183 int link = (ctx->opcode >> 6) & 0x1;
12184 int ra = (ctx->opcode >> 5) & 0x1;
12185
d9224450
MR
12186 if (nd) {
12187 check_insn(ctx, ISA_MIPS32);
12188 }
12189
364d4831 12190 if (link) {
b231c103 12191 op = OPC_JALR;
364d4831
NF
12192 } else {
12193 op = OPC_JR;
12194 }
12195
b231c103
YK
12196 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12197 (nd ? 0 : 2));
364d4831
NF
12198 }
12199 break;
12200 case RR_SDBBP:
3b3c1694
LA
12201 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12202 gen_helper_do_semihosting(cpu_env);
12203 } else {
12204 /* XXX: not clear which exception should be raised
12205 * when in debug mode...
12206 */
12207 check_insn(ctx, ISA_MIPS32);
12208 generate_exception(ctx, EXCP_DBp);
12209 }
364d4831
NF
12210 break;
12211 case RR_SLT:
d75c135e 12212 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12213 break;
12214 case RR_SLTU:
d75c135e 12215 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12216 break;
12217 case RR_BREAK:
12218 generate_exception(ctx, EXCP_BREAK);
12219 break;
12220 case RR_SLLV:
d75c135e 12221 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12222 break;
12223 case RR_SRLV:
d75c135e 12224 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12225 break;
12226 case RR_SRAV:
d75c135e 12227 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12228 break;
12229#if defined (TARGET_MIPS64)
12230 case RR_DSRL:
d9224450 12231 check_insn(ctx, ISA_MIPS3);
364d4831 12232 check_mips_64(ctx);
d75c135e 12233 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12234 break;
12235#endif
12236 case RR_CMP:
d75c135e 12237 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12238 break;
12239 case RR_NEG:
d75c135e 12240 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12241 break;
12242 case RR_AND:
d75c135e 12243 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12244 break;
12245 case RR_OR:
d75c135e 12246 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12247 break;
12248 case RR_XOR:
d75c135e 12249 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12250 break;
12251 case RR_NOT:
d75c135e 12252 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12253 break;
12254 case RR_MFHI:
26135ead 12255 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12256 break;
12257 case RR_CNVT:
d9224450 12258 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12259 switch (cnvt_op) {
12260 case RR_RY_CNVT_ZEB:
12261 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12262 break;
12263 case RR_RY_CNVT_ZEH:
12264 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12265 break;
12266 case RR_RY_CNVT_SEB:
12267 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12268 break;
12269 case RR_RY_CNVT_SEH:
12270 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12271 break;
12272#if defined (TARGET_MIPS64)
12273 case RR_RY_CNVT_ZEW:
d9224450 12274 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12275 check_mips_64(ctx);
12276 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12277 break;
12278 case RR_RY_CNVT_SEW:
d9224450 12279 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12280 check_mips_64(ctx);
12281 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12282 break;
12283#endif
12284 default:
12285 generate_exception(ctx, EXCP_RI);
12286 break;
12287 }
12288 break;
12289 case RR_MFLO:
26135ead 12290 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12291 break;
12292#if defined (TARGET_MIPS64)
12293 case RR_DSRA:
d9224450 12294 check_insn(ctx, ISA_MIPS3);
364d4831 12295 check_mips_64(ctx);
d75c135e 12296 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12297 break;
12298 case RR_DSLLV:
d9224450 12299 check_insn(ctx, ISA_MIPS3);
364d4831 12300 check_mips_64(ctx);
d75c135e 12301 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12302 break;
12303 case RR_DSRLV:
d9224450 12304 check_insn(ctx, ISA_MIPS3);
364d4831 12305 check_mips_64(ctx);
d75c135e 12306 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12307 break;
12308 case RR_DSRAV:
d9224450 12309 check_insn(ctx, ISA_MIPS3);
364d4831 12310 check_mips_64(ctx);
d75c135e 12311 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12312 break;
12313#endif
12314 case RR_MULT:
26135ead 12315 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12316 break;
12317 case RR_MULTU:
26135ead 12318 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12319 break;
12320 case RR_DIV:
26135ead 12321 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12322 break;
12323 case RR_DIVU:
26135ead 12324 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12325 break;
12326#if defined (TARGET_MIPS64)
12327 case RR_DMULT:
d9224450 12328 check_insn(ctx, ISA_MIPS3);
364d4831 12329 check_mips_64(ctx);
26135ead 12330 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12331 break;
12332 case RR_DMULTU:
d9224450 12333 check_insn(ctx, ISA_MIPS3);
364d4831 12334 check_mips_64(ctx);
26135ead 12335 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12336 break;
12337 case RR_DDIV:
d9224450 12338 check_insn(ctx, ISA_MIPS3);
364d4831 12339 check_mips_64(ctx);
26135ead 12340 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12341 break;
12342 case RR_DDIVU:
d9224450 12343 check_insn(ctx, ISA_MIPS3);
364d4831 12344 check_mips_64(ctx);
26135ead 12345 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12346 break;
12347#endif
12348 default:
12349 generate_exception(ctx, EXCP_RI);
12350 break;
12351 }
12352 break;
12353 case M16_OPC_EXTEND:
240ce26a 12354 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12355 n_bytes = 4;
12356 break;
12357#if defined(TARGET_MIPS64)
12358 case M16_OPC_I64:
12359 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12360 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12361 break;
12362#endif
12363 default:
12364 generate_exception(ctx, EXCP_RI);
12365 break;
12366 }
12367
12368 return n_bytes;
12369}
12370
211da992 12371/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12372
211da992
CWR
12373/*
12374 * microMIPS32/microMIPS64 major opcodes
12375 *
12376 * 1. MIPS Architecture for Programmers Volume II-B:
12377 * The microMIPS32 Instruction Set (Revision 3.05)
12378 *
12379 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12380 *
12381 * 2. MIPS Architecture For Programmers Volume II-A:
12382 * The MIPS64 Instruction Set (Revision 3.51)
12383 */
6af0bf9c 12384
3c824109
NF
12385enum {
12386 POOL32A = 0x00,
12387 POOL16A = 0x01,
12388 LBU16 = 0x02,
12389 MOVE16 = 0x03,
12390 ADDI32 = 0x04,
3a1f4268
YK
12391 R6_LUI = 0x04,
12392 AUI = 0x04,
3c824109
NF
12393 LBU32 = 0x05,
12394 SB32 = 0x06,
12395 LB32 = 0x07,
12396
12397 POOL32B = 0x08,
12398 POOL16B = 0x09,
12399 LHU16 = 0x0a,
12400 ANDI16 = 0x0b,
12401 ADDIU32 = 0x0c,
12402 LHU32 = 0x0d,
12403 SH32 = 0x0e,
12404 LH32 = 0x0f,
12405
12406 POOL32I = 0x10,
12407 POOL16C = 0x11,
12408 LWSP16 = 0x12,
12409 POOL16D = 0x13,
12410 ORI32 = 0x14,
12411 POOL32F = 0x15,
211da992
CWR
12412 POOL32S = 0x16, /* MIPS64 */
12413 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12414
12415 POOL32C = 0x18,
12416 LWGP16 = 0x19,
12417 LW16 = 0x1a,
12418 POOL16E = 0x1b,
12419 XORI32 = 0x1c,
12420 JALS32 = 0x1d,
3a1f4268
YK
12421 BOVC = 0x1d,
12422 BEQC = 0x1d,
12423 BEQZALC = 0x1d,
3c824109 12424 ADDIUPC = 0x1e,
3a1f4268
YK
12425 PCREL = 0x1e,
12426 BNVC = 0x1f,
12427 BNEC = 0x1f,
12428 BNEZALC = 0x1f,
3c824109 12429
3a1f4268
YK
12430 R6_BEQZC = 0x20,
12431 JIC = 0x20,
3c824109
NF
12432 POOL16F = 0x21,
12433 SB16 = 0x22,
12434 BEQZ16 = 0x23,
3a1f4268 12435 BEQZC16 = 0x23,
3c824109
NF
12436 SLTI32 = 0x24,
12437 BEQ32 = 0x25,
3a1f4268 12438 BC = 0x25,
3c824109
NF
12439 SWC132 = 0x26,
12440 LWC132 = 0x27,
12441
3a1f4268 12442 /* 0x29 is reserved */
3c824109 12443 RES_29 = 0x29,
3a1f4268
YK
12444 R6_BNEZC = 0x28,
12445 JIALC = 0x28,
3c824109
NF
12446 SH16 = 0x2a,
12447 BNEZ16 = 0x2b,
3a1f4268 12448 BNEZC16 = 0x2b,
3c824109
NF
12449 SLTIU32 = 0x2c,
12450 BNE32 = 0x2d,
3a1f4268 12451 BALC = 0x2d,
3c824109
NF
12452 SDC132 = 0x2e,
12453 LDC132 = 0x2f,
12454
3a1f4268 12455 /* 0x31 is reserved */
3c824109 12456 RES_31 = 0x31,
3a1f4268
YK
12457 BLEZALC = 0x30,
12458 BGEZALC = 0x30,
12459 BGEUC = 0x30,
3c824109
NF
12460 SWSP16 = 0x32,
12461 B16 = 0x33,
3a1f4268 12462 BC16 = 0x33,
3c824109
NF
12463 ANDI32 = 0x34,
12464 J32 = 0x35,
3a1f4268
YK
12465 BGTZC = 0x35,
12466 BLTZC = 0x35,
12467 BLTC = 0x35,
211da992
CWR
12468 SD32 = 0x36, /* MIPS64 */
12469 LD32 = 0x37, /* MIPS64 */
3c824109 12470
3a1f4268 12471 /* 0x39 is reserved */
3c824109 12472 RES_39 = 0x39,
3a1f4268
YK
12473 BGTZALC = 0x38,
12474 BLTZALC = 0x38,
12475 BLTUC = 0x38,
3c824109
NF
12476 SW16 = 0x3a,
12477 LI16 = 0x3b,
12478 JALX32 = 0x3c,
12479 JAL32 = 0x3d,
3a1f4268
YK
12480 BLEZC = 0x3d,
12481 BGEZC = 0x3d,
12482 BGEC = 0x3d,
3c824109
NF
12483 SW32 = 0x3e,
12484 LW32 = 0x3f
12485};
12486
3a1f4268
YK
12487/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12488enum {
12489 ADDIUPC_00 = 0x00,
12490 ADDIUPC_07 = 0x07,
12491 AUIPC = 0x1e,
12492 ALUIPC = 0x1f,
12493 LWPC_08 = 0x08,
12494 LWPC_0F = 0x0F,
12495};
12496
3c824109
NF
12497/* POOL32A encoding of minor opcode field */
12498
12499enum {
12500 /* These opcodes are distinguished only by bits 9..6; those bits are
12501 * what are recorded below. */
12502 SLL32 = 0x0,
12503 SRL32 = 0x1,
12504 SRA = 0x2,
12505 ROTR = 0x3,
3a1f4268
YK
12506 SELEQZ = 0x5,
12507 SELNEZ = 0x6,
3c824109
NF
12508
12509 SLLV = 0x0,
12510 SRLV = 0x1,
12511 SRAV = 0x2,
12512 ROTRV = 0x3,
12513 ADD = 0x4,
12514 ADDU32 = 0x5,
12515 SUB = 0x6,
12516 SUBU32 = 0x7,
12517 MUL = 0x8,
12518 AND = 0x9,
12519 OR32 = 0xa,
12520 NOR = 0xb,
12521 XOR32 = 0xc,
12522 SLT = 0xd,
12523 SLTU = 0xe,
12524
12525 MOVN = 0x0,
3a1f4268 12526 R6_MUL = 0x0,
3c824109 12527 MOVZ = 0x1,
3a1f4268
YK
12528 MUH = 0x1,
12529 MULU = 0x2,
12530 MUHU = 0x3,
3c824109 12531 LWXS = 0x4,
3a1f4268
YK
12532 R6_DIV = 0x4,
12533 MOD = 0x5,
12534 R6_DIVU = 0x6,
12535 MODU = 0x7,
3c824109
NF
12536
12537 /* The following can be distinguished by their lower 6 bits. */
12538 INS = 0x0c,
3a1f4268
YK
12539 LSA = 0x0f,
12540 ALIGN = 0x1f,
3c824109
NF
12541 EXT = 0x2c,
12542 POOL32AXF = 0x3c
12543};
12544
12545/* POOL32AXF encoding of minor opcode field extension */
12546
d132c79f
CWR
12547/*
12548 * 1. MIPS Architecture for Programmers Volume II-B:
12549 * The microMIPS32 Instruction Set (Revision 3.05)
12550 *
12551 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12552 *
12553 * 2. MIPS Architecture for Programmers VolumeIV-e:
12554 * The MIPS DSP Application-Specific Extension
12555 * to the microMIPS32 Architecture (Revision 2.34)
12556 *
12557 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12558 */
12559
3c824109
NF
12560enum {
12561 /* bits 11..6 */
12562 TEQ = 0x00,
12563 TGE = 0x08,
12564 TGEU = 0x10,
12565 TLT = 0x20,
12566 TLTU = 0x28,
12567 TNE = 0x30,
12568
12569 MFC0 = 0x03,
12570 MTC0 = 0x0b,
12571
d132c79f
CWR
12572 /* begin of microMIPS32 DSP */
12573
3c824109
NF
12574 /* bits 13..12 for 0x01 */
12575 MFHI_ACC = 0x0,
12576 MFLO_ACC = 0x1,
12577 MTHI_ACC = 0x2,
12578 MTLO_ACC = 0x3,
12579
12580 /* bits 13..12 for 0x2a */
12581 MADD_ACC = 0x0,
12582 MADDU_ACC = 0x1,
12583 MSUB_ACC = 0x2,
12584 MSUBU_ACC = 0x3,
12585
12586 /* bits 13..12 for 0x32 */
12587 MULT_ACC = 0x0,
6801038b 12588 MULTU_ACC = 0x1,
3c824109 12589
d132c79f
CWR
12590 /* end of microMIPS32 DSP */
12591
3c824109 12592 /* bits 15..12 for 0x2c */
3a1f4268 12593 BITSWAP = 0x0,
3c824109
NF
12594 SEB = 0x2,
12595 SEH = 0x3,
12596 CLO = 0x4,
12597 CLZ = 0x5,
12598 RDHWR = 0x6,
12599 WSBH = 0x7,
12600 MULT = 0x8,
12601 MULTU = 0x9,
12602 DIV = 0xa,
12603 DIVU = 0xb,
12604 MADD = 0xc,
12605 MADDU = 0xd,
12606 MSUB = 0xe,
12607 MSUBU = 0xf,
12608
12609 /* bits 15..12 for 0x34 */
12610 MFC2 = 0x4,
12611 MTC2 = 0x5,
12612 MFHC2 = 0x8,
12613 MTHC2 = 0x9,
12614 CFC2 = 0xc,
12615 CTC2 = 0xd,
12616
12617 /* bits 15..12 for 0x3c */
12618 JALR = 0x0,
12619 JR = 0x0, /* alias */
3a1f4268
YK
12620 JALRC = 0x0,
12621 JRC = 0x0,
3c824109 12622 JALR_HB = 0x1,
3a1f4268 12623 JALRC_HB = 0x1,
3c824109
NF
12624 JALRS = 0x4,
12625 JALRS_HB = 0x5,
12626
12627 /* bits 15..12 for 0x05 */
12628 RDPGPR = 0xe,
12629 WRPGPR = 0xf,
12630
12631 /* bits 15..12 for 0x0d */
12632 TLBP = 0x0,
12633 TLBR = 0x1,
12634 TLBWI = 0x2,
12635 TLBWR = 0x3,
e60ec063
YK
12636 TLBINV = 0x4,
12637 TLBINVF = 0x5,
3c824109
NF
12638 WAIT = 0x9,
12639 IRET = 0xd,
12640 DERET = 0xe,
12641 ERET = 0xf,
12642
12643 /* bits 15..12 for 0x15 */
12644 DMT = 0x0,
12645 DVPE = 0x1,
12646 EMT = 0x2,
12647 EVPE = 0x3,
12648
12649 /* bits 15..12 for 0x1d */
12650 DI = 0x4,
12651 EI = 0x5,
12652
12653 /* bits 15..12 for 0x2d */
12654 SYNC = 0x6,
12655 SYSCALL = 0x8,
12656 SDBBP = 0xd,
12657
12658 /* bits 15..12 for 0x35 */
12659 MFHI32 = 0x0,
12660 MFLO32 = 0x1,
12661 MTHI32 = 0x2,
12662 MTLO32 = 0x3,
12663};
12664
12665/* POOL32B encoding of minor opcode field (bits 15..12) */
12666
12667enum {
12668 LWC2 = 0x0,
12669 LWP = 0x1,
12670 LDP = 0x4,
12671 LWM32 = 0x5,
12672 CACHE = 0x6,
12673 LDM = 0x7,
12674 SWC2 = 0x8,
12675 SWP = 0x9,
12676 SDP = 0xc,
12677 SWM32 = 0xd,
12678 SDM = 0xf
12679};
12680
12681/* POOL32C encoding of minor opcode field (bits 15..12) */
12682
12683enum {
12684 LWL = 0x0,
12685 SWL = 0x8,
12686 LWR = 0x1,
12687 SWR = 0x9,
12688 PREF = 0x2,
12689 /* 0xa is reserved */
12690 LL = 0x3,
12691 SC = 0xb,
12692 LDL = 0x4,
12693 SDL = 0xc,
12694 LDR = 0x5,
12695 SDR = 0xd,
12696 /* 0x6 is reserved */
12697 LWU = 0xe,
12698 LLD = 0x7,
12699 SCD = 0xf
12700};
12701
12702/* POOL32F encoding of minor opcode field (bits 5..0) */
12703
12704enum {
12705 /* These are the bit 7..6 values */
12706 ADD_FMT = 0x0,
3c824109
NF
12707
12708 SUB_FMT = 0x1,
3c824109
NF
12709
12710 MUL_FMT = 0x2,
12711
12712 DIV_FMT = 0x3,
12713
12714 /* These are the bit 8..6 values */
3a1f4268 12715 MOVN_FMT = 0x0,
3c824109
NF
12716 RSQRT2_FMT = 0x0,
12717 MOVF_FMT = 0x0,
3a1f4268
YK
12718 RINT_FMT = 0x0,
12719 SELNEZ_FMT = 0x0,
3c824109 12720
3a1f4268 12721 MOVZ_FMT = 0x1,
3c824109
NF
12722 LWXC1 = 0x1,
12723 MOVT_FMT = 0x1,
3a1f4268
YK
12724 CLASS_FMT = 0x1,
12725 SELEQZ_FMT = 0x1,
3c824109
NF
12726
12727 PLL_PS = 0x2,
12728 SWXC1 = 0x2,
3a1f4268 12729 SEL_FMT = 0x2,
3c824109
NF
12730
12731 PLU_PS = 0x3,
12732 LDXC1 = 0x3,
12733
3a1f4268 12734 MOVN_FMT_04 = 0x4,
3c824109
NF
12735 PUL_PS = 0x4,
12736 SDXC1 = 0x4,
12737 RECIP2_FMT = 0x4,
12738
3a1f4268 12739 MOVZ_FMT_05 = 0x05,
3c824109
NF
12740 PUU_PS = 0x5,
12741 LUXC1 = 0x5,
12742
12743 CVT_PS_S = 0x6,
12744 SUXC1 = 0x6,
12745 ADDR_PS = 0x6,
12746 PREFX = 0x6,
3a1f4268 12747 MADDF_FMT = 0x6,
3c824109
NF
12748
12749 MULR_PS = 0x7,
3a1f4268 12750 MSUBF_FMT = 0x7,
3c824109
NF
12751
12752 MADD_S = 0x01,
12753 MADD_D = 0x09,
12754 MADD_PS = 0x11,
12755 ALNV_PS = 0x19,
12756 MSUB_S = 0x21,
12757 MSUB_D = 0x29,
12758 MSUB_PS = 0x31,
12759
12760 NMADD_S = 0x02,
12761 NMADD_D = 0x0a,
12762 NMADD_PS = 0x12,
12763 NMSUB_S = 0x22,
12764 NMSUB_D = 0x2a,
12765 NMSUB_PS = 0x32,
12766
3a1f4268
YK
12767 MIN_FMT = 0x3,
12768 MAX_FMT = 0xb,
12769 MINA_FMT = 0x23,
12770 MAXA_FMT = 0x2b,
3c824109
NF
12771 POOL32FXF = 0x3b,
12772
12773 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12774 C_COND_FMT = 0x3c,
12775
12776 CMP_CONDN_S = 0x5,
12777 CMP_CONDN_D = 0x15
3c824109
NF
12778};
12779
12780/* POOL32Fxf encoding of minor opcode extension field */
12781
12782enum {
12783 CVT_L = 0x04,
12784 RSQRT_FMT = 0x08,
12785 FLOOR_L = 0x0c,
12786 CVT_PW_PS = 0x1c,
12787 CVT_W = 0x24,
12788 SQRT_FMT = 0x28,
12789 FLOOR_W = 0x2c,
12790 CVT_PS_PW = 0x3c,
12791 CFC1 = 0x40,
12792 RECIP_FMT = 0x48,
12793 CEIL_L = 0x4c,
12794 CTC1 = 0x60,
12795 CEIL_W = 0x6c,
12796 MFC1 = 0x80,
12797 CVT_S_PL = 0x84,
12798 TRUNC_L = 0x8c,
12799 MTC1 = 0xa0,
12800 CVT_S_PU = 0xa4,
12801 TRUNC_W = 0xac,
12802 MFHC1 = 0xc0,
12803 ROUND_L = 0xcc,
12804 MTHC1 = 0xe0,
12805 ROUND_W = 0xec,
12806
12807 MOV_FMT = 0x01,
12808 MOVF = 0x05,
12809 ABS_FMT = 0x0d,
12810 RSQRT1_FMT = 0x1d,
12811 MOVT = 0x25,
12812 NEG_FMT = 0x2d,
12813 CVT_D = 0x4d,
12814 RECIP1_FMT = 0x5d,
12815 CVT_S = 0x6d
12816};
12817
12818/* POOL32I encoding of minor opcode field (bits 25..21) */
12819
12820enum {
12821 BLTZ = 0x00,
12822 BLTZAL = 0x01,
12823 BGEZ = 0x02,
12824 BGEZAL = 0x03,
12825 BLEZ = 0x04,
12826 BNEZC = 0x05,
12827 BGTZ = 0x06,
12828 BEQZC = 0x07,
12829 TLTI = 0x08,
3a1f4268 12830 BC1EQZC = 0x08,
3c824109 12831 TGEI = 0x09,
3a1f4268 12832 BC1NEZC = 0x09,
3c824109 12833 TLTIU = 0x0a,
3a1f4268 12834 BC2EQZC = 0x0a,
3c824109 12835 TGEIU = 0x0b,
3a1f4268 12836 BC2NEZC = 0x0a,
3c824109 12837 TNEI = 0x0c,
3a1f4268 12838 R6_SYNCI = 0x0c,
3c824109
NF
12839 LUI = 0x0d,
12840 TEQI = 0x0e,
12841 SYNCI = 0x10,
12842 BLTZALS = 0x11,
12843 BGEZALS = 0x13,
12844 BC2F = 0x14,
12845 BC2T = 0x15,
12846 BPOSGE64 = 0x1a,
12847 BPOSGE32 = 0x1b,
12848 /* These overlap and are distinguished by bit16 of the instruction */
12849 BC1F = 0x1c,
12850 BC1T = 0x1d,
12851 BC1ANY2F = 0x1c,
12852 BC1ANY2T = 0x1d,
12853 BC1ANY4F = 0x1e,
12854 BC1ANY4T = 0x1f
12855};
12856
12857/* POOL16A encoding of minor opcode field */
12858
12859enum {
12860 ADDU16 = 0x0,
12861 SUBU16 = 0x1
12862};
12863
12864/* POOL16B encoding of minor opcode field */
12865
12866enum {
12867 SLL16 = 0x0,
12868 SRL16 = 0x1
12869};
12870
12871/* POOL16C encoding of minor opcode field */
12872
12873enum {
12874 NOT16 = 0x00,
12875 XOR16 = 0x04,
12876 AND16 = 0x08,
12877 OR16 = 0x0c,
12878 LWM16 = 0x10,
12879 SWM16 = 0x14,
12880 JR16 = 0x18,
12881 JRC16 = 0x1a,
12882 JALR16 = 0x1c,
12883 JALR16S = 0x1e,
12884 MFHI16 = 0x20,
12885 MFLO16 = 0x24,
12886 BREAK16 = 0x28,
12887 SDBBP16 = 0x2c,
12888 JRADDIUSP = 0x30
12889};
12890
3a1f4268
YK
12891/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12892
12893enum {
12894 R6_NOT16 = 0x00,
12895 R6_AND16 = 0x01,
12896 R6_LWM16 = 0x02,
12897 R6_JRC16 = 0x03,
12898 MOVEP = 0x04,
12899 MOVEP_07 = 0x07,
12900 R6_XOR16 = 0x08,
12901 R6_OR16 = 0x09,
12902 R6_SWM16 = 0x0a,
12903 JALRC16 = 0x0b,
12904 MOVEP_0C = 0x0c,
12905 MOVEP_0F = 0x0f,
12906 JRCADDIUSP = 0x13,
12907 R6_BREAK16 = 0x1b,
12908 R6_SDBBP16 = 0x3b
12909};
12910
3c824109
NF
12911/* POOL16D encoding of minor opcode field */
12912
12913enum {
12914 ADDIUS5 = 0x0,
12915 ADDIUSP = 0x1
12916};
12917
12918/* POOL16E encoding of minor opcode field */
12919
12920enum {
12921 ADDIUR2 = 0x0,
12922 ADDIUR1SP = 0x1
12923};
12924
12925static int mmreg (int r)
12926{
12927 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12928
12929 return map[r];
12930}
12931
12932/* Used for 16-bit store instructions. */
12933static int mmreg2 (int r)
12934{
12935 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12936
12937 return map[r];
12938}
12939
12940#define uMIPS_RD(op) ((op >> 7) & 0x7)
12941#define uMIPS_RS(op) ((op >> 4) & 0x7)
12942#define uMIPS_RS2(op) uMIPS_RS(op)
12943#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12944#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12945#define uMIPS_RS5(op) (op & 0x1f)
12946
12947/* Signed immediate */
12948#define SIMM(op, start, width) \
12949 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12950 << (32-width)) \
12951 >> (32-width))
12952/* Zero-extended immediate */
12953#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12954
d75c135e 12955static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12956{
12957 int rd = mmreg(uMIPS_RD(ctx->opcode));
12958
d75c135e 12959 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12960}
12961
d75c135e 12962static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12963{
12964 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12965 int rd = mmreg(uMIPS_RD(ctx->opcode));
12966 int rs = mmreg(uMIPS_RS(ctx->opcode));
12967
d75c135e 12968 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12969}
12970
d75c135e 12971static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12972{
12973 int encoded = ZIMM(ctx->opcode, 1, 9);
12974 int decoded;
12975
12976 if (encoded <= 1) {
12977 decoded = 256 + encoded;
12978 } else if (encoded <= 255) {
12979 decoded = encoded;
12980 } else if (encoded <= 509) {
12981 decoded = encoded - 512;
12982 } else {
12983 decoded = encoded - 768;
12984 }
12985
d75c135e 12986 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12987}
12988
d75c135e 12989static void gen_addius5(DisasContext *ctx)
3c824109
NF
12990{
12991 int imm = SIMM(ctx->opcode, 1, 4);
12992 int rd = (ctx->opcode >> 5) & 0x1f;
12993
d75c135e 12994 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12995}
12996
d75c135e 12997static void gen_andi16(DisasContext *ctx)
3c824109
NF
12998{
12999 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13000 31, 32, 63, 64, 255, 32768, 65535 };
13001 int rd = mmreg(uMIPS_RD(ctx->opcode));
13002 int rs = mmreg(uMIPS_RS(ctx->opcode));
13003 int encoded = ZIMM(ctx->opcode, 0, 4);
13004
d75c135e 13005 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
13006}
13007
13008static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13009 int base, int16_t offset)
13010{
e1050a76 13011 const char *opn = "ldst_multiple";
3c824109
NF
13012 TCGv t0, t1;
13013 TCGv_i32 t2;
13014
13015 if (ctx->hflags & MIPS_HFLAG_BMASK) {
13016 generate_exception(ctx, EXCP_RI);
13017 return;
13018 }
13019
13020 t0 = tcg_temp_new();
13021
13022 gen_base_offset_addr(ctx, t0, base, offset);
13023
13024 t1 = tcg_const_tl(reglist);
13025 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 13026
3c824109
NF
13027 save_cpu_state(ctx, 1);
13028 switch (opc) {
13029 case LWM32:
895c2d04 13030 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 13031 opn = "lwm";
3c824109
NF
13032 break;
13033 case SWM32:
895c2d04 13034 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 13035 opn = "swm";
3c824109
NF
13036 break;
13037#ifdef TARGET_MIPS64
13038 case LDM:
895c2d04 13039 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 13040 opn = "ldm";
3c824109
NF
13041 break;
13042 case SDM:
895c2d04 13043 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 13044 opn = "sdm";
3c824109 13045 break;
6af0bf9c 13046#endif
3c824109 13047 }
e1050a76 13048 (void)opn;
3c824109
NF
13049 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
13050 tcg_temp_free(t0);
33087598 13051 tcg_temp_free(t1);
3c824109
NF
13052 tcg_temp_free_i32(t2);
13053}
6af0bf9c 13054
3c824109 13055
240ce26a 13056static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 13057{
3c824109
NF
13058 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13059 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 13060
3c824109
NF
13061 switch (((ctx->opcode) >> 4) & 0x3f) {
13062 case NOT16 + 0:
13063 case NOT16 + 1:
13064 case NOT16 + 2:
13065 case NOT16 + 3:
d75c135e 13066 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13067 break;
13068 case XOR16 + 0:
13069 case XOR16 + 1:
13070 case XOR16 + 2:
13071 case XOR16 + 3:
d75c135e 13072 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13073 break;
13074 case AND16 + 0:
13075 case AND16 + 1:
13076 case AND16 + 2:
13077 case AND16 + 3:
d75c135e 13078 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13079 break;
13080 case OR16 + 0:
13081 case OR16 + 1:
13082 case OR16 + 2:
13083 case OR16 + 3:
d75c135e 13084 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13085 break;
13086 case LWM16 + 0:
13087 case LWM16 + 1:
13088 case LWM16 + 2:
13089 case LWM16 + 3:
13090 {
13091 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13092 int offset = ZIMM(ctx->opcode, 0, 4);
13093
13094 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13095 29, offset << 2);
13096 }
13097 break;
13098 case SWM16 + 0:
13099 case SWM16 + 1:
13100 case SWM16 + 2:
13101 case SWM16 + 3:
13102 {
13103 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13104 int offset = ZIMM(ctx->opcode, 0, 4);
13105
13106 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13107 29, offset << 2);
13108 }
13109 break;
13110 case JR16 + 0:
13111 case JR16 + 1:
13112 {
13113 int reg = ctx->opcode & 0x1f;
13114
b231c103 13115 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13116 }
3c824109
NF
13117 break;
13118 case JRC16 + 0:
13119 case JRC16 + 1:
13120 {
13121 int reg = ctx->opcode & 0x1f;
b231c103 13122 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13123 /* Let normal delay slot handling in our caller take us
13124 to the branch target. */
13125 }
13126 break;
13127 case JALR16 + 0:
13128 case JALR16 + 1:
b231c103
YK
13129 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13130 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13131 break;
3c824109
NF
13132 case JALR16S + 0:
13133 case JALR16S + 1:
b231c103
YK
13134 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13135 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13136 break;
13137 case MFHI16 + 0:
13138 case MFHI16 + 1:
26135ead 13139 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13140 break;
13141 case MFLO16 + 0:
13142 case MFLO16 + 1:
26135ead 13143 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13144 break;
13145 case BREAK16:
13146 generate_exception(ctx, EXCP_BREAK);
13147 break;
13148 case SDBBP16:
3b3c1694
LA
13149 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13150 gen_helper_do_semihosting(cpu_env);
13151 } else {
13152 /* XXX: not clear which exception should be raised
13153 * when in debug mode...
13154 */
13155 check_insn(ctx, ISA_MIPS32);
13156 generate_exception(ctx, EXCP_DBp);
13157 }
3c824109
NF
13158 break;
13159 case JRADDIUSP + 0:
13160 case JRADDIUSP + 1:
13161 {
13162 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13163 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13164 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13165 /* Let normal delay slot handling in our caller take us
13166 to the branch target. */
13167 }
13168 break;
13169 default:
13170 generate_exception(ctx, EXCP_RI);
13171 break;
13172 }
13173}
13174
13175static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13176{
13177 TCGv t0 = tcg_temp_new();
13178 TCGv t1 = tcg_temp_new();
13179
13180 gen_load_gpr(t0, base);
13181
13182 if (index != 0) {
13183 gen_load_gpr(t1, index);
13184 tcg_gen_shli_tl(t1, t1, 2);
13185 gen_op_addr_add(ctx, t0, t1, t0);
13186 }
13187
5f68f5ae 13188 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13189 gen_store_gpr(t1, rd);
13190
13191 tcg_temp_free(t0);
13192 tcg_temp_free(t1);
13193}
13194
13195static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13196 int base, int16_t offset)
13197{
13198 const char *opn = "ldst_pair";
13199 TCGv t0, t1;
13200
36c6711b 13201 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 13202 generate_exception(ctx, EXCP_RI);
d796321b
FB
13203 return;
13204 }
13205
3c824109
NF
13206 t0 = tcg_temp_new();
13207 t1 = tcg_temp_new();
8e9ade68 13208
3c824109
NF
13209 gen_base_offset_addr(ctx, t0, base, offset);
13210
13211 switch (opc) {
13212 case LWP:
36c6711b
EJ
13213 if (rd == base) {
13214 generate_exception(ctx, EXCP_RI);
13215 return;
13216 }
5f68f5ae 13217 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13218 gen_store_gpr(t1, rd);
13219 tcg_gen_movi_tl(t1, 4);
13220 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13221 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13222 gen_store_gpr(t1, rd+1);
13223 opn = "lwp";
13224 break;
13225 case SWP:
3c824109 13226 gen_load_gpr(t1, rd);
5f68f5ae 13227 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13228 tcg_gen_movi_tl(t1, 4);
13229 gen_op_addr_add(ctx, t0, t0, t1);
13230 gen_load_gpr(t1, rd+1);
5f68f5ae 13231 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13232 opn = "swp";
13233 break;
13234#ifdef TARGET_MIPS64
13235 case LDP:
36c6711b
EJ
13236 if (rd == base) {
13237 generate_exception(ctx, EXCP_RI);
13238 return;
13239 }
5f68f5ae 13240 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13241 gen_store_gpr(t1, rd);
13242 tcg_gen_movi_tl(t1, 8);
13243 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13244 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13245 gen_store_gpr(t1, rd+1);
13246 opn = "ldp";
13247 break;
13248 case SDP:
3c824109 13249 gen_load_gpr(t1, rd);
5f68f5ae 13250 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13251 tcg_gen_movi_tl(t1, 8);
13252 gen_op_addr_add(ctx, t0, t0, t1);
13253 gen_load_gpr(t1, rd+1);
5f68f5ae 13254 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13255 opn = "sdp";
13256 break;
13257#endif
6af0bf9c 13258 }
2abf314d 13259 (void)opn; /* avoid a compiler warning */
3c824109
NF
13260 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
13261 tcg_temp_free(t0);
13262 tcg_temp_free(t1);
13263}
618b0fe9 13264
240ce26a 13265static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13266{
13267 int extension = (ctx->opcode >> 6) & 0x3f;
13268 int minor = (ctx->opcode >> 12) & 0xf;
13269 uint32_t mips32_op;
13270
13271 switch (extension) {
13272 case TEQ:
13273 mips32_op = OPC_TEQ;
13274 goto do_trap;
13275 case TGE:
13276 mips32_op = OPC_TGE;
13277 goto do_trap;
13278 case TGEU:
13279 mips32_op = OPC_TGEU;
13280 goto do_trap;
13281 case TLT:
13282 mips32_op = OPC_TLT;
13283 goto do_trap;
13284 case TLTU:
13285 mips32_op = OPC_TLTU;
13286 goto do_trap;
13287 case TNE:
13288 mips32_op = OPC_TNE;
13289 do_trap:
13290 gen_trap(ctx, mips32_op, rs, rt, -1);
13291 break;
13292#ifndef CONFIG_USER_ONLY
13293 case MFC0:
13294 case MFC0 + 32:
2e15497c 13295 check_cp0_enabled(ctx);
3c824109
NF
13296 if (rt == 0) {
13297 /* Treat as NOP. */
13298 break;
13299 }
d75c135e 13300 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13301 break;
13302 case MTC0:
13303 case MTC0 + 32:
2e15497c 13304 check_cp0_enabled(ctx);
3c824109
NF
13305 {
13306 TCGv t0 = tcg_temp_new();
618b0fe9 13307
3c824109 13308 gen_load_gpr(t0, rt);
d75c135e 13309 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13310 tcg_temp_free(t0);
13311 }
13312 break;
13313#endif
a1fc6246
LA
13314 case 0x2a:
13315 switch (minor & 3) {
13316 case MADD_ACC:
13317 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13318 break;
13319 case MADDU_ACC:
13320 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13321 break;
13322 case MSUB_ACC:
13323 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13324 break;
13325 case MSUBU_ACC:
13326 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13327 break;
13328 default:
13329 goto pool32axf_invalid;
13330 }
13331 break;
13332 case 0x32:
13333 switch (minor & 3) {
13334 case MULT_ACC:
13335 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13336 break;
13337 case MULTU_ACC:
13338 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13339 break;
13340 default:
13341 goto pool32axf_invalid;
13342 }
13343 break;
3c824109
NF
13344 case 0x2c:
13345 switch (minor) {
e0332095
YK
13346 case BITSWAP:
13347 check_insn(ctx, ISA_MIPS32R6);
13348 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13349 break;
3c824109
NF
13350 case SEB:
13351 gen_bshfl(ctx, OPC_SEB, rs, rt);
13352 break;
13353 case SEH:
13354 gen_bshfl(ctx, OPC_SEH, rs, rt);
13355 break;
13356 case CLO:
13357 mips32_op = OPC_CLO;
13358 goto do_cl;
13359 case CLZ:
13360 mips32_op = OPC_CLZ;
13361 do_cl:
d75c135e 13362 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13363 gen_cl(ctx, mips32_op, rt, rs);
13364 break;
13365 case RDHWR:
d75c135e 13366 gen_rdhwr(ctx, rt, rs);
3c824109
NF
13367 break;
13368 case WSBH:
13369 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13370 break;
13371 case MULT:
9e8f441a 13372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13373 mips32_op = OPC_MULT;
26135ead 13374 goto do_mul;
3c824109 13375 case MULTU:
9e8f441a 13376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13377 mips32_op = OPC_MULTU;
26135ead 13378 goto do_mul;
3c824109 13379 case DIV:
9e8f441a 13380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13381 mips32_op = OPC_DIV;
26135ead 13382 goto do_div;
3c824109 13383 case DIVU:
9e8f441a 13384 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13385 mips32_op = OPC_DIVU;
26135ead
RS
13386 goto do_div;
13387 do_div:
13388 check_insn(ctx, ISA_MIPS32);
13389 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13390 break;
3c824109 13391 case MADD:
9e8f441a 13392 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13393 mips32_op = OPC_MADD;
26135ead 13394 goto do_mul;
3c824109 13395 case MADDU:
9e8f441a 13396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13397 mips32_op = OPC_MADDU;
26135ead 13398 goto do_mul;
3c824109 13399 case MSUB:
9e8f441a 13400 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13401 mips32_op = OPC_MSUB;
26135ead 13402 goto do_mul;
3c824109 13403 case MSUBU:
9e8f441a 13404 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13405 mips32_op = OPC_MSUBU;
26135ead 13406 do_mul:
d75c135e 13407 check_insn(ctx, ISA_MIPS32);
a1fc6246 13408 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13409 break;
13410 default:
13411 goto pool32axf_invalid;
13412 }
13413 break;
13414 case 0x34:
13415 switch (minor) {
13416 case MFC2:
13417 case MTC2:
13418 case MFHC2:
13419 case MTHC2:
13420 case CFC2:
13421 case CTC2:
13422 generate_exception_err(ctx, EXCP_CpU, 2);
13423 break;
13424 default:
13425 goto pool32axf_invalid;
13426 }
13427 break;
13428 case 0x3c:
13429 switch (minor) {
65935f07
YK
13430 case JALR: /* JALRC */
13431 case JALR_HB: /* JALRC_HB */
13432 if (ctx->insn_flags & ISA_MIPS32R6) {
13433 /* JALRC, JALRC_HB */
13434 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13435 } else {
13436 /* JALR, JALR_HB */
13437 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13438 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13439 }
3c824109
NF
13440 break;
13441 case JALRS:
13442 case JALRS_HB:
9e8f441a 13443 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13444 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13445 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13446 break;
13447 default:
13448 goto pool32axf_invalid;
13449 }
13450 break;
13451 case 0x05:
13452 switch (minor) {
13453 case RDPGPR:
2e15497c 13454 check_cp0_enabled(ctx);
d75c135e 13455 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13456 gen_load_srsgpr(rs, rt);
3c824109
NF
13457 break;
13458 case WRPGPR:
2e15497c 13459 check_cp0_enabled(ctx);
d75c135e 13460 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13461 gen_store_srsgpr(rs, rt);
3c824109
NF
13462 break;
13463 default:
13464 goto pool32axf_invalid;
13465 }
13466 break;
13467#ifndef CONFIG_USER_ONLY
13468 case 0x0d:
13469 switch (minor) {
13470 case TLBP:
13471 mips32_op = OPC_TLBP;
13472 goto do_cp0;
13473 case TLBR:
13474 mips32_op = OPC_TLBR;
13475 goto do_cp0;
13476 case TLBWI:
13477 mips32_op = OPC_TLBWI;
13478 goto do_cp0;
13479 case TLBWR:
13480 mips32_op = OPC_TLBWR;
13481 goto do_cp0;
e60ec063
YK
13482 case TLBINV:
13483 mips32_op = OPC_TLBINV;
13484 goto do_cp0;
13485 case TLBINVF:
13486 mips32_op = OPC_TLBINVF;
13487 goto do_cp0;
3c824109
NF
13488 case WAIT:
13489 mips32_op = OPC_WAIT;
13490 goto do_cp0;
13491 case DERET:
13492 mips32_op = OPC_DERET;
13493 goto do_cp0;
13494 case ERET:
13495 mips32_op = OPC_ERET;
13496 do_cp0:
13497 gen_cp0(env, ctx, mips32_op, rt, rs);
13498 break;
13499 default:
13500 goto pool32axf_invalid;
13501 }
13502 break;
13503 case 0x1d:
13504 switch (minor) {
13505 case DI:
2e15497c 13506 check_cp0_enabled(ctx);
3c824109
NF
13507 {
13508 TCGv t0 = tcg_temp_new();
13509
13510 save_cpu_state(ctx, 1);
895c2d04 13511 gen_helper_di(t0, cpu_env);
3c824109
NF
13512 gen_store_gpr(t0, rs);
13513 /* Stop translation as we may have switched the execution mode */
13514 ctx->bstate = BS_STOP;
13515 tcg_temp_free(t0);
13516 }
13517 break;
13518 case EI:
2e15497c 13519 check_cp0_enabled(ctx);
3c824109
NF
13520 {
13521 TCGv t0 = tcg_temp_new();
13522
13523 save_cpu_state(ctx, 1);
895c2d04 13524 gen_helper_ei(t0, cpu_env);
3c824109
NF
13525 gen_store_gpr(t0, rs);
13526 /* Stop translation as we may have switched the execution mode */
13527 ctx->bstate = BS_STOP;
13528 tcg_temp_free(t0);
13529 }
13530 break;
13531 default:
13532 goto pool32axf_invalid;
13533 }
13534 break;
13535#endif
13536 case 0x2d:
13537 switch (minor) {
13538 case SYNC:
13539 /* NOP */
13540 break;
13541 case SYSCALL:
13542 generate_exception(ctx, EXCP_SYSCALL);
13543 ctx->bstate = BS_STOP;
13544 break;
13545 case SDBBP:
3b3c1694
LA
13546 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13547 gen_helper_do_semihosting(cpu_env);
13548 } else {
13549 check_insn(ctx, ISA_MIPS32);
e0332095
YK
13550 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13551 generate_exception(ctx, EXCP_RI);
13552 } else {
13553 generate_exception(ctx, EXCP_DBp);
13554 }
3b3c1694 13555 }
3c824109
NF
13556 break;
13557 default:
13558 goto pool32axf_invalid;
13559 }
13560 break;
a1fc6246 13561 case 0x01:
26135ead 13562 switch (minor & 3) {
a1fc6246 13563 case MFHI_ACC:
26135ead 13564 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13565 break;
a1fc6246 13566 case MFLO_ACC:
26135ead 13567 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13568 break;
a1fc6246 13569 case MTHI_ACC:
26135ead 13570 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13571 break;
a1fc6246 13572 case MTLO_ACC:
26135ead 13573 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13574 break;
13575 default:
13576 goto pool32axf_invalid;
13577 }
13578 break;
a1fc6246 13579 case 0x35:
9e8f441a 13580 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13581 switch (minor) {
13582 case MFHI32:
13583 gen_HILO(ctx, OPC_MFHI, 0, rs);
13584 break;
13585 case MFLO32:
13586 gen_HILO(ctx, OPC_MFLO, 0, rs);
13587 break;
13588 case MTHI32:
13589 gen_HILO(ctx, OPC_MTHI, 0, rs);
13590 break;
13591 case MTLO32:
13592 gen_HILO(ctx, OPC_MTLO, 0, rs);
13593 break;
13594 default:
13595 goto pool32axf_invalid;
13596 }
13597 break;
3c824109
NF
13598 default:
13599 pool32axf_invalid:
13600 MIPS_INVAL("pool32axf");
13601 generate_exception(ctx, EXCP_RI);
13602 break;
13603 }
13604}
13605
13606/* Values for microMIPS fmt field. Variable-width, depending on which
13607 formats the instruction supports. */
13608
13609enum {
13610 FMT_SD_S = 0,
13611 FMT_SD_D = 1,
13612
13613 FMT_SDPS_S = 0,
13614 FMT_SDPS_D = 1,
13615 FMT_SDPS_PS = 2,
13616
13617 FMT_SWL_S = 0,
13618 FMT_SWL_W = 1,
13619 FMT_SWL_L = 2,
13620
13621 FMT_DWL_D = 0,
13622 FMT_DWL_W = 1,
13623 FMT_DWL_L = 2
13624};
13625
d75c135e 13626static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13627{
13628 int extension = (ctx->opcode >> 6) & 0x3ff;
13629 uint32_t mips32_op;
13630
13631#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13632#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13633#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13634
13635 switch (extension) {
13636 case FLOAT_1BIT_FMT(CFC1, 0):
13637 mips32_op = OPC_CFC1;
13638 goto do_cp1;
13639 case FLOAT_1BIT_FMT(CTC1, 0):
13640 mips32_op = OPC_CTC1;
13641 goto do_cp1;
13642 case FLOAT_1BIT_FMT(MFC1, 0):
13643 mips32_op = OPC_MFC1;
13644 goto do_cp1;
13645 case FLOAT_1BIT_FMT(MTC1, 0):
13646 mips32_op = OPC_MTC1;
13647 goto do_cp1;
13648 case FLOAT_1BIT_FMT(MFHC1, 0):
13649 mips32_op = OPC_MFHC1;
13650 goto do_cp1;
13651 case FLOAT_1BIT_FMT(MTHC1, 0):
13652 mips32_op = OPC_MTHC1;
13653 do_cp1:
13654 gen_cp1(ctx, mips32_op, rt, rs);
13655 break;
13656
13657 /* Reciprocal square root */
13658 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13659 mips32_op = OPC_RSQRT_S;
13660 goto do_unaryfp;
13661 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13662 mips32_op = OPC_RSQRT_D;
13663 goto do_unaryfp;
13664
13665 /* Square root */
13666 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13667 mips32_op = OPC_SQRT_S;
13668 goto do_unaryfp;
13669 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13670 mips32_op = OPC_SQRT_D;
13671 goto do_unaryfp;
13672
13673 /* Reciprocal */
13674 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13675 mips32_op = OPC_RECIP_S;
13676 goto do_unaryfp;
13677 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13678 mips32_op = OPC_RECIP_D;
13679 goto do_unaryfp;
13680
13681 /* Floor */
13682 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13683 mips32_op = OPC_FLOOR_L_S;
13684 goto do_unaryfp;
13685 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13686 mips32_op = OPC_FLOOR_L_D;
13687 goto do_unaryfp;
13688 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13689 mips32_op = OPC_FLOOR_W_S;
13690 goto do_unaryfp;
13691 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13692 mips32_op = OPC_FLOOR_W_D;
13693 goto do_unaryfp;
13694
13695 /* Ceiling */
13696 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13697 mips32_op = OPC_CEIL_L_S;
13698 goto do_unaryfp;
13699 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13700 mips32_op = OPC_CEIL_L_D;
13701 goto do_unaryfp;
13702 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13703 mips32_op = OPC_CEIL_W_S;
13704 goto do_unaryfp;
13705 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13706 mips32_op = OPC_CEIL_W_D;
13707 goto do_unaryfp;
13708
13709 /* Truncation */
13710 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13711 mips32_op = OPC_TRUNC_L_S;
13712 goto do_unaryfp;
13713 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13714 mips32_op = OPC_TRUNC_L_D;
13715 goto do_unaryfp;
13716 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13717 mips32_op = OPC_TRUNC_W_S;
13718 goto do_unaryfp;
13719 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13720 mips32_op = OPC_TRUNC_W_D;
13721 goto do_unaryfp;
13722
13723 /* Round */
13724 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13725 mips32_op = OPC_ROUND_L_S;
13726 goto do_unaryfp;
13727 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13728 mips32_op = OPC_ROUND_L_D;
13729 goto do_unaryfp;
13730 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13731 mips32_op = OPC_ROUND_W_S;
13732 goto do_unaryfp;
13733 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13734 mips32_op = OPC_ROUND_W_D;
13735 goto do_unaryfp;
13736
13737 /* Integer to floating-point conversion */
13738 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13739 mips32_op = OPC_CVT_L_S;
13740 goto do_unaryfp;
13741 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13742 mips32_op = OPC_CVT_L_D;
13743 goto do_unaryfp;
13744 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13745 mips32_op = OPC_CVT_W_S;
13746 goto do_unaryfp;
13747 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13748 mips32_op = OPC_CVT_W_D;
13749 goto do_unaryfp;
13750
13751 /* Paired-foo conversions */
13752 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13753 mips32_op = OPC_CVT_S_PL;
13754 goto do_unaryfp;
13755 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13756 mips32_op = OPC_CVT_S_PU;
13757 goto do_unaryfp;
13758 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13759 mips32_op = OPC_CVT_PW_PS;
13760 goto do_unaryfp;
13761 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13762 mips32_op = OPC_CVT_PS_PW;
13763 goto do_unaryfp;
13764
13765 /* Floating-point moves */
13766 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13767 mips32_op = OPC_MOV_S;
13768 goto do_unaryfp;
13769 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13770 mips32_op = OPC_MOV_D;
13771 goto do_unaryfp;
13772 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13773 mips32_op = OPC_MOV_PS;
13774 goto do_unaryfp;
13775
13776 /* Absolute value */
13777 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13778 mips32_op = OPC_ABS_S;
13779 goto do_unaryfp;
13780 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13781 mips32_op = OPC_ABS_D;
13782 goto do_unaryfp;
13783 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13784 mips32_op = OPC_ABS_PS;
13785 goto do_unaryfp;
13786
13787 /* Negation */
13788 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13789 mips32_op = OPC_NEG_S;
13790 goto do_unaryfp;
13791 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13792 mips32_op = OPC_NEG_D;
13793 goto do_unaryfp;
13794 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13795 mips32_op = OPC_NEG_PS;
13796 goto do_unaryfp;
13797
13798 /* Reciprocal square root step */
13799 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13800 mips32_op = OPC_RSQRT1_S;
13801 goto do_unaryfp;
13802 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13803 mips32_op = OPC_RSQRT1_D;
13804 goto do_unaryfp;
13805 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13806 mips32_op = OPC_RSQRT1_PS;
13807 goto do_unaryfp;
13808
13809 /* Reciprocal step */
13810 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13811 mips32_op = OPC_RECIP1_S;
13812 goto do_unaryfp;
13813 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13814 mips32_op = OPC_RECIP1_S;
13815 goto do_unaryfp;
13816 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13817 mips32_op = OPC_RECIP1_PS;
13818 goto do_unaryfp;
13819
13820 /* Conversions from double */
13821 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13822 mips32_op = OPC_CVT_D_S;
13823 goto do_unaryfp;
13824 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13825 mips32_op = OPC_CVT_D_W;
13826 goto do_unaryfp;
13827 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13828 mips32_op = OPC_CVT_D_L;
13829 goto do_unaryfp;
13830
13831 /* Conversions from single */
13832 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13833 mips32_op = OPC_CVT_S_D;
13834 goto do_unaryfp;
13835 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13836 mips32_op = OPC_CVT_S_W;
13837 goto do_unaryfp;
13838 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13839 mips32_op = OPC_CVT_S_L;
13840 do_unaryfp:
13841 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13842 break;
13843
13844 /* Conditional moves on floating-point codes */
13845 case COND_FLOAT_MOV(MOVT, 0):
13846 case COND_FLOAT_MOV(MOVT, 1):
13847 case COND_FLOAT_MOV(MOVT, 2):
13848 case COND_FLOAT_MOV(MOVT, 3):
13849 case COND_FLOAT_MOV(MOVT, 4):
13850 case COND_FLOAT_MOV(MOVT, 5):
13851 case COND_FLOAT_MOV(MOVT, 6):
13852 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13853 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13854 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13855 break;
13856 case COND_FLOAT_MOV(MOVF, 0):
13857 case COND_FLOAT_MOV(MOVF, 1):
13858 case COND_FLOAT_MOV(MOVF, 2):
13859 case COND_FLOAT_MOV(MOVF, 3):
13860 case COND_FLOAT_MOV(MOVF, 4):
13861 case COND_FLOAT_MOV(MOVF, 5):
13862 case COND_FLOAT_MOV(MOVF, 6):
13863 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13865 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13866 break;
13867 default:
13868 MIPS_INVAL("pool32fxf");
13869 generate_exception(ctx, EXCP_RI);
13870 break;
13871 }
13872}
13873
f60eeb0c 13874static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13875{
13876 int32_t offset;
13877 uint16_t insn;
13878 int rt, rs, rd, rr;
13879 int16_t imm;
13880 uint32_t op, minor, mips32_op;
13881 uint32_t cond, fmt, cc;
13882
895c2d04 13883 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13884 ctx->opcode = (ctx->opcode << 16) | insn;
13885
13886 rt = (ctx->opcode >> 21) & 0x1f;
13887 rs = (ctx->opcode >> 16) & 0x1f;
13888 rd = (ctx->opcode >> 11) & 0x1f;
13889 rr = (ctx->opcode >> 6) & 0x1f;
13890 imm = (int16_t) ctx->opcode;
13891
13892 op = (ctx->opcode >> 26) & 0x3f;
13893 switch (op) {
13894 case POOL32A:
13895 minor = ctx->opcode & 0x3f;
13896 switch (minor) {
13897 case 0x00:
13898 minor = (ctx->opcode >> 6) & 0xf;
13899 switch (minor) {
13900 case SLL32:
13901 mips32_op = OPC_SLL;
13902 goto do_shifti;
13903 case SRA:
13904 mips32_op = OPC_SRA;
13905 goto do_shifti;
13906 case SRL32:
13907 mips32_op = OPC_SRL;
13908 goto do_shifti;
13909 case ROTR:
13910 mips32_op = OPC_ROTR;
13911 do_shifti:
d75c135e 13912 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13913 break;
e0332095
YK
13914 case SELEQZ:
13915 check_insn(ctx, ISA_MIPS32R6);
13916 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13917 break;
13918 case SELNEZ:
13919 check_insn(ctx, ISA_MIPS32R6);
13920 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13921 break;
3c824109
NF
13922 default:
13923 goto pool32a_invalid;
13924 }
13925 break;
13926 case 0x10:
13927 minor = (ctx->opcode >> 6) & 0xf;
13928 switch (minor) {
13929 /* Arithmetic */
13930 case ADD:
13931 mips32_op = OPC_ADD;
13932 goto do_arith;
13933 case ADDU32:
13934 mips32_op = OPC_ADDU;
13935 goto do_arith;
13936 case SUB:
13937 mips32_op = OPC_SUB;
13938 goto do_arith;
13939 case SUBU32:
13940 mips32_op = OPC_SUBU;
13941 goto do_arith;
13942 case MUL:
9e8f441a 13943 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13944 mips32_op = OPC_MUL;
13945 do_arith:
d75c135e 13946 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13947 break;
13948 /* Shifts */
13949 case SLLV:
13950 mips32_op = OPC_SLLV;
13951 goto do_shift;
13952 case SRLV:
13953 mips32_op = OPC_SRLV;
13954 goto do_shift;
13955 case SRAV:
13956 mips32_op = OPC_SRAV;
13957 goto do_shift;
13958 case ROTRV:
13959 mips32_op = OPC_ROTRV;
13960 do_shift:
d75c135e 13961 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13962 break;
13963 /* Logical operations */
13964 case AND:
13965 mips32_op = OPC_AND;
13966 goto do_logic;
13967 case OR32:
13968 mips32_op = OPC_OR;
13969 goto do_logic;
13970 case NOR:
13971 mips32_op = OPC_NOR;
13972 goto do_logic;
13973 case XOR32:
13974 mips32_op = OPC_XOR;
13975 do_logic:
d75c135e 13976 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13977 break;
13978 /* Set less than */
13979 case SLT:
13980 mips32_op = OPC_SLT;
13981 goto do_slt;
13982 case SLTU:
13983 mips32_op = OPC_SLTU;
13984 do_slt:
d75c135e 13985 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13986 break;
13987 default:
13988 goto pool32a_invalid;
13989 }
13990 break;
13991 case 0x18:
13992 minor = (ctx->opcode >> 6) & 0xf;
13993 switch (minor) {
13994 /* Conditional moves */
e0332095
YK
13995 case MOVN: /* MUL */
13996 if (ctx->insn_flags & ISA_MIPS32R6) {
13997 /* MUL */
13998 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13999 } else {
14000 /* MOVN */
14001 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14002 }
14003 break;
14004 case MOVZ: /* MUH */
14005 if (ctx->insn_flags & ISA_MIPS32R6) {
14006 /* MUH */
14007 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14008 } else {
14009 /* MOVZ */
14010 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14011 }
14012 break;
14013 case MULU:
14014 check_insn(ctx, ISA_MIPS32R6);
14015 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14016 break;
14017 case MUHU:
14018 check_insn(ctx, ISA_MIPS32R6);
14019 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14020 break;
14021 case LWXS: /* DIV */
14022 if (ctx->insn_flags & ISA_MIPS32R6) {
14023 /* DIV */
14024 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14025 } else {
14026 /* LWXS */
14027 gen_ldxs(ctx, rs, rt, rd);
14028 }
14029 break;
14030 case MOD:
14031 check_insn(ctx, ISA_MIPS32R6);
14032 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14033 break;
14034 case R6_DIVU:
14035 check_insn(ctx, ISA_MIPS32R6);
14036 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14037 break;
e0332095
YK
14038 case MODU:
14039 check_insn(ctx, ISA_MIPS32R6);
14040 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14041 break;
14042 default:
14043 goto pool32a_invalid;
14044 }
14045 break;
14046 case INS:
14047 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14048 return;
e0332095
YK
14049 case LSA:
14050 check_insn(ctx, ISA_MIPS32R6);
14051 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14052 extract32(ctx->opcode, 9, 2));
14053 break;
14054 case ALIGN:
14055 check_insn(ctx, ISA_MIPS32R6);
14056 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14057 extract32(ctx->opcode, 9, 2));
14058 break;
3c824109
NF
14059 case EXT:
14060 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14061 return;
14062 case POOL32AXF:
240ce26a 14063 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
14064 break;
14065 case 0x07:
14066 generate_exception(ctx, EXCP_BREAK);
14067 break;
14068 default:
14069 pool32a_invalid:
14070 MIPS_INVAL("pool32a");
14071 generate_exception(ctx, EXCP_RI);
14072 break;
14073 }
14074 break;
14075 case POOL32B:
14076 minor = (ctx->opcode >> 12) & 0xf;
14077 switch (minor) {
14078 case CACHE:
2e15497c 14079 check_cp0_enabled(ctx);
3c824109
NF
14080 /* Treat as no-op. */
14081 break;
14082 case LWC2:
14083 case SWC2:
14084 /* COP2: Not implemented. */
14085 generate_exception_err(ctx, EXCP_CpU, 2);
14086 break;
3c824109
NF
14087#ifdef TARGET_MIPS64
14088 case LDP:
14089 case SDP:
d9224450
MR
14090 check_insn(ctx, ISA_MIPS3);
14091 check_mips_64(ctx);
14092 /* Fallthrough */
3c824109 14093#endif
d9224450
MR
14094 case LWP:
14095 case SWP:
3c824109
NF
14096 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14097 break;
3c824109
NF
14098#ifdef TARGET_MIPS64
14099 case LDM:
14100 case SDM:
d9224450
MR
14101 check_insn(ctx, ISA_MIPS3);
14102 check_mips_64(ctx);
14103 /* Fallthrough */
3c824109 14104#endif
d9224450
MR
14105 case LWM32:
14106 case SWM32:
3c824109
NF
14107 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14108 break;
14109 default:
14110 MIPS_INVAL("pool32b");
14111 generate_exception(ctx, EXCP_RI);
14112 break;
14113 }
14114 break;
14115 case POOL32F:
5ab5c041 14116 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14117 minor = ctx->opcode & 0x3f;
14118 check_cp1_enabled(ctx);
14119 switch (minor) {
14120 case ALNV_PS:
9e8f441a 14121 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14122 mips32_op = OPC_ALNV_PS;
14123 goto do_madd;
14124 case MADD_S:
9e8f441a 14125 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14126 mips32_op = OPC_MADD_S;
14127 goto do_madd;
14128 case MADD_D:
9e8f441a 14129 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14130 mips32_op = OPC_MADD_D;
14131 goto do_madd;
14132 case MADD_PS:
9e8f441a 14133 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14134 mips32_op = OPC_MADD_PS;
14135 goto do_madd;
14136 case MSUB_S:
9e8f441a 14137 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14138 mips32_op = OPC_MSUB_S;
14139 goto do_madd;
14140 case MSUB_D:
9e8f441a 14141 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14142 mips32_op = OPC_MSUB_D;
14143 goto do_madd;
14144 case MSUB_PS:
9e8f441a 14145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14146 mips32_op = OPC_MSUB_PS;
14147 goto do_madd;
14148 case NMADD_S:
9e8f441a 14149 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14150 mips32_op = OPC_NMADD_S;
14151 goto do_madd;
14152 case NMADD_D:
9e8f441a 14153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14154 mips32_op = OPC_NMADD_D;
14155 goto do_madd;
14156 case NMADD_PS:
9e8f441a 14157 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14158 mips32_op = OPC_NMADD_PS;
14159 goto do_madd;
14160 case NMSUB_S:
9e8f441a 14161 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14162 mips32_op = OPC_NMSUB_S;
14163 goto do_madd;
14164 case NMSUB_D:
9e8f441a 14165 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14166 mips32_op = OPC_NMSUB_D;
14167 goto do_madd;
14168 case NMSUB_PS:
9e8f441a 14169 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14170 mips32_op = OPC_NMSUB_PS;
14171 do_madd:
14172 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14173 break;
14174 case CABS_COND_FMT:
9e8f441a 14175 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14176 cond = (ctx->opcode >> 6) & 0xf;
14177 cc = (ctx->opcode >> 13) & 0x7;
14178 fmt = (ctx->opcode >> 10) & 0x3;
14179 switch (fmt) {
14180 case 0x0:
14181 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14182 break;
14183 case 0x1:
14184 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14185 break;
14186 case 0x2:
14187 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14188 break;
14189 default:
14190 goto pool32f_invalid;
14191 }
14192 break;
14193 case C_COND_FMT:
9e8f441a 14194 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14195 cond = (ctx->opcode >> 6) & 0xf;
14196 cc = (ctx->opcode >> 13) & 0x7;
14197 fmt = (ctx->opcode >> 10) & 0x3;
14198 switch (fmt) {
14199 case 0x0:
14200 gen_cmp_s(ctx, cond, rt, rs, cc);
14201 break;
14202 case 0x1:
14203 gen_cmp_d(ctx, cond, rt, rs, cc);
14204 break;
14205 case 0x2:
14206 gen_cmp_ps(ctx, cond, rt, rs, cc);
14207 break;
14208 default:
14209 goto pool32f_invalid;
14210 }
14211 break;
2a24a7ba
YK
14212 case CMP_CONDN_S:
14213 check_insn(ctx, ISA_MIPS32R6);
14214 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14215 break;
14216 case CMP_CONDN_D:
14217 check_insn(ctx, ISA_MIPS32R6);
14218 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14219 break;
3c824109 14220 case POOL32FXF:
d75c135e 14221 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14222 break;
14223 case 0x00:
14224 /* PLL foo */
14225 switch ((ctx->opcode >> 6) & 0x7) {
14226 case PLL_PS:
14227 mips32_op = OPC_PLL_PS;
14228 goto do_ps;
14229 case PLU_PS:
14230 mips32_op = OPC_PLU_PS;
14231 goto do_ps;
14232 case PUL_PS:
14233 mips32_op = OPC_PUL_PS;
14234 goto do_ps;
14235 case PUU_PS:
14236 mips32_op = OPC_PUU_PS;
14237 goto do_ps;
14238 case CVT_PS_S:
9e8f441a 14239 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14240 mips32_op = OPC_CVT_PS_S;
14241 do_ps:
14242 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14243 break;
14244 default:
14245 goto pool32f_invalid;
14246 }
14247 break;
2a24a7ba
YK
14248 case MIN_FMT:
14249 check_insn(ctx, ISA_MIPS32R6);
14250 switch ((ctx->opcode >> 9) & 0x3) {
14251 case FMT_SDPS_S:
14252 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14253 break;
14254 case FMT_SDPS_D:
14255 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14256 break;
14257 default:
14258 goto pool32f_invalid;
14259 }
14260 break;
3c824109
NF
14261 case 0x08:
14262 /* [LS][WDU]XC1 */
14263 switch ((ctx->opcode >> 6) & 0x7) {
14264 case LWXC1:
9e8f441a 14265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14266 mips32_op = OPC_LWXC1;
14267 goto do_ldst_cp1;
14268 case SWXC1:
9e8f441a 14269 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14270 mips32_op = OPC_SWXC1;
14271 goto do_ldst_cp1;
14272 case LDXC1:
9e8f441a 14273 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14274 mips32_op = OPC_LDXC1;
14275 goto do_ldst_cp1;
14276 case SDXC1:
9e8f441a 14277 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14278 mips32_op = OPC_SDXC1;
14279 goto do_ldst_cp1;
14280 case LUXC1:
9e8f441a 14281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14282 mips32_op = OPC_LUXC1;
14283 goto do_ldst_cp1;
14284 case SUXC1:
9e8f441a 14285 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14286 mips32_op = OPC_SUXC1;
14287 do_ldst_cp1:
14288 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14289 break;
14290 default:
14291 goto pool32f_invalid;
14292 }
14293 break;
2a24a7ba
YK
14294 case MAX_FMT:
14295 check_insn(ctx, ISA_MIPS32R6);
14296 switch ((ctx->opcode >> 9) & 0x3) {
14297 case FMT_SDPS_S:
14298 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14299 break;
14300 case FMT_SDPS_D:
14301 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14302 break;
14303 default:
14304 goto pool32f_invalid;
14305 }
14306 break;
3c824109
NF
14307 case 0x18:
14308 /* 3D insns */
9e8f441a 14309 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14310 fmt = (ctx->opcode >> 9) & 0x3;
14311 switch ((ctx->opcode >> 6) & 0x7) {
14312 case RSQRT2_FMT:
14313 switch (fmt) {
14314 case FMT_SDPS_S:
14315 mips32_op = OPC_RSQRT2_S;
14316 goto do_3d;
14317 case FMT_SDPS_D:
14318 mips32_op = OPC_RSQRT2_D;
14319 goto do_3d;
14320 case FMT_SDPS_PS:
14321 mips32_op = OPC_RSQRT2_PS;
14322 goto do_3d;
14323 default:
14324 goto pool32f_invalid;
14325 }
14326 break;
14327 case RECIP2_FMT:
14328 switch (fmt) {
14329 case FMT_SDPS_S:
14330 mips32_op = OPC_RECIP2_S;
14331 goto do_3d;
14332 case FMT_SDPS_D:
14333 mips32_op = OPC_RECIP2_D;
14334 goto do_3d;
14335 case FMT_SDPS_PS:
14336 mips32_op = OPC_RECIP2_PS;
14337 goto do_3d;
14338 default:
14339 goto pool32f_invalid;
14340 }
14341 break;
14342 case ADDR_PS:
14343 mips32_op = OPC_ADDR_PS;
14344 goto do_3d;
14345 case MULR_PS:
14346 mips32_op = OPC_MULR_PS;
14347 do_3d:
14348 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14349 break;
14350 default:
14351 goto pool32f_invalid;
14352 }
14353 break;
14354 case 0x20:
2a24a7ba 14355 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14356 cc = (ctx->opcode >> 13) & 0x7;
14357 fmt = (ctx->opcode >> 9) & 0x3;
14358 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14359 case MOVF_FMT: /* RINT_FMT */
14360 if (ctx->insn_flags & ISA_MIPS32R6) {
14361 /* RINT_FMT */
14362 switch (fmt) {
14363 case FMT_SDPS_S:
14364 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14365 break;
14366 case FMT_SDPS_D:
14367 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14368 break;
14369 default:
14370 goto pool32f_invalid;
14371 }
14372 } else {
14373 /* MOVF_FMT */
14374 switch (fmt) {
14375 case FMT_SDPS_S:
14376 gen_movcf_s(ctx, rs, rt, cc, 0);
14377 break;
14378 case FMT_SDPS_D:
14379 gen_movcf_d(ctx, rs, rt, cc, 0);
14380 break;
14381 case FMT_SDPS_PS:
14382 check_ps(ctx);
14383 gen_movcf_ps(ctx, rs, rt, cc, 0);
14384 break;
14385 default:
14386 goto pool32f_invalid;
14387 }
3c824109
NF
14388 }
14389 break;
2a24a7ba
YK
14390 case MOVT_FMT: /* CLASS_FMT */
14391 if (ctx->insn_flags & ISA_MIPS32R6) {
14392 /* CLASS_FMT */
14393 switch (fmt) {
14394 case FMT_SDPS_S:
14395 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14396 break;
14397 case FMT_SDPS_D:
14398 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14399 break;
14400 default:
14401 goto pool32f_invalid;
14402 }
14403 } else {
14404 /* MOVT_FMT */
14405 switch (fmt) {
14406 case FMT_SDPS_S:
14407 gen_movcf_s(ctx, rs, rt, cc, 1);
14408 break;
14409 case FMT_SDPS_D:
14410 gen_movcf_d(ctx, rs, rt, cc, 1);
14411 break;
14412 case FMT_SDPS_PS:
14413 check_ps(ctx);
14414 gen_movcf_ps(ctx, rs, rt, cc, 1);
14415 break;
14416 default:
14417 goto pool32f_invalid;
14418 }
3c824109
NF
14419 }
14420 break;
14421 case PREFX:
9e8f441a 14422 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14423 break;
14424 default:
14425 goto pool32f_invalid;
14426 }
14427 break;
14428#define FINSN_3ARG_SDPS(prfx) \
14429 switch ((ctx->opcode >> 8) & 0x3) { \
14430 case FMT_SDPS_S: \
14431 mips32_op = OPC_##prfx##_S; \
14432 goto do_fpop; \
14433 case FMT_SDPS_D: \
14434 mips32_op = OPC_##prfx##_D; \
14435 goto do_fpop; \
14436 case FMT_SDPS_PS: \
e29c9628 14437 check_ps(ctx); \
3c824109
NF
14438 mips32_op = OPC_##prfx##_PS; \
14439 goto do_fpop; \
14440 default: \
14441 goto pool32f_invalid; \
14442 }
2a24a7ba
YK
14443 case MINA_FMT:
14444 check_insn(ctx, ISA_MIPS32R6);
14445 switch ((ctx->opcode >> 9) & 0x3) {
14446 case FMT_SDPS_S:
14447 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14448 break;
14449 case FMT_SDPS_D:
14450 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14451 break;
14452 default:
14453 goto pool32f_invalid;
14454 }
14455 break;
14456 case MAXA_FMT:
14457 check_insn(ctx, ISA_MIPS32R6);
14458 switch ((ctx->opcode >> 9) & 0x3) {
14459 case FMT_SDPS_S:
14460 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14461 break;
14462 case FMT_SDPS_D:
14463 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14464 break;
14465 default:
14466 goto pool32f_invalid;
14467 }
14468 break;
3c824109
NF
14469 case 0x30:
14470 /* regular FP ops */
14471 switch ((ctx->opcode >> 6) & 0x3) {
14472 case ADD_FMT:
14473 FINSN_3ARG_SDPS(ADD);
14474 break;
14475 case SUB_FMT:
14476 FINSN_3ARG_SDPS(SUB);
14477 break;
14478 case MUL_FMT:
14479 FINSN_3ARG_SDPS(MUL);
14480 break;
14481 case DIV_FMT:
14482 fmt = (ctx->opcode >> 8) & 0x3;
14483 if (fmt == 1) {
14484 mips32_op = OPC_DIV_D;
14485 } else if (fmt == 0) {
14486 mips32_op = OPC_DIV_S;
14487 } else {
14488 goto pool32f_invalid;
14489 }
14490 goto do_fpop;
14491 default:
14492 goto pool32f_invalid;
14493 }
14494 break;
14495 case 0x38:
14496 /* cmovs */
2a24a7ba
YK
14497 switch ((ctx->opcode >> 6) & 0x7) {
14498 case MOVN_FMT: /* SELNEZ_FMT */
14499 if (ctx->insn_flags & ISA_MIPS32R6) {
14500 /* SELNEZ_FMT */
14501 switch ((ctx->opcode >> 9) & 0x3) {
14502 case FMT_SDPS_S:
14503 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14504 break;
14505 case FMT_SDPS_D:
14506 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14507 break;
14508 default:
14509 goto pool32f_invalid;
14510 }
14511 } else {
14512 /* MOVN_FMT */
14513 FINSN_3ARG_SDPS(MOVN);
14514 }
14515 break;
14516 case MOVN_FMT_04:
14517 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14518 FINSN_3ARG_SDPS(MOVN);
14519 break;
2a24a7ba
YK
14520 case MOVZ_FMT: /* SELEQZ_FMT */
14521 if (ctx->insn_flags & ISA_MIPS32R6) {
14522 /* SELEQZ_FMT */
14523 switch ((ctx->opcode >> 9) & 0x3) {
14524 case FMT_SDPS_S:
14525 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14526 break;
14527 case FMT_SDPS_D:
14528 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14529 break;
14530 default:
14531 goto pool32f_invalid;
14532 }
14533 } else {
14534 /* MOVZ_FMT */
14535 FINSN_3ARG_SDPS(MOVZ);
14536 }
14537 break;
14538 case MOVZ_FMT_05:
14539 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14540 FINSN_3ARG_SDPS(MOVZ);
14541 break;
2a24a7ba
YK
14542 case SEL_FMT:
14543 check_insn(ctx, ISA_MIPS32R6);
14544 switch ((ctx->opcode >> 9) & 0x3) {
14545 case FMT_SDPS_S:
14546 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14547 break;
14548 case FMT_SDPS_D:
14549 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14550 break;
14551 default:
14552 goto pool32f_invalid;
14553 }
14554 break;
14555 case MADDF_FMT:
14556 check_insn(ctx, ISA_MIPS32R6);
14557 switch ((ctx->opcode >> 9) & 0x3) {
14558 case FMT_SDPS_S:
14559 mips32_op = OPC_MADDF_S;
14560 goto do_fpop;
14561 case FMT_SDPS_D:
14562 mips32_op = OPC_MADDF_D;
14563 goto do_fpop;
14564 default:
14565 goto pool32f_invalid;
14566 }
14567 break;
14568 case MSUBF_FMT:
14569 check_insn(ctx, ISA_MIPS32R6);
14570 switch ((ctx->opcode >> 9) & 0x3) {
14571 case FMT_SDPS_S:
14572 mips32_op = OPC_MSUBF_S;
14573 goto do_fpop;
14574 case FMT_SDPS_D:
14575 mips32_op = OPC_MSUBF_D;
14576 goto do_fpop;
14577 default:
14578 goto pool32f_invalid;
14579 }
14580 break;
3c824109
NF
14581 default:
14582 goto pool32f_invalid;
14583 }
14584 break;
14585 do_fpop:
14586 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14587 break;
14588 default:
14589 pool32f_invalid:
14590 MIPS_INVAL("pool32f");
14591 generate_exception(ctx, EXCP_RI);
14592 break;
14593 }
14594 } else {
14595 generate_exception_err(ctx, EXCP_CpU, 1);
14596 }
14597 break;
14598 case POOL32I:
14599 minor = (ctx->opcode >> 21) & 0x1f;
14600 switch (minor) {
14601 case BLTZ:
9e8f441a 14602 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14603 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14604 break;
3c824109 14605 case BLTZAL:
9e8f441a 14606 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14607 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14608 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14609 break;
3c824109 14610 case BLTZALS:
9e8f441a 14611 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14612 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14613 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14614 break;
3c824109 14615 case BGEZ:
9e8f441a 14616 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14617 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14618 break;
3c824109 14619 case BGEZAL:
9e8f441a 14620 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14621 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14622 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14623 break;
3c824109 14624 case BGEZALS:
9e8f441a 14625 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14626 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14627 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14628 break;
3c824109 14629 case BLEZ:
9e8f441a 14630 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14631 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14632 break;
3c824109 14633 case BGTZ:
9e8f441a 14634 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14635 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14636 break;
14637
14638 /* Traps */
65935f07
YK
14639 case TLTI: /* BC1EQZC */
14640 if (ctx->insn_flags & ISA_MIPS32R6) {
14641 /* BC1EQZC */
14642 check_cp1_enabled(ctx);
14643 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14644 } else {
14645 /* TLTI */
14646 mips32_op = OPC_TLTI;
14647 goto do_trapi;
14648 }
14649 break;
14650 case TGEI: /* BC1NEZC */
14651 if (ctx->insn_flags & ISA_MIPS32R6) {
14652 /* BC1NEZC */
14653 check_cp1_enabled(ctx);
14654 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14655 } else {
14656 /* TGEI */
14657 mips32_op = OPC_TGEI;
14658 goto do_trapi;
14659 }
14660 break;
3c824109 14661 case TLTIU:
9e8f441a 14662 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14663 mips32_op = OPC_TLTIU;
14664 goto do_trapi;
14665 case TGEIU:
9e8f441a 14666 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14667 mips32_op = OPC_TGEIU;
14668 goto do_trapi;
3b4a5489
YK
14669 case TNEI: /* SYNCI */
14670 if (ctx->insn_flags & ISA_MIPS32R6) {
14671 /* SYNCI */
14672 /* Break the TB to be able to sync copied instructions
14673 immediately */
14674 ctx->bstate = BS_STOP;
14675 } else {
14676 /* TNEI */
14677 mips32_op = OPC_TNEI;
14678 goto do_trapi;
14679 }
14680 break;
3c824109 14681 case TEQI:
9e8f441a 14682 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14683 mips32_op = OPC_TEQI;
14684 do_trapi:
14685 gen_trap(ctx, mips32_op, rs, -1, imm);
14686 break;
14687
14688 case BNEZC:
14689 case BEQZC:
9e8f441a 14690 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14691 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14692 4, rs, 0, imm << 1, 0);
3c824109
NF
14693 /* Compact branches don't have a delay slot, so just let
14694 the normal delay slot handling take us to the branch
14695 target. */
14696 break;
14697 case LUI:
9e8f441a 14698 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14699 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14700 break;
14701 case SYNCI:
9e8f441a 14702 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14703 /* Break the TB to be able to sync copied instructions
14704 immediately */
14705 ctx->bstate = BS_STOP;
3c824109
NF
14706 break;
14707 case BC2F:
14708 case BC2T:
9e8f441a 14709 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14710 /* COP2: Not implemented. */
14711 generate_exception_err(ctx, EXCP_CpU, 2);
14712 break;
14713 case BC1F:
9e8f441a 14714 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14715 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14716 goto do_cp1branch;
14717 case BC1T:
9e8f441a 14718 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14719 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14720 goto do_cp1branch;
14721 case BC1ANY4F:
9e8f441a 14722 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14723 mips32_op = OPC_BC1FANY4;
14724 goto do_cp1mips3d;
14725 case BC1ANY4T:
9e8f441a 14726 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14727 mips32_op = OPC_BC1TANY4;
14728 do_cp1mips3d:
14729 check_cop1x(ctx);
d75c135e 14730 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14731 /* Fall through */
14732 do_cp1branch:
272f458d
MR
14733 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14734 check_cp1_enabled(ctx);
14735 gen_compute_branch1(ctx, mips32_op,
14736 (ctx->opcode >> 18) & 0x7, imm << 1);
14737 } else {
14738 generate_exception_err(ctx, EXCP_CpU, 1);
14739 }
3c824109
NF
14740 break;
14741 case BPOSGE64:
14742 case BPOSGE32:
14743 /* MIPS DSP: not implemented */
14744 /* Fall through */
14745 default:
14746 MIPS_INVAL("pool32i");
14747 generate_exception(ctx, EXCP_RI);
14748 break;
14749 }
14750 break;
14751 case POOL32C:
14752 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14753 offset = sextract32(ctx->opcode, 0,
14754 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14755 switch (minor) {
14756 case LWL:
9e8f441a 14757 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14758 mips32_op = OPC_LWL;
5c13fdfd 14759 goto do_ld_lr;
3c824109 14760 case SWL:
9e8f441a 14761 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14762 mips32_op = OPC_SWL;
5c13fdfd 14763 goto do_st_lr;
3c824109 14764 case LWR:
9e8f441a 14765 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14766 mips32_op = OPC_LWR;
5c13fdfd 14767 goto do_ld_lr;
3c824109 14768 case SWR:
9e8f441a 14769 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14770 mips32_op = OPC_SWR;
5c13fdfd 14771 goto do_st_lr;
3c824109
NF
14772#if defined(TARGET_MIPS64)
14773 case LDL:
d9224450
MR
14774 check_insn(ctx, ISA_MIPS3);
14775 check_mips_64(ctx);
9e8f441a 14776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14777 mips32_op = OPC_LDL;
5c13fdfd 14778 goto do_ld_lr;
3c824109 14779 case SDL:
d9224450
MR
14780 check_insn(ctx, ISA_MIPS3);
14781 check_mips_64(ctx);
9e8f441a 14782 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14783 mips32_op = OPC_SDL;
5c13fdfd 14784 goto do_st_lr;
3c824109 14785 case LDR:
d9224450
MR
14786 check_insn(ctx, ISA_MIPS3);
14787 check_mips_64(ctx);
9e8f441a 14788 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14789 mips32_op = OPC_LDR;
5c13fdfd 14790 goto do_ld_lr;
3c824109 14791 case SDR:
d9224450
MR
14792 check_insn(ctx, ISA_MIPS3);
14793 check_mips_64(ctx);
9e8f441a 14794 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14795 mips32_op = OPC_SDR;
5c13fdfd 14796 goto do_st_lr;
3c824109 14797 case LWU:
d9224450
MR
14798 check_insn(ctx, ISA_MIPS3);
14799 check_mips_64(ctx);
3c824109 14800 mips32_op = OPC_LWU;
5c13fdfd 14801 goto do_ld_lr;
3c824109 14802 case LLD:
d9224450
MR
14803 check_insn(ctx, ISA_MIPS3);
14804 check_mips_64(ctx);
3c824109 14805 mips32_op = OPC_LLD;
5c13fdfd 14806 goto do_ld_lr;
3c824109
NF
14807#endif
14808 case LL:
14809 mips32_op = OPC_LL;
5c13fdfd
AJ
14810 goto do_ld_lr;
14811 do_ld_lr:
3b4a5489 14812 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14813 break;
14814 do_st_lr:
14815 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
14816 break;
14817 case SC:
3b4a5489 14818 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14819 break;
14820#if defined(TARGET_MIPS64)
14821 case SCD:
d9224450
MR
14822 check_insn(ctx, ISA_MIPS3);
14823 check_mips_64(ctx);
3b4a5489 14824 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14825 break;
14826#endif
14827 case PREF:
14828 /* Treat as no-op */
3b4a5489
YK
14829 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14830 /* hint codes 24-31 are reserved and signal RI */
14831 generate_exception(ctx, EXCP_RI);
14832 }
3c824109
NF
14833 break;
14834 default:
14835 MIPS_INVAL("pool32c");
14836 generate_exception(ctx, EXCP_RI);
14837 break;
14838 }
14839 break;
14840 case ADDI32:
14841 mips32_op = OPC_ADDI;
14842 goto do_addi;
14843 case ADDIU32:
14844 mips32_op = OPC_ADDIU;
14845 do_addi:
d75c135e 14846 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14847 break;
14848
14849 /* Logical operations */
14850 case ORI32:
14851 mips32_op = OPC_ORI;
14852 goto do_logici;
14853 case XORI32:
14854 mips32_op = OPC_XORI;
14855 goto do_logici;
14856 case ANDI32:
14857 mips32_op = OPC_ANDI;
14858 do_logici:
d75c135e 14859 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14860 break;
14861
14862 /* Set less than immediate */
14863 case SLTI32:
14864 mips32_op = OPC_SLTI;
14865 goto do_slti;
14866 case SLTIU32:
14867 mips32_op = OPC_SLTIU;
14868 do_slti:
d75c135e 14869 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14870 break;
14871 case JALX32:
9e8f441a 14872 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14873 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
14874 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14875 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 14876 break;
65935f07
YK
14877 case JALS32: /* BOVC, BEQC, BEQZALC */
14878 if (ctx->insn_flags & ISA_MIPS32R6) {
14879 if (rs >= rt) {
14880 /* BOVC */
14881 mips32_op = OPC_BOVC;
14882 } else if (rs < rt && rs == 0) {
14883 /* BEQZALC */
14884 mips32_op = OPC_BEQZALC;
14885 } else {
14886 /* BEQC */
14887 mips32_op = OPC_BEQC;
14888 }
14889 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14890 } else {
14891 /* JALS32 */
14892 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14893 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14894 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14895 }
3c824109 14896 break;
65935f07
YK
14897 case BEQ32: /* BC */
14898 if (ctx->insn_flags & ISA_MIPS32R6) {
14899 /* BC */
14900 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14901 sextract32(ctx->opcode << 1, 0, 27));
14902 } else {
14903 /* BEQ32 */
14904 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14905 }
3c824109 14906 break;
65935f07
YK
14907 case BNE32: /* BALC */
14908 if (ctx->insn_flags & ISA_MIPS32R6) {
14909 /* BALC */
14910 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14911 sextract32(ctx->opcode << 1, 0, 27));
14912 } else {
14913 /* BNE32 */
14914 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14915 }
3c824109 14916 break;
65935f07
YK
14917 case J32: /* BGTZC, BLTZC, BLTC */
14918 if (ctx->insn_flags & ISA_MIPS32R6) {
14919 if (rs == 0 && rt != 0) {
14920 /* BGTZC */
14921 mips32_op = OPC_BGTZC;
14922 } else if (rs != 0 && rt != 0 && rs == rt) {
14923 /* BLTZC */
14924 mips32_op = OPC_BLTZC;
14925 } else {
14926 /* BLTC */
14927 mips32_op = OPC_BLTC;
14928 }
14929 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14930 } else {
14931 /* J32 */
14932 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14933 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14934 }
3c824109 14935 break;
65935f07
YK
14936 case JAL32: /* BLEZC, BGEZC, BGEC */
14937 if (ctx->insn_flags & ISA_MIPS32R6) {
14938 if (rs == 0 && rt != 0) {
14939 /* BLEZC */
14940 mips32_op = OPC_BLEZC;
14941 } else if (rs != 0 && rt != 0 && rs == rt) {
14942 /* BGEZC */
14943 mips32_op = OPC_BGEZC;
14944 } else {
14945 /* BGEC */
14946 mips32_op = OPC_BGEC;
14947 }
14948 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14949 } else {
14950 /* JAL32 */
14951 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14952 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14953 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14954 }
3c824109
NF
14955 break;
14956 /* Floating point (COP1) */
14957 case LWC132:
14958 mips32_op = OPC_LWC1;
14959 goto do_cop1;
14960 case LDC132:
14961 mips32_op = OPC_LDC1;
14962 goto do_cop1;
14963 case SWC132:
14964 mips32_op = OPC_SWC1;
14965 goto do_cop1;
14966 case SDC132:
14967 mips32_op = OPC_SDC1;
14968 do_cop1:
5ab5c041 14969 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
14970 break;
14971 case ADDIUPC:
14972 {
14973 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14974 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14975
14976 gen_addiupc(ctx, reg, offset, 0, 0);
14977 }
14978 break;
65935f07
YK
14979 case BNVC: /* BNEC, BNEZALC */
14980 check_insn(ctx, ISA_MIPS32R6);
14981 if (rs >= rt) {
14982 /* BNVC */
14983 mips32_op = OPC_BNVC;
14984 } else if (rs < rt && rs == 0) {
14985 /* BNEZALC */
14986 mips32_op = OPC_BNEZALC;
14987 } else {
14988 /* BNEC */
14989 mips32_op = OPC_BNEC;
14990 }
14991 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14992 break;
14993 case R6_BNEZC: /* JIALC */
14994 check_insn(ctx, ISA_MIPS32R6);
14995 if (rt != 0) {
14996 /* BNEZC */
14997 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14998 sextract32(ctx->opcode << 1, 0, 22));
14999 } else {
15000 /* JIALC */
15001 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15002 }
15003 break;
15004 case R6_BEQZC: /* JIC */
15005 check_insn(ctx, ISA_MIPS32R6);
15006 if (rt != 0) {
15007 /* BEQZC */
15008 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15009 sextract32(ctx->opcode << 1, 0, 22));
15010 } else {
15011 /* JIC */
15012 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15013 }
15014 break;
15015 case BLEZALC: /* BGEZALC, BGEUC */
15016 check_insn(ctx, ISA_MIPS32R6);
15017 if (rs == 0 && rt != 0) {
15018 /* BLEZALC */
15019 mips32_op = OPC_BLEZALC;
15020 } else if (rs != 0 && rt != 0 && rs == rt) {
15021 /* BGEZALC */
15022 mips32_op = OPC_BGEZALC;
15023 } else {
15024 /* BGEUC */
15025 mips32_op = OPC_BGEUC;
15026 }
15027 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15028 break;
15029 case BGTZALC: /* BLTZALC, BLTUC */
15030 check_insn(ctx, ISA_MIPS32R6);
15031 if (rs == 0 && rt != 0) {
15032 /* BGTZALC */
15033 mips32_op = OPC_BGTZALC;
15034 } else if (rs != 0 && rt != 0 && rs == rt) {
15035 /* BLTZALC */
15036 mips32_op = OPC_BLTZALC;
15037 } else {
15038 /* BLTUC */
15039 mips32_op = OPC_BLTUC;
15040 }
15041 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15042 break;
3c824109
NF
15043 /* Loads and stores */
15044 case LB32:
15045 mips32_op = OPC_LB;
5c13fdfd 15046 goto do_ld;
3c824109
NF
15047 case LBU32:
15048 mips32_op = OPC_LBU;
5c13fdfd 15049 goto do_ld;
3c824109
NF
15050 case LH32:
15051 mips32_op = OPC_LH;
5c13fdfd 15052 goto do_ld;
3c824109
NF
15053 case LHU32:
15054 mips32_op = OPC_LHU;
5c13fdfd 15055 goto do_ld;
3c824109
NF
15056 case LW32:
15057 mips32_op = OPC_LW;
5c13fdfd 15058 goto do_ld;
3c824109
NF
15059#ifdef TARGET_MIPS64
15060 case LD32:
d9224450
MR
15061 check_insn(ctx, ISA_MIPS3);
15062 check_mips_64(ctx);
3c824109 15063 mips32_op = OPC_LD;
5c13fdfd 15064 goto do_ld;
3c824109 15065 case SD32:
d9224450
MR
15066 check_insn(ctx, ISA_MIPS3);
15067 check_mips_64(ctx);
3c824109 15068 mips32_op = OPC_SD;
5c13fdfd 15069 goto do_st;
3c824109
NF
15070#endif
15071 case SB32:
15072 mips32_op = OPC_SB;
5c13fdfd 15073 goto do_st;
3c824109
NF
15074 case SH32:
15075 mips32_op = OPC_SH;
5c13fdfd 15076 goto do_st;
3c824109
NF
15077 case SW32:
15078 mips32_op = OPC_SW;
5c13fdfd
AJ
15079 goto do_st;
15080 do_ld:
d75c135e 15081 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15082 break;
15083 do_st:
15084 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15085 break;
15086 default:
15087 generate_exception(ctx, EXCP_RI);
15088 break;
15089 }
15090}
15091
240ce26a 15092static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15093{
15094 uint32_t op;
15095
15096 /* make sure instructions are on a halfword boundary */
15097 if (ctx->pc & 0x1) {
15098 env->CP0_BadVAddr = ctx->pc;
15099 generate_exception(ctx, EXCP_AdEL);
15100 ctx->bstate = BS_STOP;
15101 return 2;
15102 }
15103
15104 op = (ctx->opcode >> 10) & 0x3f;
15105 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15106 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15107 switch (op & 0x7) { /* MSB-3..MSB-5 */
15108 case 0:
15109 /* POOL32A, POOL32B, POOL32I, POOL32C */
15110 case 4:
15111 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15112 case 5:
15113 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15114 case 6:
15115 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15116 case 7:
15117 /* LB32, LH32, LWC132, LDC132, LW32 */
15118 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
15119 generate_exception(ctx, EXCP_RI);
15120 /* Just stop translation; the user is confused. */
15121 ctx->bstate = BS_STOP;
15122 return 2;
15123 }
15124 break;
b231c103
YK
15125 case 1:
15126 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15127 case 2:
15128 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15129 case 3:
15130 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15131 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
15132 generate_exception(ctx, EXCP_RI);
15133 /* Just stop translation; the user is confused. */
15134 ctx->bstate = BS_STOP;
15135 return 2;
15136 }
15137 break;
3c824109
NF
15138 }
15139 }
b231c103 15140
3c824109
NF
15141 switch (op) {
15142 case POOL16A:
15143 {
15144 int rd = mmreg(uMIPS_RD(ctx->opcode));
15145 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15146 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15147 uint32_t opc = 0;
15148
15149 switch (ctx->opcode & 0x1) {
15150 case ADDU16:
15151 opc = OPC_ADDU;
15152 break;
15153 case SUBU16:
15154 opc = OPC_SUBU;
15155 break;
15156 }
15157
d75c135e 15158 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
15159 }
15160 break;
15161 case POOL16B:
15162 {
15163 int rd = mmreg(uMIPS_RD(ctx->opcode));
15164 int rs = mmreg(uMIPS_RS(ctx->opcode));
15165 int amount = (ctx->opcode >> 1) & 0x7;
15166 uint32_t opc = 0;
15167 amount = amount == 0 ? 8 : amount;
15168
15169 switch (ctx->opcode & 0x1) {
15170 case SLL16:
15171 opc = OPC_SLL;
15172 break;
15173 case SRL16:
15174 opc = OPC_SRL;
15175 break;
15176 }
15177
d75c135e 15178 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15179 }
15180 break;
15181 case POOL16C:
240ce26a 15182 gen_pool16c_insn(ctx);
3c824109
NF
15183 break;
15184 case LWGP16:
15185 {
15186 int rd = mmreg(uMIPS_RD(ctx->opcode));
15187 int rb = 28; /* GP */
15188 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15189
d75c135e 15190 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15191 }
15192 break;
15193 case POOL16F:
9e8f441a 15194 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15195 if (ctx->opcode & 1) {
15196 generate_exception(ctx, EXCP_RI);
15197 } else {
15198 /* MOVEP */
15199 int enc_dest = uMIPS_RD(ctx->opcode);
15200 int enc_rt = uMIPS_RS2(ctx->opcode);
15201 int enc_rs = uMIPS_RS1(ctx->opcode);
15202 int rd, rs, re, rt;
15203 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15204 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15205 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15206
15207 rd = rd_enc[enc_dest];
15208 re = re_enc[enc_dest];
15209 rs = rs_rt_enc[enc_rs];
15210 rt = rs_rt_enc[enc_rt];
15211
7215d7e7
MR
15212 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15213 gen_arith(ctx, OPC_ADDU, re, rt, 0);
3c824109
NF
15214 }
15215 break;
15216 case LBU16:
15217 {
15218 int rd = mmreg(uMIPS_RD(ctx->opcode));
15219 int rb = mmreg(uMIPS_RS(ctx->opcode));
15220 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15221 offset = (offset == 0xf ? -1 : offset);
15222
d75c135e 15223 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15224 }
15225 break;
15226 case LHU16:
15227 {
15228 int rd = mmreg(uMIPS_RD(ctx->opcode));
15229 int rb = mmreg(uMIPS_RS(ctx->opcode));
15230 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15231
d75c135e 15232 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15233 }
15234 break;
15235 case LWSP16:
15236 {
15237 int rd = (ctx->opcode >> 5) & 0x1f;
15238 int rb = 29; /* SP */
15239 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15240
d75c135e 15241 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15242 }
15243 break;
15244 case LW16:
15245 {
15246 int rd = mmreg(uMIPS_RD(ctx->opcode));
15247 int rb = mmreg(uMIPS_RS(ctx->opcode));
15248 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15249
d75c135e 15250 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15251 }
15252 break;
15253 case SB16:
15254 {
15255 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15256 int rb = mmreg(uMIPS_RS(ctx->opcode));
15257 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15258
5c13fdfd 15259 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15260 }
15261 break;
15262 case SH16:
15263 {
15264 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15265 int rb = mmreg(uMIPS_RS(ctx->opcode));
15266 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15267
5c13fdfd 15268 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15269 }
15270 break;
15271 case SWSP16:
15272 {
15273 int rd = (ctx->opcode >> 5) & 0x1f;
15274 int rb = 29; /* SP */
15275 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15276
5c13fdfd 15277 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15278 }
15279 break;
15280 case SW16:
15281 {
15282 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15283 int rb = mmreg(uMIPS_RS(ctx->opcode));
15284 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15285
5c13fdfd 15286 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15287 }
15288 break;
15289 case MOVE16:
15290 {
15291 int rd = uMIPS_RD5(ctx->opcode);
15292 int rs = uMIPS_RS5(ctx->opcode);
15293
7215d7e7 15294 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15295 }
15296 break;
15297 case ANDI16:
d75c135e 15298 gen_andi16(ctx);
3c824109
NF
15299 break;
15300 case POOL16D:
15301 switch (ctx->opcode & 0x1) {
15302 case ADDIUS5:
d75c135e 15303 gen_addius5(ctx);
3c824109
NF
15304 break;
15305 case ADDIUSP:
d75c135e 15306 gen_addiusp(ctx);
3c824109
NF
15307 break;
15308 }
15309 break;
15310 case POOL16E:
15311 switch (ctx->opcode & 0x1) {
15312 case ADDIUR2:
d75c135e 15313 gen_addiur2(ctx);
3c824109
NF
15314 break;
15315 case ADDIUR1SP:
d75c135e 15316 gen_addiur1sp(ctx);
3c824109
NF
15317 break;
15318 }
15319 break;
65935f07 15320 case B16: /* BC16 */
3c824109 15321 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15322 sextract32(ctx->opcode, 0, 10) << 1,
15323 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15324 break;
65935f07
YK
15325 case BNEZ16: /* BNEZC16 */
15326 case BEQZ16: /* BEQZC16 */
3c824109
NF
15327 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15328 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15329 0, sextract32(ctx->opcode, 0, 7) << 1,
15330 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15331
3c824109
NF
15332 break;
15333 case LI16:
15334 {
15335 int reg = mmreg(uMIPS_RD(ctx->opcode));
15336 int imm = ZIMM(ctx->opcode, 0, 7);
15337
15338 imm = (imm == 0x7f ? -1 : imm);
15339 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15340 }
15341 break;
3c824109 15342 case RES_29:
3c824109 15343 case RES_31:
3c824109
NF
15344 case RES_39:
15345 generate_exception(ctx, EXCP_RI);
15346 break;
15347 default:
f60eeb0c 15348 decode_micromips32_opc(env, ctx);
3c824109
NF
15349 return 4;
15350 }
15351
15352 return 2;
15353}
15354
15355/* SmartMIPS extension to MIPS32 */
15356
15357#if defined(TARGET_MIPS64)
15358
15359/* MDMX extension to MIPS64 */
15360
15361#endif
15362
9b1a1d68 15363/* MIPSDSP functions. */
d75c135e 15364static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15365 int rd, int base, int offset)
15366{
15367 const char *opn = "ldx";
15368 TCGv t0;
15369
9b1a1d68
JL
15370 check_dsp(ctx);
15371 t0 = tcg_temp_new();
15372
15373 if (base == 0) {
15374 gen_load_gpr(t0, offset);
15375 } else if (offset == 0) {
15376 gen_load_gpr(t0, base);
15377 } else {
15378 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15379 }
15380
9b1a1d68
JL
15381 switch (opc) {
15382 case OPC_LBUX:
5f68f5ae 15383 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
15384 gen_store_gpr(t0, rd);
15385 opn = "lbux";
15386 break;
15387 case OPC_LHX:
5f68f5ae 15388 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
15389 gen_store_gpr(t0, rd);
15390 opn = "lhx";
15391 break;
15392 case OPC_LWX:
5f68f5ae 15393 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
15394 gen_store_gpr(t0, rd);
15395 opn = "lwx";
15396 break;
15397#if defined(TARGET_MIPS64)
15398 case OPC_LDX:
5f68f5ae 15399 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
15400 gen_store_gpr(t0, rd);
15401 opn = "ldx";
15402 break;
15403#endif
15404 }
15405 (void)opn; /* avoid a compiler warning */
15406 MIPS_DEBUG("%s %s, %s(%s)", opn,
15407 regnames[rd], regnames[offset], regnames[base]);
15408 tcg_temp_free(t0);
15409}
15410
461c08df
JL
15411static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15412 int ret, int v1, int v2)
15413{
15414 const char *opn = "mipsdsp arith";
15415 TCGv v1_t;
15416 TCGv v2_t;
15417
15418 if (ret == 0) {
15419 /* Treat as NOP. */
15420 MIPS_DEBUG("NOP");
15421 return;
15422 }
15423
15424 v1_t = tcg_temp_new();
15425 v2_t = tcg_temp_new();
15426
15427 gen_load_gpr(v1_t, v1);
15428 gen_load_gpr(v2_t, v2);
15429
15430 switch (op1) {
15431 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15432 case OPC_MULT_G_2E:
15433 check_dspr2(ctx);
15434 switch (op2) {
15435 case OPC_ADDUH_QB:
15436 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15437 break;
15438 case OPC_ADDUH_R_QB:
15439 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15440 break;
15441 case OPC_ADDQH_PH:
15442 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15443 break;
15444 case OPC_ADDQH_R_PH:
15445 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15446 break;
15447 case OPC_ADDQH_W:
15448 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15449 break;
15450 case OPC_ADDQH_R_W:
15451 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15452 break;
15453 case OPC_SUBUH_QB:
15454 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15455 break;
15456 case OPC_SUBUH_R_QB:
15457 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15458 break;
15459 case OPC_SUBQH_PH:
15460 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15461 break;
15462 case OPC_SUBQH_R_PH:
15463 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15464 break;
15465 case OPC_SUBQH_W:
15466 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15467 break;
15468 case OPC_SUBQH_R_W:
15469 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15470 break;
15471 }
15472 break;
15473 case OPC_ABSQ_S_PH_DSP:
15474 switch (op2) {
15475 case OPC_ABSQ_S_QB:
15476 check_dspr2(ctx);
15477 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15478 break;
15479 case OPC_ABSQ_S_PH:
15480 check_dsp(ctx);
15481 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15482 break;
15483 case OPC_ABSQ_S_W:
15484 check_dsp(ctx);
15485 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15486 break;
15487 case OPC_PRECEQ_W_PHL:
15488 check_dsp(ctx);
15489 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15490 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15491 break;
15492 case OPC_PRECEQ_W_PHR:
15493 check_dsp(ctx);
15494 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15495 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15496 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15497 break;
15498 case OPC_PRECEQU_PH_QBL:
15499 check_dsp(ctx);
15500 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15501 break;
15502 case OPC_PRECEQU_PH_QBR:
15503 check_dsp(ctx);
15504 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15505 break;
15506 case OPC_PRECEQU_PH_QBLA:
15507 check_dsp(ctx);
15508 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15509 break;
15510 case OPC_PRECEQU_PH_QBRA:
15511 check_dsp(ctx);
15512 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15513 break;
15514 case OPC_PRECEU_PH_QBL:
15515 check_dsp(ctx);
15516 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15517 break;
15518 case OPC_PRECEU_PH_QBR:
15519 check_dsp(ctx);
15520 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15521 break;
15522 case OPC_PRECEU_PH_QBLA:
15523 check_dsp(ctx);
15524 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15525 break;
15526 case OPC_PRECEU_PH_QBRA:
15527 check_dsp(ctx);
15528 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15529 break;
15530 }
15531 break;
15532 case OPC_ADDU_QB_DSP:
15533 switch (op2) {
15534 case OPC_ADDQ_PH:
15535 check_dsp(ctx);
15536 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15537 break;
15538 case OPC_ADDQ_S_PH:
15539 check_dsp(ctx);
15540 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15541 break;
15542 case OPC_ADDQ_S_W:
15543 check_dsp(ctx);
15544 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15545 break;
15546 case OPC_ADDU_QB:
15547 check_dsp(ctx);
15548 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15549 break;
15550 case OPC_ADDU_S_QB:
15551 check_dsp(ctx);
15552 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15553 break;
15554 case OPC_ADDU_PH:
15555 check_dspr2(ctx);
15556 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15557 break;
15558 case OPC_ADDU_S_PH:
15559 check_dspr2(ctx);
15560 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15561 break;
15562 case OPC_SUBQ_PH:
15563 check_dsp(ctx);
15564 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15565 break;
15566 case OPC_SUBQ_S_PH:
15567 check_dsp(ctx);
15568 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15569 break;
15570 case OPC_SUBQ_S_W:
15571 check_dsp(ctx);
15572 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15573 break;
15574 case OPC_SUBU_QB:
15575 check_dsp(ctx);
15576 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15577 break;
15578 case OPC_SUBU_S_QB:
15579 check_dsp(ctx);
15580 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15581 break;
15582 case OPC_SUBU_PH:
15583 check_dspr2(ctx);
15584 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15585 break;
15586 case OPC_SUBU_S_PH:
15587 check_dspr2(ctx);
15588 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15589 break;
15590 case OPC_ADDSC:
15591 check_dsp(ctx);
15592 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15593 break;
15594 case OPC_ADDWC:
15595 check_dsp(ctx);
15596 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15597 break;
15598 case OPC_MODSUB:
15599 check_dsp(ctx);
15600 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15601 break;
15602 case OPC_RADDU_W_QB:
15603 check_dsp(ctx);
15604 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15605 break;
15606 }
15607 break;
15608 case OPC_CMPU_EQ_QB_DSP:
15609 switch (op2) {
15610 case OPC_PRECR_QB_PH:
15611 check_dspr2(ctx);
15612 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15613 break;
15614 case OPC_PRECRQ_QB_PH:
15615 check_dsp(ctx);
15616 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15617 break;
15618 case OPC_PRECR_SRA_PH_W:
15619 check_dspr2(ctx);
15620 {
15621 TCGv_i32 sa_t = tcg_const_i32(v2);
15622 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15623 cpu_gpr[ret]);
15624 tcg_temp_free_i32(sa_t);
15625 break;
15626 }
15627 case OPC_PRECR_SRA_R_PH_W:
15628 check_dspr2(ctx);
15629 {
15630 TCGv_i32 sa_t = tcg_const_i32(v2);
15631 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15632 cpu_gpr[ret]);
15633 tcg_temp_free_i32(sa_t);
15634 break;
15635 }
15636 case OPC_PRECRQ_PH_W:
15637 check_dsp(ctx);
15638 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15639 break;
15640 case OPC_PRECRQ_RS_PH_W:
15641 check_dsp(ctx);
15642 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15643 break;
15644 case OPC_PRECRQU_S_QB_PH:
15645 check_dsp(ctx);
15646 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15647 break;
15648 }
15649 break;
15650#ifdef TARGET_MIPS64
15651 case OPC_ABSQ_S_QH_DSP:
15652 switch (op2) {
15653 case OPC_PRECEQ_L_PWL:
15654 check_dsp(ctx);
15655 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15656 break;
15657 case OPC_PRECEQ_L_PWR:
15658 check_dsp(ctx);
15659 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15660 break;
15661 case OPC_PRECEQ_PW_QHL:
15662 check_dsp(ctx);
15663 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15664 break;
15665 case OPC_PRECEQ_PW_QHR:
15666 check_dsp(ctx);
15667 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15668 break;
15669 case OPC_PRECEQ_PW_QHLA:
15670 check_dsp(ctx);
15671 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15672 break;
15673 case OPC_PRECEQ_PW_QHRA:
15674 check_dsp(ctx);
15675 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15676 break;
15677 case OPC_PRECEQU_QH_OBL:
15678 check_dsp(ctx);
15679 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15680 break;
15681 case OPC_PRECEQU_QH_OBR:
15682 check_dsp(ctx);
15683 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15684 break;
15685 case OPC_PRECEQU_QH_OBLA:
15686 check_dsp(ctx);
15687 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15688 break;
15689 case OPC_PRECEQU_QH_OBRA:
15690 check_dsp(ctx);
15691 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15692 break;
15693 case OPC_PRECEU_QH_OBL:
15694 check_dsp(ctx);
15695 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15696 break;
15697 case OPC_PRECEU_QH_OBR:
15698 check_dsp(ctx);
15699 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15700 break;
15701 case OPC_PRECEU_QH_OBLA:
15702 check_dsp(ctx);
15703 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15704 break;
15705 case OPC_PRECEU_QH_OBRA:
15706 check_dsp(ctx);
15707 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15708 break;
15709 case OPC_ABSQ_S_OB:
15710 check_dspr2(ctx);
15711 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15712 break;
15713 case OPC_ABSQ_S_PW:
15714 check_dsp(ctx);
15715 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15716 break;
15717 case OPC_ABSQ_S_QH:
15718 check_dsp(ctx);
15719 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15720 break;
15721 }
15722 break;
15723 case OPC_ADDU_OB_DSP:
15724 switch (op2) {
15725 case OPC_RADDU_L_OB:
15726 check_dsp(ctx);
15727 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15728 break;
15729 case OPC_SUBQ_PW:
15730 check_dsp(ctx);
15731 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15732 break;
15733 case OPC_SUBQ_S_PW:
15734 check_dsp(ctx);
15735 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15736 break;
15737 case OPC_SUBQ_QH:
15738 check_dsp(ctx);
15739 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15740 break;
15741 case OPC_SUBQ_S_QH:
15742 check_dsp(ctx);
15743 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15744 break;
15745 case OPC_SUBU_OB:
15746 check_dsp(ctx);
15747 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15748 break;
15749 case OPC_SUBU_S_OB:
15750 check_dsp(ctx);
15751 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15752 break;
15753 case OPC_SUBU_QH:
15754 check_dspr2(ctx);
15755 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15756 break;
15757 case OPC_SUBU_S_QH:
15758 check_dspr2(ctx);
15759 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15760 break;
15761 case OPC_SUBUH_OB:
15762 check_dspr2(ctx);
15763 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15764 break;
15765 case OPC_SUBUH_R_OB:
15766 check_dspr2(ctx);
15767 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15768 break;
15769 case OPC_ADDQ_PW:
15770 check_dsp(ctx);
15771 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15772 break;
15773 case OPC_ADDQ_S_PW:
15774 check_dsp(ctx);
15775 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15776 break;
15777 case OPC_ADDQ_QH:
15778 check_dsp(ctx);
15779 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15780 break;
15781 case OPC_ADDQ_S_QH:
15782 check_dsp(ctx);
15783 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15784 break;
15785 case OPC_ADDU_OB:
15786 check_dsp(ctx);
15787 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15788 break;
15789 case OPC_ADDU_S_OB:
15790 check_dsp(ctx);
15791 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15792 break;
15793 case OPC_ADDU_QH:
15794 check_dspr2(ctx);
15795 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15796 break;
15797 case OPC_ADDU_S_QH:
15798 check_dspr2(ctx);
15799 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15800 break;
15801 case OPC_ADDUH_OB:
15802 check_dspr2(ctx);
15803 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15804 break;
15805 case OPC_ADDUH_R_OB:
15806 check_dspr2(ctx);
15807 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15808 break;
15809 }
15810 break;
15811 case OPC_CMPU_EQ_OB_DSP:
15812 switch (op2) {
15813 case OPC_PRECR_OB_QH:
15814 check_dspr2(ctx);
15815 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15816 break;
15817 case OPC_PRECR_SRA_QH_PW:
15818 check_dspr2(ctx);
15819 {
15820 TCGv_i32 ret_t = tcg_const_i32(ret);
15821 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15822 tcg_temp_free_i32(ret_t);
15823 break;
15824 }
15825 case OPC_PRECR_SRA_R_QH_PW:
15826 check_dspr2(ctx);
15827 {
15828 TCGv_i32 sa_v = tcg_const_i32(ret);
15829 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15830 tcg_temp_free_i32(sa_v);
15831 break;
15832 }
15833 case OPC_PRECRQ_OB_QH:
15834 check_dsp(ctx);
15835 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15836 break;
15837 case OPC_PRECRQ_PW_L:
15838 check_dsp(ctx);
15839 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15840 break;
15841 case OPC_PRECRQ_QH_PW:
15842 check_dsp(ctx);
15843 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15844 break;
15845 case OPC_PRECRQ_RS_QH_PW:
15846 check_dsp(ctx);
15847 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15848 break;
15849 case OPC_PRECRQU_S_OB_QH:
15850 check_dsp(ctx);
15851 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15852 break;
15853 }
15854 break;
15855#endif
15856 }
15857
15858 tcg_temp_free(v1_t);
15859 tcg_temp_free(v2_t);
15860
15861 (void)opn; /* avoid a compiler warning */
15862 MIPS_DEBUG("%s", opn);
15863}
9b1a1d68 15864
77c5fa8b
JL
15865static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15866 int ret, int v1, int v2)
15867{
15868 uint32_t op2;
15869 const char *opn = "mipsdsp shift";
15870 TCGv t0;
15871 TCGv v1_t;
15872 TCGv v2_t;
15873
15874 if (ret == 0) {
15875 /* Treat as NOP. */
15876 MIPS_DEBUG("NOP");
15877 return;
15878 }
15879
15880 t0 = tcg_temp_new();
15881 v1_t = tcg_temp_new();
15882 v2_t = tcg_temp_new();
15883
15884 tcg_gen_movi_tl(t0, v1);
15885 gen_load_gpr(v1_t, v1);
15886 gen_load_gpr(v2_t, v2);
15887
15888 switch (opc) {
15889 case OPC_SHLL_QB_DSP:
15890 {
15891 op2 = MASK_SHLL_QB(ctx->opcode);
15892 switch (op2) {
15893 case OPC_SHLL_QB:
15894 check_dsp(ctx);
15895 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15896 break;
15897 case OPC_SHLLV_QB:
15898 check_dsp(ctx);
15899 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15900 break;
15901 case OPC_SHLL_PH:
15902 check_dsp(ctx);
15903 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15904 break;
15905 case OPC_SHLLV_PH:
15906 check_dsp(ctx);
15907 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15908 break;
15909 case OPC_SHLL_S_PH:
15910 check_dsp(ctx);
15911 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15912 break;
15913 case OPC_SHLLV_S_PH:
15914 check_dsp(ctx);
15915 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15916 break;
15917 case OPC_SHLL_S_W:
15918 check_dsp(ctx);
15919 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15920 break;
15921 case OPC_SHLLV_S_W:
15922 check_dsp(ctx);
15923 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15924 break;
15925 case OPC_SHRL_QB:
15926 check_dsp(ctx);
15927 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15928 break;
15929 case OPC_SHRLV_QB:
15930 check_dsp(ctx);
15931 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15932 break;
15933 case OPC_SHRL_PH:
15934 check_dspr2(ctx);
15935 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15936 break;
15937 case OPC_SHRLV_PH:
15938 check_dspr2(ctx);
15939 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15940 break;
15941 case OPC_SHRA_QB:
15942 check_dspr2(ctx);
15943 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15944 break;
15945 case OPC_SHRA_R_QB:
15946 check_dspr2(ctx);
15947 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15948 break;
15949 case OPC_SHRAV_QB:
15950 check_dspr2(ctx);
15951 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15952 break;
15953 case OPC_SHRAV_R_QB:
15954 check_dspr2(ctx);
15955 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15956 break;
15957 case OPC_SHRA_PH:
15958 check_dsp(ctx);
15959 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15960 break;
15961 case OPC_SHRA_R_PH:
15962 check_dsp(ctx);
15963 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15964 break;
15965 case OPC_SHRAV_PH:
15966 check_dsp(ctx);
15967 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15968 break;
15969 case OPC_SHRAV_R_PH:
15970 check_dsp(ctx);
15971 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15972 break;
15973 case OPC_SHRA_R_W:
15974 check_dsp(ctx);
15975 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15976 break;
15977 case OPC_SHRAV_R_W:
15978 check_dsp(ctx);
15979 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15980 break;
15981 default: /* Invalid */
15982 MIPS_INVAL("MASK SHLL.QB");
15983 generate_exception(ctx, EXCP_RI);
15984 break;
15985 }
15986 break;
15987 }
15988#ifdef TARGET_MIPS64
15989 case OPC_SHLL_OB_DSP:
15990 op2 = MASK_SHLL_OB(ctx->opcode);
15991 switch (op2) {
15992 case OPC_SHLL_PW:
15993 check_dsp(ctx);
15994 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15995 break;
15996 case OPC_SHLLV_PW:
15997 check_dsp(ctx);
15998 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15999 break;
16000 case OPC_SHLL_S_PW:
16001 check_dsp(ctx);
16002 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16003 break;
16004 case OPC_SHLLV_S_PW:
16005 check_dsp(ctx);
16006 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16007 break;
16008 case OPC_SHLL_OB:
16009 check_dsp(ctx);
16010 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16011 break;
16012 case OPC_SHLLV_OB:
16013 check_dsp(ctx);
16014 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16015 break;
16016 case OPC_SHLL_QH:
16017 check_dsp(ctx);
16018 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16019 break;
16020 case OPC_SHLLV_QH:
16021 check_dsp(ctx);
16022 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16023 break;
16024 case OPC_SHLL_S_QH:
16025 check_dsp(ctx);
16026 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16027 break;
16028 case OPC_SHLLV_S_QH:
16029 check_dsp(ctx);
16030 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16031 break;
16032 case OPC_SHRA_OB:
16033 check_dspr2(ctx);
16034 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16035 break;
16036 case OPC_SHRAV_OB:
16037 check_dspr2(ctx);
16038 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16039 break;
16040 case OPC_SHRA_R_OB:
16041 check_dspr2(ctx);
16042 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16043 break;
16044 case OPC_SHRAV_R_OB:
16045 check_dspr2(ctx);
16046 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16047 break;
16048 case OPC_SHRA_PW:
16049 check_dsp(ctx);
16050 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16051 break;
16052 case OPC_SHRAV_PW:
16053 check_dsp(ctx);
16054 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16055 break;
16056 case OPC_SHRA_R_PW:
16057 check_dsp(ctx);
16058 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16059 break;
16060 case OPC_SHRAV_R_PW:
16061 check_dsp(ctx);
16062 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16063 break;
16064 case OPC_SHRA_QH:
16065 check_dsp(ctx);
16066 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16067 break;
16068 case OPC_SHRAV_QH:
16069 check_dsp(ctx);
16070 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16071 break;
16072 case OPC_SHRA_R_QH:
16073 check_dsp(ctx);
16074 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16075 break;
16076 case OPC_SHRAV_R_QH:
16077 check_dsp(ctx);
16078 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16079 break;
16080 case OPC_SHRL_OB:
16081 check_dsp(ctx);
16082 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16083 break;
16084 case OPC_SHRLV_OB:
16085 check_dsp(ctx);
16086 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16087 break;
16088 case OPC_SHRL_QH:
16089 check_dspr2(ctx);
16090 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16091 break;
16092 case OPC_SHRLV_QH:
16093 check_dspr2(ctx);
16094 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16095 break;
16096 default: /* Invalid */
16097 MIPS_INVAL("MASK SHLL.OB");
16098 generate_exception(ctx, EXCP_RI);
16099 break;
16100 }
16101 break;
16102#endif
16103 }
16104
16105 tcg_temp_free(t0);
16106 tcg_temp_free(v1_t);
16107 tcg_temp_free(v2_t);
16108 (void)opn; /* avoid a compiler warning */
16109 MIPS_DEBUG("%s", opn);
16110}
16111
a22260ae
JL
16112static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16113 int ret, int v1, int v2, int check_ret)
16114{
16115 const char *opn = "mipsdsp multiply";
16116 TCGv_i32 t0;
16117 TCGv v1_t;
16118 TCGv v2_t;
16119
16120 if ((ret == 0) && (check_ret == 1)) {
16121 /* Treat as NOP. */
16122 MIPS_DEBUG("NOP");
16123 return;
16124 }
16125
16126 t0 = tcg_temp_new_i32();
16127 v1_t = tcg_temp_new();
16128 v2_t = tcg_temp_new();
16129
16130 tcg_gen_movi_i32(t0, ret);
16131 gen_load_gpr(v1_t, v1);
16132 gen_load_gpr(v2_t, v2);
16133
16134 switch (op1) {
16135 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16136 * the same mask and op1. */
16137 case OPC_MULT_G_2E:
639eadb9 16138 check_dspr2(ctx);
a22260ae
JL
16139 switch (op2) {
16140 case OPC_MUL_PH:
16141 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16142 break;
16143 case OPC_MUL_S_PH:
16144 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16145 break;
16146 case OPC_MULQ_S_W:
16147 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16148 break;
16149 case OPC_MULQ_RS_W:
16150 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16151 break;
16152 }
16153 break;
16154 case OPC_DPA_W_PH_DSP:
16155 switch (op2) {
16156 case OPC_DPAU_H_QBL:
16157 check_dsp(ctx);
16158 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16159 break;
16160 case OPC_DPAU_H_QBR:
16161 check_dsp(ctx);
16162 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16163 break;
16164 case OPC_DPSU_H_QBL:
16165 check_dsp(ctx);
16166 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16167 break;
16168 case OPC_DPSU_H_QBR:
16169 check_dsp(ctx);
16170 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16171 break;
16172 case OPC_DPA_W_PH:
16173 check_dspr2(ctx);
16174 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16175 break;
16176 case OPC_DPAX_W_PH:
16177 check_dspr2(ctx);
16178 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16179 break;
16180 case OPC_DPAQ_S_W_PH:
16181 check_dsp(ctx);
16182 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16183 break;
16184 case OPC_DPAQX_S_W_PH:
16185 check_dspr2(ctx);
16186 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16187 break;
16188 case OPC_DPAQX_SA_W_PH:
16189 check_dspr2(ctx);
16190 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16191 break;
16192 case OPC_DPS_W_PH:
16193 check_dspr2(ctx);
16194 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16195 break;
16196 case OPC_DPSX_W_PH:
16197 check_dspr2(ctx);
16198 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16199 break;
16200 case OPC_DPSQ_S_W_PH:
16201 check_dsp(ctx);
16202 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16203 break;
16204 case OPC_DPSQX_S_W_PH:
16205 check_dspr2(ctx);
16206 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16207 break;
16208 case OPC_DPSQX_SA_W_PH:
16209 check_dspr2(ctx);
16210 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16211 break;
16212 case OPC_MULSAQ_S_W_PH:
16213 check_dsp(ctx);
16214 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16215 break;
16216 case OPC_DPAQ_SA_L_W:
16217 check_dsp(ctx);
16218 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16219 break;
16220 case OPC_DPSQ_SA_L_W:
16221 check_dsp(ctx);
16222 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16223 break;
16224 case OPC_MAQ_S_W_PHL:
16225 check_dsp(ctx);
16226 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16227 break;
16228 case OPC_MAQ_S_W_PHR:
16229 check_dsp(ctx);
16230 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16231 break;
16232 case OPC_MAQ_SA_W_PHL:
16233 check_dsp(ctx);
16234 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16235 break;
16236 case OPC_MAQ_SA_W_PHR:
16237 check_dsp(ctx);
16238 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16239 break;
16240 case OPC_MULSA_W_PH:
16241 check_dspr2(ctx);
16242 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16243 break;
16244 }
16245 break;
16246#ifdef TARGET_MIPS64
16247 case OPC_DPAQ_W_QH_DSP:
16248 {
16249 int ac = ret & 0x03;
16250 tcg_gen_movi_i32(t0, ac);
16251
16252 switch (op2) {
16253 case OPC_DMADD:
16254 check_dsp(ctx);
16255 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16256 break;
16257 case OPC_DMADDU:
16258 check_dsp(ctx);
16259 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16260 break;
16261 case OPC_DMSUB:
16262 check_dsp(ctx);
16263 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16264 break;
16265 case OPC_DMSUBU:
16266 check_dsp(ctx);
16267 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16268 break;
16269 case OPC_DPA_W_QH:
16270 check_dspr2(ctx);
16271 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16272 break;
16273 case OPC_DPAQ_S_W_QH:
16274 check_dsp(ctx);
16275 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16276 break;
16277 case OPC_DPAQ_SA_L_PW:
16278 check_dsp(ctx);
16279 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16280 break;
16281 case OPC_DPAU_H_OBL:
16282 check_dsp(ctx);
16283 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16284 break;
16285 case OPC_DPAU_H_OBR:
16286 check_dsp(ctx);
16287 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16288 break;
16289 case OPC_DPS_W_QH:
16290 check_dspr2(ctx);
16291 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16292 break;
16293 case OPC_DPSQ_S_W_QH:
16294 check_dsp(ctx);
16295 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16296 break;
16297 case OPC_DPSQ_SA_L_PW:
16298 check_dsp(ctx);
16299 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16300 break;
16301 case OPC_DPSU_H_OBL:
16302 check_dsp(ctx);
16303 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16304 break;
16305 case OPC_DPSU_H_OBR:
16306 check_dsp(ctx);
16307 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16308 break;
16309 case OPC_MAQ_S_L_PWL:
16310 check_dsp(ctx);
16311 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16312 break;
16313 case OPC_MAQ_S_L_PWR:
16314 check_dsp(ctx);
16315 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16316 break;
16317 case OPC_MAQ_S_W_QHLL:
16318 check_dsp(ctx);
16319 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16320 break;
16321 case OPC_MAQ_SA_W_QHLL:
16322 check_dsp(ctx);
16323 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16324 break;
16325 case OPC_MAQ_S_W_QHLR:
16326 check_dsp(ctx);
16327 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16328 break;
16329 case OPC_MAQ_SA_W_QHLR:
16330 check_dsp(ctx);
16331 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16332 break;
16333 case OPC_MAQ_S_W_QHRL:
16334 check_dsp(ctx);
16335 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16336 break;
16337 case OPC_MAQ_SA_W_QHRL:
16338 check_dsp(ctx);
16339 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16340 break;
16341 case OPC_MAQ_S_W_QHRR:
16342 check_dsp(ctx);
16343 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16344 break;
16345 case OPC_MAQ_SA_W_QHRR:
16346 check_dsp(ctx);
16347 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16348 break;
16349 case OPC_MULSAQ_S_L_PW:
16350 check_dsp(ctx);
16351 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16352 break;
16353 case OPC_MULSAQ_S_W_QH:
16354 check_dsp(ctx);
16355 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16356 break;
16357 }
16358 }
16359 break;
16360#endif
16361 case OPC_ADDU_QB_DSP:
16362 switch (op2) {
16363 case OPC_MULEU_S_PH_QBL:
16364 check_dsp(ctx);
16365 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16366 break;
16367 case OPC_MULEU_S_PH_QBR:
16368 check_dsp(ctx);
16369 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16370 break;
16371 case OPC_MULQ_RS_PH:
16372 check_dsp(ctx);
16373 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16374 break;
16375 case OPC_MULEQ_S_W_PHL:
16376 check_dsp(ctx);
16377 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16378 break;
16379 case OPC_MULEQ_S_W_PHR:
16380 check_dsp(ctx);
16381 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16382 break;
16383 case OPC_MULQ_S_PH:
16384 check_dspr2(ctx);
16385 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16386 break;
16387 }
16388 break;
16389#ifdef TARGET_MIPS64
16390 case OPC_ADDU_OB_DSP:
16391 switch (op2) {
16392 case OPC_MULEQ_S_PW_QHL:
16393 check_dsp(ctx);
16394 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16395 break;
16396 case OPC_MULEQ_S_PW_QHR:
16397 check_dsp(ctx);
16398 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16399 break;
16400 case OPC_MULEU_S_QH_OBL:
16401 check_dsp(ctx);
16402 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16403 break;
16404 case OPC_MULEU_S_QH_OBR:
16405 check_dsp(ctx);
16406 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16407 break;
16408 case OPC_MULQ_RS_QH:
16409 check_dsp(ctx);
16410 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16411 break;
16412 }
16413 break;
16414#endif
16415 }
16416
16417 tcg_temp_free_i32(t0);
16418 tcg_temp_free(v1_t);
16419 tcg_temp_free(v2_t);
16420
16421 (void)opn; /* avoid a compiler warning */
16422 MIPS_DEBUG("%s", opn);
16423
16424}
16425
d75c135e 16426static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16427 int ret, int val)
16428{
16429 const char *opn = "mipsdsp Bit/ Manipulation";
16430 int16_t imm;
16431 TCGv t0;
16432 TCGv val_t;
16433
16434 if (ret == 0) {
16435 /* Treat as NOP. */
16436 MIPS_DEBUG("NOP");
16437 return;
16438 }
16439
16440 t0 = tcg_temp_new();
16441 val_t = tcg_temp_new();
16442 gen_load_gpr(val_t, val);
16443
16444 switch (op1) {
16445 case OPC_ABSQ_S_PH_DSP:
16446 switch (op2) {
16447 case OPC_BITREV:
16448 check_dsp(ctx);
16449 gen_helper_bitrev(cpu_gpr[ret], val_t);
16450 break;
16451 case OPC_REPL_QB:
16452 check_dsp(ctx);
16453 {
16454 target_long result;
16455 imm = (ctx->opcode >> 16) & 0xFF;
16456 result = (uint32_t)imm << 24 |
16457 (uint32_t)imm << 16 |
16458 (uint32_t)imm << 8 |
16459 (uint32_t)imm;
16460 result = (int32_t)result;
16461 tcg_gen_movi_tl(cpu_gpr[ret], result);
16462 }
16463 break;
16464 case OPC_REPLV_QB:
16465 check_dsp(ctx);
16466 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16467 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16468 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16469 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16470 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16471 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16472 break;
16473 case OPC_REPL_PH:
16474 check_dsp(ctx);
16475 {
16476 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16477 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16478 tcg_gen_movi_tl(cpu_gpr[ret], \
16479 (target_long)((int32_t)imm << 16 | \
c4aaba92 16480 (uint16_t)imm));
1cb6686c
JL
16481 }
16482 break;
16483 case OPC_REPLV_PH:
16484 check_dsp(ctx);
16485 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16486 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16487 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16488 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16489 break;
16490 }
16491 break;
16492#ifdef TARGET_MIPS64
16493 case OPC_ABSQ_S_QH_DSP:
16494 switch (op2) {
16495 case OPC_REPL_OB:
16496 check_dsp(ctx);
16497 {
16498 target_long temp;
16499
16500 imm = (ctx->opcode >> 16) & 0xFF;
16501 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16502 temp = (temp << 16) | temp;
16503 temp = (temp << 32) | temp;
16504 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16505 break;
16506 }
16507 case OPC_REPL_PW:
16508 check_dsp(ctx);
16509 {
16510 target_long temp;
16511
16512 imm = (ctx->opcode >> 16) & 0x03FF;
16513 imm = (int16_t)(imm << 6) >> 6;
16514 temp = ((target_long)imm << 32) \
16515 | ((target_long)imm & 0xFFFFFFFF);
16516 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16517 break;
16518 }
16519 case OPC_REPL_QH:
16520 check_dsp(ctx);
16521 {
16522 target_long temp;
16523
16524 imm = (ctx->opcode >> 16) & 0x03FF;
16525 imm = (int16_t)(imm << 6) >> 6;
16526
16527 temp = ((uint64_t)(uint16_t)imm << 48) |
16528 ((uint64_t)(uint16_t)imm << 32) |
16529 ((uint64_t)(uint16_t)imm << 16) |
16530 (uint64_t)(uint16_t)imm;
16531 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16532 break;
16533 }
16534 case OPC_REPLV_OB:
16535 check_dsp(ctx);
16536 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16537 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16538 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16539 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16540 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16541 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16542 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16543 break;
16544 case OPC_REPLV_PW:
16545 check_dsp(ctx);
16546 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16547 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16548 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16549 break;
16550 case OPC_REPLV_QH:
16551 check_dsp(ctx);
16552 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16553 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16554 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16555 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16556 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16557 break;
16558 }
16559 break;
16560#endif
16561 }
16562 tcg_temp_free(t0);
16563 tcg_temp_free(val_t);
16564
16565 (void)opn; /* avoid a compiler warning */
16566 MIPS_DEBUG("%s", opn);
16567}
16568
26690560
JL
16569static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16570 uint32_t op1, uint32_t op2,
16571 int ret, int v1, int v2, int check_ret)
16572{
16573 const char *opn = "mipsdsp add compare pick";
26690560
JL
16574 TCGv t1;
16575 TCGv v1_t;
16576 TCGv v2_t;
16577
16578 if ((ret == 0) && (check_ret == 1)) {
16579 /* Treat as NOP. */
16580 MIPS_DEBUG("NOP");
16581 return;
16582 }
16583
26690560
JL
16584 t1 = tcg_temp_new();
16585 v1_t = tcg_temp_new();
16586 v2_t = tcg_temp_new();
16587
16588 gen_load_gpr(v1_t, v1);
16589 gen_load_gpr(v2_t, v2);
16590
16591 switch (op1) {
26690560
JL
16592 case OPC_CMPU_EQ_QB_DSP:
16593 switch (op2) {
16594 case OPC_CMPU_EQ_QB:
16595 check_dsp(ctx);
16596 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16597 break;
16598 case OPC_CMPU_LT_QB:
16599 check_dsp(ctx);
16600 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16601 break;
16602 case OPC_CMPU_LE_QB:
16603 check_dsp(ctx);
16604 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16605 break;
16606 case OPC_CMPGU_EQ_QB:
16607 check_dsp(ctx);
16608 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16609 break;
16610 case OPC_CMPGU_LT_QB:
16611 check_dsp(ctx);
16612 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16613 break;
16614 case OPC_CMPGU_LE_QB:
16615 check_dsp(ctx);
16616 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16617 break;
16618 case OPC_CMPGDU_EQ_QB:
16619 check_dspr2(ctx);
16620 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16621 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16622 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16623 tcg_gen_shli_tl(t1, t1, 24);
16624 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16625 break;
16626 case OPC_CMPGDU_LT_QB:
16627 check_dspr2(ctx);
16628 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16629 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16630 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16631 tcg_gen_shli_tl(t1, t1, 24);
16632 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16633 break;
16634 case OPC_CMPGDU_LE_QB:
16635 check_dspr2(ctx);
16636 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16637 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16638 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16639 tcg_gen_shli_tl(t1, t1, 24);
16640 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16641 break;
16642 case OPC_CMP_EQ_PH:
16643 check_dsp(ctx);
16644 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16645 break;
16646 case OPC_CMP_LT_PH:
16647 check_dsp(ctx);
16648 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16649 break;
16650 case OPC_CMP_LE_PH:
16651 check_dsp(ctx);
16652 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16653 break;
16654 case OPC_PICK_QB:
16655 check_dsp(ctx);
16656 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16657 break;
16658 case OPC_PICK_PH:
16659 check_dsp(ctx);
16660 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16661 break;
16662 case OPC_PACKRL_PH:
16663 check_dsp(ctx);
16664 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16665 break;
16666 }
16667 break;
16668#ifdef TARGET_MIPS64
16669 case OPC_CMPU_EQ_OB_DSP:
16670 switch (op2) {
16671 case OPC_CMP_EQ_PW:
16672 check_dsp(ctx);
16673 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16674 break;
16675 case OPC_CMP_LT_PW:
16676 check_dsp(ctx);
16677 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16678 break;
16679 case OPC_CMP_LE_PW:
16680 check_dsp(ctx);
16681 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16682 break;
16683 case OPC_CMP_EQ_QH:
16684 check_dsp(ctx);
16685 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16686 break;
16687 case OPC_CMP_LT_QH:
16688 check_dsp(ctx);
16689 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16690 break;
16691 case OPC_CMP_LE_QH:
16692 check_dsp(ctx);
16693 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16694 break;
16695 case OPC_CMPGDU_EQ_OB:
16696 check_dspr2(ctx);
16697 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16698 break;
16699 case OPC_CMPGDU_LT_OB:
16700 check_dspr2(ctx);
16701 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16702 break;
16703 case OPC_CMPGDU_LE_OB:
16704 check_dspr2(ctx);
16705 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16706 break;
16707 case OPC_CMPGU_EQ_OB:
16708 check_dsp(ctx);
16709 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16710 break;
16711 case OPC_CMPGU_LT_OB:
16712 check_dsp(ctx);
16713 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16714 break;
16715 case OPC_CMPGU_LE_OB:
16716 check_dsp(ctx);
16717 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16718 break;
16719 case OPC_CMPU_EQ_OB:
16720 check_dsp(ctx);
16721 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16722 break;
16723 case OPC_CMPU_LT_OB:
16724 check_dsp(ctx);
16725 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16726 break;
16727 case OPC_CMPU_LE_OB:
16728 check_dsp(ctx);
16729 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16730 break;
16731 case OPC_PACKRL_PW:
16732 check_dsp(ctx);
16733 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16734 break;
16735 case OPC_PICK_OB:
16736 check_dsp(ctx);
16737 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16738 break;
16739 case OPC_PICK_PW:
16740 check_dsp(ctx);
16741 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16742 break;
16743 case OPC_PICK_QH:
16744 check_dsp(ctx);
16745 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16746 break;
16747 }
16748 break;
df6126a7
AJ
16749#endif
16750 }
16751
16752 tcg_temp_free(t1);
16753 tcg_temp_free(v1_t);
16754 tcg_temp_free(v2_t);
16755
16756 (void)opn; /* avoid a compiler warning */
16757 MIPS_DEBUG("%s", opn);
16758}
16759
16760static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16761 uint32_t op1, int rt, int rs, int sa)
16762{
16763 const char *opn = "mipsdsp append/dappend";
16764 TCGv t0;
16765
16766 check_dspr2(ctx);
16767
16768 if (rt == 0) {
16769 /* Treat as NOP. */
16770 MIPS_DEBUG("NOP");
16771 return;
16772 }
16773
16774 t0 = tcg_temp_new();
16775 gen_load_gpr(t0, rs);
16776
16777 switch (op1) {
16778 case OPC_APPEND_DSP:
16779 switch (MASK_APPEND(ctx->opcode)) {
16780 case OPC_APPEND:
16781 if (sa != 0) {
16782 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16783 }
16784 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16785 break;
16786 case OPC_PREPEND:
16787 if (sa != 0) {
16788 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16789 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16790 tcg_gen_shli_tl(t0, t0, 32 - sa);
16791 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16792 }
16793 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16794 break;
16795 case OPC_BALIGN:
16796 sa &= 3;
16797 if (sa != 0 && sa != 2) {
16798 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16799 tcg_gen_ext32u_tl(t0, t0);
16800 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16801 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16802 }
16803 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16804 break;
16805 default: /* Invalid */
16806 MIPS_INVAL("MASK APPEND");
16807 generate_exception(ctx, EXCP_RI);
16808 break;
16809 }
16810 break;
16811#ifdef TARGET_MIPS64
26690560 16812 case OPC_DAPPEND_DSP:
df6126a7 16813 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16814 case OPC_DAPPEND:
df6126a7
AJ
16815 if (sa != 0) {
16816 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16817 }
26690560
JL
16818 break;
16819 case OPC_PREPENDD:
df6126a7
AJ
16820 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16821 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16822 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16823 break;
16824 case OPC_PREPENDW:
df6126a7
AJ
16825 if (sa != 0) {
16826 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16827 tcg_gen_shli_tl(t0, t0, 64 - sa);
16828 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16829 }
26690560
JL
16830 break;
16831 case OPC_DBALIGN:
df6126a7
AJ
16832 sa &= 7;
16833 if (sa != 0 && sa != 2 && sa != 4) {
16834 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16835 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16836 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16837 }
26690560
JL
16838 break;
16839 default: /* Invalid */
16840 MIPS_INVAL("MASK DAPPEND");
16841 generate_exception(ctx, EXCP_RI);
16842 break;
16843 }
16844 break;
16845#endif
16846 }
df6126a7 16847 tcg_temp_free(t0);
26690560
JL
16848 (void)opn; /* avoid a compiler warning */
16849 MIPS_DEBUG("%s", opn);
16850}
16851
b53371ed
JL
16852static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16853 int ret, int v1, int v2, int check_ret)
16854
16855{
16856 const char *opn = "mipsdsp accumulator";
16857 TCGv t0;
16858 TCGv t1;
16859 TCGv v1_t;
16860 TCGv v2_t;
16861 int16_t imm;
16862
16863 if ((ret == 0) && (check_ret == 1)) {
16864 /* Treat as NOP. */
16865 MIPS_DEBUG("NOP");
16866 return;
16867 }
16868
16869 t0 = tcg_temp_new();
16870 t1 = tcg_temp_new();
16871 v1_t = tcg_temp_new();
16872 v2_t = tcg_temp_new();
16873
16874 gen_load_gpr(v1_t, v1);
16875 gen_load_gpr(v2_t, v2);
16876
16877 switch (op1) {
16878 case OPC_EXTR_W_DSP:
16879 check_dsp(ctx);
16880 switch (op2) {
16881 case OPC_EXTR_W:
16882 tcg_gen_movi_tl(t0, v2);
16883 tcg_gen_movi_tl(t1, v1);
16884 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16885 break;
16886 case OPC_EXTR_R_W:
16887 tcg_gen_movi_tl(t0, v2);
16888 tcg_gen_movi_tl(t1, v1);
16889 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16890 break;
16891 case OPC_EXTR_RS_W:
16892 tcg_gen_movi_tl(t0, v2);
16893 tcg_gen_movi_tl(t1, v1);
16894 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16895 break;
16896 case OPC_EXTR_S_H:
16897 tcg_gen_movi_tl(t0, v2);
16898 tcg_gen_movi_tl(t1, v1);
16899 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16900 break;
16901 case OPC_EXTRV_S_H:
16902 tcg_gen_movi_tl(t0, v2);
16903 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16904 break;
16905 case OPC_EXTRV_W:
16906 tcg_gen_movi_tl(t0, v2);
16907 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16908 break;
16909 case OPC_EXTRV_R_W:
16910 tcg_gen_movi_tl(t0, v2);
16911 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16912 break;
16913 case OPC_EXTRV_RS_W:
16914 tcg_gen_movi_tl(t0, v2);
16915 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16916 break;
16917 case OPC_EXTP:
16918 tcg_gen_movi_tl(t0, v2);
16919 tcg_gen_movi_tl(t1, v1);
16920 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16921 break;
16922 case OPC_EXTPV:
16923 tcg_gen_movi_tl(t0, v2);
16924 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16925 break;
16926 case OPC_EXTPDP:
16927 tcg_gen_movi_tl(t0, v2);
16928 tcg_gen_movi_tl(t1, v1);
16929 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16930 break;
16931 case OPC_EXTPDPV:
16932 tcg_gen_movi_tl(t0, v2);
16933 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16934 break;
16935 case OPC_SHILO:
16936 imm = (ctx->opcode >> 20) & 0x3F;
16937 tcg_gen_movi_tl(t0, ret);
16938 tcg_gen_movi_tl(t1, imm);
16939 gen_helper_shilo(t0, t1, cpu_env);
16940 break;
16941 case OPC_SHILOV:
16942 tcg_gen_movi_tl(t0, ret);
16943 gen_helper_shilo(t0, v1_t, cpu_env);
16944 break;
16945 case OPC_MTHLIP:
16946 tcg_gen_movi_tl(t0, ret);
16947 gen_helper_mthlip(t0, v1_t, cpu_env);
16948 break;
16949 case OPC_WRDSP:
16950 imm = (ctx->opcode >> 11) & 0x3FF;
16951 tcg_gen_movi_tl(t0, imm);
16952 gen_helper_wrdsp(v1_t, t0, cpu_env);
16953 break;
16954 case OPC_RDDSP:
16955 imm = (ctx->opcode >> 16) & 0x03FF;
16956 tcg_gen_movi_tl(t0, imm);
16957 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16958 break;
16959 }
16960 break;
16961#ifdef TARGET_MIPS64
16962 case OPC_DEXTR_W_DSP:
16963 check_dsp(ctx);
16964 switch (op2) {
16965 case OPC_DMTHLIP:
16966 tcg_gen_movi_tl(t0, ret);
16967 gen_helper_dmthlip(v1_t, t0, cpu_env);
16968 break;
16969 case OPC_DSHILO:
16970 {
16971 int shift = (ctx->opcode >> 19) & 0x7F;
16972 int ac = (ctx->opcode >> 11) & 0x03;
16973 tcg_gen_movi_tl(t0, shift);
16974 tcg_gen_movi_tl(t1, ac);
16975 gen_helper_dshilo(t0, t1, cpu_env);
16976 break;
16977 }
16978 case OPC_DSHILOV:
16979 {
16980 int ac = (ctx->opcode >> 11) & 0x03;
16981 tcg_gen_movi_tl(t0, ac);
16982 gen_helper_dshilo(v1_t, t0, cpu_env);
16983 break;
16984 }
16985 case OPC_DEXTP:
16986 tcg_gen_movi_tl(t0, v2);
16987 tcg_gen_movi_tl(t1, v1);
16988
16989 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16990 break;
16991 case OPC_DEXTPV:
16992 tcg_gen_movi_tl(t0, v2);
16993 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16994 break;
16995 case OPC_DEXTPDP:
16996 tcg_gen_movi_tl(t0, v2);
16997 tcg_gen_movi_tl(t1, v1);
16998 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16999 break;
17000 case OPC_DEXTPDPV:
17001 tcg_gen_movi_tl(t0, v2);
17002 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17003 break;
17004 case OPC_DEXTR_L:
17005 tcg_gen_movi_tl(t0, v2);
17006 tcg_gen_movi_tl(t1, v1);
17007 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17008 break;
17009 case OPC_DEXTR_R_L:
17010 tcg_gen_movi_tl(t0, v2);
17011 tcg_gen_movi_tl(t1, v1);
17012 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17013 break;
17014 case OPC_DEXTR_RS_L:
17015 tcg_gen_movi_tl(t0, v2);
17016 tcg_gen_movi_tl(t1, v1);
17017 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17018 break;
17019 case OPC_DEXTR_W:
17020 tcg_gen_movi_tl(t0, v2);
17021 tcg_gen_movi_tl(t1, v1);
17022 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17023 break;
17024 case OPC_DEXTR_R_W:
17025 tcg_gen_movi_tl(t0, v2);
17026 tcg_gen_movi_tl(t1, v1);
17027 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17028 break;
17029 case OPC_DEXTR_RS_W:
17030 tcg_gen_movi_tl(t0, v2);
17031 tcg_gen_movi_tl(t1, v1);
17032 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17033 break;
17034 case OPC_DEXTR_S_H:
17035 tcg_gen_movi_tl(t0, v2);
17036 tcg_gen_movi_tl(t1, v1);
17037 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17038 break;
17039 case OPC_DEXTRV_S_H:
17040 tcg_gen_movi_tl(t0, v2);
17041 tcg_gen_movi_tl(t1, v1);
17042 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17043 break;
17044 case OPC_DEXTRV_L:
17045 tcg_gen_movi_tl(t0, v2);
17046 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17047 break;
17048 case OPC_DEXTRV_R_L:
17049 tcg_gen_movi_tl(t0, v2);
17050 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17051 break;
17052 case OPC_DEXTRV_RS_L:
17053 tcg_gen_movi_tl(t0, v2);
17054 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17055 break;
17056 case OPC_DEXTRV_W:
17057 tcg_gen_movi_tl(t0, v2);
17058 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17059 break;
17060 case OPC_DEXTRV_R_W:
17061 tcg_gen_movi_tl(t0, v2);
17062 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17063 break;
17064 case OPC_DEXTRV_RS_W:
17065 tcg_gen_movi_tl(t0, v2);
17066 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17067 break;
17068 }
17069 break;
17070#endif
17071 }
17072
17073 tcg_temp_free(t0);
17074 tcg_temp_free(t1);
17075 tcg_temp_free(v1_t);
17076 tcg_temp_free(v2_t);
17077
17078 (void)opn; /* avoid a compiler warning */
17079 MIPS_DEBUG("%s", opn);
17080}
17081
9b1a1d68
JL
17082/* End MIPSDSP functions. */
17083
10dc65db
LA
17084static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17085{
4267d3e6 17086 int rs, rt, rd, sa;
b42ee5e1 17087 uint32_t op1, op2;
10dc65db
LA
17088
17089 rs = (ctx->opcode >> 21) & 0x1f;
17090 rt = (ctx->opcode >> 16) & 0x1f;
17091 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 17092 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17093
17094 op1 = MASK_SPECIAL(ctx->opcode);
17095 switch (op1) {
d4ea6acd 17096 case OPC_LSA:
1f1b4c00 17097 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17098 break;
b42ee5e1
LA
17099 case OPC_MULT ... OPC_DIVU:
17100 op2 = MASK_R6_MULDIV(ctx->opcode);
17101 switch (op2) {
17102 case R6_OPC_MUL:
17103 case R6_OPC_MUH:
17104 case R6_OPC_MULU:
17105 case R6_OPC_MUHU:
17106 case R6_OPC_DIV:
17107 case R6_OPC_MOD:
17108 case R6_OPC_DIVU:
17109 case R6_OPC_MODU:
17110 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17111 break;
17112 default:
17113 MIPS_INVAL("special_r6 muldiv");
17114 generate_exception(ctx, EXCP_RI);
17115 break;
17116 }
17117 break;
10dc65db
LA
17118 case OPC_SELEQZ:
17119 case OPC_SELNEZ:
17120 gen_cond_move(ctx, op1, rd, rs, rt);
17121 break;
4267d3e6
LA
17122 case R6_OPC_CLO:
17123 case R6_OPC_CLZ:
17124 if (rt == 0 && sa == 1) {
17125 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17126 We need additionally to check other fields */
17127 gen_cl(ctx, op1, rd, rs);
17128 } else {
17129 generate_exception(ctx, EXCP_RI);
17130 }
17131 break;
17132 case R6_OPC_SDBBP:
3b3c1694
LA
17133 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17134 gen_helper_do_semihosting(cpu_env);
faf1f68b 17135 } else {
3b3c1694
LA
17136 if (ctx->hflags & MIPS_HFLAG_SBRI) {
17137 generate_exception(ctx, EXCP_RI);
17138 } else {
17139 generate_exception(ctx, EXCP_DBp);
17140 }
faf1f68b 17141 }
4267d3e6 17142 break;
b42ee5e1 17143#if defined(TARGET_MIPS64)
d4ea6acd
LA
17144 case OPC_DLSA:
17145 check_mips_64(ctx);
1f1b4c00 17146 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17147 break;
4267d3e6
LA
17148 case R6_OPC_DCLO:
17149 case R6_OPC_DCLZ:
17150 if (rt == 0 && sa == 1) {
17151 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17152 We need additionally to check other fields */
17153 check_mips_64(ctx);
17154 gen_cl(ctx, op1, rd, rs);
17155 } else {
17156 generate_exception(ctx, EXCP_RI);
17157 }
17158 break;
b42ee5e1
LA
17159 case OPC_DMULT ... OPC_DDIVU:
17160 op2 = MASK_R6_MULDIV(ctx->opcode);
17161 switch (op2) {
17162 case R6_OPC_DMUL:
17163 case R6_OPC_DMUH:
17164 case R6_OPC_DMULU:
17165 case R6_OPC_DMUHU:
17166 case R6_OPC_DDIV:
17167 case R6_OPC_DMOD:
17168 case R6_OPC_DDIVU:
17169 case R6_OPC_DMODU:
17170 check_mips_64(ctx);
17171 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17172 break;
17173 default:
17174 MIPS_INVAL("special_r6 muldiv");
17175 generate_exception(ctx, EXCP_RI);
17176 break;
17177 }
17178 break;
17179#endif
10dc65db
LA
17180 default: /* Invalid */
17181 MIPS_INVAL("special_r6");
17182 generate_exception(ctx, EXCP_RI);
17183 break;
17184 }
17185}
17186
17187static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17188{
b42ee5e1 17189 int rs, rt, rd, sa;
10dc65db
LA
17190 uint32_t op1;
17191
17192 rs = (ctx->opcode >> 21) & 0x1f;
17193 rt = (ctx->opcode >> 16) & 0x1f;
17194 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17195 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17196
17197 op1 = MASK_SPECIAL(ctx->opcode);
17198 switch (op1) {
17199 case OPC_MOVN: /* Conditional move */
17200 case OPC_MOVZ:
17201 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17202 INSN_LOONGSON2E | INSN_LOONGSON2F);
17203 gen_cond_move(ctx, op1, rd, rs, rt);
17204 break;
17205 case OPC_MFHI: /* Move from HI/LO */
17206 case OPC_MFLO:
17207 gen_HILO(ctx, op1, rs & 3, rd);
17208 break;
17209 case OPC_MTHI:
17210 case OPC_MTLO: /* Move to HI/LO */
17211 gen_HILO(ctx, op1, rd & 3, rs);
17212 break;
17213 case OPC_MOVCI:
17214 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17215 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17216 check_cp1_enabled(ctx);
17217 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17218 (ctx->opcode >> 16) & 1);
17219 } else {
17220 generate_exception_err(ctx, EXCP_CpU, 1);
17221 }
17222 break;
b42ee5e1
LA
17223 case OPC_MULT:
17224 case OPC_MULTU:
17225 if (sa) {
17226 check_insn(ctx, INSN_VR54XX);
17227 op1 = MASK_MUL_VR54XX(ctx->opcode);
17228 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17229 } else {
17230 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17231 }
17232 break;
17233 case OPC_DIV:
17234 case OPC_DIVU:
17235 gen_muldiv(ctx, op1, 0, rs, rt);
17236 break;
17237#if defined(TARGET_MIPS64)
17238 case OPC_DMULT ... OPC_DDIVU:
17239 check_insn(ctx, ISA_MIPS3);
17240 check_mips_64(ctx);
17241 gen_muldiv(ctx, op1, 0, rs, rt);
17242 break;
17243#endif
0aefa333 17244 case OPC_JR:
b231c103 17245 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17246 break;
4267d3e6
LA
17247 case OPC_SPIM:
17248#ifdef MIPS_STRICT_STANDARD
17249 MIPS_INVAL("SPIM");
17250 generate_exception(ctx, EXCP_RI);
17251#else
17252 /* Implemented as RI exception for now. */
17253 MIPS_INVAL("spim (unofficial)");
17254 generate_exception(ctx, EXCP_RI);
17255#endif
17256 break;
10dc65db
LA
17257 default: /* Invalid */
17258 MIPS_INVAL("special_legacy");
17259 generate_exception(ctx, EXCP_RI);
17260 break;
17261 }
17262}
17263
099e5b4d 17264static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17265{
3c824109 17266 int rs, rt, rd, sa;
099e5b4d 17267 uint32_t op1;
3c824109 17268
3c824109
NF
17269 rs = (ctx->opcode >> 21) & 0x1f;
17270 rt = (ctx->opcode >> 16) & 0x1f;
17271 rd = (ctx->opcode >> 11) & 0x1f;
17272 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17273
17274 op1 = MASK_SPECIAL(ctx->opcode);
17275 switch (op1) {
17276 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17277 if (sa == 5 && rd == 0 &&
17278 rs == 0 && rt == 0) { /* PAUSE */
17279 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17280 (ctx->hflags & MIPS_HFLAG_BMASK)) {
17281 MIPS_DEBUG("CTI in delay / forbidden slot");
17282 generate_exception(ctx, EXCP_RI);
17283 break;
17284 }
17285 }
17286 /* Fallthrough */
099e5b4d
LA
17287 case OPC_SRA:
17288 gen_shift_imm(ctx, op1, rd, rt, sa);
17289 break;
17290 case OPC_SRL:
17291 switch ((ctx->opcode >> 21) & 0x1f) {
17292 case 1:
17293 /* rotr is decoded as srl on non-R2 CPUs */
17294 if (ctx->insn_flags & ISA_MIPS32R2) {
17295 op1 = OPC_ROTR;
ea63e2c3 17296 }
099e5b4d
LA
17297 /* Fallthrough */
17298 case 0:
17299 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17300 break;
099e5b4d
LA
17301 default:
17302 generate_exception(ctx, EXCP_RI);
ea63e2c3 17303 break;
099e5b4d
LA
17304 }
17305 break;
099e5b4d
LA
17306 case OPC_ADD ... OPC_SUBU:
17307 gen_arith(ctx, op1, rd, rs, rt);
17308 break;
17309 case OPC_SLLV: /* Shifts */
17310 case OPC_SRAV:
17311 gen_shift(ctx, op1, rd, rs, rt);
17312 break;
17313 case OPC_SRLV:
17314 switch ((ctx->opcode >> 6) & 0x1f) {
17315 case 1:
17316 /* rotrv is decoded as srlv on non-R2 CPUs */
17317 if (ctx->insn_flags & ISA_MIPS32R2) {
17318 op1 = OPC_ROTRV;
26135ead 17319 }
099e5b4d
LA
17320 /* Fallthrough */
17321 case 0:
17322 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17323 break;
099e5b4d
LA
17324 default:
17325 generate_exception(ctx, EXCP_RI);
6af0bf9c 17326 break;
099e5b4d
LA
17327 }
17328 break;
17329 case OPC_SLT: /* Set on less than */
17330 case OPC_SLTU:
17331 gen_slt(ctx, op1, rd, rs, rt);
17332 break;
17333 case OPC_AND: /* Logic*/
17334 case OPC_OR:
17335 case OPC_NOR:
17336 case OPC_XOR:
17337 gen_logic(ctx, op1, rd, rs, rt);
17338 break;
0aefa333 17339 case OPC_JALR:
b231c103 17340 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
17341 break;
17342 case OPC_TGE ... OPC_TEQ: /* Traps */
17343 case OPC_TNE:
d9224450 17344 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17345 gen_trap(ctx, op1, rs, rt, -1);
17346 break;
d4ea6acd 17347 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17348 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17349 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17350 decode_opc_special_r6(env, ctx);
17351 } else {
17352 /* Pmon entry point, also R4010 selsl */
b48cfdff 17353#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
17354 MIPS_INVAL("PMON / selsl");
17355 generate_exception(ctx, EXCP_RI);
b48cfdff 17356#else
d4ea6acd 17357 gen_helper_0e0i(pmon, sa);
b48cfdff 17358#endif
d4ea6acd 17359 }
099e5b4d
LA
17360 break;
17361 case OPC_SYSCALL:
17362 generate_exception(ctx, EXCP_SYSCALL);
17363 ctx->bstate = BS_STOP;
17364 break;
17365 case OPC_BREAK:
17366 generate_exception(ctx, EXCP_BREAK);
17367 break;
099e5b4d 17368 case OPC_SYNC:
d9224450 17369 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17370 /* Treat as NOP. */
17371 break;
4ad40f36 17372
d26bc211 17373#if defined(TARGET_MIPS64)
099e5b4d
LA
17374 /* MIPS64 specific opcodes */
17375 case OPC_DSLL:
17376 case OPC_DSRA:
17377 case OPC_DSLL32:
17378 case OPC_DSRA32:
17379 check_insn(ctx, ISA_MIPS3);
17380 check_mips_64(ctx);
17381 gen_shift_imm(ctx, op1, rd, rt, sa);
17382 break;
17383 case OPC_DSRL:
17384 switch ((ctx->opcode >> 21) & 0x1f) {
17385 case 1:
17386 /* drotr is decoded as dsrl on non-R2 CPUs */
17387 if (ctx->insn_flags & ISA_MIPS32R2) {
17388 op1 = OPC_DROTR;
ea63e2c3 17389 }
099e5b4d
LA
17390 /* Fallthrough */
17391 case 0:
d75c135e 17392 check_insn(ctx, ISA_MIPS3);
e189e748 17393 check_mips_64(ctx);
099e5b4d 17394 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17395 break;
099e5b4d
LA
17396 default:
17397 generate_exception(ctx, EXCP_RI);
460f00c4 17398 break;
099e5b4d
LA
17399 }
17400 break;
17401 case OPC_DSRL32:
17402 switch ((ctx->opcode >> 21) & 0x1f) {
17403 case 1:
17404 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17405 if (ctx->insn_flags & ISA_MIPS32R2) {
17406 op1 = OPC_DROTR32;
ea63e2c3 17407 }
099e5b4d
LA
17408 /* Fallthrough */
17409 case 0:
d75c135e 17410 check_insn(ctx, ISA_MIPS3);
e189e748 17411 check_mips_64(ctx);
099e5b4d 17412 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17413 break;
099e5b4d 17414 default:
6af0bf9c
FB
17415 generate_exception(ctx, EXCP_RI);
17416 break;
17417 }
17418 break;
099e5b4d
LA
17419 case OPC_DADD ... OPC_DSUBU:
17420 check_insn(ctx, ISA_MIPS3);
17421 check_mips_64(ctx);
17422 gen_arith(ctx, op1, rd, rs, rt);
17423 break;
17424 case OPC_DSLLV:
17425 case OPC_DSRAV:
17426 check_insn(ctx, ISA_MIPS3);
17427 check_mips_64(ctx);
17428 gen_shift(ctx, op1, rd, rs, rt);
17429 break;
17430 case OPC_DSRLV:
17431 switch ((ctx->opcode >> 6) & 0x1f) {
17432 case 1:
17433 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17434 if (ctx->insn_flags & ISA_MIPS32R2) {
17435 op1 = OPC_DROTRV;
6af0bf9c 17436 }
099e5b4d
LA
17437 /* Fallthrough */
17438 case 0:
17439 check_insn(ctx, ISA_MIPS3);
e189e748 17440 check_mips_64(ctx);
099e5b4d 17441 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17442 break;
099e5b4d 17443 default:
6af0bf9c
FB
17444 generate_exception(ctx, EXCP_RI);
17445 break;
17446 }
17447 break;
f7685877
YK
17448 case OPC_DLSA:
17449 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17450 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17451 decode_opc_special_r6(env, ctx);
17452 }
17453 break;
099e5b4d 17454#endif
10dc65db
LA
17455 default:
17456 if (ctx->insn_flags & ISA_MIPS32R6) {
17457 decode_opc_special_r6(env, ctx);
17458 } else {
17459 decode_opc_special_legacy(env, ctx);
17460 }
17461 }
17462}
17463
10dc65db 17464static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17465{
17466 int rs, rt, rd;
17467 uint32_t op1;
6c5c1e20 17468
4267d3e6
LA
17469 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17470
099e5b4d
LA
17471 rs = (ctx->opcode >> 21) & 0x1f;
17472 rt = (ctx->opcode >> 16) & 0x1f;
17473 rd = (ctx->opcode >> 11) & 0x1f;
17474
17475 op1 = MASK_SPECIAL2(ctx->opcode);
17476 switch (op1) {
17477 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17478 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17479 check_insn(ctx, ISA_MIPS32);
17480 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17481 break;
17482 case OPC_MUL:
099e5b4d
LA
17483 gen_arith(ctx, op1, rd, rs, rt);
17484 break;
fac5a073
LA
17485 case OPC_DIV_G_2F:
17486 case OPC_DIVU_G_2F:
17487 case OPC_MULT_G_2F:
17488 case OPC_MULTU_G_2F:
17489 case OPC_MOD_G_2F:
17490 case OPC_MODU_G_2F:
17491 check_insn(ctx, INSN_LOONGSON2F);
17492 gen_loongson_integer(ctx, op1, rd, rs, rt);
17493 break;
099e5b4d
LA
17494 case OPC_CLO:
17495 case OPC_CLZ:
17496 check_insn(ctx, ISA_MIPS32);
17497 gen_cl(ctx, op1, rd, rs);
17498 break;
17499 case OPC_SDBBP:
3b3c1694
LA
17500 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17501 gen_helper_do_semihosting(cpu_env);
17502 } else {
17503 /* XXX: not clear which exception should be raised
17504 * when in debug mode...
17505 */
17506 check_insn(ctx, ISA_MIPS32);
17507 generate_exception(ctx, EXCP_DBp);
17508 }
099e5b4d 17509 break;
9b1a1d68 17510#if defined(TARGET_MIPS64)
099e5b4d
LA
17511 case OPC_DCLO:
17512 case OPC_DCLZ:
17513 check_insn(ctx, ISA_MIPS64);
17514 check_mips_64(ctx);
17515 gen_cl(ctx, op1, rd, rs);
17516 break;
4267d3e6
LA
17517 case OPC_DMULT_G_2F:
17518 case OPC_DMULTU_G_2F:
17519 case OPC_DDIV_G_2F:
17520 case OPC_DDIVU_G_2F:
17521 case OPC_DMOD_G_2F:
17522 case OPC_DMODU_G_2F:
17523 check_insn(ctx, INSN_LOONGSON2F);
17524 gen_loongson_integer(ctx, op1, rd, rs, rt);
17525 break;
10dc65db 17526#endif
4267d3e6
LA
17527 default: /* Invalid */
17528 MIPS_INVAL("special2_legacy");
17529 generate_exception(ctx, EXCP_RI);
17530 break;
10dc65db
LA
17531 }
17532}
17533
17534static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17535{
15eacb9b
YK
17536 int rs, rt, rd, sa;
17537 uint32_t op1, op2;
10dc65db
LA
17538 int16_t imm;
17539
17540 rs = (ctx->opcode >> 21) & 0x1f;
17541 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17542 rd = (ctx->opcode >> 11) & 0x1f;
17543 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17544 imm = (int16_t)ctx->opcode >> 7;
17545
17546 op1 = MASK_SPECIAL3(ctx->opcode);
17547 switch (op1) {
bf7910c6
LA
17548 case R6_OPC_PREF:
17549 if (rt >= 24) {
17550 /* hint codes 24-31 are reserved and signal RI */
17551 generate_exception(ctx, EXCP_RI);
17552 }
17553 /* Treat as NOP. */
17554 break;
17555 case R6_OPC_CACHE:
17556 /* Treat as NOP. */
17557 break;
10dc65db
LA
17558 case R6_OPC_SC:
17559 gen_st_cond(ctx, op1, rt, rs, imm);
17560 break;
17561 case R6_OPC_LL:
17562 gen_ld(ctx, op1, rt, rs, imm);
17563 break;
15eacb9b
YK
17564 case OPC_BSHFL:
17565 {
17566 if (rd == 0) {
17567 /* Treat as NOP. */
17568 break;
17569 }
15eacb9b
YK
17570 op2 = MASK_BSHFL(ctx->opcode);
17571 switch (op2) {
17572 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17573 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17574 break;
17575 case OPC_BITSWAP:
1f1b4c00 17576 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17577 break;
17578 }
15eacb9b
YK
17579 }
17580 break;
bf7910c6
LA
17581#if defined(TARGET_MIPS64)
17582 case R6_OPC_SCD:
17583 gen_st_cond(ctx, op1, rt, rs, imm);
17584 break;
17585 case R6_OPC_LLD:
17586 gen_ld(ctx, op1, rt, rs, imm);
17587 break;
15eacb9b
YK
17588 case OPC_DBSHFL:
17589 check_mips_64(ctx);
17590 {
17591 if (rd == 0) {
17592 /* Treat as NOP. */
17593 break;
17594 }
15eacb9b
YK
17595 op2 = MASK_DBSHFL(ctx->opcode);
17596 switch (op2) {
17597 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17598 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17599 break;
17600 case OPC_DBITSWAP:
1f1b4c00 17601 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17602 break;
17603 }
1f1b4c00 17604
15eacb9b
YK
17605 }
17606 break;
bf7910c6 17607#endif
10dc65db
LA
17608 default: /* Invalid */
17609 MIPS_INVAL("special3_r6");
17610 generate_exception(ctx, EXCP_RI);
17611 break;
17612 }
17613}
17614
17615static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17616{
fac5a073 17617 int rs, rt, rd;
099e5b4d 17618 uint32_t op1, op2;
099e5b4d
LA
17619
17620 rs = (ctx->opcode >> 21) & 0x1f;
17621 rt = (ctx->opcode >> 16) & 0x1f;
17622 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17623
17624 op1 = MASK_SPECIAL3(ctx->opcode);
17625 switch (op1) {
099e5b4d
LA
17626 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17627 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17628 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17629 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17630 * the same mask and op1. */
17631 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17632 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17633 switch (op2) {
099e5b4d
LA
17634 case OPC_ADDUH_QB:
17635 case OPC_ADDUH_R_QB:
17636 case OPC_ADDQH_PH:
17637 case OPC_ADDQH_R_PH:
17638 case OPC_ADDQH_W:
17639 case OPC_ADDQH_R_W:
17640 case OPC_SUBUH_QB:
17641 case OPC_SUBUH_R_QB:
17642 case OPC_SUBQH_PH:
17643 case OPC_SUBQH_R_PH:
17644 case OPC_SUBQH_W:
17645 case OPC_SUBQH_R_W:
461c08df
JL
17646 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17647 break;
099e5b4d
LA
17648 case OPC_MUL_PH:
17649 case OPC_MUL_S_PH:
17650 case OPC_MULQ_S_W:
17651 case OPC_MULQ_RS_W:
17652 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17653 break;
461c08df 17654 default:
099e5b4d 17655 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
17656 generate_exception(ctx, EXCP_RI);
17657 break;
17658 }
099e5b4d
LA
17659 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17660 gen_loongson_integer(ctx, op1, rd, rs, rt);
17661 } else {
17662 generate_exception(ctx, EXCP_RI);
17663 }
17664 break;
17665 case OPC_LX_DSP:
17666 op2 = MASK_LX(ctx->opcode);
17667 switch (op2) {
17668#if defined(TARGET_MIPS64)
17669 case OPC_LDX:
17670#endif
17671 case OPC_LBUX:
17672 case OPC_LHX:
17673 case OPC_LWX:
17674 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17675 break;
17676 default: /* Invalid */
17677 MIPS_INVAL("MASK LX");
17678 generate_exception(ctx, EXCP_RI);
17679 break;
17680 }
17681 break;
17682 case OPC_ABSQ_S_PH_DSP:
17683 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17684 switch (op2) {
17685 case OPC_ABSQ_S_QB:
17686 case OPC_ABSQ_S_PH:
17687 case OPC_ABSQ_S_W:
17688 case OPC_PRECEQ_W_PHL:
17689 case OPC_PRECEQ_W_PHR:
17690 case OPC_PRECEQU_PH_QBL:
17691 case OPC_PRECEQU_PH_QBR:
17692 case OPC_PRECEQU_PH_QBLA:
17693 case OPC_PRECEQU_PH_QBRA:
17694 case OPC_PRECEU_PH_QBL:
17695 case OPC_PRECEU_PH_QBR:
17696 case OPC_PRECEU_PH_QBLA:
17697 case OPC_PRECEU_PH_QBRA:
17698 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17699 break;
17700 case OPC_BITREV:
17701 case OPC_REPL_QB:
17702 case OPC_REPLV_QB:
17703 case OPC_REPL_PH:
17704 case OPC_REPLV_PH:
17705 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17706 break;
17707 default:
17708 MIPS_INVAL("MASK ABSQ_S.PH");
17709 generate_exception(ctx, EXCP_RI);
17710 break;
17711 }
17712 break;
17713 case OPC_ADDU_QB_DSP:
17714 op2 = MASK_ADDU_QB(ctx->opcode);
17715 switch (op2) {
17716 case OPC_ADDQ_PH:
17717 case OPC_ADDQ_S_PH:
17718 case OPC_ADDQ_S_W:
17719 case OPC_ADDU_QB:
17720 case OPC_ADDU_S_QB:
17721 case OPC_ADDU_PH:
17722 case OPC_ADDU_S_PH:
17723 case OPC_SUBQ_PH:
17724 case OPC_SUBQ_S_PH:
17725 case OPC_SUBQ_S_W:
17726 case OPC_SUBU_QB:
17727 case OPC_SUBU_S_QB:
17728 case OPC_SUBU_PH:
17729 case OPC_SUBU_S_PH:
17730 case OPC_ADDSC:
17731 case OPC_ADDWC:
17732 case OPC_MODSUB:
17733 case OPC_RADDU_W_QB:
17734 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17735 break;
17736 case OPC_MULEU_S_PH_QBL:
17737 case OPC_MULEU_S_PH_QBR:
17738 case OPC_MULQ_RS_PH:
17739 case OPC_MULEQ_S_W_PHL:
17740 case OPC_MULEQ_S_W_PHR:
17741 case OPC_MULQ_S_PH:
17742 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17743 break;
17744 default: /* Invalid */
17745 MIPS_INVAL("MASK ADDU.QB");
17746 generate_exception(ctx, EXCP_RI);
461c08df 17747 break;
461c08df 17748
099e5b4d
LA
17749 }
17750 break;
17751 case OPC_CMPU_EQ_QB_DSP:
17752 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17753 switch (op2) {
17754 case OPC_PRECR_SRA_PH_W:
17755 case OPC_PRECR_SRA_R_PH_W:
17756 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17757 break;
099e5b4d
LA
17758 case OPC_PRECR_QB_PH:
17759 case OPC_PRECRQ_QB_PH:
17760 case OPC_PRECRQ_PH_W:
17761 case OPC_PRECRQ_RS_PH_W:
17762 case OPC_PRECRQU_S_QB_PH:
17763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17764 break;
099e5b4d
LA
17765 case OPC_CMPU_EQ_QB:
17766 case OPC_CMPU_LT_QB:
17767 case OPC_CMPU_LE_QB:
17768 case OPC_CMP_EQ_PH:
17769 case OPC_CMP_LT_PH:
17770 case OPC_CMP_LE_PH:
17771 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17772 break;
099e5b4d
LA
17773 case OPC_CMPGU_EQ_QB:
17774 case OPC_CMPGU_LT_QB:
17775 case OPC_CMPGU_LE_QB:
17776 case OPC_CMPGDU_EQ_QB:
17777 case OPC_CMPGDU_LT_QB:
17778 case OPC_CMPGDU_LE_QB:
17779 case OPC_PICK_QB:
17780 case OPC_PICK_PH:
17781 case OPC_PACKRL_PH:
17782 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17783 break;
17784 default: /* Invalid */
17785 MIPS_INVAL("MASK CMPU.EQ.QB");
17786 generate_exception(ctx, EXCP_RI);
17787 break;
17788 }
17789 break;
17790 case OPC_SHLL_QB_DSP:
17791 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17792 break;
17793 case OPC_DPA_W_PH_DSP:
17794 op2 = MASK_DPA_W_PH(ctx->opcode);
17795 switch (op2) {
17796 case OPC_DPAU_H_QBL:
17797 case OPC_DPAU_H_QBR:
17798 case OPC_DPSU_H_QBL:
17799 case OPC_DPSU_H_QBR:
17800 case OPC_DPA_W_PH:
17801 case OPC_DPAX_W_PH:
17802 case OPC_DPAQ_S_W_PH:
17803 case OPC_DPAQX_S_W_PH:
17804 case OPC_DPAQX_SA_W_PH:
17805 case OPC_DPS_W_PH:
17806 case OPC_DPSX_W_PH:
17807 case OPC_DPSQ_S_W_PH:
17808 case OPC_DPSQX_S_W_PH:
17809 case OPC_DPSQX_SA_W_PH:
17810 case OPC_MULSAQ_S_W_PH:
17811 case OPC_DPAQ_SA_L_W:
17812 case OPC_DPSQ_SA_L_W:
17813 case OPC_MAQ_S_W_PHL:
17814 case OPC_MAQ_S_W_PHR:
17815 case OPC_MAQ_SA_W_PHL:
17816 case OPC_MAQ_SA_W_PHR:
17817 case OPC_MULSA_W_PH:
17818 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17819 break;
17820 default: /* Invalid */
17821 MIPS_INVAL("MASK DPAW.PH");
17822 generate_exception(ctx, EXCP_RI);
17823 break;
17824 }
17825 break;
17826 case OPC_INSV_DSP:
17827 op2 = MASK_INSV(ctx->opcode);
17828 switch (op2) {
17829 case OPC_INSV:
17830 check_dsp(ctx);
17831 {
17832 TCGv t0, t1;
17833
17834 if (rt == 0) {
17835 MIPS_DEBUG("NOP");
17836 break;
17837 }
17838
17839 t0 = tcg_temp_new();
17840 t1 = tcg_temp_new();
17841
17842 gen_load_gpr(t0, rt);
17843 gen_load_gpr(t1, rs);
17844
17845 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17846
17847 tcg_temp_free(t0);
17848 tcg_temp_free(t1);
a22260ae
JL
17849 break;
17850 }
099e5b4d
LA
17851 default: /* Invalid */
17852 MIPS_INVAL("MASK INSV");
17853 generate_exception(ctx, EXCP_RI);
17854 break;
17855 }
17856 break;
17857 case OPC_APPEND_DSP:
17858 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17859 break;
17860 case OPC_EXTR_W_DSP:
17861 op2 = MASK_EXTR_W(ctx->opcode);
17862 switch (op2) {
17863 case OPC_EXTR_W:
17864 case OPC_EXTR_R_W:
17865 case OPC_EXTR_RS_W:
17866 case OPC_EXTR_S_H:
17867 case OPC_EXTRV_S_H:
17868 case OPC_EXTRV_W:
17869 case OPC_EXTRV_R_W:
17870 case OPC_EXTRV_RS_W:
17871 case OPC_EXTP:
17872 case OPC_EXTPV:
17873 case OPC_EXTPDP:
17874 case OPC_EXTPDPV:
17875 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17876 break;
17877 case OPC_RDDSP:
17878 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17879 break;
17880 case OPC_SHILO:
17881 case OPC_SHILOV:
17882 case OPC_MTHLIP:
17883 case OPC_WRDSP:
17884 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17885 break;
17886 default: /* Invalid */
17887 MIPS_INVAL("MASK EXTR.W");
17888 generate_exception(ctx, EXCP_RI);
17889 break;
17890 }
17891 break;
099e5b4d 17892#if defined(TARGET_MIPS64)
fac5a073
LA
17893 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17894 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17895 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17896 check_insn(ctx, INSN_LOONGSON2E);
17897 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 17898 break;
099e5b4d
LA
17899 case OPC_ABSQ_S_QH_DSP:
17900 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17901 switch (op2) {
17902 case OPC_PRECEQ_L_PWL:
17903 case OPC_PRECEQ_L_PWR:
17904 case OPC_PRECEQ_PW_QHL:
17905 case OPC_PRECEQ_PW_QHR:
17906 case OPC_PRECEQ_PW_QHLA:
17907 case OPC_PRECEQ_PW_QHRA:
17908 case OPC_PRECEQU_QH_OBL:
17909 case OPC_PRECEQU_QH_OBR:
17910 case OPC_PRECEQU_QH_OBLA:
17911 case OPC_PRECEQU_QH_OBRA:
17912 case OPC_PRECEU_QH_OBL:
17913 case OPC_PRECEU_QH_OBR:
17914 case OPC_PRECEU_QH_OBLA:
17915 case OPC_PRECEU_QH_OBRA:
17916 case OPC_ABSQ_S_OB:
17917 case OPC_ABSQ_S_PW:
17918 case OPC_ABSQ_S_QH:
17919 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17920 break;
17921 case OPC_REPL_OB:
17922 case OPC_REPL_PW:
17923 case OPC_REPL_QH:
17924 case OPC_REPLV_OB:
17925 case OPC_REPLV_PW:
17926 case OPC_REPLV_QH:
17927 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17928 break;
17929 default: /* Invalid */
17930 MIPS_INVAL("MASK ABSQ_S.QH");
17931 generate_exception(ctx, EXCP_RI);
17932 break;
17933 }
17934 break;
17935 case OPC_ADDU_OB_DSP:
17936 op2 = MASK_ADDU_OB(ctx->opcode);
17937 switch (op2) {
17938 case OPC_RADDU_L_OB:
17939 case OPC_SUBQ_PW:
17940 case OPC_SUBQ_S_PW:
17941 case OPC_SUBQ_QH:
17942 case OPC_SUBQ_S_QH:
17943 case OPC_SUBU_OB:
17944 case OPC_SUBU_S_OB:
17945 case OPC_SUBU_QH:
17946 case OPC_SUBU_S_QH:
17947 case OPC_SUBUH_OB:
17948 case OPC_SUBUH_R_OB:
17949 case OPC_ADDQ_PW:
17950 case OPC_ADDQ_S_PW:
17951 case OPC_ADDQ_QH:
17952 case OPC_ADDQ_S_QH:
17953 case OPC_ADDU_OB:
17954 case OPC_ADDU_S_OB:
17955 case OPC_ADDU_QH:
17956 case OPC_ADDU_S_QH:
17957 case OPC_ADDUH_OB:
17958 case OPC_ADDUH_R_OB:
17959 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17960 break;
099e5b4d
LA
17961 case OPC_MULEQ_S_PW_QHL:
17962 case OPC_MULEQ_S_PW_QHR:
17963 case OPC_MULEU_S_QH_OBL:
17964 case OPC_MULEU_S_QH_OBR:
17965 case OPC_MULQ_RS_QH:
17966 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17967 break;
099e5b4d
LA
17968 default: /* Invalid */
17969 MIPS_INVAL("MASK ADDU.OB");
17970 generate_exception(ctx, EXCP_RI);
26690560 17971 break;
099e5b4d
LA
17972 }
17973 break;
17974 case OPC_CMPU_EQ_OB_DSP:
17975 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17976 switch (op2) {
17977 case OPC_PRECR_SRA_QH_PW:
17978 case OPC_PRECR_SRA_R_QH_PW:
17979 /* Return value is rt. */
17980 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17981 break;
099e5b4d
LA
17982 case OPC_PRECR_OB_QH:
17983 case OPC_PRECRQ_OB_QH:
17984 case OPC_PRECRQ_PW_L:
17985 case OPC_PRECRQ_QH_PW:
17986 case OPC_PRECRQ_RS_QH_PW:
17987 case OPC_PRECRQU_S_OB_QH:
17988 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17989 break;
099e5b4d
LA
17990 case OPC_CMPU_EQ_OB:
17991 case OPC_CMPU_LT_OB:
17992 case OPC_CMPU_LE_OB:
17993 case OPC_CMP_EQ_QH:
17994 case OPC_CMP_LT_QH:
17995 case OPC_CMP_LE_QH:
17996 case OPC_CMP_EQ_PW:
17997 case OPC_CMP_LT_PW:
17998 case OPC_CMP_LE_PW:
17999 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 18000 break;
099e5b4d
LA
18001 case OPC_CMPGDU_EQ_OB:
18002 case OPC_CMPGDU_LT_OB:
18003 case OPC_CMPGDU_LE_OB:
18004 case OPC_CMPGU_EQ_OB:
18005 case OPC_CMPGU_LT_OB:
18006 case OPC_CMPGU_LE_OB:
18007 case OPC_PACKRL_PW:
18008 case OPC_PICK_OB:
18009 case OPC_PICK_PW:
18010 case OPC_PICK_QH:
18011 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 18012 break;
099e5b4d
LA
18013 default: /* Invalid */
18014 MIPS_INVAL("MASK CMPU_EQ.OB");
18015 generate_exception(ctx, EXCP_RI);
161f85e6 18016 break;
099e5b4d
LA
18017 }
18018 break;
18019 case OPC_DAPPEND_DSP:
18020 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18021 break;
18022 case OPC_DEXTR_W_DSP:
18023 op2 = MASK_DEXTR_W(ctx->opcode);
18024 switch (op2) {
18025 case OPC_DEXTP:
18026 case OPC_DEXTPDP:
18027 case OPC_DEXTPDPV:
18028 case OPC_DEXTPV:
18029 case OPC_DEXTR_L:
18030 case OPC_DEXTR_R_L:
18031 case OPC_DEXTR_RS_L:
18032 case OPC_DEXTR_W:
18033 case OPC_DEXTR_R_W:
18034 case OPC_DEXTR_RS_W:
18035 case OPC_DEXTR_S_H:
18036 case OPC_DEXTRV_L:
18037 case OPC_DEXTRV_R_L:
18038 case OPC_DEXTRV_RS_L:
18039 case OPC_DEXTRV_S_H:
18040 case OPC_DEXTRV_W:
18041 case OPC_DEXTRV_R_W:
18042 case OPC_DEXTRV_RS_W:
18043 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 18044 break;
099e5b4d
LA
18045 case OPC_DMTHLIP:
18046 case OPC_DSHILO:
18047 case OPC_DSHILOV:
18048 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 18049 break;
099e5b4d
LA
18050 default: /* Invalid */
18051 MIPS_INVAL("MASK EXTR.W");
18052 generate_exception(ctx, EXCP_RI);
461c08df 18053 break;
099e5b4d
LA
18054 }
18055 break;
18056 case OPC_DPAQ_W_QH_DSP:
18057 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18058 switch (op2) {
18059 case OPC_DPAU_H_OBL:
18060 case OPC_DPAU_H_OBR:
18061 case OPC_DPSU_H_OBL:
18062 case OPC_DPSU_H_OBR:
18063 case OPC_DPA_W_QH:
18064 case OPC_DPAQ_S_W_QH:
18065 case OPC_DPS_W_QH:
18066 case OPC_DPSQ_S_W_QH:
18067 case OPC_MULSAQ_S_W_QH:
18068 case OPC_DPAQ_SA_L_PW:
18069 case OPC_DPSQ_SA_L_PW:
18070 case OPC_MULSAQ_S_L_PW:
18071 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18072 break;
18073 case OPC_MAQ_S_W_QHLL:
18074 case OPC_MAQ_S_W_QHLR:
18075 case OPC_MAQ_S_W_QHRL:
18076 case OPC_MAQ_S_W_QHRR:
18077 case OPC_MAQ_SA_W_QHLL:
18078 case OPC_MAQ_SA_W_QHLR:
18079 case OPC_MAQ_SA_W_QHRL:
18080 case OPC_MAQ_SA_W_QHRR:
18081 case OPC_MAQ_S_L_PWL:
18082 case OPC_MAQ_S_L_PWR:
18083 case OPC_DMADD:
18084 case OPC_DMADDU:
18085 case OPC_DMSUB:
18086 case OPC_DMSUBU:
18087 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 18088 break;
099e5b4d
LA
18089 default: /* Invalid */
18090 MIPS_INVAL("MASK DPAQ.W.QH");
18091 generate_exception(ctx, EXCP_RI);
b53371ed 18092 break;
099e5b4d
LA
18093 }
18094 break;
18095 case OPC_DINSV_DSP:
18096 op2 = MASK_INSV(ctx->opcode);
18097 switch (op2) {
18098 case OPC_DINSV:
18099 {
18100 TCGv t0, t1;
18101
18102 if (rt == 0) {
18103 MIPS_DEBUG("NOP");
a22260ae
JL
18104 break;
18105 }
099e5b4d 18106 check_dsp(ctx);
1cb6686c 18107
099e5b4d
LA
18108 t0 = tcg_temp_new();
18109 t1 = tcg_temp_new();
1cb6686c 18110
099e5b4d
LA
18111 gen_load_gpr(t0, rt);
18112 gen_load_gpr(t1, rs);
1cb6686c 18113
099e5b4d 18114 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 18115
099e5b4d
LA
18116 tcg_temp_free(t0);
18117 tcg_temp_free(t1);
77c5fa8b 18118 break;
099e5b4d 18119 }
7a387fff 18120 default: /* Invalid */
099e5b4d 18121 MIPS_INVAL("MASK DINSV");
7a387fff
TS
18122 generate_exception(ctx, EXCP_RI);
18123 break;
18124 }
18125 break;
099e5b4d
LA
18126 case OPC_SHLL_OB_DSP:
18127 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18128 break;
18129#endif
fac5a073
LA
18130 default: /* Invalid */
18131 MIPS_INVAL("special3_legacy");
18132 generate_exception(ctx, EXCP_RI);
18133 break;
18134 }
18135}
18136
18137static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18138{
18139 int rs, rt, rd, sa;
18140 uint32_t op1, op2;
18141
18142 rs = (ctx->opcode >> 21) & 0x1f;
18143 rt = (ctx->opcode >> 16) & 0x1f;
18144 rd = (ctx->opcode >> 11) & 0x1f;
18145 sa = (ctx->opcode >> 6) & 0x1f;
18146
18147 op1 = MASK_SPECIAL3(ctx->opcode);
18148 switch (op1) {
18149 case OPC_EXT:
18150 case OPC_INS:
18151 check_insn(ctx, ISA_MIPS32R2);
18152 gen_bitops(ctx, op1, rt, rs, sa, rd);
18153 break;
18154 case OPC_BSHFL:
fac5a073 18155 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
18156 switch (op2) {
18157 case OPC_ALIGN ... OPC_ALIGN_END:
18158 case OPC_BITSWAP:
18159 check_insn(ctx, ISA_MIPS32R6);
18160 decode_opc_special3_r6(env, ctx);
18161 break;
18162 default:
18163 check_insn(ctx, ISA_MIPS32R2);
18164 gen_bshfl(ctx, op2, rt, rd);
18165 break;
18166 }
fac5a073
LA
18167 break;
18168#if defined(TARGET_MIPS64)
18169 case OPC_DEXTM ... OPC_DEXT:
18170 case OPC_DINSM ... OPC_DINS:
18171 check_insn(ctx, ISA_MIPS64R2);
18172 check_mips_64(ctx);
18173 gen_bitops(ctx, op1, rt, rs, sa, rd);
18174 break;
18175 case OPC_DBSHFL:
fac5a073 18176 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
18177 switch (op2) {
18178 case OPC_DALIGN ... OPC_DALIGN_END:
18179 case OPC_DBITSWAP:
18180 check_insn(ctx, ISA_MIPS32R6);
18181 decode_opc_special3_r6(env, ctx);
18182 break;
18183 default:
18184 check_insn(ctx, ISA_MIPS64R2);
18185 check_mips_64(ctx);
18186 op2 = MASK_DBSHFL(ctx->opcode);
18187 gen_bshfl(ctx, op2, rt, rd);
18188 break;
18189 }
fac5a073
LA
18190 break;
18191#endif
18192 case OPC_RDHWR:
18193 gen_rdhwr(ctx, rt, rd);
18194 break;
18195 case OPC_FORK:
18196 check_insn(ctx, ASE_MT);
18197 {
18198 TCGv t0 = tcg_temp_new();
18199 TCGv t1 = tcg_temp_new();
18200
18201 gen_load_gpr(t0, rt);
18202 gen_load_gpr(t1, rs);
18203 gen_helper_fork(t0, t1);
18204 tcg_temp_free(t0);
18205 tcg_temp_free(t1);
18206 }
18207 break;
18208 case OPC_YIELD:
18209 check_insn(ctx, ASE_MT);
18210 {
18211 TCGv t0 = tcg_temp_new();
18212
18213 save_cpu_state(ctx, 1);
18214 gen_load_gpr(t0, rs);
18215 gen_helper_yield(t0, cpu_env, t0);
18216 gen_store_gpr(t0, rd);
18217 tcg_temp_free(t0);
18218 }
18219 break;
10dc65db
LA
18220 default:
18221 if (ctx->insn_flags & ISA_MIPS32R6) {
18222 decode_opc_special3_r6(env, ctx);
18223 } else {
18224 decode_opc_special3_legacy(env, ctx);
18225 }
099e5b4d
LA
18226 }
18227}
18228
863f264d
YK
18229/* MIPS SIMD Architecture (MSA) */
18230static inline int check_msa_access(DisasContext *ctx)
18231{
18232 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18233 !(ctx->hflags & MIPS_HFLAG_F64))) {
18234 generate_exception(ctx, EXCP_RI);
18235 return 0;
18236 }
18237
18238 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18239 if (ctx->insn_flags & ASE_MSA) {
18240 generate_exception(ctx, EXCP_MSADIS);
18241 return 0;
18242 } else {
18243 generate_exception(ctx, EXCP_RI);
18244 return 0;
18245 }
18246 }
18247 return 1;
18248}
18249
5692c6e1
YK
18250static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18251{
18252 /* generates tcg ops to check if any element is 0 */
18253 /* Note this function only works with MSA_WRLEN = 128 */
18254 uint64_t eval_zero_or_big = 0;
18255 uint64_t eval_big = 0;
18256 TCGv_i64 t0 = tcg_temp_new_i64();
18257 TCGv_i64 t1 = tcg_temp_new_i64();
18258 switch (df) {
18259 case DF_BYTE:
18260 eval_zero_or_big = 0x0101010101010101ULL;
18261 eval_big = 0x8080808080808080ULL;
18262 break;
18263 case DF_HALF:
18264 eval_zero_or_big = 0x0001000100010001ULL;
18265 eval_big = 0x8000800080008000ULL;
18266 break;
18267 case DF_WORD:
18268 eval_zero_or_big = 0x0000000100000001ULL;
18269 eval_big = 0x8000000080000000ULL;
18270 break;
18271 case DF_DOUBLE:
18272 eval_zero_or_big = 0x0000000000000001ULL;
18273 eval_big = 0x8000000000000000ULL;
18274 break;
18275 }
18276 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18277 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18278 tcg_gen_andi_i64(t0, t0, eval_big);
18279 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18280 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18281 tcg_gen_andi_i64(t1, t1, eval_big);
18282 tcg_gen_or_i64(t0, t0, t1);
18283 /* if all bits are zero then all elements are not zero */
18284 /* if some bit is non-zero then some element is zero */
18285 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18286 tcg_gen_trunc_i64_tl(tresult, t0);
18287 tcg_temp_free_i64(t0);
18288 tcg_temp_free_i64(t1);
18289}
18290
18291static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18292{
18293 uint8_t df = (ctx->opcode >> 21) & 0x3;
18294 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18295 int64_t s16 = (int16_t)ctx->opcode;
18296
18297 check_msa_access(ctx);
18298
18299 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
18300 MIPS_DEBUG("CTI in delay / forbidden slot");
18301 generate_exception(ctx, EXCP_RI);
18302 return;
18303 }
18304 switch (op1) {
18305 case OPC_BZ_V:
18306 case OPC_BNZ_V:
18307 {
18308 TCGv_i64 t0 = tcg_temp_new_i64();
18309 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18310 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18311 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18312 tcg_gen_trunc_i64_tl(bcond, t0);
18313 tcg_temp_free_i64(t0);
18314 }
18315 break;
18316 case OPC_BZ_B:
18317 case OPC_BZ_H:
18318 case OPC_BZ_W:
18319 case OPC_BZ_D:
18320 gen_check_zero_element(bcond, df, wt);
18321 break;
18322 case OPC_BNZ_B:
18323 case OPC_BNZ_H:
18324 case OPC_BNZ_W:
18325 case OPC_BNZ_D:
18326 gen_check_zero_element(bcond, df, wt);
18327 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18328 break;
18329 }
18330
18331 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18332
18333 ctx->hflags |= MIPS_HFLAG_BC;
18334 ctx->hflags |= MIPS_HFLAG_BDS32;
18335}
18336
4c789546
YK
18337static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18338{
18339#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18340 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18341 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18342 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18343
18344 TCGv_i32 twd = tcg_const_i32(wd);
18345 TCGv_i32 tws = tcg_const_i32(ws);
18346 TCGv_i32 ti8 = tcg_const_i32(i8);
18347
18348 switch (MASK_MSA_I8(ctx->opcode)) {
18349 case OPC_ANDI_B:
18350 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18351 break;
18352 case OPC_ORI_B:
18353 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18354 break;
18355 case OPC_NORI_B:
18356 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18357 break;
18358 case OPC_XORI_B:
18359 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18360 break;
18361 case OPC_BMNZI_B:
18362 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18363 break;
18364 case OPC_BMZI_B:
18365 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18366 break;
18367 case OPC_BSELI_B:
18368 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18369 break;
18370 case OPC_SHF_B:
18371 case OPC_SHF_H:
18372 case OPC_SHF_W:
18373 {
18374 uint8_t df = (ctx->opcode >> 24) & 0x3;
18375 if (df == DF_DOUBLE) {
18376 generate_exception(ctx, EXCP_RI);
18377 } else {
18378 TCGv_i32 tdf = tcg_const_i32(df);
18379 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18380 tcg_temp_free_i32(tdf);
18381 }
18382 }
18383 break;
18384 default:
18385 MIPS_INVAL("MSA instruction");
18386 generate_exception(ctx, EXCP_RI);
18387 break;
18388 }
18389
18390 tcg_temp_free_i32(twd);
18391 tcg_temp_free_i32(tws);
18392 tcg_temp_free_i32(ti8);
18393}
18394
80e71591
YK
18395static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18396{
18397#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18398 uint8_t df = (ctx->opcode >> 21) & 0x3;
18399 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18400 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18401 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18402 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18403
18404 TCGv_i32 tdf = tcg_const_i32(df);
18405 TCGv_i32 twd = tcg_const_i32(wd);
18406 TCGv_i32 tws = tcg_const_i32(ws);
18407 TCGv_i32 timm = tcg_temp_new_i32();
18408 tcg_gen_movi_i32(timm, u5);
18409
18410 switch (MASK_MSA_I5(ctx->opcode)) {
18411 case OPC_ADDVI_df:
18412 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18413 break;
18414 case OPC_SUBVI_df:
18415 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18416 break;
18417 case OPC_MAXI_S_df:
18418 tcg_gen_movi_i32(timm, s5);
18419 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18420 break;
18421 case OPC_MAXI_U_df:
18422 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18423 break;
18424 case OPC_MINI_S_df:
18425 tcg_gen_movi_i32(timm, s5);
18426 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18427 break;
18428 case OPC_MINI_U_df:
18429 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18430 break;
18431 case OPC_CEQI_df:
18432 tcg_gen_movi_i32(timm, s5);
18433 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18434 break;
18435 case OPC_CLTI_S_df:
18436 tcg_gen_movi_i32(timm, s5);
18437 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18438 break;
18439 case OPC_CLTI_U_df:
18440 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18441 break;
18442 case OPC_CLEI_S_df:
18443 tcg_gen_movi_i32(timm, s5);
18444 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18445 break;
18446 case OPC_CLEI_U_df:
18447 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18448 break;
18449 case OPC_LDI_df:
18450 {
18451 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18452 tcg_gen_movi_i32(timm, s10);
18453 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18454 }
18455 break;
18456 default:
18457 MIPS_INVAL("MSA instruction");
18458 generate_exception(ctx, EXCP_RI);
18459 break;
18460 }
18461
18462 tcg_temp_free_i32(tdf);
18463 tcg_temp_free_i32(twd);
18464 tcg_temp_free_i32(tws);
18465 tcg_temp_free_i32(timm);
18466}
18467
d4cf28de
YK
18468static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18469{
18470#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18471 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18472 uint32_t df = 0, m = 0;
18473 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18474 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18475
18476 TCGv_i32 tdf;
18477 TCGv_i32 tm;
18478 TCGv_i32 twd;
18479 TCGv_i32 tws;
18480
18481 if ((dfm & 0x40) == 0x00) {
18482 m = dfm & 0x3f;
18483 df = DF_DOUBLE;
18484 } else if ((dfm & 0x60) == 0x40) {
18485 m = dfm & 0x1f;
18486 df = DF_WORD;
18487 } else if ((dfm & 0x70) == 0x60) {
18488 m = dfm & 0x0f;
18489 df = DF_HALF;
18490 } else if ((dfm & 0x78) == 0x70) {
18491 m = dfm & 0x7;
18492 df = DF_BYTE;
18493 } else {
18494 generate_exception(ctx, EXCP_RI);
18495 return;
18496 }
18497
18498 tdf = tcg_const_i32(df);
18499 tm = tcg_const_i32(m);
18500 twd = tcg_const_i32(wd);
18501 tws = tcg_const_i32(ws);
18502
18503 switch (MASK_MSA_BIT(ctx->opcode)) {
18504 case OPC_SLLI_df:
18505 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18506 break;
18507 case OPC_SRAI_df:
18508 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18509 break;
18510 case OPC_SRLI_df:
18511 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18512 break;
18513 case OPC_BCLRI_df:
18514 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18515 break;
18516 case OPC_BSETI_df:
18517 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18518 break;
18519 case OPC_BNEGI_df:
18520 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18521 break;
18522 case OPC_BINSLI_df:
18523 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18524 break;
18525 case OPC_BINSRI_df:
18526 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18527 break;
18528 case OPC_SAT_S_df:
18529 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18530 break;
18531 case OPC_SAT_U_df:
18532 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18533 break;
18534 case OPC_SRARI_df:
18535 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18536 break;
18537 case OPC_SRLRI_df:
18538 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18539 break;
18540 default:
18541 MIPS_INVAL("MSA instruction");
18542 generate_exception(ctx, EXCP_RI);
18543 break;
18544 }
18545
18546 tcg_temp_free_i32(tdf);
18547 tcg_temp_free_i32(tm);
18548 tcg_temp_free_i32(twd);
18549 tcg_temp_free_i32(tws);
18550}
18551
28f99f08
YK
18552static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18553{
18554#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18555 uint8_t df = (ctx->opcode >> 21) & 0x3;
18556 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18557 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18558 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18559
18560 TCGv_i32 tdf = tcg_const_i32(df);
18561 TCGv_i32 twd = tcg_const_i32(wd);
18562 TCGv_i32 tws = tcg_const_i32(ws);
18563 TCGv_i32 twt = tcg_const_i32(wt);
18564
18565 switch (MASK_MSA_3R(ctx->opcode)) {
18566 case OPC_SLL_df:
18567 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18568 break;
18569 case OPC_ADDV_df:
18570 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_CEQ_df:
18573 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_ADD_A_df:
18576 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_SUBS_S_df:
18579 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18580 break;
18581 case OPC_MULV_df:
18582 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18583 break;
18584 case OPC_SLD_df:
18585 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18586 break;
18587 case OPC_VSHF_df:
18588 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18589 break;
18590 case OPC_SRA_df:
18591 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18592 break;
18593 case OPC_SUBV_df:
18594 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18595 break;
18596 case OPC_ADDS_A_df:
18597 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18598 break;
18599 case OPC_SUBS_U_df:
18600 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18601 break;
18602 case OPC_MADDV_df:
18603 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18604 break;
18605 case OPC_SPLAT_df:
18606 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18607 break;
18608 case OPC_SRAR_df:
18609 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18610 break;
18611 case OPC_SRL_df:
18612 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18613 break;
18614 case OPC_MAX_S_df:
18615 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18616 break;
18617 case OPC_CLT_S_df:
18618 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18619 break;
18620 case OPC_ADDS_S_df:
18621 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18622 break;
18623 case OPC_SUBSUS_U_df:
18624 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18625 break;
18626 case OPC_MSUBV_df:
18627 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18628 break;
18629 case OPC_PCKEV_df:
18630 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18631 break;
18632 case OPC_SRLR_df:
18633 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18634 break;
18635 case OPC_BCLR_df:
18636 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18637 break;
18638 case OPC_MAX_U_df:
18639 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18640 break;
18641 case OPC_CLT_U_df:
18642 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18643 break;
18644 case OPC_ADDS_U_df:
18645 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18646 break;
18647 case OPC_SUBSUU_S_df:
18648 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18649 break;
18650 case OPC_PCKOD_df:
18651 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18652 break;
18653 case OPC_BSET_df:
18654 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18655 break;
18656 case OPC_MIN_S_df:
18657 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18658 break;
18659 case OPC_CLE_S_df:
18660 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18661 break;
18662 case OPC_AVE_S_df:
18663 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18664 break;
18665 case OPC_ASUB_S_df:
18666 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18667 break;
18668 case OPC_DIV_S_df:
18669 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18670 break;
18671 case OPC_ILVL_df:
18672 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18673 break;
18674 case OPC_BNEG_df:
18675 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18676 break;
18677 case OPC_MIN_U_df:
18678 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18679 break;
18680 case OPC_CLE_U_df:
18681 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18682 break;
18683 case OPC_AVE_U_df:
18684 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18685 break;
18686 case OPC_ASUB_U_df:
18687 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18688 break;
18689 case OPC_DIV_U_df:
18690 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18691 break;
18692 case OPC_ILVR_df:
18693 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18694 break;
18695 case OPC_BINSL_df:
18696 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18697 break;
18698 case OPC_MAX_A_df:
18699 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18700 break;
18701 case OPC_AVER_S_df:
18702 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18703 break;
18704 case OPC_MOD_S_df:
18705 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18706 break;
18707 case OPC_ILVEV_df:
18708 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18709 break;
18710 case OPC_BINSR_df:
18711 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18712 break;
18713 case OPC_MIN_A_df:
18714 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18715 break;
18716 case OPC_AVER_U_df:
18717 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18718 break;
18719 case OPC_MOD_U_df:
18720 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18721 break;
18722 case OPC_ILVOD_df:
18723 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18724 break;
18725
18726 case OPC_DOTP_S_df:
18727 case OPC_DOTP_U_df:
18728 case OPC_DPADD_S_df:
18729 case OPC_DPADD_U_df:
18730 case OPC_DPSUB_S_df:
18731 case OPC_HADD_S_df:
18732 case OPC_DPSUB_U_df:
18733 case OPC_HADD_U_df:
18734 case OPC_HSUB_S_df:
18735 case OPC_HSUB_U_df:
18736 if (df == DF_BYTE) {
18737 generate_exception(ctx, EXCP_RI);
18738 }
18739 switch (MASK_MSA_3R(ctx->opcode)) {
18740 case OPC_DOTP_S_df:
18741 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18742 break;
18743 case OPC_DOTP_U_df:
18744 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18745 break;
18746 case OPC_DPADD_S_df:
18747 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18748 break;
18749 case OPC_DPADD_U_df:
18750 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18751 break;
18752 case OPC_DPSUB_S_df:
18753 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18754 break;
18755 case OPC_HADD_S_df:
18756 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18757 break;
18758 case OPC_DPSUB_U_df:
18759 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18760 break;
18761 case OPC_HADD_U_df:
18762 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18763 break;
18764 case OPC_HSUB_S_df:
18765 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18766 break;
18767 case OPC_HSUB_U_df:
18768 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18769 break;
18770 }
18771 break;
18772 default:
18773 MIPS_INVAL("MSA instruction");
18774 generate_exception(ctx, EXCP_RI);
18775 break;
18776 }
18777 tcg_temp_free_i32(twd);
18778 tcg_temp_free_i32(tws);
18779 tcg_temp_free_i32(twt);
18780 tcg_temp_free_i32(tdf);
18781}
18782
1e608ec1
YK
18783static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18784{
18785#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18786 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18787 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18788 TCGv telm = tcg_temp_new();
18789 TCGv_i32 tsr = tcg_const_i32(source);
18790 TCGv_i32 tdt = tcg_const_i32(dest);
18791
18792 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18793 case OPC_CTCMSA:
18794 gen_load_gpr(telm, source);
18795 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18796 break;
18797 case OPC_CFCMSA:
18798 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18799 gen_store_gpr(telm, dest);
18800 break;
18801 case OPC_MOVE_V:
18802 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18803 break;
18804 default:
18805 MIPS_INVAL("MSA instruction");
18806 generate_exception(ctx, EXCP_RI);
18807 break;
18808 }
18809
18810 tcg_temp_free(telm);
18811 tcg_temp_free_i32(tdt);
18812 tcg_temp_free_i32(tsr);
18813}
18814
18815static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18816 uint32_t n)
18817{
18818#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18819 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18820 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18821
18822 TCGv_i32 tws = tcg_const_i32(ws);
18823 TCGv_i32 twd = tcg_const_i32(wd);
18824 TCGv_i32 tn = tcg_const_i32(n);
18825 TCGv_i32 tdf = tcg_const_i32(df);
18826
18827 switch (MASK_MSA_ELM(ctx->opcode)) {
18828 case OPC_SLDI_df:
18829 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18830 break;
18831 case OPC_SPLATI_df:
18832 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18833 break;
18834 case OPC_INSVE_df:
18835 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18836 break;
18837 case OPC_COPY_S_df:
18838 case OPC_COPY_U_df:
18839 case OPC_INSERT_df:
18840#if !defined(TARGET_MIPS64)
18841 /* Double format valid only for MIPS64 */
18842 if (df == DF_DOUBLE) {
18843 generate_exception(ctx, EXCP_RI);
18844 break;
18845 }
18846#endif
18847 switch (MASK_MSA_ELM(ctx->opcode)) {
18848 case OPC_COPY_S_df:
18849 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18850 break;
18851 case OPC_COPY_U_df:
18852 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18853 break;
18854 case OPC_INSERT_df:
18855 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18856 break;
18857 }
18858 break;
18859 default:
18860 MIPS_INVAL("MSA instruction");
18861 generate_exception(ctx, EXCP_RI);
18862 }
18863 tcg_temp_free_i32(twd);
18864 tcg_temp_free_i32(tws);
18865 tcg_temp_free_i32(tn);
18866 tcg_temp_free_i32(tdf);
18867}
18868
18869static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18870{
18871 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18872 uint32_t df = 0, n = 0;
18873
18874 if ((dfn & 0x30) == 0x00) {
18875 n = dfn & 0x0f;
18876 df = DF_BYTE;
18877 } else if ((dfn & 0x38) == 0x20) {
18878 n = dfn & 0x07;
18879 df = DF_HALF;
18880 } else if ((dfn & 0x3c) == 0x30) {
18881 n = dfn & 0x03;
18882 df = DF_WORD;
18883 } else if ((dfn & 0x3e) == 0x38) {
18884 n = dfn & 0x01;
18885 df = DF_DOUBLE;
18886 } else if (dfn == 0x3E) {
18887 /* CTCMSA, CFCMSA, MOVE.V */
18888 gen_msa_elm_3e(env, ctx);
18889 return;
18890 } else {
18891 generate_exception(ctx, EXCP_RI);
18892 return;
18893 }
18894
18895 gen_msa_elm_df(env, ctx, df, n);
18896}
18897
7d05b9c8
YK
18898static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18899{
18900#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18901 uint8_t df = (ctx->opcode >> 21) & 0x1;
18902 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18903 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18904 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18905
18906 TCGv_i32 twd = tcg_const_i32(wd);
18907 TCGv_i32 tws = tcg_const_i32(ws);
18908 TCGv_i32 twt = tcg_const_i32(wt);
18909 TCGv_i32 tdf = tcg_temp_new_i32();
18910
18911 /* adjust df value for floating-point instruction */
18912 tcg_gen_movi_i32(tdf, df + 2);
18913
18914 switch (MASK_MSA_3RF(ctx->opcode)) {
18915 case OPC_FCAF_df:
18916 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18917 break;
18918 case OPC_FADD_df:
18919 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18920 break;
18921 case OPC_FCUN_df:
18922 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18923 break;
18924 case OPC_FSUB_df:
18925 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18926 break;
18927 case OPC_FCOR_df:
18928 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18929 break;
18930 case OPC_FCEQ_df:
18931 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18932 break;
18933 case OPC_FMUL_df:
18934 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18935 break;
18936 case OPC_FCUNE_df:
18937 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18938 break;
18939 case OPC_FCUEQ_df:
18940 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18941 break;
18942 case OPC_FDIV_df:
18943 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18944 break;
18945 case OPC_FCNE_df:
18946 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18947 break;
18948 case OPC_FCLT_df:
18949 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18950 break;
18951 case OPC_FMADD_df:
18952 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18953 break;
18954 case OPC_MUL_Q_df:
18955 tcg_gen_movi_i32(tdf, df + 1);
18956 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18957 break;
18958 case OPC_FCULT_df:
18959 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18960 break;
18961 case OPC_FMSUB_df:
18962 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18963 break;
18964 case OPC_MADD_Q_df:
18965 tcg_gen_movi_i32(tdf, df + 1);
18966 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18967 break;
18968 case OPC_FCLE_df:
18969 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18970 break;
18971 case OPC_MSUB_Q_df:
18972 tcg_gen_movi_i32(tdf, df + 1);
18973 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18974 break;
18975 case OPC_FCULE_df:
18976 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18977 break;
18978 case OPC_FEXP2_df:
18979 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18980 break;
18981 case OPC_FSAF_df:
18982 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18983 break;
18984 case OPC_FEXDO_df:
18985 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18986 break;
18987 case OPC_FSUN_df:
18988 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18989 break;
18990 case OPC_FSOR_df:
18991 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18992 break;
18993 case OPC_FSEQ_df:
18994 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18995 break;
18996 case OPC_FTQ_df:
18997 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18998 break;
18999 case OPC_FSUNE_df:
19000 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19001 break;
19002 case OPC_FSUEQ_df:
19003 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19004 break;
19005 case OPC_FSNE_df:
19006 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19007 break;
19008 case OPC_FSLT_df:
19009 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19010 break;
19011 case OPC_FMIN_df:
19012 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19013 break;
19014 case OPC_MULR_Q_df:
19015 tcg_gen_movi_i32(tdf, df + 1);
19016 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19017 break;
19018 case OPC_FSULT_df:
19019 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19020 break;
19021 case OPC_FMIN_A_df:
19022 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19023 break;
19024 case OPC_MADDR_Q_df:
19025 tcg_gen_movi_i32(tdf, df + 1);
19026 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19027 break;
19028 case OPC_FSLE_df:
19029 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19030 break;
19031 case OPC_FMAX_df:
19032 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19033 break;
19034 case OPC_MSUBR_Q_df:
19035 tcg_gen_movi_i32(tdf, df + 1);
19036 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19037 break;
19038 case OPC_FSULE_df:
19039 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19040 break;
19041 case OPC_FMAX_A_df:
19042 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19043 break;
19044 default:
19045 MIPS_INVAL("MSA instruction");
19046 generate_exception(ctx, EXCP_RI);
19047 break;
19048 }
19049
19050 tcg_temp_free_i32(twd);
19051 tcg_temp_free_i32(tws);
19052 tcg_temp_free_i32(twt);
19053 tcg_temp_free_i32(tdf);
19054}
19055
cbe50b9a
YK
19056static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19057{
19058#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19059 (op & (0x7 << 18)))
19060 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19061 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19062 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19063 uint8_t df = (ctx->opcode >> 16) & 0x3;
19064 TCGv_i32 twd = tcg_const_i32(wd);
19065 TCGv_i32 tws = tcg_const_i32(ws);
19066 TCGv_i32 twt = tcg_const_i32(wt);
19067 TCGv_i32 tdf = tcg_const_i32(df);
19068
19069 switch (MASK_MSA_2R(ctx->opcode)) {
19070 case OPC_FILL_df:
19071#if !defined(TARGET_MIPS64)
19072 /* Double format valid only for MIPS64 */
19073 if (df == DF_DOUBLE) {
19074 generate_exception(ctx, EXCP_RI);
19075 break;
19076 }
19077#endif
19078 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19079 break;
19080 case OPC_PCNT_df:
19081 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19082 break;
19083 case OPC_NLOC_df:
19084 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19085 break;
19086 case OPC_NLZC_df:
19087 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19088 break;
19089 default:
19090 MIPS_INVAL("MSA instruction");
19091 generate_exception(ctx, EXCP_RI);
19092 break;
19093 }
19094
19095 tcg_temp_free_i32(twd);
19096 tcg_temp_free_i32(tws);
19097 tcg_temp_free_i32(twt);
19098 tcg_temp_free_i32(tdf);
19099}
19100
3bdeb688
YK
19101static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19102{
19103#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19104 (op & (0xf << 17)))
19105 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19106 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19107 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19108 uint8_t df = (ctx->opcode >> 16) & 0x1;
19109 TCGv_i32 twd = tcg_const_i32(wd);
19110 TCGv_i32 tws = tcg_const_i32(ws);
19111 TCGv_i32 twt = tcg_const_i32(wt);
19112 /* adjust df value for floating-point instruction */
19113 TCGv_i32 tdf = tcg_const_i32(df + 2);
19114
19115 switch (MASK_MSA_2RF(ctx->opcode)) {
19116 case OPC_FCLASS_df:
19117 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19118 break;
19119 case OPC_FTRUNC_S_df:
19120 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19121 break;
19122 case OPC_FTRUNC_U_df:
19123 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19124 break;
19125 case OPC_FSQRT_df:
19126 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19127 break;
19128 case OPC_FRSQRT_df:
19129 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19130 break;
19131 case OPC_FRCP_df:
19132 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19133 break;
19134 case OPC_FRINT_df:
19135 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19136 break;
19137 case OPC_FLOG2_df:
19138 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19139 break;
19140 case OPC_FEXUPL_df:
19141 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19142 break;
19143 case OPC_FEXUPR_df:
19144 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19145 break;
19146 case OPC_FFQL_df:
19147 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19148 break;
19149 case OPC_FFQR_df:
19150 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19151 break;
19152 case OPC_FTINT_S_df:
19153 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19154 break;
19155 case OPC_FTINT_U_df:
19156 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19157 break;
19158 case OPC_FFINT_S_df:
19159 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19160 break;
19161 case OPC_FFINT_U_df:
19162 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19163 break;
19164 }
19165
19166 tcg_temp_free_i32(twd);
19167 tcg_temp_free_i32(tws);
19168 tcg_temp_free_i32(twt);
19169 tcg_temp_free_i32(tdf);
19170}
19171
cbe50b9a
YK
19172static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19173{
19174#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19175 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19176 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19177 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19178 TCGv_i32 twd = tcg_const_i32(wd);
19179 TCGv_i32 tws = tcg_const_i32(ws);
19180 TCGv_i32 twt = tcg_const_i32(wt);
19181
19182 switch (MASK_MSA_VEC(ctx->opcode)) {
19183 case OPC_AND_V:
19184 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19185 break;
19186 case OPC_OR_V:
19187 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19188 break;
19189 case OPC_NOR_V:
19190 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19191 break;
19192 case OPC_XOR_V:
19193 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19194 break;
19195 case OPC_BMNZ_V:
19196 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19197 break;
19198 case OPC_BMZ_V:
19199 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19200 break;
19201 case OPC_BSEL_V:
19202 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19203 break;
19204 default:
19205 MIPS_INVAL("MSA instruction");
19206 generate_exception(ctx, EXCP_RI);
19207 break;
19208 }
19209
19210 tcg_temp_free_i32(twd);
19211 tcg_temp_free_i32(tws);
19212 tcg_temp_free_i32(twt);
19213}
19214
19215static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19216{
19217 switch (MASK_MSA_VEC(ctx->opcode)) {
19218 case OPC_AND_V:
19219 case OPC_OR_V:
19220 case OPC_NOR_V:
19221 case OPC_XOR_V:
19222 case OPC_BMNZ_V:
19223 case OPC_BMZ_V:
19224 case OPC_BSEL_V:
19225 gen_msa_vec_v(env, ctx);
19226 break;
19227 case OPC_MSA_2R:
19228 gen_msa_2r(env, ctx);
19229 break;
3bdeb688
YK
19230 case OPC_MSA_2RF:
19231 gen_msa_2rf(env, ctx);
19232 break;
cbe50b9a
YK
19233 default:
19234 MIPS_INVAL("MSA instruction");
19235 generate_exception(ctx, EXCP_RI);
19236 break;
19237 }
19238}
19239
4c789546
YK
19240static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19241{
19242 uint32_t opcode = ctx->opcode;
19243 check_insn(ctx, ASE_MSA);
19244 check_msa_access(ctx);
19245
19246 switch (MASK_MSA_MINOR(opcode)) {
19247 case OPC_MSA_I8_00:
19248 case OPC_MSA_I8_01:
19249 case OPC_MSA_I8_02:
19250 gen_msa_i8(env, ctx);
19251 break;
80e71591
YK
19252 case OPC_MSA_I5_06:
19253 case OPC_MSA_I5_07:
19254 gen_msa_i5(env, ctx);
19255 break;
d4cf28de
YK
19256 case OPC_MSA_BIT_09:
19257 case OPC_MSA_BIT_0A:
19258 gen_msa_bit(env, ctx);
19259 break;
28f99f08
YK
19260 case OPC_MSA_3R_0D:
19261 case OPC_MSA_3R_0E:
19262 case OPC_MSA_3R_0F:
19263 case OPC_MSA_3R_10:
19264 case OPC_MSA_3R_11:
19265 case OPC_MSA_3R_12:
19266 case OPC_MSA_3R_13:
19267 case OPC_MSA_3R_14:
19268 case OPC_MSA_3R_15:
19269 gen_msa_3r(env, ctx);
19270 break;
1e608ec1
YK
19271 case OPC_MSA_ELM:
19272 gen_msa_elm(env, ctx);
19273 break;
7d05b9c8
YK
19274 case OPC_MSA_3RF_1A:
19275 case OPC_MSA_3RF_1B:
19276 case OPC_MSA_3RF_1C:
19277 gen_msa_3rf(env, ctx);
19278 break;
cbe50b9a
YK
19279 case OPC_MSA_VEC:
19280 gen_msa_vec(env, ctx);
19281 break;
f7685877
YK
19282 case OPC_LD_B:
19283 case OPC_LD_H:
19284 case OPC_LD_W:
19285 case OPC_LD_D:
19286 case OPC_ST_B:
19287 case OPC_ST_H:
19288 case OPC_ST_W:
19289 case OPC_ST_D:
19290 {
19291 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19292 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19293 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19294 uint8_t df = (ctx->opcode >> 0) & 0x3;
19295
f7685877 19296 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19297 TCGv taddr = tcg_temp_new();
19298 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19299
19300 switch (MASK_MSA_MINOR(opcode)) {
19301 case OPC_LD_B:
adc370a4
YK
19302 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19303 break;
f7685877 19304 case OPC_LD_H:
adc370a4
YK
19305 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19306 break;
f7685877 19307 case OPC_LD_W:
adc370a4
YK
19308 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19309 break;
f7685877 19310 case OPC_LD_D:
adc370a4 19311 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19312 break;
19313 case OPC_ST_B:
adc370a4
YK
19314 gen_helper_msa_st_b(cpu_env, twd, taddr);
19315 break;
f7685877 19316 case OPC_ST_H:
adc370a4
YK
19317 gen_helper_msa_st_h(cpu_env, twd, taddr);
19318 break;
f7685877 19319 case OPC_ST_W:
adc370a4
YK
19320 gen_helper_msa_st_w(cpu_env, twd, taddr);
19321 break;
f7685877 19322 case OPC_ST_D:
adc370a4 19323 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19324 break;
19325 }
19326
19327 tcg_temp_free_i32(twd);
adc370a4 19328 tcg_temp_free(taddr);
f7685877
YK
19329 }
19330 break;
4c789546
YK
19331 default:
19332 MIPS_INVAL("MSA instruction");
19333 generate_exception(ctx, EXCP_RI);
19334 break;
19335 }
19336
19337}
19338
d2bfa6e6 19339static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19340{
19341 int32_t offset;
19342 int rs, rt, rd, sa;
19343 uint32_t op, op1;
19344 int16_t imm;
19345
19346 /* make sure instructions are on a word boundary */
19347 if (ctx->pc & 0x3) {
19348 env->CP0_BadVAddr = ctx->pc;
aea14095 19349 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
62c68869 19350 ctx->bstate = BS_STOP;
099e5b4d
LA
19351 return;
19352 }
19353
19354 /* Handle blikely not taken case */
19355 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19356 TCGLabel *l1 = gen_new_label();
099e5b4d
LA
19357
19358 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
19359 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19360 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19361 gen_goto_tb(ctx, 1, ctx->pc + 4);
19362 gen_set_label(l1);
19363 }
19364
19365 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
19366 tcg_gen_debug_insn_start(ctx->pc);
19367 }
19368
19369 op = MASK_OP_MAJOR(ctx->opcode);
19370 rs = (ctx->opcode >> 21) & 0x1f;
19371 rt = (ctx->opcode >> 16) & 0x1f;
19372 rd = (ctx->opcode >> 11) & 0x1f;
19373 sa = (ctx->opcode >> 6) & 0x1f;
19374 imm = (int16_t)ctx->opcode;
19375 switch (op) {
19376 case OPC_SPECIAL:
19377 decode_opc_special(env, ctx);
19378 break;
19379 case OPC_SPECIAL2:
4267d3e6 19380 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19381 break;
19382 case OPC_SPECIAL3:
19383 decode_opc_special3(env, ctx);
19384 break;
7a387fff
TS
19385 case OPC_REGIMM:
19386 op1 = MASK_REGIMM(ctx->opcode);
19387 switch (op1) {
fecd2646
LA
19388 case OPC_BLTZL: /* REGIMM branches */
19389 case OPC_BGEZL:
19390 case OPC_BLTZALL:
19391 case OPC_BGEZALL:
d9224450 19392 check_insn(ctx, ISA_MIPS2);
fecd2646 19393 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19394 /* Fallthrough */
fecd2646
LA
19395 case OPC_BLTZ:
19396 case OPC_BGEZ:
b231c103 19397 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19398 break;
fecd2646
LA
19399 case OPC_BLTZAL:
19400 case OPC_BGEZAL:
0aefa333
YK
19401 if (ctx->insn_flags & ISA_MIPS32R6) {
19402 if (rs == 0) {
19403 /* OPC_NAL, OPC_BAL */
b231c103 19404 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
19405 } else {
19406 generate_exception(ctx, EXCP_RI);
19407 }
19408 } else {
b231c103 19409 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19410 }
c9602061 19411 break;
7a387fff
TS
19412 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19413 case OPC_TNEI:
d9224450 19414 check_insn(ctx, ISA_MIPS2);
fecd2646 19415 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19416 gen_trap(ctx, op1, rs, -1, imm);
19417 break;
19418 case OPC_SYNCI:
d75c135e 19419 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19420 /* Break the TB to be able to sync copied instructions
19421 immediately */
19422 ctx->bstate = BS_STOP;
6af0bf9c 19423 break;
e45a93e2
JL
19424 case OPC_BPOSGE32: /* MIPS DSP branch */
19425#if defined(TARGET_MIPS64)
19426 case OPC_BPOSGE64:
19427#endif
19428 check_dsp(ctx);
b231c103 19429 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19430 break;
d4ea6acd
LA
19431#if defined(TARGET_MIPS64)
19432 case OPC_DAHI:
19433 check_insn(ctx, ISA_MIPS32R6);
19434 check_mips_64(ctx);
19435 if (rs != 0) {
19436 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19437 }
19438 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
19439 break;
19440 case OPC_DATI:
19441 check_insn(ctx, ISA_MIPS32R6);
19442 check_mips_64(ctx);
19443 if (rs != 0) {
19444 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19445 }
19446 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
19447 break;
19448#endif
6af0bf9c 19449 default: /* Invalid */
923617a3 19450 MIPS_INVAL("regimm");
6af0bf9c
FB
19451 generate_exception(ctx, EXCP_RI);
19452 break;
19453 }
19454 break;
7a387fff 19455 case OPC_CP0:
387a8fe5 19456 check_cp0_enabled(ctx);
7a387fff 19457 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19458 switch (op1) {
7a387fff
TS
19459 case OPC_MFC0:
19460 case OPC_MTC0:
ead9360e
TS
19461 case OPC_MFTR:
19462 case OPC_MTTR:
5204ea79
LA
19463 case OPC_MFHC0:
19464 case OPC_MTHC0:
d26bc211 19465#if defined(TARGET_MIPS64)
7a387fff
TS
19466 case OPC_DMFC0:
19467 case OPC_DMTC0:
19468#endif
f1aa6320 19469#ifndef CONFIG_USER_ONLY
932e71cd 19470 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19471#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19472 break;
19473 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19474#ifndef CONFIG_USER_ONLY
932e71cd 19475 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19476#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19477 break;
19478 case OPC_MFMC0:
8706c382 19479#ifndef CONFIG_USER_ONLY
932e71cd 19480 {
099e5b4d 19481 uint32_t op2;
35fbce2c 19482 TCGv t0 = tcg_temp_new();
6c5c1e20 19483
0eaef5aa 19484 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19485 switch (op2) {
19486 case OPC_DMT:
d75c135e 19487 check_insn(ctx, ASE_MT);
9ed5726c 19488 gen_helper_dmt(t0);
35fbce2c 19489 gen_store_gpr(t0, rt);
6c5c1e20
TS
19490 break;
19491 case OPC_EMT:
d75c135e 19492 check_insn(ctx, ASE_MT);
9ed5726c 19493 gen_helper_emt(t0);
35fbce2c 19494 gen_store_gpr(t0, rt);
da80682b 19495 break;
6c5c1e20 19496 case OPC_DVPE:
d75c135e 19497 check_insn(ctx, ASE_MT);
895c2d04 19498 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19499 gen_store_gpr(t0, rt);
6c5c1e20
TS
19500 break;
19501 case OPC_EVPE:
d75c135e 19502 check_insn(ctx, ASE_MT);
895c2d04 19503 gen_helper_evpe(t0, cpu_env);
35fbce2c 19504 gen_store_gpr(t0, rt);
6c5c1e20
TS
19505 break;
19506 case OPC_DI:
d75c135e 19507 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19508 save_cpu_state(ctx, 1);
895c2d04 19509 gen_helper_di(t0, cpu_env);
35fbce2c 19510 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19511 /* Stop translation as we may have switched
19512 the execution mode. */
6c5c1e20
TS
19513 ctx->bstate = BS_STOP;
19514 break;
19515 case OPC_EI:
d75c135e 19516 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19517 save_cpu_state(ctx, 1);
895c2d04 19518 gen_helper_ei(t0, cpu_env);
35fbce2c 19519 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19520 /* Stop translation as we may have switched
19521 the execution mode. */
6c5c1e20
TS
19522 ctx->bstate = BS_STOP;
19523 break;
19524 default: /* Invalid */
19525 MIPS_INVAL("mfmc0");
19526 generate_exception(ctx, EXCP_RI);
19527 break;
19528 }
6c5c1e20 19529 tcg_temp_free(t0);
7a387fff 19530 }
0eaef5aa 19531#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19532 break;
7a387fff 19533 case OPC_RDPGPR:
d75c135e 19534 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19535 gen_load_srsgpr(rt, rd);
ead9360e 19536 break;
7a387fff 19537 case OPC_WRPGPR:
d75c135e 19538 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19539 gen_store_srsgpr(rt, rd);
38121543 19540 break;
6af0bf9c 19541 default:
923617a3 19542 MIPS_INVAL("cp0");
7a387fff 19543 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
19544 break;
19545 }
19546 break;
31837be3
YK
19547 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19548 if (ctx->insn_flags & ISA_MIPS32R6) {
19549 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19550 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19551 } else {
19552 /* OPC_ADDI */
19553 /* Arithmetic with immediate opcode */
19554 gen_arith_imm(ctx, op, rt, rs, imm);
19555 }
19556 break;
324d9e32 19557 case OPC_ADDIU:
d75c135e 19558 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19559 break;
324d9e32
AJ
19560 case OPC_SLTI: /* Set on less than with immediate opcode */
19561 case OPC_SLTIU:
d75c135e 19562 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19563 break;
19564 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19565 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19566 case OPC_ORI:
19567 case OPC_XORI:
d75c135e 19568 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19569 break;
7a387fff
TS
19570 case OPC_J ... OPC_JAL: /* Jump */
19571 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19572 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19573 break;
31837be3
YK
19574 /* Branch */
19575 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19576 if (ctx->insn_flags & ISA_MIPS32R6) {
19577 if (rt == 0) {
19578 generate_exception(ctx, EXCP_RI);
19579 break;
19580 }
19581 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19582 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19583 } else {
19584 /* OPC_BLEZL */
b231c103 19585 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19586 }
19587 break;
19588 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19589 if (ctx->insn_flags & ISA_MIPS32R6) {
19590 if (rt == 0) {
19591 generate_exception(ctx, EXCP_RI);
19592 break;
19593 }
19594 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19595 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19596 } else {
19597 /* OPC_BGTZL */
b231c103 19598 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19599 }
19600 break;
19601 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19602 if (rt == 0) {
19603 /* OPC_BLEZ */
b231c103 19604 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19605 } else {
19606 check_insn(ctx, ISA_MIPS32R6);
19607 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19608 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19609 }
19610 break;
19611 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19612 if (rt == 0) {
19613 /* OPC_BGTZ */
b231c103 19614 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19615 } else {
19616 check_insn(ctx, ISA_MIPS32R6);
19617 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19618 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19619 }
19620 break;
19621 case OPC_BEQL:
19622 case OPC_BNEL:
d9224450 19623 check_insn(ctx, ISA_MIPS2);
fecd2646 19624 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19625 /* Fallthrough */
31837be3
YK
19626 case OPC_BEQ:
19627 case OPC_BNE:
b231c103 19628 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19629 break;
d9224450
MR
19630 case OPC_LL: /* Load and stores */
19631 check_insn(ctx, ISA_MIPS2);
19632 /* Fallthrough */
19633 case OPC_LWL:
fecd2646
LA
19634 case OPC_LWR:
19635 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19636 /* Fallthrough */
fecd2646
LA
19637 case OPC_LB ... OPC_LH:
19638 case OPC_LW ... OPC_LHU:
d75c135e 19639 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19640 break;
fecd2646 19641 case OPC_SWL:
7a387fff 19642 case OPC_SWR:
fecd2646 19643 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19644 /* fall through */
fecd2646
LA
19645 case OPC_SB ... OPC_SH:
19646 case OPC_SW:
5c13fdfd 19647 gen_st(ctx, op, rt, rs, imm);
7a387fff 19648 break;
d66c7132 19649 case OPC_SC:
d9224450 19650 check_insn(ctx, ISA_MIPS2);
4368b29a 19651 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19652 gen_st_cond(ctx, op, rt, rs, imm);
19653 break;
7a387fff 19654 case OPC_CACHE:
bf7910c6 19655 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19656 check_cp0_enabled(ctx);
d75c135e 19657 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 19658 /* Treat as NOP. */
34ae7b51 19659 break;
7a387fff 19660 case OPC_PREF:
bf7910c6 19661 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19662 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19663 /* Treat as NOP. */
6af0bf9c 19664 break;
4ad40f36 19665
923617a3 19666 /* Floating point (COP1). */
7a387fff
TS
19667 case OPC_LWC1:
19668 case OPC_LDC1:
19669 case OPC_SWC1:
19670 case OPC_SDC1:
5ab5c041 19671 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19672 break;
19673
7a387fff 19674 case OPC_CP1:
5692c6e1
YK
19675 op1 = MASK_CP1(ctx->opcode);
19676
19677 switch (op1) {
19678 case OPC_MFHC1:
19679 case OPC_MTHC1:
5e755519 19680 check_cp1_enabled(ctx);
5692c6e1
YK
19681 check_insn(ctx, ISA_MIPS32R2);
19682 case OPC_MFC1:
19683 case OPC_CFC1:
19684 case OPC_MTC1:
19685 case OPC_CTC1:
19686 check_cp1_enabled(ctx);
19687 gen_cp1(ctx, op1, rt, rd);
19688 break;
d26bc211 19689#if defined(TARGET_MIPS64)
5692c6e1
YK
19690 case OPC_DMFC1:
19691 case OPC_DMTC1:
19692 check_cp1_enabled(ctx);
19693 check_insn(ctx, ISA_MIPS3);
d9224450 19694 check_mips_64(ctx);
5692c6e1
YK
19695 gen_cp1(ctx, op1, rt, rd);
19696 break;
e189e748 19697#endif
5692c6e1
YK
19698 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19699 check_cp1_enabled(ctx);
19700 if (ctx->insn_flags & ISA_MIPS32R6) {
19701 /* OPC_BC1EQZ */
31837be3 19702 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19703 rt, imm << 2, 4);
5692c6e1
YK
19704 } else {
19705 /* OPC_BC1ANY2 */
b8aa4598 19706 check_cop1x(ctx);
d75c135e 19707 check_insn(ctx, ASE_MIPS3D);
d75c135e 19708 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19709 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19710 }
19711 break;
19712 case OPC_BC1NEZ:
19713 check_cp1_enabled(ctx);
19714 check_insn(ctx, ISA_MIPS32R6);
19715 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19716 rt, imm << 2, 4);
5692c6e1
YK
19717 break;
19718 case OPC_BC1ANY4:
19719 check_cp1_enabled(ctx);
19720 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19721 check_cop1x(ctx);
19722 check_insn(ctx, ASE_MIPS3D);
19723 /* fall through */
19724 case OPC_BC1:
19725 check_cp1_enabled(ctx);
19726 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19727 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19728 (rt >> 2) & 0x7, imm << 2);
19729 break;
19730 case OPC_PS_FMT:
e29c9628 19731 check_ps(ctx);
b6f3b233 19732 /* fall through */
5692c6e1
YK
19733 case OPC_S_FMT:
19734 case OPC_D_FMT:
19735 check_cp1_enabled(ctx);
19736 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19737 (imm >> 8) & 0x7);
19738 break;
19739 case OPC_W_FMT:
19740 case OPC_L_FMT:
19741 {
19742 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19743 check_cp1_enabled(ctx);
19744 if (ctx->insn_flags & ISA_MIPS32R6) {
19745 switch (r6_op) {
19746 case R6_OPC_CMP_AF_S:
19747 case R6_OPC_CMP_UN_S:
19748 case R6_OPC_CMP_EQ_S:
19749 case R6_OPC_CMP_UEQ_S:
19750 case R6_OPC_CMP_LT_S:
19751 case R6_OPC_CMP_ULT_S:
19752 case R6_OPC_CMP_LE_S:
19753 case R6_OPC_CMP_ULE_S:
19754 case R6_OPC_CMP_SAF_S:
19755 case R6_OPC_CMP_SUN_S:
19756 case R6_OPC_CMP_SEQ_S:
19757 case R6_OPC_CMP_SEUQ_S:
19758 case R6_OPC_CMP_SLT_S:
19759 case R6_OPC_CMP_SULT_S:
19760 case R6_OPC_CMP_SLE_S:
19761 case R6_OPC_CMP_SULE_S:
19762 case R6_OPC_CMP_OR_S:
19763 case R6_OPC_CMP_UNE_S:
19764 case R6_OPC_CMP_NE_S:
19765 case R6_OPC_CMP_SOR_S:
19766 case R6_OPC_CMP_SUNE_S:
19767 case R6_OPC_CMP_SNE_S:
19768 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19769 break;
19770 case R6_OPC_CMP_AF_D:
19771 case R6_OPC_CMP_UN_D:
19772 case R6_OPC_CMP_EQ_D:
19773 case R6_OPC_CMP_UEQ_D:
19774 case R6_OPC_CMP_LT_D:
19775 case R6_OPC_CMP_ULT_D:
19776 case R6_OPC_CMP_LE_D:
19777 case R6_OPC_CMP_ULE_D:
19778 case R6_OPC_CMP_SAF_D:
19779 case R6_OPC_CMP_SUN_D:
19780 case R6_OPC_CMP_SEQ_D:
19781 case R6_OPC_CMP_SEUQ_D:
19782 case R6_OPC_CMP_SLT_D:
19783 case R6_OPC_CMP_SULT_D:
19784 case R6_OPC_CMP_SLE_D:
19785 case R6_OPC_CMP_SULE_D:
19786 case R6_OPC_CMP_OR_D:
19787 case R6_OPC_CMP_UNE_D:
19788 case R6_OPC_CMP_NE_D:
19789 case R6_OPC_CMP_SOR_D:
19790 case R6_OPC_CMP_SUNE_D:
19791 case R6_OPC_CMP_SNE_D:
19792 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19793 break;
19794 default:
d2bfa6e6
MR
19795 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19796 rt, rd, sa, (imm >> 8) & 0x7);
19797
5692c6e1 19798 break;
3f493883 19799 }
5692c6e1
YK
19800 } else {
19801 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19802 (imm >> 8) & 0x7);
36d23958 19803 }
5692c6e1
YK
19804 break;
19805 }
19806 case OPC_BZ_V:
19807 case OPC_BNZ_V:
19808 case OPC_BZ_B:
19809 case OPC_BZ_H:
19810 case OPC_BZ_W:
19811 case OPC_BZ_D:
19812 case OPC_BNZ_B:
19813 case OPC_BNZ_H:
19814 case OPC_BNZ_W:
19815 case OPC_BNZ_D:
19816 check_insn(ctx, ASE_MSA);
19817 gen_msa_branch(env, ctx, op1);
19818 break;
19819 default:
19820 MIPS_INVAL("cp1");
19821 generate_exception(ctx, EXCP_RI);
19822 break;
6ea83fed 19823 }
4ad40f36
FB
19824 break;
19825
31837be3
YK
19826 /* Compact branches [R6] and COP2 [non-R6] */
19827 case OPC_BC: /* OPC_LWC2 */
19828 case OPC_BALC: /* OPC_SWC2 */
19829 if (ctx->insn_flags & ISA_MIPS32R6) {
19830 /* OPC_BC, OPC_BALC */
19831 gen_compute_compact_branch(ctx, op, 0, 0,
19832 sextract32(ctx->opcode << 2, 0, 28));
19833 } else {
19834 /* OPC_LWC2, OPC_SWC2 */
19835 /* COP2: Not implemented. */
19836 generate_exception_err(ctx, EXCP_CpU, 2);
19837 }
19838 break;
19839 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19840 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19841 if (ctx->insn_flags & ISA_MIPS32R6) {
19842 if (rs != 0) {
19843 /* OPC_BEQZC, OPC_BNEZC */
19844 gen_compute_compact_branch(ctx, op, rs, 0,
19845 sextract32(ctx->opcode << 2, 0, 23));
19846 } else {
19847 /* OPC_JIC, OPC_JIALC */
19848 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19849 }
19850 } else {
19851 /* OPC_LWC2, OPC_SWC2 */
19852 /* COP2: Not implemented. */
19853 generate_exception_err(ctx, EXCP_CpU, 2);
19854 }
4ad40f36 19855 break;
bd277fa1 19856 case OPC_CP2:
d75c135e 19857 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
19858 /* Note that these instructions use different fields. */
19859 gen_loongson_multimedia(ctx, sa, rd, rt);
19860 break;
4ad40f36 19861
7a387fff 19862 case OPC_CP3:
fecd2646 19863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 19864 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 19865 check_cp1_enabled(ctx);
36d23958
TS
19866 op1 = MASK_CP3(ctx->opcode);
19867 switch (op1) {
d9224450
MR
19868 case OPC_LUXC1:
19869 case OPC_SUXC1:
19870 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19871 /* Fallthrough */
5a5012ec
TS
19872 case OPC_LWXC1:
19873 case OPC_LDXC1:
5a5012ec
TS
19874 case OPC_SWXC1:
19875 case OPC_SDXC1:
d9224450 19876 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 19877 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 19878 break;
e0c84da7 19879 case OPC_PREFX:
d9224450 19880 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 19881 /* Treat as NOP. */
e0c84da7 19882 break;
5a5012ec 19883 case OPC_ALNV_PS:
d9224450
MR
19884 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19885 /* Fallthrough */
5a5012ec
TS
19886 case OPC_MADD_S:
19887 case OPC_MADD_D:
19888 case OPC_MADD_PS:
19889 case OPC_MSUB_S:
19890 case OPC_MSUB_D:
19891 case OPC_MSUB_PS:
19892 case OPC_NMADD_S:
19893 case OPC_NMADD_D:
19894 case OPC_NMADD_PS:
19895 case OPC_NMSUB_S:
19896 case OPC_NMSUB_D:
19897 case OPC_NMSUB_PS:
d9224450 19898 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
19899 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19900 break;
36d23958 19901 default:
923617a3 19902 MIPS_INVAL("cp3");
e397ee33 19903 generate_exception (ctx, EXCP_RI);
36d23958
TS
19904 break;
19905 }
19906 } else {
e397ee33 19907 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 19908 }
4ad40f36
FB
19909 break;
19910
d26bc211 19911#if defined(TARGET_MIPS64)
7a387fff 19912 /* MIPS64 opcodes */
7a387fff 19913 case OPC_LDL ... OPC_LDR:
bf7910c6 19914 case OPC_LLD:
fecd2646 19915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19916 /* fall through */
fecd2646 19917 case OPC_LWU:
7a387fff 19918 case OPC_LD:
d75c135e 19919 check_insn(ctx, ISA_MIPS3);
5c13fdfd 19920 check_mips_64(ctx);
d75c135e 19921 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
19922 break;
19923 case OPC_SDL ... OPC_SDR:
fecd2646 19924 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19925 /* fall through */
7a387fff 19926 case OPC_SD:
d75c135e 19927 check_insn(ctx, ISA_MIPS3);
e189e748 19928 check_mips_64(ctx);
5c13fdfd 19929 gen_st(ctx, op, rt, rs, imm);
7a387fff 19930 break;
d66c7132 19931 case OPC_SCD:
bf7910c6 19932 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19933 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19934 check_mips_64(ctx);
19935 gen_st_cond(ctx, op, rt, rs, imm);
19936 break;
31837be3
YK
19937 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19938 if (ctx->insn_flags & ISA_MIPS32R6) {
19939 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19940 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19941 } else {
19942 /* OPC_DADDI */
19943 check_insn(ctx, ISA_MIPS3);
19944 check_mips_64(ctx);
19945 gen_arith_imm(ctx, op, rt, rs, imm);
19946 }
19947 break;
324d9e32 19948 case OPC_DADDIU:
d75c135e 19949 check_insn(ctx, ISA_MIPS3);
e189e748 19950 check_mips_64(ctx);
d75c135e 19951 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19952 break;
31837be3
YK
19953#else
19954 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19955 if (ctx->insn_flags & ISA_MIPS32R6) {
19956 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19957 } else {
19958 MIPS_INVAL("major opcode");
19959 generate_exception(ctx, EXCP_RI);
19960 }
19961 break;
6af0bf9c 19962#endif
d4ea6acd
LA
19963 case OPC_DAUI: /* OPC_JALX */
19964 if (ctx->insn_flags & ISA_MIPS32R6) {
19965#if defined(TARGET_MIPS64)
19966 /* OPC_DAUI */
19967 check_mips_64(ctx);
19968 if (rt != 0) {
19969 TCGv t0 = tcg_temp_new();
19970 gen_load_gpr(t0, rs);
19971 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19972 tcg_temp_free(t0);
19973 }
19974 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19975#else
19976 generate_exception(ctx, EXCP_RI);
19977 MIPS_INVAL("major opcode");
19978#endif
19979 } else {
19980 /* OPC_JALX */
19981 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19982 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19983 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19984 }
364d4831 19985 break;
4c789546 19986 case OPC_MSA: /* OPC_MDMX */
7a387fff 19987 /* MDMX: Not implemented. */
4c789546 19988 gen_msa(env, ctx);
d4ea6acd
LA
19989 break;
19990 case OPC_PCREL:
19991 check_insn(ctx, ISA_MIPS32R6);
19992 gen_pcrel(ctx, rs, imm);
19993 break;
6af0bf9c 19994 default: /* Invalid */
923617a3 19995 MIPS_INVAL("major opcode");
6af0bf9c
FB
19996 generate_exception(ctx, EXCP_RI);
19997 break;
19998 }
6af0bf9c
FB
19999}
20000
2cfc5f17 20001static inline void
6429db34
AF
20002gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
20003 bool search_pc)
6af0bf9c 20004{
ed2803da 20005 CPUState *cs = CPU(cpu);
6429db34 20006 CPUMIPSState *env = &cpu->env;
278d0702 20007 DisasContext ctx;
6af0bf9c 20008 target_ulong pc_start;
fe237291 20009 target_ulong next_page_start;
a1d1bb31 20010 CPUBreakpoint *bp;
6af0bf9c 20011 int j, lj = -1;
2e70f6ef
PB
20012 int num_insns;
20013 int max_insns;
c9602061 20014 int insn_bytes;
339cd2a8 20015 int is_slot;
6af0bf9c 20016
93fcfe39
AL
20017 if (search_pc)
20018 qemu_log("search pc %d\n", search_pc);
4ad40f36 20019
6af0bf9c 20020 pc_start = tb->pc;
fe237291 20021 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
6af0bf9c 20022 ctx.pc = pc_start;
4ad40f36 20023 ctx.saved_pc = -1;
ed2803da 20024 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 20025 ctx.insn_flags = env->insn_flags;
5ab5c041 20026 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
20027 ctx.tb = tb;
20028 ctx.bstate = BS_NONE;
e98c0d17 20029 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 20030 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 20031 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
20032 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20033 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
20034 ctx.PAMask = env->PAMask;
20035 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
20036 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
4ad40f36 20037 /* Restore delay slot state from the tb context. */
c068688b 20038 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
66991d11 20039 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
20040 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
20041 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
fd4a04eb 20042 restore_cpu_state(env, &ctx);
932e71cd 20043#ifdef CONFIG_USER_ONLY
0eaef5aa 20044 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 20045#else
0eaef5aa 20046 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 20047#endif
be3a8c53
YK
20048 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
20049 MO_UNALN : MO_ALIGN;
2e70f6ef
PB
20050 num_insns = 0;
20051 max_insns = tb->cflags & CF_COUNT_MASK;
20052 if (max_insns == 0)
20053 max_insns = CF_COUNT_MASK;
d12d51d5 20054 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 20055 gen_tb_start(tb);
faf7aaa9 20056 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
20057 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
20058 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 20059 if (bp->pc == ctx.pc) {
278d0702 20060 save_cpu_state(&ctx, 1);
4ad40f36 20061 ctx.bstate = BS_BRANCH;
895c2d04 20062 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
20063 /* Include the breakpoint location or the tb won't
20064 * be flushed when it must be. */
20065 ctx.pc += 4;
4ad40f36
FB
20066 goto done_generating;
20067 }
20068 }
20069 }
20070
6af0bf9c 20071 if (search_pc) {
fe700adb 20072 j = tcg_op_buf_count();
6af0bf9c
FB
20073 if (lj < j) {
20074 lj++;
20075 while (lj < j)
ab1103de 20076 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 20077 }
25983cad 20078 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 20079 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 20080 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 20081 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 20082 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 20083 }
2e70f6ef
PB
20084 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
20085 gen_io_start();
c9602061 20086
339cd2a8 20087 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 20088 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 20089 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 20090 insn_bytes = 4;
240ce26a 20091 decode_opc(env, &ctx);
d75c135e 20092 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 20093 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 20094 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 20095 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 20096 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 20097 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
20098 } else {
20099 generate_exception(&ctx, EXCP_RI);
3c824109 20100 ctx.bstate = BS_STOP;
c9602061
NF
20101 break;
20102 }
31837be3 20103
b231c103 20104 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
20105 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20106 MIPS_HFLAG_FBNSLOT))) {
20107 /* force to generate branch as there is neither delay nor
20108 forbidden slot */
20109 is_slot = 1;
b231c103 20110 }
65935f07
YK
20111 if ((ctx.hflags & MIPS_HFLAG_M16) &&
20112 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
20113 /* Force to generate branch as microMIPS R6 doesn't restrict
20114 branches in the forbidden slot. */
20115 is_slot = 1;
20116 }
b231c103 20117 }
339cd2a8 20118 if (is_slot) {
31837be3 20119 gen_branch(&ctx, insn_bytes);
c9602061
NF
20120 }
20121 ctx.pc += insn_bytes;
20122
2e70f6ef 20123 num_insns++;
4ad40f36 20124
7b270ef2
NF
20125 /* Execute a branch and its delay slot as a single instruction.
20126 This is what GDB expects and is consistent with what the
20127 hardware does (e.g. if a delay slot instruction faults, the
20128 reported PC is the PC of the branch). */
ed2803da 20129 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 20130 break;
ed2803da 20131 }
4ad40f36 20132
fe237291 20133 if (ctx.pc >= next_page_start) {
6af0bf9c 20134 break;
fe237291 20135 }
4ad40f36 20136
fe700adb 20137 if (tcg_op_buf_full()) {
faf7aaa9 20138 break;
efd7f486 20139 }
faf7aaa9 20140
2e70f6ef
PB
20141 if (num_insns >= max_insns)
20142 break;
1b530a6d
AJ
20143
20144 if (singlestep)
20145 break;
6af0bf9c 20146 }
ed2803da 20147 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 20148 gen_io_end();
ed2803da
AF
20149 }
20150 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 20151 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
895c2d04 20152 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 20153 } else {
6958549d 20154 switch (ctx.bstate) {
16c00cb2 20155 case BS_STOP:
df1561e2
TS
20156 gen_goto_tb(&ctx, 0, ctx.pc);
20157 break;
16c00cb2 20158 case BS_NONE:
278d0702 20159 save_cpu_state(&ctx, 0);
16c00cb2
TS
20160 gen_goto_tb(&ctx, 0, ctx.pc);
20161 break;
5a5012ec 20162 case BS_EXCP:
57fec1fe 20163 tcg_gen_exit_tb(0);
16c00cb2 20164 break;
5a5012ec
TS
20165 case BS_BRANCH:
20166 default:
20167 break;
6958549d 20168 }
6af0bf9c 20169 }
4ad40f36 20170done_generating:
806f352d 20171 gen_tb_end(tb, num_insns);
0a7df5da 20172
6af0bf9c 20173 if (search_pc) {
fe700adb 20174 j = tcg_op_buf_count();
6af0bf9c
FB
20175 lj++;
20176 while (lj <= j)
ab1103de 20177 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
20178 } else {
20179 tb->size = ctx.pc - pc_start;
2e70f6ef 20180 tb->icount = num_insns;
6af0bf9c
FB
20181 }
20182#ifdef DEBUG_DISAS
d12d51d5 20183 LOG_DISAS("\n");
8fec2b8c 20184 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 20185 qemu_log("IN: %s\n", lookup_symbol(pc_start));
d49190c4 20186 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
93fcfe39 20187 qemu_log("\n");
6af0bf9c
FB
20188 }
20189#endif
6af0bf9c
FB
20190}
20191
7db13fae 20192void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 20193{
6429db34 20194 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
20195}
20196
7db13fae 20197void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 20198{
6429db34 20199 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
20200}
20201
7db13fae 20202static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20203 int flags)
6ea83fed
FB
20204{
20205 int i;
5e755519 20206 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20207
2a5612e6
SW
20208#define printfpr(fp) \
20209 do { \
20210 if (is_fpu64) \
20211 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20212 " fd:%13g fs:%13g psu: %13g\n", \
20213 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20214 (double)(fp)->fd, \
20215 (double)(fp)->fs[FP_ENDIAN_IDX], \
20216 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20217 else { \
20218 fpr_t tmp; \
20219 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20220 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20221 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20222 " fd:%13g fs:%13g psu:%13g\n", \
20223 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20224 (double)tmp.fd, \
20225 (double)tmp.fs[FP_ENDIAN_IDX], \
20226 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20227 } \
6ea83fed
FB
20228 } while(0)
20229
5a5012ec 20230
9a78eead
SW
20231 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20232 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20233 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20234 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20235 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20236 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20237 }
20238
20239#undef printfpr
20240}
20241
d26bc211 20242#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 20243/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 20244 sign-extended values on 64bit machines. */
c570fd16
TS
20245
20246#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
20247
8706c382 20248static void
7db13fae 20249cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 20250 fprintf_function cpu_fprintf,
8706c382 20251 int flags)
c570fd16
TS
20252{
20253 int i;
20254
b5dc7732
TS
20255 if (!SIGN_EXT_P(env->active_tc.PC))
20256 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
20257 if (!SIGN_EXT_P(env->active_tc.HI[0]))
20258 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
20259 if (!SIGN_EXT_P(env->active_tc.LO[0]))
20260 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 20261 if (!SIGN_EXT_P(env->btarget))
3594c774 20262 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
20263
20264 for (i = 0; i < 32; i++) {
b5dc7732
TS
20265 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
20266 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
20267 }
20268
20269 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 20270 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
20271 if (!SIGN_EXT_P(env->lladdr))
20272 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
20273}
20274#endif
20275
878096ee
AF
20276void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20277 int flags)
6af0bf9c 20278{
878096ee
AF
20279 MIPSCPU *cpu = MIPS_CPU(cs);
20280 CPUMIPSState *env = &cpu->env;
6af0bf9c 20281 int i;
3b46e624 20282
a7200c9f
SW
20283 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20284 " LO=0x" TARGET_FMT_lx " ds %04x "
20285 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20286 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20287 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20288 for (i = 0; i < 32; i++) {
20289 if ((i & 3) == 0)
20290 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20291 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20292 if ((i & 3) == 3)
20293 cpu_fprintf(f, "\n");
20294 }
568b600d 20295
3594c774 20296 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20297 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20298 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20299 PRIx64 "\n",
5499b6ff 20300 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20301 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20302 env->CP0_Config2, env->CP0_Config3);
20303 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20304 env->CP0_Config4, env->CP0_Config5);
5e755519 20305 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 20306 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 20307#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
20308 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
20309#endif
6af0bf9c
FB
20310}
20311
78ce64f4 20312void mips_tcg_init(void)
39454628 20313{
f01be154 20314 int i;
39454628
TS
20315 static int inited;
20316
20317 /* Initialize various static tables. */
20318 if (inited)
6958549d 20319 return;
39454628 20320
a7812ae4 20321 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 20322 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 20323 for (i = 1; i < 32; i++)
a7812ae4 20324 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 20325 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20326 regnames[i]);
d73ee8a2 20327
863f264d
YK
20328 for (i = 0; i < 32; i++) {
20329 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20330 msa_wr_d[i * 2] =
20331 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
20332 /* The scalar floating-point unit (FPU) registers are mapped on
20333 * the MSA vector registers. */
20334 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20335 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20336 msa_wr_d[i * 2 + 1] =
20337 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
20338 }
20339
a7812ae4 20340 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 20341 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20342 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 20343 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 20344 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20345 regnames_HI[i]);
a7812ae4 20346 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 20347 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20348 regnames_LO[i]);
4b2eb8d2 20349 }
a7812ae4 20350 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 20351 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20352 "DSPControl");
1ba74fb8 20353 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 20354 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 20355 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 20356 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 20357 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 20358 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20359
a7812ae4 20360 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 20361 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
20362 "fcr0");
20363 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 20364 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20365 "fcr31");
39454628
TS
20366
20367 inited = 1;
20368}
20369
aaed909a
FB
20370#include "translate_init.c"
20371
30bf942d 20372MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 20373{
0f71a709 20374 MIPSCPU *cpu;
6af0bf9c 20375 CPUMIPSState *env;
c227f099 20376 const mips_def_t *def;
6af0bf9c 20377
aaed909a
FB
20378 def = cpu_mips_find_by_name(cpu_model);
20379 if (!def)
20380 return NULL;
0f71a709
AF
20381 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20382 env = &cpu->env;
aaed909a
FB
20383 env->cpu_model = def;
20384
51cc2e78
BS
20385#ifndef CONFIG_USER_ONLY
20386 mmu_init(env, def);
20387#endif
20388 fpu_init(env, def);
20389 mvp_init(env, def);
c1caf1d9
AF
20390
20391 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20392
30bf942d 20393 return cpu;
6ae81775
TS
20394}
20395
1bba0dc9 20396void cpu_state_reset(CPUMIPSState *env)
6ae81775 20397{
55e5c285
AF
20398 MIPSCPU *cpu = mips_env_get_cpu(env);
20399 CPUState *cs = CPU(cpu);
6ae81775 20400
51cc2e78
BS
20401 /* Reset registers to their default values */
20402 env->CP0_PRid = env->cpu_model->CP0_PRid;
20403 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20404#ifdef TARGET_WORDS_BIGENDIAN
20405 env->CP0_Config0 |= (1 << CP0C0_BE);
20406#endif
20407 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20408 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20409 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20410 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20411 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20412 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20413 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20414 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20415 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20416 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20417 << env->cpu_model->CP0_LLAddr_shift;
20418 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20419 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20420 env->CCRes = env->cpu_model->CCRes;
20421 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20422 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20423 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20424 env->current_tc = 0;
20425 env->SEGBITS = env->cpu_model->SEGBITS;
20426 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20427#if defined(TARGET_MIPS64)
20428 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20429 env->SEGMask |= 3ULL << 62;
20430 }
20431#endif
20432 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20433 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20434 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20435 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20436 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20437 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20438 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20439 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20440 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20441 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20442 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20443 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20444 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 20445 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 20446 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20447 env->insn_flags = env->cpu_model->insn_flags;
20448
0eaef5aa 20449#if defined(CONFIG_USER_ONLY)
03e6e501 20450 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20451# ifdef TARGET_MIPS64
20452 /* Enable 64-bit register mode. */
20453 env->CP0_Status |= (1 << CP0St_PX);
20454# endif
20455# ifdef TARGET_ABI_MIPSN64
20456 /* Enable 64-bit address mode. */
20457 env->CP0_Status |= (1 << CP0St_UX);
20458# endif
94159135
MI
20459 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20460 hardware registers. */
20461 env->CP0_HWREna |= 0x0000000F;
91a75935 20462 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20463 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20464 }
6f0af304
PJ
20465 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20466 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20467 }
4d66261f
PJ
20468# if defined(TARGET_MIPS64)
20469 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20470 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20471 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20472 env->CP0_Status |= (1 << CP0St_FR);
20473 }
4d66261f 20474# endif
932e71cd
AJ
20475#else
20476 if (env->hflags & MIPS_HFLAG_BMASK) {
20477 /* If the exception was raised from a delay slot,
20478 come back to the jump. */
c3577479
MR
20479 env->CP0_ErrorEPC = (env->active_tc.PC
20480 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20481 } else {
932e71cd
AJ
20482 env->CP0_ErrorEPC = env->active_tc.PC;
20483 }
20484 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
20485 env->CP0_Random = env->tlb->nb_tlb - 1;
20486 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20487 env->CP0_Wired = 0;
0a2672b7
JH
20488 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20489 if (kvm_enabled()) {
20490 env->CP0_EBase |= 0x40000000;
20491 } else {
20492 env->CP0_EBase |= 0x80000000;
20493 }
932e71cd
AJ
20494 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20495 /* vectored interrupts not implemented, timer on int 7,
20496 no performance counters. */
20497 env->CP0_IntCtl = 0xe0000000;
20498 {
20499 int i;
20500
20501 for (i = 0; i < 7; i++) {
20502 env->CP0_WatchLo[i] = 0;
20503 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20504 }
932e71cd
AJ
20505 env->CP0_WatchLo[7] = 0;
20506 env->CP0_WatchHi[7] = 0;
fd88b6ab 20507 }
932e71cd
AJ
20508 /* Count register increments in debug mode, EJTAG version 1 */
20509 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20510
4b69c7e2
JH
20511 cpu_mips_store_count(env, 1);
20512
9e56e756
EI
20513 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20514 int i;
20515
20516 /* Only TC0 on VPE 0 starts as active. */
20517 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20518 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20519 env->tcs[i].CP0_TCHalt = 1;
20520 }
20521 env->active_tc.CP0_TCHalt = 1;
259186a7 20522 cs->halted = 1;
9e56e756 20523
55e5c285 20524 if (cs->cpu_index == 0) {
9e56e756
EI
20525 /* VPE0 starts up enabled. */
20526 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20527 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20528
20529 /* TC0 starts up unhalted. */
259186a7 20530 cs->halted = 0;
9e56e756
EI
20531 env->active_tc.CP0_TCHalt = 0;
20532 env->tcs[0].CP0_TCHalt = 0;
20533 /* With thread 0 active. */
20534 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20535 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20536 }
20537 }
51cc2e78 20538#endif
ddc584bd
LA
20539 if ((env->insn_flags & ISA_MIPS32R6) &&
20540 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20541 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20542 env->CP0_Status |= (1 << CP0St_FR);
20543 }
20544
863f264d
YK
20545 /* MSA */
20546 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20547 msa_reset(env);
20548 }
20549
03e6e501 20550 compute_hflags(env);
bb962386
MR
20551 restore_rounding_mode(env);
20552 restore_flush_mode(env);
e117f526 20553 restore_pamask(env);
27103424 20554 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20555
20556 if (semihosting_get_argc()) {
20557 /* UHI interface can be used to obtain argc and argv */
20558 env->active_tc.gpr[4] = -1;
20559 }
6af0bf9c 20560}
d2856f1a 20561
7db13fae 20562void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 20563{
25983cad 20564 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
20565 env->hflags &= ~MIPS_HFLAG_BMASK;
20566 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
20567 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20568 case MIPS_HFLAG_BR:
20569 break;
20570 case MIPS_HFLAG_BC:
20571 case MIPS_HFLAG_BL:
20572 case MIPS_HFLAG_B:
20573 env->btarget = gen_opc_btarget[pc_pos];
20574 break;
20575 }
d2856f1a 20576}