]> git.proxmox.com Git - mirror_qemu.git/blame - target-mips/translate.c
target-mips: Tighten ISA level checks
[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"
a7812ae4 32
a7e30d84
LV
33#include "trace-tcg.h"
34
35
fb7729e2 36#define MIPS_DEBUG_DISAS 0
c570fd16 37//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 38
7a387fff
TS
39/* MIPS major opcodes */
40#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
41
42enum {
43 /* indirect opcode tables */
7a387fff
TS
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 52 /* arithmetic with immediate */
7a387fff
TS
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
324d9e32 57 /* logic with immediate */
7a387fff
TS
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
324d9e32 62 /* arithmetic with immediate */
7a387fff
TS
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
e37e863f 65 /* Jump and branches */
7a387fff
TS
66 OPC_J = (0x02 << 26),
67 OPC_JAL = (0x03 << 26),
68 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
69 OPC_BEQL = (0x14 << 26),
70 OPC_BNE = (0x05 << 26),
71 OPC_BNEL = (0x15 << 26),
72 OPC_BLEZ = (0x06 << 26),
73 OPC_BLEZL = (0x16 << 26),
74 OPC_BGTZ = (0x07 << 26),
75 OPC_BGTZL = (0x17 << 26),
b231c103 76 OPC_JALX = (0x1D << 26),
d4ea6acd 77 OPC_DAUI = (0x1D << 26),
e37e863f 78 /* Load and stores */
7a387fff
TS
79 OPC_LDL = (0x1A << 26),
80 OPC_LDR = (0x1B << 26),
81 OPC_LB = (0x20 << 26),
82 OPC_LH = (0x21 << 26),
83 OPC_LWL = (0x22 << 26),
84 OPC_LW = (0x23 << 26),
364d4831 85 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
86 OPC_LBU = (0x24 << 26),
87 OPC_LHU = (0x25 << 26),
88 OPC_LWR = (0x26 << 26),
89 OPC_LWU = (0x27 << 26),
90 OPC_SB = (0x28 << 26),
91 OPC_SH = (0x29 << 26),
92 OPC_SWL = (0x2A << 26),
93 OPC_SW = (0x2B << 26),
94 OPC_SDL = (0x2C << 26),
95 OPC_SDR = (0x2D << 26),
96 OPC_SWR = (0x2E << 26),
97 OPC_LL = (0x30 << 26),
98 OPC_LLD = (0x34 << 26),
99 OPC_LD = (0x37 << 26),
364d4831 100 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
101 OPC_SC = (0x38 << 26),
102 OPC_SCD = (0x3C << 26),
103 OPC_SD = (0x3F << 26),
e37e863f 104 /* Floating point load/store */
7a387fff
TS
105 OPC_LWC1 = (0x31 << 26),
106 OPC_LWC2 = (0x32 << 26),
107 OPC_LDC1 = (0x35 << 26),
108 OPC_LDC2 = (0x36 << 26),
109 OPC_SWC1 = (0x39 << 26),
110 OPC_SWC2 = (0x3A << 26),
111 OPC_SDC1 = (0x3D << 26),
112 OPC_SDC2 = (0x3E << 26),
31837be3
YK
113 /* Compact Branches */
114 OPC_BLEZALC = (0x06 << 26),
115 OPC_BGEZALC = (0x06 << 26),
116 OPC_BGEUC = (0x06 << 26),
117 OPC_BGTZALC = (0x07 << 26),
118 OPC_BLTZALC = (0x07 << 26),
119 OPC_BLTUC = (0x07 << 26),
120 OPC_BOVC = (0x08 << 26),
121 OPC_BEQZALC = (0x08 << 26),
122 OPC_BEQC = (0x08 << 26),
123 OPC_BLEZC = (0x16 << 26),
124 OPC_BGEZC = (0x16 << 26),
125 OPC_BGEC = (0x16 << 26),
126 OPC_BGTZC = (0x17 << 26),
127 OPC_BLTZC = (0x17 << 26),
128 OPC_BLTC = (0x17 << 26),
129 OPC_BNVC = (0x18 << 26),
130 OPC_BNEZALC = (0x18 << 26),
131 OPC_BNEC = (0x18 << 26),
132 OPC_BC = (0x32 << 26),
133 OPC_BEQZC = (0x36 << 26),
134 OPC_JIC = (0x36 << 26),
135 OPC_BALC = (0x3A << 26),
136 OPC_BNEZC = (0x3E << 26),
137 OPC_JIALC = (0x3E << 26),
7a387fff
TS
138 /* MDMX ASE specific */
139 OPC_MDMX = (0x1E << 26),
239dfebe
YK
140 /* MSA ASE, same as MDMX */
141 OPC_MSA = OPC_MDMX,
e37e863f 142 /* Cache and prefetch */
7a387fff
TS
143 OPC_CACHE = (0x2F << 26),
144 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
145 /* PC-relative address computation / loads */
146 OPC_PCREL = (0x3B << 26),
147};
148
149/* PC-relative address computation / loads */
150#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152enum {
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
155 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
156 OPC_LWUPC = OPC_PCREL | (2 << 19),
157
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
160 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
161
162 /* Other */
163 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
164};
165
166/* MIPS special opcodes */
7a387fff
TS
167#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
168
e37e863f
FB
169enum {
170 /* Shifts */
7a387fff 171 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 176 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
177 OPC_SRA = 0x03 | OPC_SPECIAL,
178 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 179 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 180 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
181 OPC_SRAV = 0x07 | OPC_SPECIAL,
182 OPC_DSLLV = 0x14 | OPC_SPECIAL,
183 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 184 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
185 OPC_DSRAV = 0x17 | OPC_SPECIAL,
186 OPC_DSLL = 0x38 | OPC_SPECIAL,
187 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 188 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
189 OPC_DSRA = 0x3B | OPC_SPECIAL,
190 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
191 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 192 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 193 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 194 /* Multiplication / division */
7a387fff
TS
195 OPC_MULT = 0x18 | OPC_SPECIAL,
196 OPC_MULTU = 0x19 | OPC_SPECIAL,
197 OPC_DIV = 0x1A | OPC_SPECIAL,
198 OPC_DIVU = 0x1B | OPC_SPECIAL,
199 OPC_DMULT = 0x1C | OPC_SPECIAL,
200 OPC_DMULTU = 0x1D | OPC_SPECIAL,
201 OPC_DDIV = 0x1E | OPC_SPECIAL,
202 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 203
e37e863f 204 /* 2 registers arithmetic / logic */
7a387fff
TS
205 OPC_ADD = 0x20 | OPC_SPECIAL,
206 OPC_ADDU = 0x21 | OPC_SPECIAL,
207 OPC_SUB = 0x22 | OPC_SPECIAL,
208 OPC_SUBU = 0x23 | OPC_SPECIAL,
209 OPC_AND = 0x24 | OPC_SPECIAL,
210 OPC_OR = 0x25 | OPC_SPECIAL,
211 OPC_XOR = 0x26 | OPC_SPECIAL,
212 OPC_NOR = 0x27 | OPC_SPECIAL,
213 OPC_SLT = 0x2A | OPC_SPECIAL,
214 OPC_SLTU = 0x2B | OPC_SPECIAL,
215 OPC_DADD = 0x2C | OPC_SPECIAL,
216 OPC_DADDU = 0x2D | OPC_SPECIAL,
217 OPC_DSUB = 0x2E | OPC_SPECIAL,
218 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 219 /* Jumps */
7a387fff
TS
220 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
221 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 222 /* Traps */
7a387fff
TS
223 OPC_TGE = 0x30 | OPC_SPECIAL,
224 OPC_TGEU = 0x31 | OPC_SPECIAL,
225 OPC_TLT = 0x32 | OPC_SPECIAL,
226 OPC_TLTU = 0x33 | OPC_SPECIAL,
227 OPC_TEQ = 0x34 | OPC_SPECIAL,
228 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 229 /* HI / LO registers load & stores */
7a387fff
TS
230 OPC_MFHI = 0x10 | OPC_SPECIAL,
231 OPC_MTHI = 0x11 | OPC_SPECIAL,
232 OPC_MFLO = 0x12 | OPC_SPECIAL,
233 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 234 /* Conditional moves */
7a387fff
TS
235 OPC_MOVZ = 0x0A | OPC_SPECIAL,
236 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 237
b691d9d2
LA
238 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
239 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
240
7a387fff 241 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
242
243 /* Special */
a0d700e4 244 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
245 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
246 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 247 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
248 OPC_SYNC = 0x0F | OPC_SPECIAL,
249
7a387fff
TS
250 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
251 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
252 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
253 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
254};
255
b42ee5e1
LA
256/* R6 Multiply and Divide instructions have the same Opcode
257 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
258#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
259
260enum {
261 R6_OPC_MUL = OPC_MULT | (2 << 6),
262 R6_OPC_MUH = OPC_MULT | (3 << 6),
263 R6_OPC_MULU = OPC_MULTU | (2 << 6),
264 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
265 R6_OPC_DIV = OPC_DIV | (2 << 6),
266 R6_OPC_MOD = OPC_DIV | (3 << 6),
267 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
268 R6_OPC_MODU = OPC_DIVU | (3 << 6),
269
270 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
271 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
272 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
273 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
274 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
275 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
276 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
277 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
278
279 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
280 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
281 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
282 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
283 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
284
285 OPC_LSA = 0x05 | OPC_SPECIAL,
286 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
287};
288
e9c71dd1
TS
289/* Multiplication variants of the vr54xx. */
290#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
291
292enum {
293 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
294 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
295 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
296 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
297 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
298 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
299 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
300 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
302 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
303 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
304 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
305 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
306 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
307};
308
7a387fff
TS
309/* REGIMM (rt field) opcodes */
310#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
311
312enum {
313 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
314 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
315 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
316 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
317 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
318 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
319 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
320 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
321 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
322 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
323 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
324 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
325 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
326 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
327 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
328
329 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
330 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
331};
332
7a387fff
TS
333/* Special2 opcodes */
334#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
335
e37e863f 336enum {
7a387fff
TS
337 /* Multiply & xxx operations */
338 OPC_MADD = 0x00 | OPC_SPECIAL2,
339 OPC_MADDU = 0x01 | OPC_SPECIAL2,
340 OPC_MUL = 0x02 | OPC_SPECIAL2,
341 OPC_MSUB = 0x04 | OPC_SPECIAL2,
342 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
343 /* Loongson 2F */
344 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
345 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
346 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
347 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
348 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
349 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
350 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
351 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
352 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
353 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
354 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
355 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 356 /* Misc */
7a387fff
TS
357 OPC_CLZ = 0x20 | OPC_SPECIAL2,
358 OPC_CLO = 0x21 | OPC_SPECIAL2,
359 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
360 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 361 /* Special */
7a387fff
TS
362 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
363};
364
365/* Special3 opcodes */
366#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
367
368enum {
369 OPC_EXT = 0x00 | OPC_SPECIAL3,
370 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
371 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
372 OPC_DEXT = 0x03 | OPC_SPECIAL3,
373 OPC_INS = 0x04 | OPC_SPECIAL3,
374 OPC_DINSM = 0x05 | OPC_SPECIAL3,
375 OPC_DINSU = 0x06 | OPC_SPECIAL3,
376 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
377 OPC_FORK = 0x08 | OPC_SPECIAL3,
378 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
379 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
380 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
381 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
382
383 /* Loongson 2E */
384 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
385 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
386 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
387 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
388 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
389 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
390 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
391 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
392 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
393 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
394 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
395 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
396
397 /* MIPS DSP Load */
398 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
399 /* MIPS DSP Arithmetic */
400 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 401 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 402 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 403 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
404 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
405 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
406 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 407 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
408 /* MIPS DSP GPR-Based Shift Sub-class */
409 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 410 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
411 /* MIPS DSP Multiply Sub-class insns */
412 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
413 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
414 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 415 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
416 /* DSP Bit/Manipulation Sub-class */
417 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 418 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 419 /* MIPS DSP Append Sub-class */
26690560 420 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 421 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
422 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
423 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 424 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
425
426 /* R6 */
bf7910c6
LA
427 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
428 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
429 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
430 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
431 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
432 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
433};
434
7a387fff
TS
435/* BSHFL opcodes */
436#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
437
e37e863f 438enum {
15eacb9b
YK
439 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
440 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
441 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
442 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
443 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
444 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
445};
446
7a387fff
TS
447/* DBSHFL opcodes */
448#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
449
e37e863f 450enum {
15eacb9b
YK
451 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
452 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
453 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
454 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
455 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
456};
457
e45a93e2
JL
458/* MIPS DSP REGIMM opcodes */
459enum {
460 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 461 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
462};
463
9b1a1d68
JL
464#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
465/* MIPS DSP Load */
466enum {
467 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
468 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
469 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 470 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
471};
472
461c08df
JL
473#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
474enum {
475 /* MIPS DSP Arithmetic Sub-class */
476 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
491 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
492 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
493 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
494 /* MIPS DSP Multiply Sub-class insns */
495 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
501};
502
503#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
504#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
505enum {
506 /* MIPS DSP Arithmetic Sub-class */
507 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
519 /* MIPS DSP Multiply Sub-class insns */
520 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
524};
525
526#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527enum {
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
542 /* DSP Bit/Manipulation Sub-class */
543 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
548};
549
550#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551enum {
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
560 /* DSP Compare-Pick Sub-class */
561 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 576};
a22260ae 577
77c5fa8b
JL
578#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
579enum {
580 /* MIPS DSP GPR-Based Shift Sub-class */
581 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
603};
461c08df 604
a22260ae
JL
605#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606enum {
607 /* MIPS DSP Multiply Sub-class insns */
608 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
622 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
630};
631
1cb6686c
JL
632#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
633enum {
634 /* DSP Bit/Manipulation Sub-class */
635 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
636};
637
26690560
JL
638#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639enum {
df6126a7 640 /* MIPS DSP Append Sub-class */
26690560
JL
641 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
642 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
643 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
644};
645
b53371ed
JL
646#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
647enum {
648 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
649 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
662 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
663 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
664 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
665 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
666};
667
461c08df
JL
668#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
670 /* MIPS DSP Arithmetic Sub-class */
671 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
688 /* DSP Bit/Manipulation Sub-class */
689 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 695};
461c08df 696
461c08df
JL
697#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
698enum {
a22260ae
JL
699 /* MIPS DSP Multiply Sub-class insns */
700 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
727};
461c08df 728
461c08df
JL
729#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730enum {
26690560
JL
731 /* DSP Compare-Pick Sub-class */
732 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
751 /* MIPS DSP Arithmetic Sub-class */
752 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
760};
461c08df 761
26690560
JL
762#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763enum {
df6126a7 764 /* DSP Append Sub-class */
26690560
JL
765 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
767 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
768 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
769};
26690560 770
b53371ed
JL
771#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
772enum {
773 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
774 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
775 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
795};
796
1cb6686c
JL
797#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798enum {
799 /* DSP Bit/Manipulation Sub-class */
800 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
801};
1cb6686c 802
a22260ae
JL
803#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804enum {
805 /* MIPS DSP Multiply Sub-class insns */
806 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
832};
a22260ae 833
77c5fa8b
JL
834#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
835enum {
836 /* MIPS DSP GPR-Based Shift Sub-class */
837 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
863};
77c5fa8b 864
7a387fff
TS
865/* Coprocessor 0 (rs field) */
866#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
867
6ea83fed 868enum {
7a387fff
TS
869 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
870 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 873 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
874 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
875 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 876 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
877 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
878 OPC_C0 = (0x10 << 21) | OPC_CP0,
879 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
880 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 881};
7a387fff
TS
882
883/* MFMC0 opcodes */
b48cfdff 884#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
885
886enum {
ead9360e
TS
887 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
888 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
890 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
891 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
892 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
893};
894
895/* Coprocessor 0 (with rs == C0) */
896#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
897
898enum {
899 OPC_TLBR = 0x01 | OPC_C0,
900 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
901 OPC_TLBINV = 0x03 | OPC_C0,
902 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
903 OPC_TLBWR = 0x06 | OPC_C0,
904 OPC_TLBP = 0x08 | OPC_C0,
905 OPC_RFE = 0x10 | OPC_C0,
906 OPC_ERET = 0x18 | OPC_C0,
907 OPC_DERET = 0x1F | OPC_C0,
908 OPC_WAIT = 0x20 | OPC_C0,
909};
910
911/* Coprocessor 1 (rs field) */
912#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
913
bf4120ad
NF
914/* Values for the fmt field in FP instructions */
915enum {
916 /* 0 - 15 are reserved */
e459440a
AJ
917 FMT_S = 16, /* single fp */
918 FMT_D = 17, /* double fp */
919 FMT_E = 18, /* extended fp */
920 FMT_Q = 19, /* quad fp */
921 FMT_W = 20, /* 32-bit fixed */
922 FMT_L = 21, /* 64-bit fixed */
923 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
924 /* 23 - 31 are reserved */
925};
926
7a387fff
TS
927enum {
928 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
929 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
930 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 931 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
932 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
933 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
934 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 935 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 936 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
937 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
938 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
939 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
940 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
941 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
942 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
943 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
944 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
945 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
946 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
947 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
948 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
949 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
950 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
951 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
952 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
953 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
954 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
955 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
956 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
957 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
958};
959
5a5012ec
TS
960#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
961#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
962
7a387fff
TS
963enum {
964 OPC_BC1F = (0x00 << 16) | OPC_BC1,
965 OPC_BC1T = (0x01 << 16) | OPC_BC1,
966 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
967 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
968};
969
5a5012ec
TS
970enum {
971 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
972 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
973};
974
975enum {
976 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
977 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
978};
7a387fff
TS
979
980#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
981
982enum {
983 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
984 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
985 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
986 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
987 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
988 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
989 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
990 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
991 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
992 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
993 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
994};
995
bd277fa1
RH
996#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
997
998enum {
999 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1000 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1007
1008 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1009 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1016
1017 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1018 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1021 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1022 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1023 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1024 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1025
1026 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1027 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1030 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1034
1035 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1036 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1037 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1041
1042 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1043 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1048
1049 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1050 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1055
1056 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1057 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1062
1063 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1064 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1065 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1066 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1067 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1069
1070 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1071 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1072 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1073 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1074 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1076
1077 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1078 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1079 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1081 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1083
1084 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1085 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1086 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1087 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1088 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1089 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1090};
1091
1092
e0c84da7
TS
1093#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1094
1095enum {
1096 OPC_LWXC1 = 0x00 | OPC_CP3,
1097 OPC_LDXC1 = 0x01 | OPC_CP3,
1098 OPC_LUXC1 = 0x05 | OPC_CP3,
1099 OPC_SWXC1 = 0x08 | OPC_CP3,
1100 OPC_SDXC1 = 0x09 | OPC_CP3,
1101 OPC_SUXC1 = 0x0D | OPC_CP3,
1102 OPC_PREFX = 0x0F | OPC_CP3,
1103 OPC_ALNV_PS = 0x1E | OPC_CP3,
1104 OPC_MADD_S = 0x20 | OPC_CP3,
1105 OPC_MADD_D = 0x21 | OPC_CP3,
1106 OPC_MADD_PS = 0x26 | OPC_CP3,
1107 OPC_MSUB_S = 0x28 | OPC_CP3,
1108 OPC_MSUB_D = 0x29 | OPC_CP3,
1109 OPC_MSUB_PS = 0x2E | OPC_CP3,
1110 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1111 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1112 OPC_NMADD_PS= 0x36 | OPC_CP3,
1113 OPC_NMSUB_S = 0x38 | OPC_CP3,
1114 OPC_NMSUB_D = 0x39 | OPC_CP3,
1115 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1116};
1117
239dfebe
YK
1118/* MSA Opcodes */
1119#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1120enum {
1121 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1122 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1123 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1124 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1125 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1126 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1127 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1128 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1129 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1130 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1131 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1132 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1133 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1134 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1135 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1136 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1137 OPC_MSA_ELM = 0x19 | OPC_MSA,
1138 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1139 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1140 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1141 OPC_MSA_VEC = 0x1E | OPC_MSA,
1142
1143 /* MI10 instruction */
1144 OPC_LD_B = (0x20) | OPC_MSA,
1145 OPC_LD_H = (0x21) | OPC_MSA,
1146 OPC_LD_W = (0x22) | OPC_MSA,
1147 OPC_LD_D = (0x23) | OPC_MSA,
1148 OPC_ST_B = (0x24) | OPC_MSA,
1149 OPC_ST_H = (0x25) | OPC_MSA,
1150 OPC_ST_W = (0x26) | OPC_MSA,
1151 OPC_ST_D = (0x27) | OPC_MSA,
1152};
1153
1154enum {
1155 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1156 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1157 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1158 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1159 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1160 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1161 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1162 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1163 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1164 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1165 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1166 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1167 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1168
1169 /* I8 instruction */
1170 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1171 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1172 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1173 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1174 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1175 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1176 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1177 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1179 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1180
1181 /* VEC/2R/2RF instruction */
1182 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1183 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1184 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1185 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1186 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1187 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1188 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1189
1190 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1191 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1192
1193 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1194 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1195 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1196 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1197 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1198
1199 /* 2RF instruction df(bit 16) = _w, _d */
1200 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1201 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1203 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1204 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1205 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1206 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1207 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1208 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1210 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1211 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1212 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1214 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1216
1217 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1218 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1219 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1220 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1221 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1222 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1223 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1224 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1225 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1226 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1227 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1228 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1229 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1230 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1231 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1232 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1233 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1234 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1235 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1236 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1237 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1238 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1239 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1240 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1241 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1242 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1243 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1244 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1245 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1246 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1247 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1248 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1249 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1250 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1251 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1252 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1253 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1254 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1255 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1256 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1257 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1258 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1259 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1260 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1261 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1262 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1263 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1264 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1265 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1266 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1267 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1268 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1269 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1270 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1271 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1272 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1273 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1274 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1276 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1281
1282 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1283 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1284 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1285 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1286 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1287 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1288 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1289 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292
1293 /* 3RF instruction _df(bit 21) = _w, _d */
1294 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1295 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1296 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1297 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1298 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1299 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1300 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1301 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1302 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1307 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1310 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1312 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1313 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1314 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1315 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1316 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1317 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1318 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1320 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1322 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1323 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1324 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1325 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1326 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1327 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1328 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1329 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1332 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1335
1336 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1337 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1338 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1339 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1340 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1341 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1342 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1343 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1344 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1345 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1346 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1347 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1349};
1350
39454628 1351/* global register indices */
a7812ae4
PB
1352static TCGv_ptr cpu_env;
1353static TCGv cpu_gpr[32], cpu_PC;
340fff72 1354static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1355static TCGv cpu_dspctrl, btarget, bcond;
1356static TCGv_i32 hflags;
a7812ae4 1357static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1358static TCGv_i64 fpu_f64[32];
863f264d 1359static TCGv_i64 msa_wr_d[64];
aa0bf00b 1360
1a7ff922 1361static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1362static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1363
022c62cb 1364#include "exec/gen-icount.h"
2e70f6ef 1365
895c2d04 1366#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1368 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1369 tcg_temp_free_i32(helper_tmp); \
1370 } while(0)
be24bb4f 1371
895c2d04 1372#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1375 tcg_temp_free_i32(helper_tmp); \
1376 } while(0)
be24bb4f 1377
895c2d04
BS
1378#define gen_helper_1e0i(name, ret, arg1) do { \
1379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1380 gen_helper_##name(ret, cpu_env, helper_tmp); \
1381 tcg_temp_free_i32(helper_tmp); \
1382 } while(0)
1383
1384#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1387 tcg_temp_free_i32(helper_tmp); \
1388 } while(0)
1389
1390#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1393 tcg_temp_free_i32(helper_tmp); \
1394 } while(0)
1395
1396#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1399 tcg_temp_free_i32(helper_tmp); \
1400 } while(0)
be24bb4f 1401
895c2d04 1402#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1405 tcg_temp_free_i32(helper_tmp); \
1406 } while(0)
c239529e 1407
8e9ade68
TS
1408typedef struct DisasContext {
1409 struct TranslationBlock *tb;
1410 target_ulong pc, saved_pc;
1411 uint32_t opcode;
7b270ef2 1412 int singlestep_enabled;
d75c135e 1413 int insn_flags;
5ab5c041 1414 int32_t CP0_Config1;
8e9ade68
TS
1415 /* Routine used to access memory */
1416 int mem_idx;
1417 uint32_t hflags, saved_hflags;
1418 int bstate;
1419 target_ulong btarget;
d279279e 1420 bool ulri;
e98c0d17 1421 int kscrexist;
7207c7f9 1422 bool rxi;
9456c2fb 1423 int ie;
aea14095
LA
1424 bool bi;
1425 bool bp;
8e9ade68
TS
1426} DisasContext;
1427
1428enum {
1429 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1430 * exception condition */
8e9ade68
TS
1431 BS_STOP = 1, /* We want to stop translation for any reason */
1432 BS_BRANCH = 2, /* We reached a branch condition */
1433 BS_EXCP = 3, /* We reached an exception condition */
1434};
1435
d73ee8a2
RH
1436static const char * const regnames[] = {
1437 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1438 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1439 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1440 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1441};
6af0bf9c 1442
d73ee8a2
RH
1443static const char * const regnames_HI[] = {
1444 "HI0", "HI1", "HI2", "HI3",
1445};
4b2eb8d2 1446
d73ee8a2
RH
1447static const char * const regnames_LO[] = {
1448 "LO0", "LO1", "LO2", "LO3",
1449};
4b2eb8d2 1450
d73ee8a2
RH
1451static const char * const fregnames[] = {
1452 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1453 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1454 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1455 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1456};
958fb4a9 1457
863f264d
YK
1458static const char * const msaregnames[] = {
1459 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1460 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1461 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1462 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1463 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1464 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1465 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1466 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1467 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1468 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1469 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1470 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1471 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1472 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1473 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1474 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1475};
1476
fb7729e2
RH
1477#define MIPS_DEBUG(fmt, ...) \
1478 do { \
1479 if (MIPS_DEBUG_DISAS) { \
1480 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1481 TARGET_FMT_lx ": %08x " fmt "\n", \
1482 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1483 } \
1484 } while (0)
1485
1486#define LOG_DISAS(...) \
1487 do { \
1488 if (MIPS_DEBUG_DISAS) { \
1489 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1490 } \
1491 } while (0)
958fb4a9 1492
8e9ade68 1493#define MIPS_INVAL(op) \
8e9ade68 1494 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1495 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1496
8e9ade68
TS
1497/* General purpose registers moves. */
1498static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1499{
8e9ade68
TS
1500 if (reg == 0)
1501 tcg_gen_movi_tl(t, 0);
1502 else
4b2eb8d2 1503 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1504}
1505
8e9ade68 1506static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1507{
8e9ade68 1508 if (reg != 0)
4b2eb8d2 1509 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1510}
1511
8e9ade68 1512/* Moves to/from shadow registers. */
be24bb4f 1513static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1514{
d9bea114 1515 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1516
1517 if (from == 0)
d9bea114 1518 tcg_gen_movi_tl(t0, 0);
8e9ade68 1519 else {
d9bea114 1520 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1521 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1522
7db13fae 1523 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1524 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1525 tcg_gen_andi_i32(t2, t2, 0xf);
1526 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1527 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1528 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1529
d9bea114 1530 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1531 tcg_temp_free_ptr(addr);
d9bea114 1532 tcg_temp_free_i32(t2);
8e9ade68 1533 }
d9bea114
AJ
1534 gen_store_gpr(t0, to);
1535 tcg_temp_free(t0);
aaa9128a
TS
1536}
1537
be24bb4f 1538static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1539{
be24bb4f 1540 if (to != 0) {
d9bea114
AJ
1541 TCGv t0 = tcg_temp_new();
1542 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1543 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1544
d9bea114 1545 gen_load_gpr(t0, from);
7db13fae 1546 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1547 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1548 tcg_gen_andi_i32(t2, t2, 0xf);
1549 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1550 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1551 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1552
d9bea114 1553 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1554 tcg_temp_free_ptr(addr);
d9bea114
AJ
1555 tcg_temp_free_i32(t2);
1556 tcg_temp_free(t0);
8e9ade68 1557 }
aaa9128a
TS
1558}
1559
aaa9128a 1560/* Floating point register moves. */
d73ee8a2 1561static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1562{
d73ee8a2 1563 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1564}
1565
d73ee8a2 1566static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1567{
d73ee8a2
RH
1568 TCGv_i64 t64 = tcg_temp_new_i64();
1569 tcg_gen_extu_i32_i64(t64, t);
1570 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1571 tcg_temp_free_i64(t64);
6d066274
AJ
1572}
1573
7f6613ce 1574static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1575{
7f6613ce
PJ
1576 if (ctx->hflags & MIPS_HFLAG_F64) {
1577 TCGv_i64 t64 = tcg_temp_new_i64();
1578 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1579 tcg_gen_trunc_i64_i32(t, t64);
1580 tcg_temp_free_i64(t64);
1581 } else {
1582 gen_load_fpr32(t, reg | 1);
1583 }
6d066274
AJ
1584}
1585
7f6613ce 1586static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1587{
7f6613ce
PJ
1588 if (ctx->hflags & MIPS_HFLAG_F64) {
1589 TCGv_i64 t64 = tcg_temp_new_i64();
1590 tcg_gen_extu_i32_i64(t64, t);
1591 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1592 tcg_temp_free_i64(t64);
1593 } else {
1594 gen_store_fpr32(t, reg | 1);
1595 }
aa0bf00b 1596}
6ea83fed 1597
d73ee8a2 1598static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1599{
f364515c 1600 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1601 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1602 } else {
d73ee8a2 1603 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1604 }
1605}
6ea83fed 1606
d73ee8a2 1607static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1608{
f364515c 1609 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1610 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1611 } else {
d73ee8a2
RH
1612 TCGv_i64 t0;
1613 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1614 t0 = tcg_temp_new_i64();
6d066274 1615 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1616 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1617 tcg_temp_free_i64(t0);
aa0bf00b
TS
1618 }
1619}
6ea83fed 1620
d94536f4 1621static inline int get_fp_bit (int cc)
a16336e4 1622{
d94536f4
AJ
1623 if (cc)
1624 return 24 + cc;
1625 else
1626 return 23;
a16336e4
TS
1627}
1628
30898801 1629/* Tests */
8e9ade68
TS
1630static inline void gen_save_pc(target_ulong pc)
1631{
1eb75d4a 1632 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1633}
30898801 1634
356265ae 1635static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1636{
d12d51d5 1637 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1638 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1639 gen_save_pc(ctx->pc);
6af0bf9c
FB
1640 ctx->saved_pc = ctx->pc;
1641 }
1642 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1643 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1644 ctx->saved_hflags = ctx->hflags;
364d4831 1645 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1646 case MIPS_HFLAG_BR:
5a5012ec
TS
1647 break;
1648 case MIPS_HFLAG_BC:
5a5012ec 1649 case MIPS_HFLAG_BL:
5a5012ec 1650 case MIPS_HFLAG_B:
d077b6f7 1651 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1652 break;
6af0bf9c
FB
1653 }
1654 }
1655}
1656
7db13fae 1657static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1658{
fd4a04eb 1659 ctx->saved_hflags = ctx->hflags;
364d4831 1660 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1661 case MIPS_HFLAG_BR:
fd4a04eb
TS
1662 break;
1663 case MIPS_HFLAG_BC:
1664 case MIPS_HFLAG_BL:
39454628 1665 case MIPS_HFLAG_B:
fd4a04eb 1666 ctx->btarget = env->btarget;
fd4a04eb 1667 break;
5a5012ec
TS
1668 }
1669}
1670
356265ae 1671static inline void
48d38ca5 1672generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1673{
a7812ae4
PB
1674 TCGv_i32 texcp = tcg_const_i32(excp);
1675 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1676 save_cpu_state(ctx, 1);
895c2d04 1677 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1678 tcg_temp_free_i32(terr);
1679 tcg_temp_free_i32(texcp);
aaa9128a
TS
1680}
1681
356265ae 1682static inline void
48d38ca5 1683generate_exception (DisasContext *ctx, int excp)
aaa9128a 1684{
6af0bf9c 1685 save_cpu_state(ctx, 1);
895c2d04 1686 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1687}
1688
48d38ca5 1689/* Addresses computation */
941694d0 1690static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1691{
941694d0 1692 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1693
1694#if defined(TARGET_MIPS64)
01f72885 1695 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1696 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1697 }
1698#endif
4ad40f36
FB
1699}
1700
31837be3
YK
1701/* Addresses computation (translation time) */
1702static target_long addr_add(DisasContext *ctx, target_long base,
1703 target_long offset)
1704{
1705 target_long sum = base + offset;
1706
1707#if defined(TARGET_MIPS64)
1708 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1709 sum = (int32_t)sum;
1710 }
1711#endif
1712 return sum;
1713}
1714
356265ae 1715static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1716{
fe253235 1717 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1718 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1719}
1720
356265ae 1721static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1722{
fe253235 1723 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1724 generate_exception_err(ctx, EXCP_CpU, 1);
1725}
1726
b8aa4598
TS
1727/* Verify that the processor is running with COP1X instructions enabled.
1728 This is associated with the nabla symbol in the MIPS32 and MIPS64
1729 opcode tables. */
1730
356265ae 1731static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1732{
1733 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1734 generate_exception(ctx, EXCP_RI);
1735}
1736
1737/* Verify that the processor is running with 64-bit floating-point
1738 operations enabled. */
1739
356265ae 1740static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1741{
b8aa4598 1742 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1743 generate_exception(ctx, EXCP_RI);
1744}
1745
1746/*
1747 * Verify if floating point register is valid; an operation is not defined
1748 * if bit 0 of any register specification is set and the FR bit in the
1749 * Status register equals zero, since the register numbers specify an
1750 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1751 * in the Status register equals one, both even and odd register numbers
1752 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1753 *
1754 * Multiple 64 bit wide registers can be checked by calling
1755 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1756 */
356265ae 1757static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1758{
fe253235 1759 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1760 generate_exception(ctx, EXCP_RI);
1761}
1762
853c3240
JL
1763/* Verify that the processor is running with DSP instructions enabled.
1764 This is enabled by CP0 Status register MX(24) bit.
1765 */
1766
1767static inline void check_dsp(DisasContext *ctx)
1768{
1769 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1770 if (ctx->insn_flags & ASE_DSP) {
1771 generate_exception(ctx, EXCP_DSPDIS);
1772 } else {
1773 generate_exception(ctx, EXCP_RI);
1774 }
853c3240
JL
1775 }
1776}
1777
1778static inline void check_dspr2(DisasContext *ctx)
1779{
1780 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1781 if (ctx->insn_flags & ASE_DSP) {
1782 generate_exception(ctx, EXCP_DSPDIS);
1783 } else {
1784 generate_exception(ctx, EXCP_RI);
1785 }
853c3240
JL
1786 }
1787}
1788
3a95e3a7 1789/* This code generates a "reserved instruction" exception if the
e189e748 1790 CPU does not support the instruction set corresponding to flags. */
d75c135e 1791static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1792{
d75c135e 1793 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1794 generate_exception(ctx, EXCP_RI);
d75c135e 1795 }
3a95e3a7
TS
1796}
1797
fecd2646
LA
1798/* This code generates a "reserved instruction" exception if the
1799 CPU has corresponding flag set which indicates that the instruction
1800 has been removed. */
1801static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1802{
1803 if (unlikely(ctx->insn_flags & flags)) {
1804 generate_exception(ctx, EXCP_RI);
1805 }
1806}
1807
c7986fd6 1808#ifdef TARGET_MIPS64
e189e748
TS
1809/* This code generates a "reserved instruction" exception if 64-bit
1810 instructions are not enabled. */
356265ae 1811static inline void check_mips_64(DisasContext *ctx)
e189e748 1812{
fe253235 1813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1814 generate_exception(ctx, EXCP_RI);
1815}
c7986fd6 1816#endif
e189e748 1817
8153667c
NF
1818/* Define small wrappers for gen_load_fpr* so that we have a uniform
1819 calling interface for 32 and 64-bit FPRs. No sense in changing
1820 all callers for gen_load_fpr32 when we need the CTX parameter for
1821 this one use. */
1822#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1823#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1824#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1825static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1826 int ft, int fs, int cc) \
1827{ \
1828 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1829 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1830 switch (ifmt) { \
1831 case FMT_PS: \
1832 check_cp1_64bitmode(ctx); \
1833 break; \
1834 case FMT_D: \
1835 if (abs) { \
1836 check_cop1x(ctx); \
1837 } \
1838 check_cp1_registers(ctx, fs | ft); \
1839 break; \
1840 case FMT_S: \
1841 if (abs) { \
1842 check_cop1x(ctx); \
1843 } \
1844 break; \
1845 } \
1846 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1847 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1848 switch (n) { \
895c2d04
BS
1849 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1850 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1851 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1852 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1853 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1854 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1855 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1856 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1857 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1858 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1859 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1860 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1861 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1862 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1863 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1864 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1865 default: abort(); \
1866 } \
1867 tcg_temp_free_i##bits (fp0); \
1868 tcg_temp_free_i##bits (fp1); \
1869}
1870
1871FOP_CONDS(, 0, d, FMT_D, 64)
1872FOP_CONDS(abs, 1, d, FMT_D, 64)
1873FOP_CONDS(, 0, s, FMT_S, 32)
1874FOP_CONDS(abs, 1, s, FMT_S, 32)
1875FOP_CONDS(, 0, ps, FMT_PS, 64)
1876FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1877#undef FOP_CONDS
3f493883
YK
1878
1879#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1880static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1881 int ft, int fs, int fd) \
1882{ \
1883 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1884 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1885 switch (ifmt) { \
1886 case FMT_D: \
1887 check_cp1_registers(ctx, fs | ft | fd); \
1888 break; \
1889 } \
1890 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1891 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1892 switch (n) { \
1893 case 0: \
1894 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1895 break; \
1896 case 1: \
1897 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1898 break; \
1899 case 2: \
1900 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1901 break; \
1902 case 3: \
1903 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1904 break; \
1905 case 4: \
1906 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1907 break; \
1908 case 5: \
1909 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1910 break; \
1911 case 6: \
1912 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1913 break; \
1914 case 7: \
1915 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1916 break; \
1917 case 8: \
1918 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1919 break; \
1920 case 9: \
1921 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1922 break; \
1923 case 10: \
1924 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1925 break; \
1926 case 11: \
1927 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1928 break; \
1929 case 12: \
1930 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1931 break; \
1932 case 13: \
1933 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1934 break; \
1935 case 14: \
1936 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1937 break; \
1938 case 15: \
1939 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1940 break; \
1941 case 17: \
1942 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1943 break; \
1944 case 18: \
1945 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 19: \
1948 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 25: \
1951 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 26: \
1954 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 27: \
1957 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 default: \
1960 abort(); \
1961 } \
1962 STORE; \
1963 tcg_temp_free_i ## bits (fp0); \
1964 tcg_temp_free_i ## bits (fp1); \
1965}
1966
1967FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1968FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1969#undef FOP_CONDNS
8153667c
NF
1970#undef gen_ldcmp_fpr32
1971#undef gen_ldcmp_fpr64
1972
958fb4a9 1973/* load/store instructions. */
e7139c44 1974#ifdef CONFIG_USER_ONLY
d9bea114 1975#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1976static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1977{ \
1978 TCGv t0 = tcg_temp_new(); \
1979 tcg_gen_mov_tl(t0, arg1); \
1980 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1981 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1982 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1983 tcg_temp_free(t0); \
aaa9128a 1984}
e7139c44
AJ
1985#else
1986#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1987static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1988{ \
895c2d04 1989 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1990}
1991#endif
aaa9128a
TS
1992OP_LD_ATOMIC(ll,ld32s);
1993#if defined(TARGET_MIPS64)
1994OP_LD_ATOMIC(lld,ld64);
1995#endif
1996#undef OP_LD_ATOMIC
1997
590bc601
PB
1998#ifdef CONFIG_USER_ONLY
1999#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2000static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2001{ \
2002 TCGv t0 = tcg_temp_new(); \
2003 int l1 = gen_new_label(); \
2004 int l2 = gen_new_label(); \
2005 \
2006 tcg_gen_andi_tl(t0, arg2, almask); \
2007 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2008 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2009 generate_exception(ctx, EXCP_AdES); \
2010 gen_set_label(l1); \
7db13fae 2011 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2012 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2013 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2014 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2015 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 2016 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
2017 gen_set_label(l2); \
2018 tcg_gen_movi_tl(t0, 0); \
2019 gen_store_gpr(t0, rt); \
2020 tcg_temp_free(t0); \
2021}
2022#else
2023#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 2024static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
2025{ \
2026 TCGv t0 = tcg_temp_new(); \
895c2d04 2027 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 2028 gen_store_gpr(t0, rt); \
590bc601
PB
2029 tcg_temp_free(t0); \
2030}
2031#endif
590bc601 2032OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2033#if defined(TARGET_MIPS64)
590bc601 2034OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2035#endif
2036#undef OP_ST_ATOMIC
2037
662d7485
NF
2038static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2039 int base, int16_t offset)
2040{
2041 if (base == 0) {
2042 tcg_gen_movi_tl(addr, offset);
2043 } else if (offset == 0) {
2044 gen_load_gpr(addr, base);
2045 } else {
2046 tcg_gen_movi_tl(addr, offset);
2047 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2048 }
2049}
2050
364d4831
NF
2051static target_ulong pc_relative_pc (DisasContext *ctx)
2052{
2053 target_ulong pc = ctx->pc;
2054
2055 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2056 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2057
2058 pc -= branch_bytes;
2059 }
2060
2061 pc &= ~(target_ulong)3;
2062 return pc;
2063}
2064
5c13fdfd 2065/* Load */
d75c135e
AJ
2066static void gen_ld(DisasContext *ctx, uint32_t opc,
2067 int rt, int base, int16_t offset)
6af0bf9c 2068{
5c13fdfd 2069 const char *opn = "ld";
fc40787a 2070 TCGv t0, t1, t2;
afa88c3a 2071
d75c135e 2072 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2073 /* Loongson CPU uses a load to zero register for prefetch.
2074 We emulate it as a NOP. On other CPU we must perform the
2075 actual memory access. */
2076 MIPS_DEBUG("NOP");
2077 return;
2078 }
6af0bf9c 2079
afa88c3a 2080 t0 = tcg_temp_new();
662d7485 2081 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2082
6af0bf9c 2083 switch (opc) {
d26bc211 2084#if defined(TARGET_MIPS64)
6e473128 2085 case OPC_LWU:
5f68f5ae 2086 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 2087 gen_store_gpr(t0, rt);
6e473128
TS
2088 opn = "lwu";
2089 break;
6af0bf9c 2090 case OPC_LD:
5f68f5ae 2091 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 2092 gen_store_gpr(t0, rt);
6af0bf9c
FB
2093 opn = "ld";
2094 break;
7a387fff 2095 case OPC_LLD:
bf7910c6 2096 case R6_OPC_LLD:
b835e919 2097 save_cpu_state(ctx, 1);
5c13fdfd 2098 op_ld_lld(t0, t0, ctx);
78723684 2099 gen_store_gpr(t0, rt);
7a387fff
TS
2100 opn = "lld";
2101 break;
6af0bf9c 2102 case OPC_LDL:
3cee3050 2103 t1 = tcg_temp_new();
fc40787a
AJ
2104 tcg_gen_andi_tl(t1, t0, 7);
2105#ifndef TARGET_WORDS_BIGENDIAN
2106 tcg_gen_xori_tl(t1, t1, 7);
2107#endif
2108 tcg_gen_shli_tl(t1, t1, 3);
2109 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2110 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2111 tcg_gen_shl_tl(t0, t0, t1);
2112 tcg_gen_xori_tl(t1, t1, 63);
2113 t2 = tcg_const_tl(0x7fffffffffffffffull);
2114 tcg_gen_shr_tl(t2, t2, t1);
78723684 2115 gen_load_gpr(t1, rt);
fc40787a
AJ
2116 tcg_gen_and_tl(t1, t1, t2);
2117 tcg_temp_free(t2);
2118 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2119 tcg_temp_free(t1);
fc40787a 2120 gen_store_gpr(t0, rt);
6af0bf9c
FB
2121 opn = "ldl";
2122 break;
6af0bf9c 2123 case OPC_LDR:
3cee3050 2124 t1 = tcg_temp_new();
fc40787a
AJ
2125 tcg_gen_andi_tl(t1, t0, 7);
2126#ifdef TARGET_WORDS_BIGENDIAN
2127 tcg_gen_xori_tl(t1, t1, 7);
2128#endif
2129 tcg_gen_shli_tl(t1, t1, 3);
2130 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 2131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
2132 tcg_gen_shr_tl(t0, t0, t1);
2133 tcg_gen_xori_tl(t1, t1, 63);
2134 t2 = tcg_const_tl(0xfffffffffffffffeull);
2135 tcg_gen_shl_tl(t2, t2, t1);
78723684 2136 gen_load_gpr(t1, rt);
fc40787a
AJ
2137 tcg_gen_and_tl(t1, t1, t2);
2138 tcg_temp_free(t2);
2139 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2140 tcg_temp_free(t1);
fc40787a 2141 gen_store_gpr(t0, rt);
6af0bf9c
FB
2142 opn = "ldr";
2143 break;
364d4831 2144 case OPC_LDPC:
3cee3050 2145 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2146 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2147 tcg_temp_free(t1);
5f68f5ae 2148 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 2149 gen_store_gpr(t0, rt);
5c13fdfd 2150 opn = "ldpc";
364d4831 2151 break;
6af0bf9c 2152#endif
364d4831 2153 case OPC_LWPC:
3cee3050 2154 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2155 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2156 tcg_temp_free(t1);
5f68f5ae 2157 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 2158 gen_store_gpr(t0, rt);
5c13fdfd 2159 opn = "lwpc";
364d4831 2160 break;
6af0bf9c 2161 case OPC_LW:
5f68f5ae 2162 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 2163 gen_store_gpr(t0, rt);
6af0bf9c
FB
2164 opn = "lw";
2165 break;
6af0bf9c 2166 case OPC_LH:
5f68f5ae 2167 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 2168 gen_store_gpr(t0, rt);
6af0bf9c
FB
2169 opn = "lh";
2170 break;
6af0bf9c 2171 case OPC_LHU:
5f68f5ae 2172 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 2173 gen_store_gpr(t0, rt);
6af0bf9c
FB
2174 opn = "lhu";
2175 break;
2176 case OPC_LB:
5f68f5ae 2177 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 2178 gen_store_gpr(t0, rt);
6af0bf9c
FB
2179 opn = "lb";
2180 break;
6af0bf9c 2181 case OPC_LBU:
5f68f5ae 2182 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 2183 gen_store_gpr(t0, rt);
6af0bf9c
FB
2184 opn = "lbu";
2185 break;
2186 case OPC_LWL:
3cee3050 2187 t1 = tcg_temp_new();
fc40787a
AJ
2188 tcg_gen_andi_tl(t1, t0, 3);
2189#ifndef TARGET_WORDS_BIGENDIAN
2190 tcg_gen_xori_tl(t1, t1, 3);
2191#endif
2192 tcg_gen_shli_tl(t1, t1, 3);
2193 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2194 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2195 tcg_gen_shl_tl(t0, t0, t1);
2196 tcg_gen_xori_tl(t1, t1, 31);
2197 t2 = tcg_const_tl(0x7fffffffull);
2198 tcg_gen_shr_tl(t2, t2, t1);
6958549d 2199 gen_load_gpr(t1, rt);
fc40787a
AJ
2200 tcg_gen_and_tl(t1, t1, t2);
2201 tcg_temp_free(t2);
2202 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2203 tcg_temp_free(t1);
fc40787a
AJ
2204 tcg_gen_ext32s_tl(t0, t0);
2205 gen_store_gpr(t0, rt);
6af0bf9c
FB
2206 opn = "lwl";
2207 break;
6af0bf9c 2208 case OPC_LWR:
3cee3050 2209 t1 = tcg_temp_new();
fc40787a
AJ
2210 tcg_gen_andi_tl(t1, t0, 3);
2211#ifdef TARGET_WORDS_BIGENDIAN
2212 tcg_gen_xori_tl(t1, t1, 3);
2213#endif
2214 tcg_gen_shli_tl(t1, t1, 3);
2215 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 2216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
2217 tcg_gen_shr_tl(t0, t0, t1);
2218 tcg_gen_xori_tl(t1, t1, 31);
2219 t2 = tcg_const_tl(0xfffffffeull);
2220 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2221 gen_load_gpr(t1, rt);
fc40787a
AJ
2222 tcg_gen_and_tl(t1, t1, t2);
2223 tcg_temp_free(t2);
2224 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2225 tcg_temp_free(t1);
c728154b 2226 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2227 gen_store_gpr(t0, rt);
6af0bf9c
FB
2228 opn = "lwr";
2229 break;
6af0bf9c 2230 case OPC_LL:
4368b29a 2231 case R6_OPC_LL:
e7139c44 2232 save_cpu_state(ctx, 1);
5c13fdfd 2233 op_ld_ll(t0, t0, ctx);
78723684 2234 gen_store_gpr(t0, rt);
6af0bf9c
FB
2235 opn = "ll";
2236 break;
d66c7132 2237 }
2abf314d 2238 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
2239 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2240 tcg_temp_free(t0);
d66c7132
AJ
2241}
2242
5c13fdfd
AJ
2243/* Store */
2244static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2245 int base, int16_t offset)
2246{
2247 const char *opn = "st";
2248 TCGv t0 = tcg_temp_new();
2249 TCGv t1 = tcg_temp_new();
2250
2251 gen_base_offset_addr(ctx, t0, base, offset);
2252 gen_load_gpr(t1, rt);
2253 switch (opc) {
2254#if defined(TARGET_MIPS64)
2255 case OPC_SD:
5f68f5ae 2256 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
2257 opn = "sd";
2258 break;
2259 case OPC_SDL:
2260 save_cpu_state(ctx, 1);
895c2d04 2261 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2262 opn = "sdl";
2263 break;
2264 case OPC_SDR:
2265 save_cpu_state(ctx, 1);
895c2d04 2266 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2267 opn = "sdr";
2268 break;
2269#endif
2270 case OPC_SW:
5f68f5ae 2271 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
2272 opn = "sw";
2273 break;
2274 case OPC_SH:
5f68f5ae 2275 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
2276 opn = "sh";
2277 break;
2278 case OPC_SB:
5f68f5ae 2279 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2280 opn = "sb";
2281 break;
2282 case OPC_SWL:
2283 save_cpu_state(ctx, 1);
895c2d04 2284 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2285 opn = "swl";
2286 break;
2287 case OPC_SWR:
2288 save_cpu_state(ctx, 1);
895c2d04 2289 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2290 opn = "swr";
2291 break;
2292 }
2abf314d 2293 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2294 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2295 tcg_temp_free(t0);
2296 tcg_temp_free(t1);
2297}
2298
2299
d66c7132
AJ
2300/* Store conditional */
2301static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2302 int base, int16_t offset)
2303{
2304 const char *opn = "st_cond";
2305 TCGv t0, t1;
2306
2d2826b9 2307#ifdef CONFIG_USER_ONLY
d66c7132 2308 t0 = tcg_temp_local_new();
d66c7132 2309 t1 = tcg_temp_local_new();
2d2826b9
AJ
2310#else
2311 t0 = tcg_temp_new();
2312 t1 = tcg_temp_new();
2313#endif
2314 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2315 gen_load_gpr(t1, rt);
2316 switch (opc) {
2317#if defined(TARGET_MIPS64)
2318 case OPC_SCD:
bf7910c6 2319 case R6_OPC_SCD:
b835e919 2320 save_cpu_state(ctx, 1);
5c13fdfd 2321 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2322 opn = "scd";
2323 break;
2324#endif
6af0bf9c 2325 case OPC_SC:
4368b29a 2326 case R6_OPC_SC:
e7139c44 2327 save_cpu_state(ctx, 1);
5c13fdfd 2328 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2329 opn = "sc";
2330 break;
6af0bf9c 2331 }
2abf314d 2332 (void)opn; /* avoid a compiler warning */
6af0bf9c 2333 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2334 tcg_temp_free(t1);
d66c7132 2335 tcg_temp_free(t0);
6af0bf9c
FB
2336}
2337
6ea83fed 2338/* Load and store */
7a387fff 2339static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2340 int base, int16_t offset)
6ea83fed 2341{
923617a3 2342 const char *opn = "flt_ldst";
4e2474d6 2343 TCGv t0 = tcg_temp_new();
6ea83fed 2344
662d7485 2345 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2346 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2347 memory access. */
6ea83fed
FB
2348 switch (opc) {
2349 case OPC_LWC1:
b6d96bed 2350 {
a7812ae4 2351 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 2352 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 2353 gen_store_fpr32(fp0, ft);
a7812ae4 2354 tcg_temp_free_i32(fp0);
b6d96bed 2355 }
6ea83fed
FB
2356 opn = "lwc1";
2357 break;
2358 case OPC_SWC1:
b6d96bed 2359 {
a7812ae4 2360 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 2361 gen_load_fpr32(fp0, ft);
5f68f5ae 2362 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 2363 tcg_temp_free_i32(fp0);
b6d96bed 2364 }
6ea83fed
FB
2365 opn = "swc1";
2366 break;
2367 case OPC_LDC1:
b6d96bed 2368 {
a7812ae4 2369 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 2370 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 2371 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2372 tcg_temp_free_i64(fp0);
b6d96bed 2373 }
6ea83fed
FB
2374 opn = "ldc1";
2375 break;
2376 case OPC_SDC1:
b6d96bed 2377 {
a7812ae4 2378 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2379 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 2380 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 2381 tcg_temp_free_i64(fp0);
b6d96bed 2382 }
6ea83fed
FB
2383 opn = "sdc1";
2384 break;
2385 default:
923617a3 2386 MIPS_INVAL(opn);
e397ee33 2387 generate_exception(ctx, EXCP_RI);
78723684 2388 goto out;
6ea83fed 2389 }
2abf314d 2390 (void)opn; /* avoid a compiler warning */
6ea83fed 2391 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2392 out:
2393 tcg_temp_free(t0);
6ea83fed 2394}
6ea83fed 2395
5ab5c041
AJ
2396static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2397 int rs, int16_t imm)
26ebe468 2398{
5ab5c041 2399 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2400 check_cp1_enabled(ctx);
d9224450
MR
2401 switch (op) {
2402 case OPC_LDC1:
2403 case OPC_SDC1:
2404 check_insn(ctx, ISA_MIPS2);
2405 /* Fallthrough */
2406 default:
2407 gen_flt_ldst(ctx, op, rt, rs, imm);
2408 }
26ebe468
NF
2409 } else {
2410 generate_exception_err(ctx, EXCP_CpU, 1);
2411 }
2412}
2413
6af0bf9c 2414/* Arithmetic with immediate operand */
d75c135e
AJ
2415static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2416 int rt, int rs, int16_t imm)
6af0bf9c 2417{
324d9e32 2418 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2419 const char *opn = "imm arith";
6af0bf9c 2420
7a387fff 2421 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2422 /* If no destination, treat it as a NOP.
2423 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2424 MIPS_DEBUG("NOP");
324d9e32 2425 return;
6af0bf9c
FB
2426 }
2427 switch (opc) {
2428 case OPC_ADDI:
48d38ca5 2429 {
324d9e32
AJ
2430 TCGv t0 = tcg_temp_local_new();
2431 TCGv t1 = tcg_temp_new();
2432 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2433 int l1 = gen_new_label();
2434
324d9e32
AJ
2435 gen_load_gpr(t1, rs);
2436 tcg_gen_addi_tl(t0, t1, uimm);
2437 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2438
324d9e32
AJ
2439 tcg_gen_xori_tl(t1, t1, ~uimm);
2440 tcg_gen_xori_tl(t2, t0, uimm);
2441 tcg_gen_and_tl(t1, t1, t2);
2442 tcg_temp_free(t2);
2443 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2444 tcg_temp_free(t1);
48d38ca5
TS
2445 /* operands of same sign, result different sign */
2446 generate_exception(ctx, EXCP_OVERFLOW);
2447 gen_set_label(l1);
78723684 2448 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2449 gen_store_gpr(t0, rt);
2450 tcg_temp_free(t0);
48d38ca5 2451 }
6af0bf9c
FB
2452 opn = "addi";
2453 break;
2454 case OPC_ADDIU:
324d9e32
AJ
2455 if (rs != 0) {
2456 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2457 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2458 } else {
2459 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2460 }
6af0bf9c
FB
2461 opn = "addiu";
2462 break;
d26bc211 2463#if defined(TARGET_MIPS64)
7a387fff 2464 case OPC_DADDI:
48d38ca5 2465 {
324d9e32
AJ
2466 TCGv t0 = tcg_temp_local_new();
2467 TCGv t1 = tcg_temp_new();
2468 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2469 int l1 = gen_new_label();
2470
324d9e32
AJ
2471 gen_load_gpr(t1, rs);
2472 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2473
324d9e32
AJ
2474 tcg_gen_xori_tl(t1, t1, ~uimm);
2475 tcg_gen_xori_tl(t2, t0, uimm);
2476 tcg_gen_and_tl(t1, t1, t2);
2477 tcg_temp_free(t2);
2478 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2479 tcg_temp_free(t1);
48d38ca5
TS
2480 /* operands of same sign, result different sign */
2481 generate_exception(ctx, EXCP_OVERFLOW);
2482 gen_set_label(l1);
324d9e32
AJ
2483 gen_store_gpr(t0, rt);
2484 tcg_temp_free(t0);
48d38ca5 2485 }
7a387fff
TS
2486 opn = "daddi";
2487 break;
2488 case OPC_DADDIU:
324d9e32
AJ
2489 if (rs != 0) {
2490 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2491 } else {
2492 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2493 }
7a387fff
TS
2494 opn = "daddiu";
2495 break;
2496#endif
324d9e32 2497 }
2abf314d 2498 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2499 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2500}
2501
2502/* Logic with immediate operand */
d75c135e 2503static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2504 int rt, int rs, int16_t imm)
324d9e32
AJ
2505{
2506 target_ulong uimm;
324d9e32
AJ
2507
2508 if (rt == 0) {
2509 /* If no destination, treat it as a NOP. */
2510 MIPS_DEBUG("NOP");
2511 return;
2512 }
2513 uimm = (uint16_t)imm;
2514 switch (opc) {
6af0bf9c 2515 case OPC_ANDI:
324d9e32
AJ
2516 if (likely(rs != 0))
2517 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2518 else
2519 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2520 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2521 regnames[rs], uimm);
6af0bf9c
FB
2522 break;
2523 case OPC_ORI:
324d9e32
AJ
2524 if (rs != 0)
2525 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2526 else
2527 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2528 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2529 regnames[rs], uimm);
6af0bf9c
FB
2530 break;
2531 case OPC_XORI:
324d9e32
AJ
2532 if (likely(rs != 0))
2533 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2534 else
2535 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2536 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2537 regnames[rs], uimm);
6af0bf9c
FB
2538 break;
2539 case OPC_LUI:
d4ea6acd
LA
2540 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2541 /* OPC_AUI */
2542 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2543 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2544 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2545 } else {
2546 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2547 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2548 }
7c2c3ea3
EJ
2549 break;
2550
2551 default:
2552 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2553 break;
324d9e32 2554 }
324d9e32
AJ
2555}
2556
2557/* Set on less than with immediate operand */
d75c135e 2558static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2559 int rt, int rs, int16_t imm)
324d9e32
AJ
2560{
2561 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2562 const char *opn = "imm arith";
2563 TCGv t0;
2564
2565 if (rt == 0) {
2566 /* If no destination, treat it as a NOP. */
2567 MIPS_DEBUG("NOP");
2568 return;
2569 }
2570 t0 = tcg_temp_new();
2571 gen_load_gpr(t0, rs);
2572 switch (opc) {
2573 case OPC_SLTI:
e68dd28f 2574 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2575 opn = "slti";
2576 break;
2577 case OPC_SLTIU:
e68dd28f 2578 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2579 opn = "sltiu";
2580 break;
2581 }
2abf314d 2582 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2583 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2584 tcg_temp_free(t0);
2585}
2586
2587/* Shifts with immediate operand */
d75c135e 2588static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2589 int rt, int rs, int16_t imm)
2590{
2591 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2592 const char *opn = "imm shift";
2593 TCGv t0;
2594
2595 if (rt == 0) {
2596 /* If no destination, treat it as a NOP. */
2597 MIPS_DEBUG("NOP");
2598 return;
2599 }
2600
2601 t0 = tcg_temp_new();
2602 gen_load_gpr(t0, rs);
2603 switch (opc) {
6af0bf9c 2604 case OPC_SLL:
78723684 2605 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2606 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2607 opn = "sll";
2608 break;
2609 case OPC_SRA:
324d9e32 2610 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2611 opn = "sra";
2612 break;
2613 case OPC_SRL:
ea63e2c3
NF
2614 if (uimm != 0) {
2615 tcg_gen_ext32u_tl(t0, t0);
2616 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2617 } else {
2618 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2619 }
ea63e2c3
NF
2620 opn = "srl";
2621 break;
2622 case OPC_ROTR:
2623 if (uimm != 0) {
2624 TCGv_i32 t1 = tcg_temp_new_i32();
2625
2626 tcg_gen_trunc_tl_i32(t1, t0);
2627 tcg_gen_rotri_i32(t1, t1, uimm);
2628 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2629 tcg_temp_free_i32(t1);
3399e30f
NF
2630 } else {
2631 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2632 }
2633 opn = "rotr";
7a387fff 2634 break;
d26bc211 2635#if defined(TARGET_MIPS64)
7a387fff 2636 case OPC_DSLL:
324d9e32 2637 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2638 opn = "dsll";
2639 break;
2640 case OPC_DSRA:
324d9e32 2641 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2642 opn = "dsra";
2643 break;
2644 case OPC_DSRL:
ea63e2c3
NF
2645 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2646 opn = "dsrl";
2647 break;
2648 case OPC_DROTR:
2649 if (uimm != 0) {
2650 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2651 } else {
2652 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2653 }
ea63e2c3 2654 opn = "drotr";
7a387fff
TS
2655 break;
2656 case OPC_DSLL32:
324d9e32 2657 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2658 opn = "dsll32";
2659 break;
2660 case OPC_DSRA32:
324d9e32 2661 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2662 opn = "dsra32";
2663 break;
2664 case OPC_DSRL32:
ea63e2c3
NF
2665 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2666 opn = "dsrl32";
2667 break;
2668 case OPC_DROTR32:
2669 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2670 opn = "drotr32";
6af0bf9c 2671 break;
7a387fff 2672#endif
6af0bf9c 2673 }
2abf314d 2674 (void)opn; /* avoid a compiler warning */
93b12ccc 2675 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2676 tcg_temp_free(t0);
6af0bf9c
FB
2677}
2678
2679/* Arithmetic */
d75c135e
AJ
2680static void gen_arith(DisasContext *ctx, uint32_t opc,
2681 int rd, int rs, int rt)
6af0bf9c 2682{
923617a3 2683 const char *opn = "arith";
6af0bf9c 2684
7a387fff
TS
2685 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2686 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2687 /* If no destination, treat it as a NOP.
2688 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2689 MIPS_DEBUG("NOP");
460f00c4 2690 return;
185f0762 2691 }
460f00c4 2692
6af0bf9c
FB
2693 switch (opc) {
2694 case OPC_ADD:
48d38ca5 2695 {
460f00c4
AJ
2696 TCGv t0 = tcg_temp_local_new();
2697 TCGv t1 = tcg_temp_new();
2698 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2699 int l1 = gen_new_label();
2700
460f00c4
AJ
2701 gen_load_gpr(t1, rs);
2702 gen_load_gpr(t2, rt);
2703 tcg_gen_add_tl(t0, t1, t2);
2704 tcg_gen_ext32s_tl(t0, t0);
2705 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2706 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2707 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2708 tcg_temp_free(t2);
2709 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2710 tcg_temp_free(t1);
48d38ca5
TS
2711 /* operands of same sign, result different sign */
2712 generate_exception(ctx, EXCP_OVERFLOW);
2713 gen_set_label(l1);
460f00c4
AJ
2714 gen_store_gpr(t0, rd);
2715 tcg_temp_free(t0);
48d38ca5 2716 }
6af0bf9c
FB
2717 opn = "add";
2718 break;
2719 case OPC_ADDU:
460f00c4
AJ
2720 if (rs != 0 && rt != 0) {
2721 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2722 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2723 } else if (rs == 0 && rt != 0) {
2724 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2725 } else if (rs != 0 && rt == 0) {
2726 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2727 } else {
2728 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2729 }
6af0bf9c
FB
2730 opn = "addu";
2731 break;
2732 case OPC_SUB:
48d38ca5 2733 {
460f00c4
AJ
2734 TCGv t0 = tcg_temp_local_new();
2735 TCGv t1 = tcg_temp_new();
2736 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2737 int l1 = gen_new_label();
2738
460f00c4
AJ
2739 gen_load_gpr(t1, rs);
2740 gen_load_gpr(t2, rt);
2741 tcg_gen_sub_tl(t0, t1, t2);
2742 tcg_gen_ext32s_tl(t0, t0);
2743 tcg_gen_xor_tl(t2, t1, t2);
2744 tcg_gen_xor_tl(t1, t0, t1);
2745 tcg_gen_and_tl(t1, t1, t2);
2746 tcg_temp_free(t2);
2747 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2748 tcg_temp_free(t1);
31e3104f 2749 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2750 generate_exception(ctx, EXCP_OVERFLOW);
2751 gen_set_label(l1);
460f00c4
AJ
2752 gen_store_gpr(t0, rd);
2753 tcg_temp_free(t0);
48d38ca5 2754 }
6af0bf9c
FB
2755 opn = "sub";
2756 break;
2757 case OPC_SUBU:
460f00c4
AJ
2758 if (rs != 0 && rt != 0) {
2759 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2760 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2761 } else if (rs == 0 && rt != 0) {
2762 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2763 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2764 } else if (rs != 0 && rt == 0) {
2765 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2766 } else {
2767 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2768 }
6af0bf9c
FB
2769 opn = "subu";
2770 break;
d26bc211 2771#if defined(TARGET_MIPS64)
7a387fff 2772 case OPC_DADD:
48d38ca5 2773 {
460f00c4
AJ
2774 TCGv t0 = tcg_temp_local_new();
2775 TCGv t1 = tcg_temp_new();
2776 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2777 int l1 = gen_new_label();
2778
460f00c4
AJ
2779 gen_load_gpr(t1, rs);
2780 gen_load_gpr(t2, rt);
2781 tcg_gen_add_tl(t0, t1, t2);
2782 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2783 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2784 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2785 tcg_temp_free(t2);
2786 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2787 tcg_temp_free(t1);
48d38ca5
TS
2788 /* operands of same sign, result different sign */
2789 generate_exception(ctx, EXCP_OVERFLOW);
2790 gen_set_label(l1);
460f00c4
AJ
2791 gen_store_gpr(t0, rd);
2792 tcg_temp_free(t0);
48d38ca5 2793 }
7a387fff
TS
2794 opn = "dadd";
2795 break;
2796 case OPC_DADDU:
460f00c4
AJ
2797 if (rs != 0 && rt != 0) {
2798 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2799 } else if (rs == 0 && rt != 0) {
2800 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2801 } else if (rs != 0 && rt == 0) {
2802 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2803 } else {
2804 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2805 }
7a387fff
TS
2806 opn = "daddu";
2807 break;
2808 case OPC_DSUB:
48d38ca5 2809 {
460f00c4
AJ
2810 TCGv t0 = tcg_temp_local_new();
2811 TCGv t1 = tcg_temp_new();
2812 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2813 int l1 = gen_new_label();
2814
460f00c4
AJ
2815 gen_load_gpr(t1, rs);
2816 gen_load_gpr(t2, rt);
2817 tcg_gen_sub_tl(t0, t1, t2);
2818 tcg_gen_xor_tl(t2, t1, t2);
2819 tcg_gen_xor_tl(t1, t0, t1);
2820 tcg_gen_and_tl(t1, t1, t2);
2821 tcg_temp_free(t2);
2822 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2823 tcg_temp_free(t1);
31e3104f 2824 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2825 generate_exception(ctx, EXCP_OVERFLOW);
2826 gen_set_label(l1);
460f00c4
AJ
2827 gen_store_gpr(t0, rd);
2828 tcg_temp_free(t0);
48d38ca5 2829 }
7a387fff
TS
2830 opn = "dsub";
2831 break;
2832 case OPC_DSUBU:
460f00c4
AJ
2833 if (rs != 0 && rt != 0) {
2834 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2835 } else if (rs == 0 && rt != 0) {
2836 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2837 } else if (rs != 0 && rt == 0) {
2838 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2839 } else {
2840 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2841 }
7a387fff
TS
2842 opn = "dsubu";
2843 break;
2844#endif
460f00c4
AJ
2845 case OPC_MUL:
2846 if (likely(rs != 0 && rt != 0)) {
2847 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2848 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2849 } else {
2850 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2851 }
2852 opn = "mul";
6af0bf9c 2853 break;
460f00c4 2854 }
2abf314d 2855 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2856 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2857}
2858
2859/* Conditional move */
d75c135e 2860static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2861 int rd, int rs, int rt)
460f00c4
AJ
2862{
2863 const char *opn = "cond move";
acf12465 2864 TCGv t0, t1, t2;
460f00c4
AJ
2865
2866 if (rd == 0) {
acf12465 2867 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2868 MIPS_DEBUG("NOP");
2869 return;
2870 }
2871
acf12465
AJ
2872 t0 = tcg_temp_new();
2873 gen_load_gpr(t0, rt);
2874 t1 = tcg_const_tl(0);
2875 t2 = tcg_temp_new();
2876 gen_load_gpr(t2, rs);
460f00c4
AJ
2877 switch (opc) {
2878 case OPC_MOVN:
acf12465 2879 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2880 opn = "movn";
6af0bf9c 2881 break;
460f00c4 2882 case OPC_MOVZ:
acf12465 2883 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2884 opn = "movz";
2885 break;
b691d9d2
LA
2886 case OPC_SELNEZ:
2887 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2888 opn = "selnez";
2889 break;
2890 case OPC_SELEQZ:
2891 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2892 opn = "seleqz";
2893 break;
460f00c4 2894 }
acf12465
AJ
2895 tcg_temp_free(t2);
2896 tcg_temp_free(t1);
2897 tcg_temp_free(t0);
460f00c4 2898
2abf314d 2899 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2900 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2901}
2902
2903/* Logic */
d75c135e 2904static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2905 int rd, int rs, int rt)
460f00c4
AJ
2906{
2907 const char *opn = "logic";
2908
2909 if (rd == 0) {
2910 /* If no destination, treat it as a NOP. */
2911 MIPS_DEBUG("NOP");
2912 return;
2913 }
2914
2915 switch (opc) {
6af0bf9c 2916 case OPC_AND:
460f00c4
AJ
2917 if (likely(rs != 0 && rt != 0)) {
2918 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2919 } else {
2920 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2921 }
6af0bf9c
FB
2922 opn = "and";
2923 break;
2924 case OPC_NOR:
460f00c4
AJ
2925 if (rs != 0 && rt != 0) {
2926 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2927 } else if (rs == 0 && rt != 0) {
2928 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2929 } else if (rs != 0 && rt == 0) {
2930 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2931 } else {
2932 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2933 }
6af0bf9c
FB
2934 opn = "nor";
2935 break;
2936 case OPC_OR:
460f00c4
AJ
2937 if (likely(rs != 0 && rt != 0)) {
2938 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2939 } else if (rs == 0 && rt != 0) {
2940 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2941 } else if (rs != 0 && rt == 0) {
2942 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2943 } else {
2944 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2945 }
6af0bf9c
FB
2946 opn = "or";
2947 break;
2948 case OPC_XOR:
460f00c4
AJ
2949 if (likely(rs != 0 && rt != 0)) {
2950 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2951 } else if (rs == 0 && rt != 0) {
2952 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2953 } else if (rs != 0 && rt == 0) {
2954 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2955 } else {
2956 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2957 }
6af0bf9c
FB
2958 opn = "xor";
2959 break;
460f00c4 2960 }
2abf314d 2961 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2962 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2963}
2964
2965/* Set on lower than */
d75c135e 2966static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2967 int rd, int rs, int rt)
460f00c4
AJ
2968{
2969 const char *opn = "slt";
2970 TCGv t0, t1;
2971
2972 if (rd == 0) {
2973 /* If no destination, treat it as a NOP. */
2974 MIPS_DEBUG("NOP");
2975 return;
2976 }
2977
2978 t0 = tcg_temp_new();
2979 t1 = tcg_temp_new();
2980 gen_load_gpr(t0, rs);
2981 gen_load_gpr(t1, rt);
2982 switch (opc) {
2983 case OPC_SLT:
e68dd28f 2984 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2985 opn = "slt";
6af0bf9c 2986 break;
460f00c4 2987 case OPC_SLTU:
e68dd28f 2988 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2989 opn = "sltu";
2990 break;
2991 }
2abf314d 2992 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2993 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2994 tcg_temp_free(t0);
2995 tcg_temp_free(t1);
2996}
20c4c97c 2997
460f00c4 2998/* Shifts */
d75c135e
AJ
2999static void gen_shift(DisasContext *ctx, uint32_t opc,
3000 int rd, int rs, int rt)
460f00c4
AJ
3001{
3002 const char *opn = "shifts";
3003 TCGv t0, t1;
20c4c97c 3004
460f00c4
AJ
3005 if (rd == 0) {
3006 /* If no destination, treat it as a NOP.
3007 For add & sub, we must generate the overflow exception when needed. */
3008 MIPS_DEBUG("NOP");
3009 return;
3010 }
3011
3012 t0 = tcg_temp_new();
3013 t1 = tcg_temp_new();
3014 gen_load_gpr(t0, rs);
3015 gen_load_gpr(t1, rt);
3016 switch (opc) {
6af0bf9c 3017 case OPC_SLLV:
78723684
TS
3018 tcg_gen_andi_tl(t0, t0, 0x1f);
3019 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3020 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3021 opn = "sllv";
3022 break;
3023 case OPC_SRAV:
78723684 3024 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3025 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3026 opn = "srav";
3027 break;
3028 case OPC_SRLV:
ea63e2c3
NF
3029 tcg_gen_ext32u_tl(t1, t1);
3030 tcg_gen_andi_tl(t0, t0, 0x1f);
3031 tcg_gen_shr_tl(t0, t1, t0);
3032 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3033 opn = "srlv";
3034 break;
3035 case OPC_ROTRV:
3036 {
3037 TCGv_i32 t2 = tcg_temp_new_i32();
3038 TCGv_i32 t3 = tcg_temp_new_i32();
3039
3040 tcg_gen_trunc_tl_i32(t2, t0);
3041 tcg_gen_trunc_tl_i32(t3, t1);
3042 tcg_gen_andi_i32(t2, t2, 0x1f);
3043 tcg_gen_rotr_i32(t2, t3, t2);
3044 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3045 tcg_temp_free_i32(t2);
3046 tcg_temp_free_i32(t3);
3047 opn = "rotrv";
5a63bcb2 3048 }
7a387fff 3049 break;
d26bc211 3050#if defined(TARGET_MIPS64)
7a387fff 3051 case OPC_DSLLV:
78723684 3052 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3053 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3054 opn = "dsllv";
3055 break;
3056 case OPC_DSRAV:
78723684 3057 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3058 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3059 opn = "dsrav";
3060 break;
3061 case OPC_DSRLV:
ea63e2c3
NF
3062 tcg_gen_andi_tl(t0, t0, 0x3f);
3063 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3064 opn = "dsrlv";
3065 break;
3066 case OPC_DROTRV:
3067 tcg_gen_andi_tl(t0, t0, 0x3f);
3068 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3069 opn = "drotrv";
6af0bf9c 3070 break;
7a387fff 3071#endif
6af0bf9c 3072 }
2abf314d 3073 (void)opn; /* avoid a compiler warning */
6af0bf9c 3074 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
3075 tcg_temp_free(t0);
3076 tcg_temp_free(t1);
6af0bf9c
FB
3077}
3078
3079/* Arithmetic on HI/LO registers */
26135ead 3080static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3081{
923617a3 3082 const char *opn = "hilo";
6af0bf9c
FB
3083
3084 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3085 /* Treat as NOP. */
6af0bf9c 3086 MIPS_DEBUG("NOP");
a1f6684d 3087 return;
6af0bf9c 3088 }
4133498f 3089
4133498f
JL
3090 if (acc != 0) {
3091 check_dsp(ctx);
3092 }
3093
6af0bf9c
FB
3094 switch (opc) {
3095 case OPC_MFHI:
4133498f
JL
3096#if defined(TARGET_MIPS64)
3097 if (acc != 0) {
3098 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3099 } else
3100#endif
3101 {
3102 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3103 }
6af0bf9c
FB
3104 opn = "mfhi";
3105 break;
3106 case OPC_MFLO:
4133498f
JL
3107#if defined(TARGET_MIPS64)
3108 if (acc != 0) {
3109 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3110 } else
3111#endif
3112 {
3113 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3114 }
6af0bf9c
FB
3115 opn = "mflo";
3116 break;
3117 case OPC_MTHI:
4133498f
JL
3118 if (reg != 0) {
3119#if defined(TARGET_MIPS64)
3120 if (acc != 0) {
3121 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3122 } else
3123#endif
3124 {
3125 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3126 }
3127 } else {
3128 tcg_gen_movi_tl(cpu_HI[acc], 0);
3129 }
6af0bf9c
FB
3130 opn = "mthi";
3131 break;
3132 case OPC_MTLO:
4133498f
JL
3133 if (reg != 0) {
3134#if defined(TARGET_MIPS64)
3135 if (acc != 0) {
3136 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3137 } else
3138#endif
3139 {
3140 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3141 }
3142 } else {
3143 tcg_gen_movi_tl(cpu_LO[acc], 0);
3144 }
6af0bf9c
FB
3145 opn = "mtlo";
3146 break;
6af0bf9c 3147 }
2abf314d 3148 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
3149 MIPS_DEBUG("%s %s", opn, regnames[reg]);
3150}
3151
d4ea6acd
LA
3152static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3153 TCGMemOp memop)
3154{
3155 TCGv t0 = tcg_const_tl(addr);
3156 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3157 gen_store_gpr(t0, reg);
3158 tcg_temp_free(t0);
3159}
3160
3161static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
3162{
3163 target_long offset;
3164 target_long addr;
3165
3166 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
3167 case OPC_ADDIUPC:
3168 if (rs != 0) {
3169 offset = sextract32(ctx->opcode << 2, 0, 21);
3170 addr = addr_add(ctx, ctx->pc, offset);
3171 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3172 }
3173 break;
3174 case R6_OPC_LWPC:
3175 offset = sextract32(ctx->opcode << 2, 0, 21);
3176 addr = addr_add(ctx, ctx->pc, offset);
3177 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3178 break;
3179#if defined(TARGET_MIPS64)
3180 case OPC_LWUPC:
3181 check_mips_64(ctx);
3182 offset = sextract32(ctx->opcode << 2, 0, 21);
3183 addr = addr_add(ctx, ctx->pc, offset);
3184 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3185 break;
3186#endif
3187 default:
3188 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
3189 case OPC_AUIPC:
3190 if (rs != 0) {
3191 offset = imm << 16;
3192 addr = addr_add(ctx, ctx->pc, offset);
3193 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3194 }
3195 break;
3196 case OPC_ALUIPC:
3197 if (rs != 0) {
3198 offset = imm << 16;
3199 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
3200 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3201 }
3202 break;
3203#if defined(TARGET_MIPS64)
3204 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3205 case R6_OPC_LDPC + (1 << 16):
3206 case R6_OPC_LDPC + (2 << 16):
3207 case R6_OPC_LDPC + (3 << 16):
3208 check_mips_64(ctx);
3209 offset = sextract32(ctx->opcode << 3, 0, 21);
3210 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
3211 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3212 break;
3213#endif
3214 default:
3215 MIPS_INVAL("OPC_PCREL");
3216 generate_exception(ctx, EXCP_RI);
3217 break;
3218 }
3219 break;
3220 }
3221}
3222
b42ee5e1
LA
3223static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3224{
3225 const char *opn = "r6 mul/div";
3226 TCGv t0, t1;
3227
3228 if (rd == 0) {
3229 /* Treat as NOP. */
3230 MIPS_DEBUG("NOP");
3231 return;
3232 }
3233
3234 t0 = tcg_temp_new();
3235 t1 = tcg_temp_new();
3236
3237 gen_load_gpr(t0, rs);
3238 gen_load_gpr(t1, rt);
3239
3240 switch (opc) {
3241 case R6_OPC_DIV:
3242 {
3243 TCGv t2 = tcg_temp_new();
3244 TCGv t3 = tcg_temp_new();
3245 tcg_gen_ext32s_tl(t0, t0);
3246 tcg_gen_ext32s_tl(t1, t1);
3247 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3248 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3249 tcg_gen_and_tl(t2, t2, t3);
3250 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3251 tcg_gen_or_tl(t2, t2, t3);
3252 tcg_gen_movi_tl(t3, 0);
3253 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3254 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3255 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3256 tcg_temp_free(t3);
3257 tcg_temp_free(t2);
3258 }
3259 opn = "div";
3260 break;
3261 case R6_OPC_MOD:
3262 {
3263 TCGv t2 = tcg_temp_new();
3264 TCGv t3 = tcg_temp_new();
3265 tcg_gen_ext32s_tl(t0, t0);
3266 tcg_gen_ext32s_tl(t1, t1);
3267 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3268 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3269 tcg_gen_and_tl(t2, t2, t3);
3270 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3271 tcg_gen_or_tl(t2, t2, t3);
3272 tcg_gen_movi_tl(t3, 0);
3273 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3274 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3275 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3276 tcg_temp_free(t3);
3277 tcg_temp_free(t2);
3278 }
3279 opn = "mod";
3280 break;
3281 case R6_OPC_DIVU:
3282 {
3283 TCGv t2 = tcg_const_tl(0);
3284 TCGv t3 = tcg_const_tl(1);
3285 tcg_gen_ext32u_tl(t0, t0);
3286 tcg_gen_ext32u_tl(t1, t1);
3287 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3288 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3289 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3290 tcg_temp_free(t3);
3291 tcg_temp_free(t2);
3292 }
3293 opn = "divu";
3294 break;
3295 case R6_OPC_MODU:
3296 {
3297 TCGv t2 = tcg_const_tl(0);
3298 TCGv t3 = tcg_const_tl(1);
3299 tcg_gen_ext32u_tl(t0, t0);
3300 tcg_gen_ext32u_tl(t1, t1);
3301 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3302 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3303 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3304 tcg_temp_free(t3);
3305 tcg_temp_free(t2);
3306 }
3307 opn = "modu";
3308 break;
3309 case R6_OPC_MUL:
3310 {
3311 TCGv_i32 t2 = tcg_temp_new_i32();
3312 TCGv_i32 t3 = tcg_temp_new_i32();
3313 tcg_gen_trunc_tl_i32(t2, t0);
3314 tcg_gen_trunc_tl_i32(t3, t1);
3315 tcg_gen_mul_i32(t2, t2, t3);
3316 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3317 tcg_temp_free_i32(t2);
3318 tcg_temp_free_i32(t3);
3319 }
3320 opn = "mul";
3321 break;
3322 case R6_OPC_MUH:
3323 {
3324 TCGv_i32 t2 = tcg_temp_new_i32();
3325 TCGv_i32 t3 = tcg_temp_new_i32();
3326 tcg_gen_trunc_tl_i32(t2, t0);
3327 tcg_gen_trunc_tl_i32(t3, t1);
3328 tcg_gen_muls2_i32(t2, t3, t2, t3);
3329 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3330 tcg_temp_free_i32(t2);
3331 tcg_temp_free_i32(t3);
3332 }
3333 opn = "muh";
3334 break;
3335 case R6_OPC_MULU:
3336 {
3337 TCGv_i32 t2 = tcg_temp_new_i32();
3338 TCGv_i32 t3 = tcg_temp_new_i32();
3339 tcg_gen_trunc_tl_i32(t2, t0);
3340 tcg_gen_trunc_tl_i32(t3, t1);
3341 tcg_gen_mul_i32(t2, t2, t3);
3342 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3343 tcg_temp_free_i32(t2);
3344 tcg_temp_free_i32(t3);
3345 }
3346 opn = "mulu";
3347 break;
3348 case R6_OPC_MUHU:
3349 {
3350 TCGv_i32 t2 = tcg_temp_new_i32();
3351 TCGv_i32 t3 = tcg_temp_new_i32();
3352 tcg_gen_trunc_tl_i32(t2, t0);
3353 tcg_gen_trunc_tl_i32(t3, t1);
3354 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3355 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3356 tcg_temp_free_i32(t2);
3357 tcg_temp_free_i32(t3);
3358 }
3359 opn = "muhu";
3360 break;
3361#if defined(TARGET_MIPS64)
3362 case R6_OPC_DDIV:
3363 {
3364 TCGv t2 = tcg_temp_new();
3365 TCGv t3 = tcg_temp_new();
3366 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3367 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3368 tcg_gen_and_tl(t2, t2, t3);
3369 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3370 tcg_gen_or_tl(t2, t2, t3);
3371 tcg_gen_movi_tl(t3, 0);
3372 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3373 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3374 tcg_temp_free(t3);
3375 tcg_temp_free(t2);
3376 }
3377 opn = "ddiv";
3378 break;
3379 case R6_OPC_DMOD:
3380 {
3381 TCGv t2 = tcg_temp_new();
3382 TCGv t3 = tcg_temp_new();
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3385 tcg_gen_and_tl(t2, t2, t3);
3386 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3387 tcg_gen_or_tl(t2, t2, t3);
3388 tcg_gen_movi_tl(t3, 0);
3389 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3390 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3391 tcg_temp_free(t3);
3392 tcg_temp_free(t2);
3393 }
3394 opn = "dmod";
3395 break;
3396 case R6_OPC_DDIVU:
3397 {
3398 TCGv t2 = tcg_const_tl(0);
3399 TCGv t3 = tcg_const_tl(1);
3400 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3401 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3402 tcg_temp_free(t3);
3403 tcg_temp_free(t2);
3404 }
3405 opn = "ddivu";
3406 break;
3407 case R6_OPC_DMODU:
3408 {
3409 TCGv t2 = tcg_const_tl(0);
3410 TCGv t3 = tcg_const_tl(1);
3411 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3412 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3413 tcg_temp_free(t3);
3414 tcg_temp_free(t2);
3415 }
3416 opn = "dmodu";
3417 break;
3418 case R6_OPC_DMUL:
3419 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3420 opn = "dmul";
3421 break;
3422 case R6_OPC_DMUH:
3423 {
3424 TCGv t2 = tcg_temp_new();
3425 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3426 tcg_temp_free(t2);
3427 }
3428 opn = "dmuh";
3429 break;
3430 case R6_OPC_DMULU:
3431 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3432 opn = "dmulu";
3433 break;
3434 case R6_OPC_DMUHU:
3435 {
3436 TCGv t2 = tcg_temp_new();
3437 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3438 tcg_temp_free(t2);
3439 }
3440 opn = "dmuhu";
3441 break;
3442#endif
3443 default:
3444 MIPS_INVAL(opn);
3445 generate_exception(ctx, EXCP_RI);
3446 goto out;
3447 }
3448 (void)opn; /* avoid a compiler warning */
3449 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3450 out:
3451 tcg_temp_free(t0);
3452 tcg_temp_free(t1);
3453}
3454
26135ead
RS
3455static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3456 int acc, int rs, int rt)
6af0bf9c 3457{
923617a3 3458 const char *opn = "mul/div";
d45f89f4
AJ
3459 TCGv t0, t1;
3460
51127181
AJ
3461 t0 = tcg_temp_new();
3462 t1 = tcg_temp_new();
6af0bf9c 3463
78723684
TS
3464 gen_load_gpr(t0, rs);
3465 gen_load_gpr(t1, rt);
51127181 3466
26135ead
RS
3467 if (acc != 0) {
3468 check_dsp(ctx);
3469 }
3470
6af0bf9c
FB
3471 switch (opc) {
3472 case OPC_DIV:
48d38ca5 3473 {
51127181
AJ
3474 TCGv t2 = tcg_temp_new();
3475 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3476 tcg_gen_ext32s_tl(t0, t0);
3477 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3478 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3479 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3480 tcg_gen_and_tl(t2, t2, t3);
3481 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3482 tcg_gen_or_tl(t2, t2, t3);
3483 tcg_gen_movi_tl(t3, 0);
3484 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3485 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3486 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3487 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3488 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3489 tcg_temp_free(t3);
3490 tcg_temp_free(t2);
48d38ca5 3491 }
6af0bf9c
FB
3492 opn = "div";
3493 break;
3494 case OPC_DIVU:
48d38ca5 3495 {
51127181
AJ
3496 TCGv t2 = tcg_const_tl(0);
3497 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3498 tcg_gen_ext32u_tl(t0, t0);
3499 tcg_gen_ext32u_tl(t1, t1);
51127181 3500 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3501 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3502 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3503 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3504 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3505 tcg_temp_free(t3);
3506 tcg_temp_free(t2);
48d38ca5 3507 }
6af0bf9c
FB
3508 opn = "divu";
3509 break;
3510 case OPC_MULT:
214c465f 3511 {
ce1dd5d1
RH
3512 TCGv_i32 t2 = tcg_temp_new_i32();
3513 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3514 tcg_gen_trunc_tl_i32(t2, t0);
3515 tcg_gen_trunc_tl_i32(t3, t1);
3516 tcg_gen_muls2_i32(t2, t3, t2, t3);
3517 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3518 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3519 tcg_temp_free_i32(t2);
3520 tcg_temp_free_i32(t3);
214c465f 3521 }
6af0bf9c
FB
3522 opn = "mult";
3523 break;
3524 case OPC_MULTU:
214c465f 3525 {
ce1dd5d1
RH
3526 TCGv_i32 t2 = tcg_temp_new_i32();
3527 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3528 tcg_gen_trunc_tl_i32(t2, t0);
3529 tcg_gen_trunc_tl_i32(t3, t1);
3530 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3531 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3532 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3533 tcg_temp_free_i32(t2);
3534 tcg_temp_free_i32(t3);
214c465f 3535 }
6af0bf9c
FB
3536 opn = "multu";
3537 break;
d26bc211 3538#if defined(TARGET_MIPS64)
7a387fff 3539 case OPC_DDIV:
48d38ca5 3540 {
51127181
AJ
3541 TCGv t2 = tcg_temp_new();
3542 TCGv t3 = tcg_temp_new();
3543 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3544 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3545 tcg_gen_and_tl(t2, t2, t3);
3546 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3547 tcg_gen_or_tl(t2, t2, t3);
3548 tcg_gen_movi_tl(t3, 0);
3549 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3550 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3551 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3552 tcg_temp_free(t3);
3553 tcg_temp_free(t2);
48d38ca5 3554 }
7a387fff
TS
3555 opn = "ddiv";
3556 break;
3557 case OPC_DDIVU:
48d38ca5 3558 {
51127181
AJ
3559 TCGv t2 = tcg_const_tl(0);
3560 TCGv t3 = tcg_const_tl(1);
3561 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3562 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3563 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3564 tcg_temp_free(t3);
3565 tcg_temp_free(t2);
48d38ca5 3566 }
7a387fff
TS
3567 opn = "ddivu";
3568 break;
3569 case OPC_DMULT:
26135ead 3570 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3571 opn = "dmult";
3572 break;
3573 case OPC_DMULTU:
26135ead 3574 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3575 opn = "dmultu";
3576 break;
3577#endif
6af0bf9c 3578 case OPC_MADD:
214c465f 3579 {
d45f89f4
AJ
3580 TCGv_i64 t2 = tcg_temp_new_i64();
3581 TCGv_i64 t3 = tcg_temp_new_i64();
3582
3583 tcg_gen_ext_tl_i64(t2, t0);
3584 tcg_gen_ext_tl_i64(t3, t1);
3585 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3586 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3587 tcg_gen_add_i64(t2, t2, t3);
3588 tcg_temp_free_i64(t3);
3589 tcg_gen_trunc_i64_tl(t0, t2);
3590 tcg_gen_shri_i64(t2, t2, 32);
3591 tcg_gen_trunc_i64_tl(t1, t2);
3592 tcg_temp_free_i64(t2);
4133498f
JL
3593 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3594 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3595 }
6af0bf9c
FB
3596 opn = "madd";
3597 break;
3598 case OPC_MADDU:
4133498f 3599 {
d45f89f4
AJ
3600 TCGv_i64 t2 = tcg_temp_new_i64();
3601 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3602
78723684
TS
3603 tcg_gen_ext32u_tl(t0, t0);
3604 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3605 tcg_gen_extu_tl_i64(t2, t0);
3606 tcg_gen_extu_tl_i64(t3, t1);
3607 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3608 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3609 tcg_gen_add_i64(t2, t2, t3);
3610 tcg_temp_free_i64(t3);
3611 tcg_gen_trunc_i64_tl(t0, t2);
3612 tcg_gen_shri_i64(t2, t2, 32);
3613 tcg_gen_trunc_i64_tl(t1, t2);
3614 tcg_temp_free_i64(t2);
4133498f
JL
3615 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3616 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3617 }
6af0bf9c
FB
3618 opn = "maddu";
3619 break;
3620 case OPC_MSUB:
214c465f 3621 {
d45f89f4
AJ
3622 TCGv_i64 t2 = tcg_temp_new_i64();
3623 TCGv_i64 t3 = tcg_temp_new_i64();
3624
3625 tcg_gen_ext_tl_i64(t2, t0);
3626 tcg_gen_ext_tl_i64(t3, t1);
3627 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3628 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3629 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3630 tcg_temp_free_i64(t3);
3631 tcg_gen_trunc_i64_tl(t0, t2);
3632 tcg_gen_shri_i64(t2, t2, 32);
3633 tcg_gen_trunc_i64_tl(t1, t2);
3634 tcg_temp_free_i64(t2);
4133498f
JL
3635 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3636 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3637 }
6af0bf9c
FB
3638 opn = "msub";
3639 break;
3640 case OPC_MSUBU:
214c465f 3641 {
d45f89f4
AJ
3642 TCGv_i64 t2 = tcg_temp_new_i64();
3643 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3644
78723684
TS
3645 tcg_gen_ext32u_tl(t0, t0);
3646 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3647 tcg_gen_extu_tl_i64(t2, t0);
3648 tcg_gen_extu_tl_i64(t3, t1);
3649 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3650 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3651 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3652 tcg_temp_free_i64(t3);
3653 tcg_gen_trunc_i64_tl(t0, t2);
3654 tcg_gen_shri_i64(t2, t2, 32);
3655 tcg_gen_trunc_i64_tl(t1, t2);
3656 tcg_temp_free_i64(t2);
4133498f
JL
3657 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3658 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3659 }
6af0bf9c
FB
3660 opn = "msubu";
3661 break;
3662 default:
923617a3 3663 MIPS_INVAL(opn);
6af0bf9c 3664 generate_exception(ctx, EXCP_RI);
78723684 3665 goto out;
6af0bf9c 3666 }
2abf314d 3667 (void)opn; /* avoid a compiler warning */
6af0bf9c 3668 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3669 out:
3670 tcg_temp_free(t0);
3671 tcg_temp_free(t1);
6af0bf9c
FB
3672}
3673
e9c71dd1
TS
3674static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3675 int rd, int rs, int rt)
3676{
3677 const char *opn = "mul vr54xx";
f157bfe1
AJ
3678 TCGv t0 = tcg_temp_new();
3679 TCGv t1 = tcg_temp_new();
e9c71dd1 3680
6c5c1e20
TS
3681 gen_load_gpr(t0, rs);
3682 gen_load_gpr(t1, rt);
e9c71dd1
TS
3683
3684 switch (opc) {
3685 case OPC_VR54XX_MULS:
895c2d04 3686 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3687 opn = "muls";
6958549d 3688 break;
e9c71dd1 3689 case OPC_VR54XX_MULSU:
895c2d04 3690 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3691 opn = "mulsu";
6958549d 3692 break;
e9c71dd1 3693 case OPC_VR54XX_MACC:
895c2d04 3694 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3695 opn = "macc";
6958549d 3696 break;
e9c71dd1 3697 case OPC_VR54XX_MACCU:
895c2d04 3698 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3699 opn = "maccu";
6958549d 3700 break;
e9c71dd1 3701 case OPC_VR54XX_MSAC:
895c2d04 3702 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3703 opn = "msac";
6958549d 3704 break;
e9c71dd1 3705 case OPC_VR54XX_MSACU:
895c2d04 3706 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3707 opn = "msacu";
6958549d 3708 break;
e9c71dd1 3709 case OPC_VR54XX_MULHI:
895c2d04 3710 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3711 opn = "mulhi";
6958549d 3712 break;
e9c71dd1 3713 case OPC_VR54XX_MULHIU:
895c2d04 3714 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3715 opn = "mulhiu";
6958549d 3716 break;
e9c71dd1 3717 case OPC_VR54XX_MULSHI:
895c2d04 3718 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3719 opn = "mulshi";
6958549d 3720 break;
e9c71dd1 3721 case OPC_VR54XX_MULSHIU:
895c2d04 3722 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3723 opn = "mulshiu";
6958549d 3724 break;
e9c71dd1 3725 case OPC_VR54XX_MACCHI:
895c2d04 3726 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3727 opn = "macchi";
6958549d 3728 break;
e9c71dd1 3729 case OPC_VR54XX_MACCHIU:
895c2d04 3730 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3731 opn = "macchiu";
6958549d 3732 break;
e9c71dd1 3733 case OPC_VR54XX_MSACHI:
895c2d04 3734 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3735 opn = "msachi";
6958549d 3736 break;
e9c71dd1 3737 case OPC_VR54XX_MSACHIU:
895c2d04 3738 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3739 opn = "msachiu";
6958549d 3740 break;
e9c71dd1
TS
3741 default:
3742 MIPS_INVAL("mul vr54xx");
3743 generate_exception(ctx, EXCP_RI);
6c5c1e20 3744 goto out;
e9c71dd1 3745 }
6c5c1e20 3746 gen_store_gpr(t0, rd);
2abf314d 3747 (void)opn; /* avoid a compiler warning */
e9c71dd1 3748 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3749
3750 out:
3751 tcg_temp_free(t0);
3752 tcg_temp_free(t1);
e9c71dd1
TS
3753}
3754
7a387fff 3755static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3756 int rd, int rs)
3757{
923617a3 3758 const char *opn = "CLx";
20e1fb52 3759 TCGv t0;
6c5c1e20 3760
6af0bf9c 3761 if (rd == 0) {
ead9360e 3762 /* Treat as NOP. */
6af0bf9c 3763 MIPS_DEBUG("NOP");
20e1fb52 3764 return;
6af0bf9c 3765 }
20e1fb52 3766 t0 = tcg_temp_new();
6c5c1e20 3767 gen_load_gpr(t0, rs);
6af0bf9c
FB
3768 switch (opc) {
3769 case OPC_CLO:
4267d3e6 3770 case R6_OPC_CLO:
20e1fb52 3771 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3772 opn = "clo";
3773 break;
3774 case OPC_CLZ:
4267d3e6 3775 case R6_OPC_CLZ:
20e1fb52 3776 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3777 opn = "clz";
3778 break;
d26bc211 3779#if defined(TARGET_MIPS64)
7a387fff 3780 case OPC_DCLO:
4267d3e6 3781 case R6_OPC_DCLO:
20e1fb52 3782 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3783 opn = "dclo";
3784 break;
3785 case OPC_DCLZ:
4267d3e6 3786 case R6_OPC_DCLZ:
20e1fb52 3787 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3788 opn = "dclz";
3789 break;
3790#endif
6af0bf9c 3791 }
2abf314d 3792 (void)opn; /* avoid a compiler warning */
6af0bf9c 3793 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3794 tcg_temp_free(t0);
6af0bf9c
FB
3795}
3796
161f85e6 3797/* Godson integer instructions */
bd277fa1
RH
3798static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3799 int rd, int rs, int rt)
161f85e6
AJ
3800{
3801 const char *opn = "loongson";
3802 TCGv t0, t1;
3803
3804 if (rd == 0) {
3805 /* Treat as NOP. */
3806 MIPS_DEBUG("NOP");
3807 return;
3808 }
3809
3810 switch (opc) {
3811 case OPC_MULT_G_2E:
3812 case OPC_MULT_G_2F:
3813 case OPC_MULTU_G_2E:
3814 case OPC_MULTU_G_2F:
3815#if defined(TARGET_MIPS64)
3816 case OPC_DMULT_G_2E:
3817 case OPC_DMULT_G_2F:
3818 case OPC_DMULTU_G_2E:
3819 case OPC_DMULTU_G_2F:
3820#endif
3821 t0 = tcg_temp_new();
3822 t1 = tcg_temp_new();
3823 break;
3824 default:
3825 t0 = tcg_temp_local_new();
3826 t1 = tcg_temp_local_new();
3827 break;
3828 }
3829
3830 gen_load_gpr(t0, rs);
3831 gen_load_gpr(t1, rt);
3832
3833 switch (opc) {
3834 case OPC_MULT_G_2E:
3835 case OPC_MULT_G_2F:
3836 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3837 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3838 opn = "mult.g";
3839 break;
3840 case OPC_MULTU_G_2E:
3841 case OPC_MULTU_G_2F:
3842 tcg_gen_ext32u_tl(t0, t0);
3843 tcg_gen_ext32u_tl(t1, t1);
3844 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3845 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3846 opn = "multu.g";
3847 break;
3848 case OPC_DIV_G_2E:
3849 case OPC_DIV_G_2F:
3850 {
3851 int l1 = gen_new_label();
3852 int l2 = gen_new_label();
3853 int l3 = gen_new_label();
3854 tcg_gen_ext32s_tl(t0, t0);
3855 tcg_gen_ext32s_tl(t1, t1);
3856 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3857 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3858 tcg_gen_br(l3);
3859 gen_set_label(l1);
3860 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3861 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3862 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3863 tcg_gen_br(l3);
3864 gen_set_label(l2);
3865 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3866 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3867 gen_set_label(l3);
3868 }
3869 opn = "div.g";
3870 break;
3871 case OPC_DIVU_G_2E:
3872 case OPC_DIVU_G_2F:
3873 {
3874 int l1 = gen_new_label();
3875 int l2 = gen_new_label();
3876 tcg_gen_ext32u_tl(t0, t0);
3877 tcg_gen_ext32u_tl(t1, t1);
3878 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3879 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3880 tcg_gen_br(l2);
3881 gen_set_label(l1);
3882 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3883 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3884 gen_set_label(l2);
3885 }
3886 opn = "divu.g";
3887 break;
3888 case OPC_MOD_G_2E:
3889 case OPC_MOD_G_2F:
3890 {
3891 int l1 = gen_new_label();
3892 int l2 = gen_new_label();
3893 int l3 = gen_new_label();
3894 tcg_gen_ext32u_tl(t0, t0);
3895 tcg_gen_ext32u_tl(t1, t1);
3896 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3897 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3898 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3899 gen_set_label(l1);
3900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3901 tcg_gen_br(l3);
3902 gen_set_label(l2);
3903 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3904 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3905 gen_set_label(l3);
3906 }
3907 opn = "mod.g";
3908 break;
3909 case OPC_MODU_G_2E:
3910 case OPC_MODU_G_2F:
3911 {
3912 int l1 = gen_new_label();
3913 int l2 = gen_new_label();
3914 tcg_gen_ext32u_tl(t0, t0);
3915 tcg_gen_ext32u_tl(t1, t1);
3916 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3917 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3918 tcg_gen_br(l2);
3919 gen_set_label(l1);
3920 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3921 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3922 gen_set_label(l2);
3923 }
3924 opn = "modu.g";
3925 break;
3926#if defined(TARGET_MIPS64)
3927 case OPC_DMULT_G_2E:
3928 case OPC_DMULT_G_2F:
3929 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3930 opn = "dmult.g";
3931 break;
3932 case OPC_DMULTU_G_2E:
3933 case OPC_DMULTU_G_2F:
3934 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3935 opn = "dmultu.g";
3936 break;
3937 case OPC_DDIV_G_2E:
3938 case OPC_DDIV_G_2F:
3939 {
3940 int l1 = gen_new_label();
3941 int l2 = gen_new_label();
3942 int l3 = gen_new_label();
3943 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3944 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3945 tcg_gen_br(l3);
3946 gen_set_label(l1);
3947 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3948 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3949 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3950 tcg_gen_br(l3);
3951 gen_set_label(l2);
3952 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3953 gen_set_label(l3);
3954 }
3955 opn = "ddiv.g";
3956 break;
3957 case OPC_DDIVU_G_2E:
3958 case OPC_DDIVU_G_2F:
3959 {
3960 int l1 = gen_new_label();
3961 int l2 = gen_new_label();
3962 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3963 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3964 tcg_gen_br(l2);
3965 gen_set_label(l1);
3966 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3967 gen_set_label(l2);
3968 }
3969 opn = "ddivu.g";
3970 break;
3971 case OPC_DMOD_G_2E:
3972 case OPC_DMOD_G_2F:
3973 {
3974 int l1 = gen_new_label();
3975 int l2 = gen_new_label();
3976 int l3 = gen_new_label();
3977 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3978 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3979 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3980 gen_set_label(l1);
3981 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3982 tcg_gen_br(l3);
3983 gen_set_label(l2);
3984 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3985 gen_set_label(l3);
3986 }
3987 opn = "dmod.g";
3988 break;
3989 case OPC_DMODU_G_2E:
3990 case OPC_DMODU_G_2F:
3991 {
3992 int l1 = gen_new_label();
3993 int l2 = gen_new_label();
3994 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3995 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3996 tcg_gen_br(l2);
3997 gen_set_label(l1);
3998 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3999 gen_set_label(l2);
4000 }
4001 opn = "dmodu.g";
4002 break;
4003#endif
4004 }
4005
2abf314d 4006 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
4007 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
4008 tcg_temp_free(t0);
4009 tcg_temp_free(t1);
4010}
4011
bd277fa1
RH
4012/* Loongson multimedia instructions */
4013static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4014{
4015 const char *opn = "loongson_cp2";
4016 uint32_t opc, shift_max;
4017 TCGv_i64 t0, t1;
4018
4019 opc = MASK_LMI(ctx->opcode);
4020 switch (opc) {
4021 case OPC_ADD_CP2:
4022 case OPC_SUB_CP2:
4023 case OPC_DADD_CP2:
4024 case OPC_DSUB_CP2:
4025 t0 = tcg_temp_local_new_i64();
4026 t1 = tcg_temp_local_new_i64();
4027 break;
4028 default:
4029 t0 = tcg_temp_new_i64();
4030 t1 = tcg_temp_new_i64();
4031 break;
4032 }
4033
4034 gen_load_fpr64(ctx, t0, rs);
4035 gen_load_fpr64(ctx, t1, rt);
4036
4037#define LMI_HELPER(UP, LO) \
4038 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4039#define LMI_HELPER_1(UP, LO) \
4040 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4041#define LMI_DIRECT(UP, LO, OP) \
4042 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4043
4044 switch (opc) {
4045 LMI_HELPER(PADDSH, paddsh);
4046 LMI_HELPER(PADDUSH, paddush);
4047 LMI_HELPER(PADDH, paddh);
4048 LMI_HELPER(PADDW, paddw);
4049 LMI_HELPER(PADDSB, paddsb);
4050 LMI_HELPER(PADDUSB, paddusb);
4051 LMI_HELPER(PADDB, paddb);
4052
4053 LMI_HELPER(PSUBSH, psubsh);
4054 LMI_HELPER(PSUBUSH, psubush);
4055 LMI_HELPER(PSUBH, psubh);
4056 LMI_HELPER(PSUBW, psubw);
4057 LMI_HELPER(PSUBSB, psubsb);
4058 LMI_HELPER(PSUBUSB, psubusb);
4059 LMI_HELPER(PSUBB, psubb);
4060
4061 LMI_HELPER(PSHUFH, pshufh);
4062 LMI_HELPER(PACKSSWH, packsswh);
4063 LMI_HELPER(PACKSSHB, packsshb);
4064 LMI_HELPER(PACKUSHB, packushb);
4065
4066 LMI_HELPER(PUNPCKLHW, punpcklhw);
4067 LMI_HELPER(PUNPCKHHW, punpckhhw);
4068 LMI_HELPER(PUNPCKLBH, punpcklbh);
4069 LMI_HELPER(PUNPCKHBH, punpckhbh);
4070 LMI_HELPER(PUNPCKLWD, punpcklwd);
4071 LMI_HELPER(PUNPCKHWD, punpckhwd);
4072
4073 LMI_HELPER(PAVGH, pavgh);
4074 LMI_HELPER(PAVGB, pavgb);
4075 LMI_HELPER(PMAXSH, pmaxsh);
4076 LMI_HELPER(PMINSH, pminsh);
4077 LMI_HELPER(PMAXUB, pmaxub);
4078 LMI_HELPER(PMINUB, pminub);
4079
4080 LMI_HELPER(PCMPEQW, pcmpeqw);
4081 LMI_HELPER(PCMPGTW, pcmpgtw);
4082 LMI_HELPER(PCMPEQH, pcmpeqh);
4083 LMI_HELPER(PCMPGTH, pcmpgth);
4084 LMI_HELPER(PCMPEQB, pcmpeqb);
4085 LMI_HELPER(PCMPGTB, pcmpgtb);
4086
4087 LMI_HELPER(PSLLW, psllw);
4088 LMI_HELPER(PSLLH, psllh);
4089 LMI_HELPER(PSRLW, psrlw);
4090 LMI_HELPER(PSRLH, psrlh);
4091 LMI_HELPER(PSRAW, psraw);
4092 LMI_HELPER(PSRAH, psrah);
4093
4094 LMI_HELPER(PMULLH, pmullh);
4095 LMI_HELPER(PMULHH, pmulhh);
4096 LMI_HELPER(PMULHUH, pmulhuh);
4097 LMI_HELPER(PMADDHW, pmaddhw);
4098
4099 LMI_HELPER(PASUBUB, pasubub);
4100 LMI_HELPER_1(BIADD, biadd);
4101 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4102
4103 LMI_DIRECT(PADDD, paddd, add);
4104 LMI_DIRECT(PSUBD, psubd, sub);
4105 LMI_DIRECT(XOR_CP2, xor, xor);
4106 LMI_DIRECT(NOR_CP2, nor, nor);
4107 LMI_DIRECT(AND_CP2, and, and);
4108 LMI_DIRECT(PANDN, pandn, andc);
4109 LMI_DIRECT(OR, or, or);
4110
4111 case OPC_PINSRH_0:
4112 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4113 opn = "pinsrh_0";
4114 break;
4115 case OPC_PINSRH_1:
4116 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4117 opn = "pinsrh_1";
4118 break;
4119 case OPC_PINSRH_2:
4120 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4121 opn = "pinsrh_2";
4122 break;
4123 case OPC_PINSRH_3:
4124 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4125 opn = "pinsrh_3";
4126 break;
4127
4128 case OPC_PEXTRH:
4129 tcg_gen_andi_i64(t1, t1, 3);
4130 tcg_gen_shli_i64(t1, t1, 4);
4131 tcg_gen_shr_i64(t0, t0, t1);
4132 tcg_gen_ext16u_i64(t0, t0);
4133 opn = "pextrh";
4134 break;
4135
4136 case OPC_ADDU_CP2:
4137 tcg_gen_add_i64(t0, t0, t1);
4138 tcg_gen_ext32s_i64(t0, t0);
4139 opn = "addu";
4140 break;
4141 case OPC_SUBU_CP2:
4142 tcg_gen_sub_i64(t0, t0, t1);
4143 tcg_gen_ext32s_i64(t0, t0);
4144 opn = "addu";
4145 break;
4146
4147 case OPC_SLL_CP2:
4148 opn = "sll";
4149 shift_max = 32;
4150 goto do_shift;
4151 case OPC_SRL_CP2:
4152 opn = "srl";
4153 shift_max = 32;
4154 goto do_shift;
4155 case OPC_SRA_CP2:
4156 opn = "sra";
4157 shift_max = 32;
4158 goto do_shift;
4159 case OPC_DSLL_CP2:
4160 opn = "dsll";
4161 shift_max = 64;
4162 goto do_shift;
4163 case OPC_DSRL_CP2:
4164 opn = "dsrl";
4165 shift_max = 64;
4166 goto do_shift;
4167 case OPC_DSRA_CP2:
4168 opn = "dsra";
4169 shift_max = 64;
4170 goto do_shift;
4171 do_shift:
4172 /* Make sure shift count isn't TCG undefined behaviour. */
4173 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4174
4175 switch (opc) {
4176 case OPC_SLL_CP2:
4177 case OPC_DSLL_CP2:
4178 tcg_gen_shl_i64(t0, t0, t1);
4179 break;
4180 case OPC_SRA_CP2:
4181 case OPC_DSRA_CP2:
4182 /* Since SRA is UndefinedResult without sign-extended inputs,
4183 we can treat SRA and DSRA the same. */
4184 tcg_gen_sar_i64(t0, t0, t1);
4185 break;
4186 case OPC_SRL_CP2:
4187 /* We want to shift in zeros for SRL; zero-extend first. */
4188 tcg_gen_ext32u_i64(t0, t0);
4189 /* FALLTHRU */
4190 case OPC_DSRL_CP2:
4191 tcg_gen_shr_i64(t0, t0, t1);
4192 break;
4193 }
4194
4195 if (shift_max == 32) {
4196 tcg_gen_ext32s_i64(t0, t0);
4197 }
4198
4199 /* Shifts larger than MAX produce zero. */
4200 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4201 tcg_gen_neg_i64(t1, t1);
4202 tcg_gen_and_i64(t0, t0, t1);
4203 break;
4204
4205 case OPC_ADD_CP2:
4206 case OPC_DADD_CP2:
4207 {
4208 TCGv_i64 t2 = tcg_temp_new_i64();
4209 int lab = gen_new_label();
4210
4211 tcg_gen_mov_i64(t2, t0);
4212 tcg_gen_add_i64(t0, t1, t2);
4213 if (opc == OPC_ADD_CP2) {
4214 tcg_gen_ext32s_i64(t0, t0);
4215 }
4216 tcg_gen_xor_i64(t1, t1, t2);
4217 tcg_gen_xor_i64(t2, t2, t0);
4218 tcg_gen_andc_i64(t1, t2, t1);
4219 tcg_temp_free_i64(t2);
4220 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4221 generate_exception(ctx, EXCP_OVERFLOW);
4222 gen_set_label(lab);
4223
4224 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
4225 break;
4226 }
4227
4228 case OPC_SUB_CP2:
4229 case OPC_DSUB_CP2:
4230 {
4231 TCGv_i64 t2 = tcg_temp_new_i64();
4232 int lab = gen_new_label();
4233
4234 tcg_gen_mov_i64(t2, t0);
4235 tcg_gen_sub_i64(t0, t1, t2);
4236 if (opc == OPC_SUB_CP2) {
4237 tcg_gen_ext32s_i64(t0, t0);
4238 }
4239 tcg_gen_xor_i64(t1, t1, t2);
4240 tcg_gen_xor_i64(t2, t2, t0);
4241 tcg_gen_and_i64(t1, t1, t2);
4242 tcg_temp_free_i64(t2);
4243 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4244 generate_exception(ctx, EXCP_OVERFLOW);
4245 gen_set_label(lab);
4246
4247 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
4248 break;
4249 }
4250
4251 case OPC_PMULUW:
4252 tcg_gen_ext32u_i64(t0, t0);
4253 tcg_gen_ext32u_i64(t1, t1);
4254 tcg_gen_mul_i64(t0, t0, t1);
4255 opn = "pmuluw";
4256 break;
4257
4258 case OPC_SEQU_CP2:
4259 case OPC_SEQ_CP2:
4260 case OPC_SLTU_CP2:
4261 case OPC_SLT_CP2:
4262 case OPC_SLEU_CP2:
4263 case OPC_SLE_CP2:
4264 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4265 FD field is the CC field? */
4266 default:
4267 MIPS_INVAL(opn);
4268 generate_exception(ctx, EXCP_RI);
4269 return;
4270 }
4271
4272#undef LMI_HELPER
4273#undef LMI_DIRECT
4274
4275 gen_store_fpr64(ctx, t0, rd);
4276
4277 (void)opn; /* avoid a compiler warning */
4278 MIPS_DEBUG("%s %s, %s, %s", opn,
4279 fregnames[rd], fregnames[rs], fregnames[rt]);
4280 tcg_temp_free_i64(t0);
4281 tcg_temp_free_i64(t1);
4282}
4283
6af0bf9c 4284/* Traps */
7a387fff 4285static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4286 int rs, int rt, int16_t imm)
4287{
4288 int cond;
cdc0faa6 4289 TCGv t0 = tcg_temp_new();
1ba74fb8 4290 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4291
4292 cond = 0;
4293 /* Load needed operands */
4294 switch (opc) {
4295 case OPC_TEQ:
4296 case OPC_TGE:
4297 case OPC_TGEU:
4298 case OPC_TLT:
4299 case OPC_TLTU:
4300 case OPC_TNE:
4301 /* Compare two registers */
4302 if (rs != rt) {
be24bb4f
TS
4303 gen_load_gpr(t0, rs);
4304 gen_load_gpr(t1, rt);
6af0bf9c
FB
4305 cond = 1;
4306 }
179e32bb 4307 break;
6af0bf9c
FB
4308 case OPC_TEQI:
4309 case OPC_TGEI:
4310 case OPC_TGEIU:
4311 case OPC_TLTI:
4312 case OPC_TLTIU:
4313 case OPC_TNEI:
4314 /* Compare register to immediate */
4315 if (rs != 0 || imm != 0) {
be24bb4f
TS
4316 gen_load_gpr(t0, rs);
4317 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4318 cond = 1;
4319 }
4320 break;
4321 }
4322 if (cond == 0) {
4323 switch (opc) {
4324 case OPC_TEQ: /* rs == rs */
4325 case OPC_TEQI: /* r0 == 0 */
4326 case OPC_TGE: /* rs >= rs */
4327 case OPC_TGEI: /* r0 >= 0 */
4328 case OPC_TGEU: /* rs >= rs unsigned */
4329 case OPC_TGEIU: /* r0 >= 0 unsigned */
4330 /* Always trap */
cdc0faa6 4331 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4332 break;
4333 case OPC_TLT: /* rs < rs */
4334 case OPC_TLTI: /* r0 < 0 */
4335 case OPC_TLTU: /* rs < rs unsigned */
4336 case OPC_TLTIU: /* r0 < 0 unsigned */
4337 case OPC_TNE: /* rs != rs */
4338 case OPC_TNEI: /* r0 != 0 */
ead9360e 4339 /* Never trap: treat as NOP. */
cdc0faa6 4340 break;
6af0bf9c
FB
4341 }
4342 } else {
cdc0faa6
AJ
4343 int l1 = gen_new_label();
4344
6af0bf9c
FB
4345 switch (opc) {
4346 case OPC_TEQ:
4347 case OPC_TEQI:
cdc0faa6 4348 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4349 break;
4350 case OPC_TGE:
4351 case OPC_TGEI:
cdc0faa6 4352 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4353 break;
4354 case OPC_TGEU:
4355 case OPC_TGEIU:
cdc0faa6 4356 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4357 break;
4358 case OPC_TLT:
4359 case OPC_TLTI:
cdc0faa6 4360 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4361 break;
4362 case OPC_TLTU:
4363 case OPC_TLTIU:
cdc0faa6 4364 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4365 break;
4366 case OPC_TNE:
4367 case OPC_TNEI:
cdc0faa6 4368 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4369 break;
6af0bf9c 4370 }
cdc0faa6 4371 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4372 gen_set_label(l1);
4373 }
be24bb4f
TS
4374 tcg_temp_free(t0);
4375 tcg_temp_free(t1);
6af0bf9c
FB
4376}
4377
356265ae 4378static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4379{
6e256c93
FB
4380 TranslationBlock *tb;
4381 tb = ctx->tb;
7b270ef2
NF
4382 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4383 likely(!ctx->singlestep_enabled)) {
57fec1fe 4384 tcg_gen_goto_tb(n);
9b9e4393 4385 gen_save_pc(dest);
8cfd0495 4386 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4387 } else {
9b9e4393 4388 gen_save_pc(dest);
7b270ef2
NF
4389 if (ctx->singlestep_enabled) {
4390 save_cpu_state(ctx, 0);
895c2d04 4391 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4392 }
57fec1fe 4393 tcg_gen_exit_tb(0);
6e256c93 4394 }
c53be334
FB
4395}
4396
6af0bf9c 4397/* Branches (before delay slot) */
7a387fff 4398static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4399 int insn_bytes,
b231c103
YK
4400 int rs, int rt, int32_t offset,
4401 int delayslot_size)
6af0bf9c 4402{
d077b6f7 4403 target_ulong btgt = -1;
3ad4bb2d 4404 int blink = 0;
2fdbad25 4405 int bcond_compute = 0;
1ba74fb8
AJ
4406 TCGv t0 = tcg_temp_new();
4407 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4408
4409 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4410#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
4411 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4412 TARGET_FMT_lx "\n", ctx->pc);
923617a3 4413#endif
3ad4bb2d 4414 generate_exception(ctx, EXCP_RI);
6c5c1e20 4415 goto out;
3ad4bb2d 4416 }
6af0bf9c 4417
6af0bf9c
FB
4418 /* Load needed operands */
4419 switch (opc) {
4420 case OPC_BEQ:
4421 case OPC_BEQL:
4422 case OPC_BNE:
4423 case OPC_BNEL:
4424 /* Compare two registers */
4425 if (rs != rt) {
6c5c1e20
TS
4426 gen_load_gpr(t0, rs);
4427 gen_load_gpr(t1, rt);
2fdbad25 4428 bcond_compute = 1;
6af0bf9c 4429 }
7dca4ad0 4430 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4431 break;
4432 case OPC_BGEZ:
4433 case OPC_BGEZAL:
4434 case OPC_BGEZALL:
4435 case OPC_BGEZL:
4436 case OPC_BGTZ:
4437 case OPC_BGTZL:
4438 case OPC_BLEZ:
4439 case OPC_BLEZL:
4440 case OPC_BLTZ:
4441 case OPC_BLTZAL:
4442 case OPC_BLTZALL:
4443 case OPC_BLTZL:
4444 /* Compare to zero */
4445 if (rs != 0) {
6c5c1e20 4446 gen_load_gpr(t0, rs);
2fdbad25 4447 bcond_compute = 1;
6af0bf9c 4448 }
7dca4ad0 4449 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4450 break;
e45a93e2
JL
4451 case OPC_BPOSGE32:
4452#if defined(TARGET_MIPS64)
4453 case OPC_BPOSGE64:
4454 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4455#else
4456 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4457#endif
4458 bcond_compute = 1;
4459 btgt = ctx->pc + insn_bytes + offset;
4460 break;
6af0bf9c
FB
4461 case OPC_J:
4462 case OPC_JAL:
364d4831 4463 case OPC_JALX:
6af0bf9c 4464 /* Jump to immediate */
7dca4ad0 4465 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4466 break;
4467 case OPC_JR:
4468 case OPC_JALR:
4469 /* Jump to register */
7a387fff
TS
4470 if (offset != 0 && offset != 16) {
4471 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4472 others are reserved. */
923617a3 4473 MIPS_INVAL("jump hint");
6af0bf9c 4474 generate_exception(ctx, EXCP_RI);
6c5c1e20 4475 goto out;
6af0bf9c 4476 }
d077b6f7 4477 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4478 break;
4479 default:
4480 MIPS_INVAL("branch/jump");
4481 generate_exception(ctx, EXCP_RI);
6c5c1e20 4482 goto out;
6af0bf9c 4483 }
2fdbad25 4484 if (bcond_compute == 0) {
6af0bf9c
FB
4485 /* No condition to be computed */
4486 switch (opc) {
4487 case OPC_BEQ: /* rx == rx */
4488 case OPC_BEQL: /* rx == rx likely */
4489 case OPC_BGEZ: /* 0 >= 0 */
4490 case OPC_BGEZL: /* 0 >= 0 likely */
4491 case OPC_BLEZ: /* 0 <= 0 */
4492 case OPC_BLEZL: /* 0 <= 0 likely */
4493 /* Always take */
4ad40f36 4494 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4495 MIPS_DEBUG("balways");
4496 break;
4497 case OPC_BGEZAL: /* 0 >= 0 */
4498 case OPC_BGEZALL: /* 0 >= 0 likely */
4499 /* Always take and link */
4500 blink = 31;
4ad40f36 4501 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4502 MIPS_DEBUG("balways and link");
4503 break;
4504 case OPC_BNE: /* rx != rx */
4505 case OPC_BGTZ: /* 0 > 0 */
4506 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4507 /* Treat as NOP. */
6af0bf9c 4508 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4509 goto out;
eeef26cd 4510 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4511 /* Handle as an unconditional branch to get correct delay
4512 slot checking. */
4513 blink = 31;
b231c103 4514 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4515 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4516 MIPS_DEBUG("bnever and link");
3c824109 4517 break;
eeef26cd 4518 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4519 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4520 /* Skip the instruction in the delay slot */
4521 MIPS_DEBUG("bnever, link and skip");
4522 ctx->pc += 4;
6c5c1e20 4523 goto out;
6af0bf9c
FB
4524 case OPC_BNEL: /* rx != rx likely */
4525 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4526 case OPC_BLTZL: /* 0 < 0 likely */
4527 /* Skip the instruction in the delay slot */
4528 MIPS_DEBUG("bnever and skip");
9898128f 4529 ctx->pc += 4;
6c5c1e20 4530 goto out;
6af0bf9c 4531 case OPC_J:
4ad40f36 4532 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4533 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4534 break;
364d4831
NF
4535 case OPC_JALX:
4536 ctx->hflags |= MIPS_HFLAG_BX;
4537 /* Fallthrough */
6af0bf9c
FB
4538 case OPC_JAL:
4539 blink = 31;
4ad40f36 4540 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4541 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4542 break;
4543 case OPC_JR:
4ad40f36 4544 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4545 MIPS_DEBUG("jr %s", regnames[rs]);
4546 break;
4547 case OPC_JALR:
4548 blink = rt;
4ad40f36 4549 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4550 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4551 break;
4552 default:
4553 MIPS_INVAL("branch/jump");
4554 generate_exception(ctx, EXCP_RI);
6c5c1e20 4555 goto out;
6af0bf9c
FB
4556 }
4557 } else {
4558 switch (opc) {
4559 case OPC_BEQ:
e68dd28f 4560 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4561 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4562 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4563 goto not_likely;
4564 case OPC_BEQL:
e68dd28f 4565 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4566 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4567 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4568 goto likely;
4569 case OPC_BNE:
e68dd28f 4570 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4571 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4572 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4573 goto not_likely;
4574 case OPC_BNEL:
e68dd28f 4575 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4576 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4577 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4578 goto likely;
4579 case OPC_BGEZ:
e68dd28f 4580 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4581 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4582 goto not_likely;
4583 case OPC_BGEZL:
e68dd28f 4584 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4585 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4586 goto likely;
4587 case OPC_BGEZAL:
e68dd28f 4588 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4589 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4590 blink = 31;
4591 goto not_likely;
4592 case OPC_BGEZALL:
e68dd28f 4593 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4594 blink = 31;
d077b6f7 4595 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4596 goto likely;
4597 case OPC_BGTZ:
e68dd28f 4598 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4599 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4600 goto not_likely;
4601 case OPC_BGTZL:
e68dd28f 4602 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4603 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4604 goto likely;
4605 case OPC_BLEZ:
e68dd28f 4606 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4607 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4608 goto not_likely;
4609 case OPC_BLEZL:
e68dd28f 4610 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4611 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4612 goto likely;
4613 case OPC_BLTZ:
e68dd28f 4614 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4615 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4616 goto not_likely;
4617 case OPC_BLTZL:
e68dd28f 4618 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4619 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4620 goto likely;
e45a93e2
JL
4621 case OPC_BPOSGE32:
4622 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4623 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4624 goto not_likely;
4625#if defined(TARGET_MIPS64)
4626 case OPC_BPOSGE64:
4627 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4628 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4629 goto not_likely;
4630#endif
6af0bf9c 4631 case OPC_BLTZAL:
e68dd28f 4632 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4633 blink = 31;
d077b6f7 4634 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4635 not_likely:
4ad40f36 4636 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4637 break;
4638 case OPC_BLTZALL:
e68dd28f 4639 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4640 blink = 31;
d077b6f7 4641 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4642 likely:
4ad40f36 4643 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4644 break;
c53f4a62
TS
4645 default:
4646 MIPS_INVAL("conditional branch/jump");
4647 generate_exception(ctx, EXCP_RI);
6c5c1e20 4648 goto out;
6af0bf9c 4649 }
6af0bf9c 4650 }
923617a3 4651 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4652 blink, ctx->hflags, btgt);
9b9e4393 4653
d077b6f7 4654 ctx->btarget = btgt;
b231c103
YK
4655
4656 switch (delayslot_size) {
4657 case 2:
4658 ctx->hflags |= MIPS_HFLAG_BDS16;
4659 break;
4660 case 4:
4661 ctx->hflags |= MIPS_HFLAG_BDS32;
4662 break;
4663 }
4664
6af0bf9c 4665 if (blink > 0) {
b231c103 4666 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4667 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4668
364d4831 4669 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4670 }
6c5c1e20
TS
4671
4672 out:
364d4831
NF
4673 if (insn_bytes == 2)
4674 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4675 tcg_temp_free(t0);
4676 tcg_temp_free(t1);
6af0bf9c
FB
4677}
4678
7a387fff
TS
4679/* special3 bitfield operations */
4680static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4681 int rs, int lsb, int msb)
7a387fff 4682{
a7812ae4
PB
4683 TCGv t0 = tcg_temp_new();
4684 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4685
4686 gen_load_gpr(t1, rs);
7a387fff
TS
4687 switch (opc) {
4688 case OPC_EXT:
4689 if (lsb + msb > 31)
4690 goto fail;
505ad7c2
AJ
4691 tcg_gen_shri_tl(t0, t1, lsb);
4692 if (msb != 31) {
4693 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4694 } else {
4695 tcg_gen_ext32s_tl(t0, t0);
4696 }
7a387fff 4697 break;
c6d6dd7c 4698#if defined(TARGET_MIPS64)
7a387fff 4699 case OPC_DEXTM:
505ad7c2
AJ
4700 tcg_gen_shri_tl(t0, t1, lsb);
4701 if (msb != 31) {
4702 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4703 }
7a387fff
TS
4704 break;
4705 case OPC_DEXTU:
505ad7c2
AJ
4706 tcg_gen_shri_tl(t0, t1, lsb + 32);
4707 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4708 break;
4709 case OPC_DEXT:
505ad7c2
AJ
4710 tcg_gen_shri_tl(t0, t1, lsb);
4711 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4712 break;
c6d6dd7c 4713#endif
7a387fff
TS
4714 case OPC_INS:
4715 if (lsb > msb)
4716 goto fail;
6c5c1e20 4717 gen_load_gpr(t0, rt);
e0d002f1 4718 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4719 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4720 break;
c6d6dd7c 4721#if defined(TARGET_MIPS64)
7a387fff 4722 case OPC_DINSM:
6c5c1e20 4723 gen_load_gpr(t0, rt);
e0d002f1 4724 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4725 break;
4726 case OPC_DINSU:
6c5c1e20 4727 gen_load_gpr(t0, rt);
e0d002f1 4728 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4729 break;
4730 case OPC_DINS:
6c5c1e20 4731 gen_load_gpr(t0, rt);
e0d002f1 4732 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4733 break;
c6d6dd7c 4734#endif
7a387fff
TS
4735 default:
4736fail:
4737 MIPS_INVAL("bitops");
4738 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4739 tcg_temp_free(t0);
4740 tcg_temp_free(t1);
7a387fff
TS
4741 return;
4742 }
6c5c1e20
TS
4743 gen_store_gpr(t0, rt);
4744 tcg_temp_free(t0);
4745 tcg_temp_free(t1);
7a387fff
TS
4746}
4747
49bcf33c
AJ
4748static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4749{
3a55fa47 4750 TCGv t0;
49bcf33c 4751
3a55fa47
AJ
4752 if (rd == 0) {
4753 /* If no destination, treat it as a NOP. */
4754 MIPS_DEBUG("NOP");
4755 return;
4756 }
4757
4758 t0 = tcg_temp_new();
4759 gen_load_gpr(t0, rt);
49bcf33c
AJ
4760 switch (op2) {
4761 case OPC_WSBH:
3a55fa47
AJ
4762 {
4763 TCGv t1 = tcg_temp_new();
4764
4765 tcg_gen_shri_tl(t1, t0, 8);
4766 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4767 tcg_gen_shli_tl(t0, t0, 8);
4768 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4769 tcg_gen_or_tl(t0, t0, t1);
4770 tcg_temp_free(t1);
4771 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4772 }
49bcf33c
AJ
4773 break;
4774 case OPC_SEB:
3a55fa47 4775 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4776 break;
4777 case OPC_SEH:
3a55fa47 4778 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4779 break;
4780#if defined(TARGET_MIPS64)
4781 case OPC_DSBH:
3a55fa47
AJ
4782 {
4783 TCGv t1 = tcg_temp_new();
4784
4785 tcg_gen_shri_tl(t1, t0, 8);
4786 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4787 tcg_gen_shli_tl(t0, t0, 8);
4788 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4789 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4790 tcg_temp_free(t1);
4791 }
49bcf33c
AJ
4792 break;
4793 case OPC_DSHD:
3a55fa47
AJ
4794 {
4795 TCGv t1 = tcg_temp_new();
4796
4797 tcg_gen_shri_tl(t1, t0, 16);
4798 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4799 tcg_gen_shli_tl(t0, t0, 16);
4800 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4801 tcg_gen_or_tl(t0, t0, t1);
4802 tcg_gen_shri_tl(t1, t0, 32);
4803 tcg_gen_shli_tl(t0, t0, 32);
4804 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4805 tcg_temp_free(t1);
4806 }
49bcf33c
AJ
4807 break;
4808#endif
4809 default:
4810 MIPS_INVAL("bsfhl");
4811 generate_exception(ctx, EXCP_RI);
4812 tcg_temp_free(t0);
49bcf33c
AJ
4813 return;
4814 }
49bcf33c 4815 tcg_temp_free(t0);
49bcf33c
AJ
4816}
4817
f1aa6320 4818#ifndef CONFIG_USER_ONLY
0eaef5aa 4819/* CP0 (MMU and control) */
d9bea114 4820static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4821{
d9bea114 4822 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4823
d9bea114
AJ
4824 tcg_gen_ld_i32(t0, cpu_env, off);
4825 tcg_gen_ext_i32_tl(arg, t0);
4826 tcg_temp_free_i32(t0);
4f57689a
TS
4827}
4828
d9bea114 4829static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4830{
d9bea114
AJ
4831 tcg_gen_ld_tl(arg, cpu_env, off);
4832 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4833}
4834
d9bea114 4835static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4836{
d9bea114 4837 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4838
d9bea114
AJ
4839 tcg_gen_trunc_tl_i32(t0, arg);
4840 tcg_gen_st_i32(t0, cpu_env, off);
4841 tcg_temp_free_i32(t0);
f1aa6320
TS
4842}
4843
d9bea114 4844static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4845{
d9bea114
AJ
4846 tcg_gen_ext32s_tl(arg, arg);
4847 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4848}
4849
e98c0d17
LA
4850static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4851{
4852 if (ctx->insn_flags & ISA_MIPS32R6) {
4853 tcg_gen_movi_tl(arg, 0);
4854 } else {
4855 tcg_gen_movi_tl(arg, ~0);
4856 }
4857}
4858
f31b035a
LA
4859#define CP0_CHECK(c) \
4860 do { \
4861 if (!(c)) { \
4862 goto cp0_unimplemented; \
4863 } \
4864 } while (0)
4865
d75c135e 4866static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4867{
7a387fff 4868 const char *rn = "invalid";
873eb012 4869
e189e748 4870 if (sel != 0)
d75c135e 4871 check_insn(ctx, ISA_MIPS32);
e189e748 4872
873eb012
TS
4873 switch (reg) {
4874 case 0:
7a387fff
TS
4875 switch (sel) {
4876 case 0:
7db13fae 4877 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4878 rn = "Index";
4879 break;
4880 case 1:
f31b035a 4881 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4882 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4883 rn = "MVPControl";
ead9360e 4884 break;
7a387fff 4885 case 2:
f31b035a 4886 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4887 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4888 rn = "MVPConf0";
ead9360e 4889 break;
7a387fff 4890 case 3:
f31b035a 4891 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4892 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4893 rn = "MVPConf1";
ead9360e 4894 break;
7a387fff 4895 default:
f31b035a 4896 goto cp0_unimplemented;
7a387fff 4897 }
873eb012
TS
4898 break;
4899 case 1:
7a387fff
TS
4900 switch (sel) {
4901 case 0:
f31b035a 4902 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 4903 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4904 rn = "Random";
2423f660 4905 break;
7a387fff 4906 case 1:
f31b035a 4907 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4908 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4909 rn = "VPEControl";
ead9360e 4910 break;
7a387fff 4911 case 2:
f31b035a 4912 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4914 rn = "VPEConf0";
ead9360e 4915 break;
7a387fff 4916 case 3:
f31b035a 4917 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4919 rn = "VPEConf1";
ead9360e 4920 break;
7a387fff 4921 case 4:
f31b035a 4922 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4923 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4924 rn = "YQMask";
ead9360e 4925 break;
7a387fff 4926 case 5:
f31b035a 4927 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4928 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4929 rn = "VPESchedule";
ead9360e 4930 break;
7a387fff 4931 case 6:
f31b035a 4932 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4933 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4934 rn = "VPEScheFBack";
ead9360e 4935 break;
7a387fff 4936 case 7:
f31b035a 4937 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 4938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4939 rn = "VPEOpt";
ead9360e 4940 break;
7a387fff 4941 default:
f31b035a 4942 goto cp0_unimplemented;
7a387fff 4943 }
873eb012
TS
4944 break;
4945 case 2:
7a387fff
TS
4946 switch (sel) {
4947 case 0:
7db13fae 4948 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9
LA
4949#if defined(TARGET_MIPS64)
4950 if (ctx->rxi) {
4951 TCGv tmp = tcg_temp_new();
4952 tcg_gen_andi_tl(tmp, arg, (3ull << 62));
4953 tcg_gen_shri_tl(tmp, tmp, 32);
4954 tcg_gen_or_tl(arg, arg, tmp);
4955 tcg_temp_free(tmp);
4956 }
4957#endif
d9bea114 4958 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4959 rn = "EntryLo0";
4960 break;
7a387fff 4961 case 1:
f31b035a 4962 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4963 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4964 rn = "TCStatus";
ead9360e 4965 break;
7a387fff 4966 case 2:
f31b035a 4967 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4968 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4969 rn = "TCBind";
ead9360e 4970 break;
7a387fff 4971 case 3:
f31b035a 4972 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4973 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4974 rn = "TCRestart";
ead9360e 4975 break;
7a387fff 4976 case 4:
f31b035a 4977 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4978 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4979 rn = "TCHalt";
ead9360e 4980 break;
7a387fff 4981 case 5:
f31b035a 4982 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4983 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4984 rn = "TCContext";
ead9360e 4985 break;
7a387fff 4986 case 6:
f31b035a 4987 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4988 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4989 rn = "TCSchedule";
ead9360e 4990 break;
7a387fff 4991 case 7:
f31b035a 4992 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 4993 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4994 rn = "TCScheFBack";
ead9360e 4995 break;
7a387fff 4996 default:
f31b035a 4997 goto cp0_unimplemented;
7a387fff 4998 }
873eb012
TS
4999 break;
5000 case 3:
7a387fff
TS
5001 switch (sel) {
5002 case 0:
7db13fae 5003 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9
LA
5004#if defined(TARGET_MIPS64)
5005 if (ctx->rxi) {
5006 TCGv tmp = tcg_temp_new();
5007 tcg_gen_andi_tl(tmp, arg, (3ull << 62));
5008 tcg_gen_shri_tl(tmp, tmp, 32);
5009 tcg_gen_or_tl(arg, arg, tmp);
5010 tcg_temp_free(tmp);
5011 }
5012#endif
d9bea114 5013 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5014 rn = "EntryLo1";
5015 break;
7a387fff 5016 default:
f31b035a 5017 goto cp0_unimplemented;
1579a72e 5018 }
873eb012
TS
5019 break;
5020 case 4:
7a387fff
TS
5021 switch (sel) {
5022 case 0:
7db13fae 5023 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5024 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5025 rn = "Context";
5026 break;
7a387fff 5027 case 1:
d9bea114 5028// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5029 rn = "ContextConfig";
f31b035a 5030 goto cp0_unimplemented;
2423f660 5031// break;
d279279e 5032 case 2:
f31b035a
LA
5033 CP0_CHECK(ctx->ulri);
5034 tcg_gen_ld32s_tl(arg, cpu_env,
5035 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5036 rn = "UserLocal";
d279279e 5037 break;
7a387fff 5038 default:
f31b035a 5039 goto cp0_unimplemented;
1579a72e 5040 }
873eb012
TS
5041 break;
5042 case 5:
7a387fff
TS
5043 switch (sel) {
5044 case 0:
7db13fae 5045 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5046 rn = "PageMask";
5047 break;
7a387fff 5048 case 1:
d75c135e 5049 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5050 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5051 rn = "PageGrain";
5052 break;
7a387fff 5053 default:
f31b035a 5054 goto cp0_unimplemented;
1579a72e 5055 }
873eb012
TS
5056 break;
5057 case 6:
7a387fff
TS
5058 switch (sel) {
5059 case 0:
7db13fae 5060 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5061 rn = "Wired";
5062 break;
7a387fff 5063 case 1:
d75c135e 5064 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5066 rn = "SRSConf0";
ead9360e 5067 break;
7a387fff 5068 case 2:
d75c135e 5069 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5070 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5071 rn = "SRSConf1";
ead9360e 5072 break;
7a387fff 5073 case 3:
d75c135e 5074 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5075 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5076 rn = "SRSConf2";
ead9360e 5077 break;
7a387fff 5078 case 4:
d75c135e 5079 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5081 rn = "SRSConf3";
ead9360e 5082 break;
7a387fff 5083 case 5:
d75c135e 5084 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5086 rn = "SRSConf4";
ead9360e 5087 break;
7a387fff 5088 default:
f31b035a 5089 goto cp0_unimplemented;
1579a72e 5090 }
873eb012 5091 break;
8c0fdd85 5092 case 7:
7a387fff
TS
5093 switch (sel) {
5094 case 0:
d75c135e 5095 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5097 rn = "HWREna";
5098 break;
7a387fff 5099 default:
f31b035a 5100 goto cp0_unimplemented;
1579a72e 5101 }
8c0fdd85 5102 break;
873eb012 5103 case 8:
7a387fff
TS
5104 switch (sel) {
5105 case 0:
7db13fae 5106 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5107 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5108 rn = "BadVAddr";
2423f660 5109 break;
aea14095 5110 case 1:
f31b035a
LA
5111 CP0_CHECK(ctx->bi);
5112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5113 rn = "BadInstr";
aea14095
LA
5114 break;
5115 case 2:
f31b035a
LA
5116 CP0_CHECK(ctx->bp);
5117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5118 rn = "BadInstrP";
aea14095 5119 break;
7a387fff 5120 default:
f31b035a 5121 goto cp0_unimplemented;
aea14095 5122 }
873eb012
TS
5123 break;
5124 case 9:
7a387fff
TS
5125 switch (sel) {
5126 case 0:
2e70f6ef
PB
5127 /* Mark as an IO operation because we read the time. */
5128 if (use_icount)
5129 gen_io_start();
895c2d04 5130 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5131 if (use_icount) {
5132 gen_io_end();
2e70f6ef 5133 }
55807224
EI
5134 /* Break the TB to be able to take timer interrupts immediately
5135 after reading count. */
5136 ctx->bstate = BS_STOP;
2423f660
TS
5137 rn = "Count";
5138 break;
5139 /* 6,7 are implementation dependent */
7a387fff 5140 default:
f31b035a 5141 goto cp0_unimplemented;
2423f660 5142 }
873eb012
TS
5143 break;
5144 case 10:
7a387fff
TS
5145 switch (sel) {
5146 case 0:
7db13fae 5147 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5148 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5149 rn = "EntryHi";
5150 break;
7a387fff 5151 default:
f31b035a 5152 goto cp0_unimplemented;
1579a72e 5153 }
873eb012
TS
5154 break;
5155 case 11:
7a387fff
TS
5156 switch (sel) {
5157 case 0:
7db13fae 5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5159 rn = "Compare";
5160 break;
5161 /* 6,7 are implementation dependent */
7a387fff 5162 default:
f31b035a 5163 goto cp0_unimplemented;
2423f660 5164 }
873eb012
TS
5165 break;
5166 case 12:
7a387fff
TS
5167 switch (sel) {
5168 case 0:
7db13fae 5169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5170 rn = "Status";
5171 break;
7a387fff 5172 case 1:
d75c135e 5173 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5175 rn = "IntCtl";
5176 break;
7a387fff 5177 case 2:
d75c135e 5178 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5180 rn = "SRSCtl";
5181 break;
7a387fff 5182 case 3:
d75c135e 5183 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5184 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5185 rn = "SRSMap";
fd88b6ab 5186 break;
7a387fff 5187 default:
f31b035a 5188 goto cp0_unimplemented;
7a387fff 5189 }
873eb012
TS
5190 break;
5191 case 13:
7a387fff
TS
5192 switch (sel) {
5193 case 0:
7db13fae 5194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5195 rn = "Cause";
5196 break;
7a387fff 5197 default:
f31b035a 5198 goto cp0_unimplemented;
7a387fff 5199 }
873eb012
TS
5200 break;
5201 case 14:
7a387fff
TS
5202 switch (sel) {
5203 case 0:
7db13fae 5204 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5205 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5206 rn = "EPC";
5207 break;
7a387fff 5208 default:
f31b035a 5209 goto cp0_unimplemented;
1579a72e 5210 }
873eb012
TS
5211 break;
5212 case 15:
7a387fff
TS
5213 switch (sel) {
5214 case 0:
7db13fae 5215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5216 rn = "PRid";
5217 break;
7a387fff 5218 case 1:
d75c135e 5219 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5221 rn = "EBase";
5222 break;
7a387fff 5223 default:
f31b035a 5224 goto cp0_unimplemented;
7a387fff 5225 }
873eb012
TS
5226 break;
5227 case 16:
5228 switch (sel) {
5229 case 0:
7db13fae 5230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5231 rn = "Config";
5232 break;
5233 case 1:
7db13fae 5234 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5235 rn = "Config1";
5236 break;
7a387fff 5237 case 2:
7db13fae 5238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5239 rn = "Config2";
5240 break;
5241 case 3:
7db13fae 5242 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5243 rn = "Config3";
5244 break;
b4160af1
PJ
5245 case 4:
5246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5247 rn = "Config4";
5248 break;
b4dd99a3
PJ
5249 case 5:
5250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5251 rn = "Config5";
5252 break;
e397ee33
TS
5253 /* 6,7 are implementation dependent */
5254 case 6:
7db13fae 5255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5256 rn = "Config6";
5257 break;
5258 case 7:
7db13fae 5259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5260 rn = "Config7";
5261 break;
873eb012 5262 default:
f31b035a 5263 goto cp0_unimplemented;
873eb012
TS
5264 }
5265 break;
5266 case 17:
7a387fff
TS
5267 switch (sel) {
5268 case 0:
895c2d04 5269 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5270 rn = "LLAddr";
5271 break;
7a387fff 5272 default:
f31b035a 5273 goto cp0_unimplemented;
7a387fff 5274 }
873eb012
TS
5275 break;
5276 case 18:
7a387fff 5277 switch (sel) {
fd88b6ab 5278 case 0 ... 7:
895c2d04 5279 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5280 rn = "WatchLo";
5281 break;
7a387fff 5282 default:
f31b035a 5283 goto cp0_unimplemented;
7a387fff 5284 }
873eb012
TS
5285 break;
5286 case 19:
7a387fff 5287 switch (sel) {
fd88b6ab 5288 case 0 ...7:
895c2d04 5289 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5290 rn = "WatchHi";
5291 break;
7a387fff 5292 default:
f31b035a 5293 goto cp0_unimplemented;
7a387fff 5294 }
873eb012 5295 break;
8c0fdd85 5296 case 20:
7a387fff
TS
5297 switch (sel) {
5298 case 0:
d26bc211 5299#if defined(TARGET_MIPS64)
d75c135e 5300 check_insn(ctx, ISA_MIPS3);
7db13fae 5301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5302 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5303 rn = "XContext";
5304 break;
703eaf37 5305#endif
7a387fff 5306 default:
f31b035a 5307 goto cp0_unimplemented;
7a387fff 5308 }
8c0fdd85
TS
5309 break;
5310 case 21:
7a387fff 5311 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5312 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5313 switch (sel) {
5314 case 0:
7db13fae 5315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5316 rn = "Framemask";
5317 break;
7a387fff 5318 default:
f31b035a 5319 goto cp0_unimplemented;
7a387fff 5320 }
8c0fdd85
TS
5321 break;
5322 case 22:
d9bea114 5323 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5324 rn = "'Diagnostic"; /* implementation dependent */
5325 break;
873eb012 5326 case 23:
7a387fff
TS
5327 switch (sel) {
5328 case 0:
895c2d04 5329 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5330 rn = "Debug";
5331 break;
7a387fff 5332 case 1:
d9bea114 5333// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5334 rn = "TraceControl";
5335// break;
7a387fff 5336 case 2:
d9bea114 5337// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5338 rn = "TraceControl2";
5339// break;
7a387fff 5340 case 3:
d9bea114 5341// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5342 rn = "UserTraceData";
5343// break;
7a387fff 5344 case 4:
d9bea114 5345// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5346 rn = "TraceBPC";
5347// break;
7a387fff 5348 default:
f31b035a 5349 goto cp0_unimplemented;
7a387fff 5350 }
873eb012
TS
5351 break;
5352 case 24:
7a387fff
TS
5353 switch (sel) {
5354 case 0:
f0b3f3ae 5355 /* EJTAG support */
7db13fae 5356 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5357 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5358 rn = "DEPC";
5359 break;
7a387fff 5360 default:
f31b035a 5361 goto cp0_unimplemented;
7a387fff 5362 }
873eb012 5363 break;
8c0fdd85 5364 case 25:
7a387fff
TS
5365 switch (sel) {
5366 case 0:
7db13fae 5367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5368 rn = "Performance0";
7a387fff
TS
5369 break;
5370 case 1:
d9bea114 5371// gen_helper_mfc0_performance1(arg);
2423f660
TS
5372 rn = "Performance1";
5373// break;
7a387fff 5374 case 2:
d9bea114 5375// gen_helper_mfc0_performance2(arg);
2423f660
TS
5376 rn = "Performance2";
5377// break;
7a387fff 5378 case 3:
d9bea114 5379// gen_helper_mfc0_performance3(arg);
2423f660
TS
5380 rn = "Performance3";
5381// break;
7a387fff 5382 case 4:
d9bea114 5383// gen_helper_mfc0_performance4(arg);
2423f660
TS
5384 rn = "Performance4";
5385// break;
7a387fff 5386 case 5:
d9bea114 5387// gen_helper_mfc0_performance5(arg);
2423f660
TS
5388 rn = "Performance5";
5389// break;
7a387fff 5390 case 6:
d9bea114 5391// gen_helper_mfc0_performance6(arg);
2423f660
TS
5392 rn = "Performance6";
5393// break;
7a387fff 5394 case 7:
d9bea114 5395// gen_helper_mfc0_performance7(arg);
2423f660
TS
5396 rn = "Performance7";
5397// break;
7a387fff 5398 default:
f31b035a 5399 goto cp0_unimplemented;
7a387fff 5400 }
8c0fdd85
TS
5401 break;
5402 case 26:
d9bea114 5403 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5404 rn = "ECC";
5405 break;
8c0fdd85 5406 case 27:
7a387fff 5407 switch (sel) {
7a387fff 5408 case 0 ... 3:
d9bea114 5409 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5410 rn = "CacheErr";
5411 break;
7a387fff 5412 default:
f31b035a 5413 goto cp0_unimplemented;
7a387fff 5414 }
8c0fdd85 5415 break;
873eb012
TS
5416 case 28:
5417 switch (sel) {
5418 case 0:
7a387fff
TS
5419 case 2:
5420 case 4:
5421 case 6:
7db13fae 5422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5423 rn = "TagLo";
5424 break;
5425 case 1:
7a387fff
TS
5426 case 3:
5427 case 5:
5428 case 7:
7db13fae 5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5430 rn = "DataLo";
5431 break;
5432 default:
f31b035a 5433 goto cp0_unimplemented;
873eb012
TS
5434 }
5435 break;
8c0fdd85 5436 case 29:
7a387fff
TS
5437 switch (sel) {
5438 case 0:
5439 case 2:
5440 case 4:
5441 case 6:
7db13fae 5442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5443 rn = "TagHi";
5444 break;
5445 case 1:
5446 case 3:
5447 case 5:
5448 case 7:
7db13fae 5449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5450 rn = "DataHi";
5451 break;
5452 default:
f31b035a 5453 goto cp0_unimplemented;
7a387fff 5454 }
8c0fdd85 5455 break;
873eb012 5456 case 30:
7a387fff
TS
5457 switch (sel) {
5458 case 0:
7db13fae 5459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5460 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5461 rn = "ErrorEPC";
5462 break;
7a387fff 5463 default:
f31b035a 5464 goto cp0_unimplemented;
7a387fff 5465 }
873eb012
TS
5466 break;
5467 case 31:
7a387fff
TS
5468 switch (sel) {
5469 case 0:
f0b3f3ae 5470 /* EJTAG support */
7db13fae 5471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5472 rn = "DESAVE";
5473 break;
e98c0d17 5474 case 2 ... 7:
f31b035a
LA
5475 CP0_CHECK(ctx->kscrexist & (1 << sel));
5476 tcg_gen_ld_tl(arg, cpu_env,
5477 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5478 tcg_gen_ext32s_tl(arg, arg);
5479 rn = "KScratch";
e98c0d17 5480 break;
7a387fff 5481 default:
f31b035a 5482 goto cp0_unimplemented;
7a387fff 5483 }
873eb012
TS
5484 break;
5485 default:
f31b035a 5486 goto cp0_unimplemented;
873eb012 5487 }
2abf314d 5488 (void)rn; /* avoid a compiler warning */
d12d51d5 5489 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5490 return;
5491
f31b035a 5492cp0_unimplemented:
d12d51d5 5493 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5494 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5495}
5496
d75c135e 5497static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5498{
7a387fff
TS
5499 const char *rn = "invalid";
5500
e189e748 5501 if (sel != 0)
d75c135e 5502 check_insn(ctx, ISA_MIPS32);
e189e748 5503
2e70f6ef
PB
5504 if (use_icount)
5505 gen_io_start();
5506
8c0fdd85
TS
5507 switch (reg) {
5508 case 0:
7a387fff
TS
5509 switch (sel) {
5510 case 0:
895c2d04 5511 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5512 rn = "Index";
5513 break;
5514 case 1:
f31b035a 5515 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5516 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5517 rn = "MVPControl";
ead9360e 5518 break;
7a387fff 5519 case 2:
f31b035a 5520 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5521 /* ignored */
7a387fff 5522 rn = "MVPConf0";
ead9360e 5523 break;
7a387fff 5524 case 3:
f31b035a 5525 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5526 /* ignored */
7a387fff 5527 rn = "MVPConf1";
ead9360e 5528 break;
7a387fff 5529 default:
f31b035a 5530 goto cp0_unimplemented;
7a387fff 5531 }
8c0fdd85
TS
5532 break;
5533 case 1:
7a387fff
TS
5534 switch (sel) {
5535 case 0:
2423f660 5536 /* ignored */
7a387fff 5537 rn = "Random";
2423f660 5538 break;
7a387fff 5539 case 1:
f31b035a 5540 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5541 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5542 rn = "VPEControl";
ead9360e 5543 break;
7a387fff 5544 case 2:
f31b035a 5545 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5546 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5547 rn = "VPEConf0";
ead9360e 5548 break;
7a387fff 5549 case 3:
f31b035a 5550 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5551 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5552 rn = "VPEConf1";
ead9360e 5553 break;
7a387fff 5554 case 4:
f31b035a 5555 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5556 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5557 rn = "YQMask";
ead9360e 5558 break;
7a387fff 5559 case 5:
f31b035a 5560 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5561 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5562 rn = "VPESchedule";
ead9360e 5563 break;
7a387fff 5564 case 6:
f31b035a 5565 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5566 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5567 rn = "VPEScheFBack";
ead9360e 5568 break;
7a387fff 5569 case 7:
f31b035a 5570 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5571 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5572 rn = "VPEOpt";
ead9360e 5573 break;
7a387fff 5574 default:
f31b035a 5575 goto cp0_unimplemented;
7a387fff 5576 }
8c0fdd85
TS
5577 break;
5578 case 2:
7a387fff
TS
5579 switch (sel) {
5580 case 0:
895c2d04 5581 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5582 rn = "EntryLo0";
5583 break;
7a387fff 5584 case 1:
f31b035a 5585 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5586 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5587 rn = "TCStatus";
ead9360e 5588 break;
7a387fff 5589 case 2:
f31b035a 5590 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5591 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5592 rn = "TCBind";
ead9360e 5593 break;
7a387fff 5594 case 3:
f31b035a 5595 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5596 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5597 rn = "TCRestart";
ead9360e 5598 break;
7a387fff 5599 case 4:
f31b035a 5600 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5601 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5602 rn = "TCHalt";
ead9360e 5603 break;
7a387fff 5604 case 5:
f31b035a 5605 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5606 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5607 rn = "TCContext";
ead9360e 5608 break;
7a387fff 5609 case 6:
f31b035a 5610 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5611 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5612 rn = "TCSchedule";
ead9360e 5613 break;
7a387fff 5614 case 7:
f31b035a 5615 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5616 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5617 rn = "TCScheFBack";
ead9360e 5618 break;
7a387fff 5619 default:
f31b035a 5620 goto cp0_unimplemented;
7a387fff 5621 }
8c0fdd85
TS
5622 break;
5623 case 3:
7a387fff
TS
5624 switch (sel) {
5625 case 0:
895c2d04 5626 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5627 rn = "EntryLo1";
5628 break;
7a387fff 5629 default:
f31b035a 5630 goto cp0_unimplemented;
876d4b07 5631 }
8c0fdd85
TS
5632 break;
5633 case 4:
7a387fff
TS
5634 switch (sel) {
5635 case 0:
895c2d04 5636 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5637 rn = "Context";
5638 break;
7a387fff 5639 case 1:
895c2d04 5640// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5641 rn = "ContextConfig";
f31b035a 5642 goto cp0_unimplemented;
2423f660 5643// break;
d279279e 5644 case 2:
f31b035a
LA
5645 CP0_CHECK(ctx->ulri);
5646 tcg_gen_st_tl(arg, cpu_env,
5647 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5648 rn = "UserLocal";
d279279e 5649 break;
7a387fff 5650 default:
f31b035a 5651 goto cp0_unimplemented;
876d4b07 5652 }
8c0fdd85
TS
5653 break;
5654 case 5:
7a387fff
TS
5655 switch (sel) {
5656 case 0:
895c2d04 5657 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5658 rn = "PageMask";
5659 break;
7a387fff 5660 case 1:
d75c135e 5661 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5662 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5663 rn = "PageGrain";
5664 break;
7a387fff 5665 default:
f31b035a 5666 goto cp0_unimplemented;
876d4b07 5667 }
8c0fdd85
TS
5668 break;
5669 case 6:
7a387fff
TS
5670 switch (sel) {
5671 case 0:
895c2d04 5672 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5673 rn = "Wired";
5674 break;
7a387fff 5675 case 1:
d75c135e 5676 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5677 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5678 rn = "SRSConf0";
ead9360e 5679 break;
7a387fff 5680 case 2:
d75c135e 5681 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5682 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5683 rn = "SRSConf1";
ead9360e 5684 break;
7a387fff 5685 case 3:
d75c135e 5686 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5687 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5688 rn = "SRSConf2";
ead9360e 5689 break;
7a387fff 5690 case 4:
d75c135e 5691 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5692 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5693 rn = "SRSConf3";
ead9360e 5694 break;
7a387fff 5695 case 5:
d75c135e 5696 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5697 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5698 rn = "SRSConf4";
ead9360e 5699 break;
7a387fff 5700 default:
f31b035a 5701 goto cp0_unimplemented;
876d4b07 5702 }
8c0fdd85
TS
5703 break;
5704 case 7:
7a387fff
TS
5705 switch (sel) {
5706 case 0:
d75c135e 5707 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5708 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5709 ctx->bstate = BS_STOP;
2423f660
TS
5710 rn = "HWREna";
5711 break;
7a387fff 5712 default:
f31b035a 5713 goto cp0_unimplemented;
876d4b07 5714 }
8c0fdd85
TS
5715 break;
5716 case 8:
aea14095
LA
5717 switch (sel) {
5718 case 0:
5719 /* ignored */
5720 rn = "BadVAddr";
5721 break;
5722 case 1:
5723 /* ignored */
5724 rn = "BadInstr";
5725 break;
5726 case 2:
5727 /* ignored */
5728 rn = "BadInstrP";
5729 break;
5730 default:
f31b035a 5731 goto cp0_unimplemented;
aea14095 5732 }
8c0fdd85
TS
5733 break;
5734 case 9:
7a387fff
TS
5735 switch (sel) {
5736 case 0:
895c2d04 5737 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5738 rn = "Count";
5739 break;
876d4b07 5740 /* 6,7 are implementation dependent */
7a387fff 5741 default:
f31b035a 5742 goto cp0_unimplemented;
876d4b07 5743 }
8c0fdd85
TS
5744 break;
5745 case 10:
7a387fff
TS
5746 switch (sel) {
5747 case 0:
895c2d04 5748 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5749 rn = "EntryHi";
5750 break;
7a387fff 5751 default:
f31b035a 5752 goto cp0_unimplemented;
876d4b07 5753 }
8c0fdd85
TS
5754 break;
5755 case 11:
7a387fff
TS
5756 switch (sel) {
5757 case 0:
895c2d04 5758 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5759 rn = "Compare";
5760 break;
5761 /* 6,7 are implementation dependent */
7a387fff 5762 default:
f31b035a 5763 goto cp0_unimplemented;
876d4b07 5764 }
8c0fdd85
TS
5765 break;
5766 case 12:
7a387fff
TS
5767 switch (sel) {
5768 case 0:
867abc7e 5769 save_cpu_state(ctx, 1);
895c2d04 5770 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5771 /* BS_STOP isn't good enough here, hflags may have changed. */
5772 gen_save_pc(ctx->pc + 4);
5773 ctx->bstate = BS_EXCP;
2423f660
TS
5774 rn = "Status";
5775 break;
7a387fff 5776 case 1:
d75c135e 5777 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5778 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5779 /* Stop translation as we may have switched the execution mode */
5780 ctx->bstate = BS_STOP;
2423f660
TS
5781 rn = "IntCtl";
5782 break;
7a387fff 5783 case 2:
d75c135e 5784 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5785 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5786 /* Stop translation as we may have switched the execution mode */
5787 ctx->bstate = BS_STOP;
2423f660
TS
5788 rn = "SRSCtl";
5789 break;
7a387fff 5790 case 3:
d75c135e 5791 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5792 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5793 /* Stop translation as we may have switched the execution mode */
5794 ctx->bstate = BS_STOP;
2423f660 5795 rn = "SRSMap";
fd88b6ab 5796 break;
7a387fff 5797 default:
f31b035a 5798 goto cp0_unimplemented;
876d4b07 5799 }
8c0fdd85
TS
5800 break;
5801 case 13:
7a387fff
TS
5802 switch (sel) {
5803 case 0:
867abc7e 5804 save_cpu_state(ctx, 1);
895c2d04 5805 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5806 rn = "Cause";
5807 break;
7a387fff 5808 default:
f31b035a 5809 goto cp0_unimplemented;
876d4b07 5810 }
8c0fdd85
TS
5811 break;
5812 case 14:
7a387fff
TS
5813 switch (sel) {
5814 case 0:
7db13fae 5815 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5816 rn = "EPC";
5817 break;
7a387fff 5818 default:
f31b035a 5819 goto cp0_unimplemented;
876d4b07 5820 }
8c0fdd85
TS
5821 break;
5822 case 15:
7a387fff
TS
5823 switch (sel) {
5824 case 0:
2423f660
TS
5825 /* ignored */
5826 rn = "PRid";
5827 break;
7a387fff 5828 case 1:
d75c135e 5829 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5830 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5831 rn = "EBase";
5832 break;
7a387fff 5833 default:
f31b035a 5834 goto cp0_unimplemented;
1579a72e 5835 }
8c0fdd85
TS
5836 break;
5837 case 16:
5838 switch (sel) {
5839 case 0:
895c2d04 5840 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5841 rn = "Config";
2423f660
TS
5842 /* Stop translation as we may have switched the execution mode */
5843 ctx->bstate = BS_STOP;
7a387fff
TS
5844 break;
5845 case 1:
e397ee33 5846 /* ignored, read only */
7a387fff
TS
5847 rn = "Config1";
5848 break;
5849 case 2:
895c2d04 5850 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5851 rn = "Config2";
2423f660
TS
5852 /* Stop translation as we may have switched the execution mode */
5853 ctx->bstate = BS_STOP;
8c0fdd85 5854 break;
7a387fff 5855 case 3:
90f12d73 5856 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 5857 rn = "Config3";
90f12d73
MR
5858 /* Stop translation as we may have switched the execution mode */
5859 ctx->bstate = BS_STOP;
7a387fff 5860 break;
b4160af1
PJ
5861 case 4:
5862 gen_helper_mtc0_config4(cpu_env, arg);
5863 rn = "Config4";
5864 ctx->bstate = BS_STOP;
5865 break;
b4dd99a3
PJ
5866 case 5:
5867 gen_helper_mtc0_config5(cpu_env, arg);
5868 rn = "Config5";
5869 /* Stop translation as we may have switched the execution mode */
5870 ctx->bstate = BS_STOP;
5871 break;
e397ee33
TS
5872 /* 6,7 are implementation dependent */
5873 case 6:
5874 /* ignored */
5875 rn = "Config6";
5876 break;
5877 case 7:
5878 /* ignored */
5879 rn = "Config7";
5880 break;
8c0fdd85
TS
5881 default:
5882 rn = "Invalid config selector";
f31b035a 5883 goto cp0_unimplemented;
8c0fdd85
TS
5884 }
5885 break;
5886 case 17:
7a387fff
TS
5887 switch (sel) {
5888 case 0:
895c2d04 5889 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5890 rn = "LLAddr";
5891 break;
7a387fff 5892 default:
f31b035a 5893 goto cp0_unimplemented;
7a387fff 5894 }
8c0fdd85
TS
5895 break;
5896 case 18:
7a387fff 5897 switch (sel) {
fd88b6ab 5898 case 0 ... 7:
895c2d04 5899 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5900 rn = "WatchLo";
5901 break;
7a387fff 5902 default:
f31b035a 5903 goto cp0_unimplemented;
7a387fff 5904 }
8c0fdd85
TS
5905 break;
5906 case 19:
7a387fff 5907 switch (sel) {
fd88b6ab 5908 case 0 ... 7:
895c2d04 5909 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5910 rn = "WatchHi";
5911 break;
7a387fff 5912 default:
f31b035a 5913 goto cp0_unimplemented;
7a387fff 5914 }
8c0fdd85
TS
5915 break;
5916 case 20:
7a387fff
TS
5917 switch (sel) {
5918 case 0:
d26bc211 5919#if defined(TARGET_MIPS64)
d75c135e 5920 check_insn(ctx, ISA_MIPS3);
895c2d04 5921 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5922 rn = "XContext";
5923 break;
703eaf37 5924#endif
7a387fff 5925 default:
f31b035a 5926 goto cp0_unimplemented;
7a387fff 5927 }
8c0fdd85
TS
5928 break;
5929 case 21:
7a387fff 5930 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5931 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5932 switch (sel) {
5933 case 0:
895c2d04 5934 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5935 rn = "Framemask";
5936 break;
7a387fff 5937 default:
f31b035a 5938 goto cp0_unimplemented;
7a387fff
TS
5939 }
5940 break;
8c0fdd85 5941 case 22:
7a387fff
TS
5942 /* ignored */
5943 rn = "Diagnostic"; /* implementation dependent */
2423f660 5944 break;
8c0fdd85 5945 case 23:
7a387fff
TS
5946 switch (sel) {
5947 case 0:
895c2d04 5948 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5949 /* BS_STOP isn't good enough here, hflags may have changed. */
5950 gen_save_pc(ctx->pc + 4);
5951 ctx->bstate = BS_EXCP;
2423f660
TS
5952 rn = "Debug";
5953 break;
7a387fff 5954 case 1:
895c2d04 5955// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5956 rn = "TraceControl";
8487327a
TS
5957 /* Stop translation as we may have switched the execution mode */
5958 ctx->bstate = BS_STOP;
2423f660 5959// break;
7a387fff 5960 case 2:
895c2d04 5961// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5962 rn = "TraceControl2";
8487327a
TS
5963 /* Stop translation as we may have switched the execution mode */
5964 ctx->bstate = BS_STOP;
2423f660 5965// break;
7a387fff 5966 case 3:
8487327a
TS
5967 /* Stop translation as we may have switched the execution mode */
5968 ctx->bstate = BS_STOP;
895c2d04 5969// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5970 rn = "UserTraceData";
8487327a
TS
5971 /* Stop translation as we may have switched the execution mode */
5972 ctx->bstate = BS_STOP;
2423f660 5973// break;
7a387fff 5974 case 4:
895c2d04 5975// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5976 /* Stop translation as we may have switched the execution mode */
5977 ctx->bstate = BS_STOP;
2423f660
TS
5978 rn = "TraceBPC";
5979// break;
7a387fff 5980 default:
f31b035a 5981 goto cp0_unimplemented;
7a387fff 5982 }
8c0fdd85
TS
5983 break;
5984 case 24:
7a387fff
TS
5985 switch (sel) {
5986 case 0:
f1aa6320 5987 /* EJTAG support */
7db13fae 5988 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5989 rn = "DEPC";
5990 break;
7a387fff 5991 default:
f31b035a 5992 goto cp0_unimplemented;
7a387fff 5993 }
8c0fdd85
TS
5994 break;
5995 case 25:
7a387fff
TS
5996 switch (sel) {
5997 case 0:
895c2d04 5998 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5999 rn = "Performance0";
6000 break;
7a387fff 6001 case 1:
d9bea114 6002// gen_helper_mtc0_performance1(arg);
2423f660
TS
6003 rn = "Performance1";
6004// break;
7a387fff 6005 case 2:
d9bea114 6006// gen_helper_mtc0_performance2(arg);
2423f660
TS
6007 rn = "Performance2";
6008// break;
7a387fff 6009 case 3:
d9bea114 6010// gen_helper_mtc0_performance3(arg);
2423f660
TS
6011 rn = "Performance3";
6012// break;
7a387fff 6013 case 4:
d9bea114 6014// gen_helper_mtc0_performance4(arg);
2423f660
TS
6015 rn = "Performance4";
6016// break;
7a387fff 6017 case 5:
d9bea114 6018// gen_helper_mtc0_performance5(arg);
2423f660
TS
6019 rn = "Performance5";
6020// break;
7a387fff 6021 case 6:
d9bea114 6022// gen_helper_mtc0_performance6(arg);
2423f660
TS
6023 rn = "Performance6";
6024// break;
7a387fff 6025 case 7:
d9bea114 6026// gen_helper_mtc0_performance7(arg);
2423f660
TS
6027 rn = "Performance7";
6028// break;
7a387fff 6029 default:
f31b035a 6030 goto cp0_unimplemented;
7a387fff 6031 }
8c0fdd85
TS
6032 break;
6033 case 26:
2423f660 6034 /* ignored */
8c0fdd85 6035 rn = "ECC";
2423f660 6036 break;
8c0fdd85 6037 case 27:
7a387fff
TS
6038 switch (sel) {
6039 case 0 ... 3:
2423f660
TS
6040 /* ignored */
6041 rn = "CacheErr";
6042 break;
7a387fff 6043 default:
f31b035a 6044 goto cp0_unimplemented;
7a387fff 6045 }
8c0fdd85
TS
6046 break;
6047 case 28:
6048 switch (sel) {
6049 case 0:
7a387fff
TS
6050 case 2:
6051 case 4:
6052 case 6:
895c2d04 6053 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6054 rn = "TagLo";
6055 break;
7a387fff
TS
6056 case 1:
6057 case 3:
6058 case 5:
6059 case 7:
895c2d04 6060 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6061 rn = "DataLo";
6062 break;
8c0fdd85 6063 default:
f31b035a 6064 goto cp0_unimplemented;
8c0fdd85
TS
6065 }
6066 break;
6067 case 29:
7a387fff
TS
6068 switch (sel) {
6069 case 0:
6070 case 2:
6071 case 4:
6072 case 6:
895c2d04 6073 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6074 rn = "TagHi";
6075 break;
6076 case 1:
6077 case 3:
6078 case 5:
6079 case 7:
895c2d04 6080 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6081 rn = "DataHi";
6082 break;
6083 default:
6084 rn = "invalid sel";
f31b035a 6085 goto cp0_unimplemented;
7a387fff 6086 }
8c0fdd85
TS
6087 break;
6088 case 30:
7a387fff
TS
6089 switch (sel) {
6090 case 0:
7db13fae 6091 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6092 rn = "ErrorEPC";
6093 break;
7a387fff 6094 default:
f31b035a 6095 goto cp0_unimplemented;
7a387fff 6096 }
8c0fdd85
TS
6097 break;
6098 case 31:
7a387fff
TS
6099 switch (sel) {
6100 case 0:
f1aa6320 6101 /* EJTAG support */
7db13fae 6102 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6103 rn = "DESAVE";
6104 break;
e98c0d17 6105 case 2 ... 7:
f31b035a
LA
6106 CP0_CHECK(ctx->kscrexist & (1 << sel));
6107 tcg_gen_st_tl(arg, cpu_env,
6108 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6109 rn = "KScratch";
e98c0d17 6110 break;
7a387fff 6111 default:
f31b035a 6112 goto cp0_unimplemented;
7a387fff 6113 }
2423f660
TS
6114 /* Stop translation as we may have switched the execution mode */
6115 ctx->bstate = BS_STOP;
8c0fdd85
TS
6116 break;
6117 default:
f31b035a 6118 goto cp0_unimplemented;
8c0fdd85 6119 }
2abf314d 6120 (void)rn; /* avoid a compiler warning */
d12d51d5 6121 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6122 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6123 if (use_icount) {
6124 gen_io_end();
6125 ctx->bstate = BS_STOP;
6126 }
8c0fdd85
TS
6127 return;
6128
f31b035a 6129cp0_unimplemented:
d12d51d5 6130 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6131}
6132
d26bc211 6133#if defined(TARGET_MIPS64)
d75c135e 6134static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6135{
6136 const char *rn = "invalid";
6137
e189e748 6138 if (sel != 0)
d75c135e 6139 check_insn(ctx, ISA_MIPS64);
e189e748 6140
9c2149c8
TS
6141 switch (reg) {
6142 case 0:
6143 switch (sel) {
6144 case 0:
7db13fae 6145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6146 rn = "Index";
6147 break;
6148 case 1:
f31b035a 6149 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6150 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6151 rn = "MVPControl";
ead9360e 6152 break;
9c2149c8 6153 case 2:
f31b035a 6154 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6155 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6156 rn = "MVPConf0";
ead9360e 6157 break;
9c2149c8 6158 case 3:
f31b035a 6159 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6160 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6161 rn = "MVPConf1";
ead9360e 6162 break;
9c2149c8 6163 default:
f31b035a 6164 goto cp0_unimplemented;
9c2149c8
TS
6165 }
6166 break;
6167 case 1:
6168 switch (sel) {
6169 case 0:
f31b035a 6170 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6171 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6172 rn = "Random";
2423f660 6173 break;
9c2149c8 6174 case 1:
f31b035a 6175 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6176 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6177 rn = "VPEControl";
ead9360e 6178 break;
9c2149c8 6179 case 2:
f31b035a 6180 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6182 rn = "VPEConf0";
ead9360e 6183 break;
9c2149c8 6184 case 3:
f31b035a 6185 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6186 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6187 rn = "VPEConf1";
ead9360e 6188 break;
9c2149c8 6189 case 4:
f31b035a 6190 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6191 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6192 rn = "YQMask";
ead9360e 6193 break;
9c2149c8 6194 case 5:
f31b035a 6195 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6196 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6197 rn = "VPESchedule";
ead9360e 6198 break;
9c2149c8 6199 case 6:
f31b035a 6200 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6201 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6202 rn = "VPEScheFBack";
ead9360e 6203 break;
9c2149c8 6204 case 7:
f31b035a 6205 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6206 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6207 rn = "VPEOpt";
ead9360e 6208 break;
9c2149c8 6209 default:
f31b035a 6210 goto cp0_unimplemented;
9c2149c8
TS
6211 }
6212 break;
6213 case 2:
6214 switch (sel) {
6215 case 0:
7db13fae 6216 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6217 rn = "EntryLo0";
6218 break;
9c2149c8 6219 case 1:
f31b035a 6220 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6221 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6222 rn = "TCStatus";
ead9360e 6223 break;
9c2149c8 6224 case 2:
f31b035a 6225 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6226 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6227 rn = "TCBind";
ead9360e 6228 break;
9c2149c8 6229 case 3:
f31b035a 6230 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6231 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6232 rn = "TCRestart";
ead9360e 6233 break;
9c2149c8 6234 case 4:
f31b035a 6235 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6236 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6237 rn = "TCHalt";
ead9360e 6238 break;
9c2149c8 6239 case 5:
f31b035a 6240 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6241 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6242 rn = "TCContext";
ead9360e 6243 break;
9c2149c8 6244 case 6:
f31b035a 6245 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6246 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6247 rn = "TCSchedule";
ead9360e 6248 break;
9c2149c8 6249 case 7:
f31b035a 6250 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6251 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6252 rn = "TCScheFBack";
ead9360e 6253 break;
9c2149c8 6254 default:
f31b035a 6255 goto cp0_unimplemented;
9c2149c8
TS
6256 }
6257 break;
6258 case 3:
6259 switch (sel) {
6260 case 0:
7db13fae 6261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6262 rn = "EntryLo1";
6263 break;
9c2149c8 6264 default:
f31b035a 6265 goto cp0_unimplemented;
1579a72e 6266 }
9c2149c8
TS
6267 break;
6268 case 4:
6269 switch (sel) {
6270 case 0:
7db13fae 6271 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6272 rn = "Context";
6273 break;
9c2149c8 6274 case 1:
d9bea114 6275// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6276 rn = "ContextConfig";
f31b035a 6277 goto cp0_unimplemented;
2423f660 6278// break;
d279279e 6279 case 2:
f31b035a
LA
6280 CP0_CHECK(ctx->ulri);
6281 tcg_gen_ld_tl(arg, cpu_env,
6282 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6283 rn = "UserLocal";
d279279e 6284 break;
9c2149c8 6285 default:
f31b035a 6286 goto cp0_unimplemented;
876d4b07 6287 }
9c2149c8
TS
6288 break;
6289 case 5:
6290 switch (sel) {
6291 case 0:
7db13fae 6292 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6293 rn = "PageMask";
6294 break;
9c2149c8 6295 case 1:
d75c135e 6296 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6298 rn = "PageGrain";
6299 break;
9c2149c8 6300 default:
f31b035a 6301 goto cp0_unimplemented;
876d4b07 6302 }
9c2149c8
TS
6303 break;
6304 case 6:
6305 switch (sel) {
6306 case 0:
7db13fae 6307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6308 rn = "Wired";
6309 break;
9c2149c8 6310 case 1:
d75c135e 6311 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6313 rn = "SRSConf0";
ead9360e 6314 break;
9c2149c8 6315 case 2:
d75c135e 6316 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6318 rn = "SRSConf1";
ead9360e 6319 break;
9c2149c8 6320 case 3:
d75c135e 6321 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6323 rn = "SRSConf2";
ead9360e 6324 break;
9c2149c8 6325 case 4:
d75c135e 6326 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6328 rn = "SRSConf3";
ead9360e 6329 break;
9c2149c8 6330 case 5:
d75c135e 6331 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6333 rn = "SRSConf4";
ead9360e 6334 break;
9c2149c8 6335 default:
f31b035a 6336 goto cp0_unimplemented;
876d4b07 6337 }
9c2149c8
TS
6338 break;
6339 case 7:
6340 switch (sel) {
6341 case 0:
d75c135e 6342 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6344 rn = "HWREna";
6345 break;
9c2149c8 6346 default:
f31b035a 6347 goto cp0_unimplemented;
876d4b07 6348 }
9c2149c8
TS
6349 break;
6350 case 8:
6351 switch (sel) {
6352 case 0:
7db13fae 6353 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6354 rn = "BadVAddr";
2423f660 6355 break;
aea14095 6356 case 1:
f31b035a
LA
6357 CP0_CHECK(ctx->bi);
6358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6359 rn = "BadInstr";
aea14095
LA
6360 break;
6361 case 2:
f31b035a
LA
6362 CP0_CHECK(ctx->bp);
6363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6364 rn = "BadInstrP";
aea14095 6365 break;
9c2149c8 6366 default:
f31b035a 6367 goto cp0_unimplemented;
876d4b07 6368 }
9c2149c8
TS
6369 break;
6370 case 9:
6371 switch (sel) {
6372 case 0:
2e70f6ef
PB
6373 /* Mark as an IO operation because we read the time. */
6374 if (use_icount)
6375 gen_io_start();
895c2d04 6376 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
6377 if (use_icount) {
6378 gen_io_end();
2e70f6ef 6379 }
55807224
EI
6380 /* Break the TB to be able to take timer interrupts immediately
6381 after reading count. */
6382 ctx->bstate = BS_STOP;
2423f660
TS
6383 rn = "Count";
6384 break;
6385 /* 6,7 are implementation dependent */
9c2149c8 6386 default:
f31b035a 6387 goto cp0_unimplemented;
876d4b07 6388 }
9c2149c8
TS
6389 break;
6390 case 10:
6391 switch (sel) {
6392 case 0:
7db13fae 6393 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6394 rn = "EntryHi";
6395 break;
9c2149c8 6396 default:
f31b035a 6397 goto cp0_unimplemented;
876d4b07 6398 }
9c2149c8
TS
6399 break;
6400 case 11:
6401 switch (sel) {
6402 case 0:
7db13fae 6403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6404 rn = "Compare";
6405 break;
876d4b07 6406 /* 6,7 are implementation dependent */
9c2149c8 6407 default:
f31b035a 6408 goto cp0_unimplemented;
876d4b07 6409 }
9c2149c8
TS
6410 break;
6411 case 12:
6412 switch (sel) {
6413 case 0:
7db13fae 6414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6415 rn = "Status";
6416 break;
9c2149c8 6417 case 1:
d75c135e 6418 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6420 rn = "IntCtl";
6421 break;
9c2149c8 6422 case 2:
d75c135e 6423 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6425 rn = "SRSCtl";
6426 break;
9c2149c8 6427 case 3:
d75c135e 6428 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6430 rn = "SRSMap";
6431 break;
9c2149c8 6432 default:
f31b035a 6433 goto cp0_unimplemented;
876d4b07 6434 }
9c2149c8
TS
6435 break;
6436 case 13:
6437 switch (sel) {
6438 case 0:
7db13fae 6439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6440 rn = "Cause";
6441 break;
9c2149c8 6442 default:
f31b035a 6443 goto cp0_unimplemented;
876d4b07 6444 }
9c2149c8
TS
6445 break;
6446 case 14:
6447 switch (sel) {
6448 case 0:
7db13fae 6449 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6450 rn = "EPC";
6451 break;
9c2149c8 6452 default:
f31b035a 6453 goto cp0_unimplemented;
876d4b07 6454 }
9c2149c8
TS
6455 break;
6456 case 15:
6457 switch (sel) {
6458 case 0:
7db13fae 6459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6460 rn = "PRid";
6461 break;
9c2149c8 6462 case 1:
d75c135e 6463 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6465 rn = "EBase";
6466 break;
9c2149c8 6467 default:
f31b035a 6468 goto cp0_unimplemented;
876d4b07 6469 }
9c2149c8
TS
6470 break;
6471 case 16:
6472 switch (sel) {
6473 case 0:
7db13fae 6474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6475 rn = "Config";
6476 break;
6477 case 1:
7db13fae 6478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6479 rn = "Config1";
6480 break;
6481 case 2:
7db13fae 6482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6483 rn = "Config2";
6484 break;
6485 case 3:
7db13fae 6486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6487 rn = "Config3";
6488 break;
faf1f68b
LA
6489 case 4:
6490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6491 rn = "Config4";
6492 break;
6493 case 5:
6494 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6495 rn = "Config5";
6496 break;
9c2149c8 6497 /* 6,7 are implementation dependent */
f0b3f3ae 6498 case 6:
7db13fae 6499 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6500 rn = "Config6";
6501 break;
6502 case 7:
7db13fae 6503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6504 rn = "Config7";
6505 break;
9c2149c8 6506 default:
f31b035a 6507 goto cp0_unimplemented;
9c2149c8
TS
6508 }
6509 break;
6510 case 17:
6511 switch (sel) {
6512 case 0:
895c2d04 6513 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6514 rn = "LLAddr";
6515 break;
9c2149c8 6516 default:
f31b035a 6517 goto cp0_unimplemented;
9c2149c8
TS
6518 }
6519 break;
6520 case 18:
6521 switch (sel) {
fd88b6ab 6522 case 0 ... 7:
895c2d04 6523 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6524 rn = "WatchLo";
6525 break;
9c2149c8 6526 default:
f31b035a 6527 goto cp0_unimplemented;
9c2149c8
TS
6528 }
6529 break;
6530 case 19:
6531 switch (sel) {
fd88b6ab 6532 case 0 ... 7:
895c2d04 6533 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6534 rn = "WatchHi";
6535 break;
9c2149c8 6536 default:
f31b035a 6537 goto cp0_unimplemented;
9c2149c8
TS
6538 }
6539 break;
6540 case 20:
6541 switch (sel) {
6542 case 0:
d75c135e 6543 check_insn(ctx, ISA_MIPS3);
7db13fae 6544 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6545 rn = "XContext";
6546 break;
9c2149c8 6547 default:
f31b035a 6548 goto cp0_unimplemented;
9c2149c8
TS
6549 }
6550 break;
6551 case 21:
6552 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6553 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6554 switch (sel) {
6555 case 0:
7db13fae 6556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6557 rn = "Framemask";
6558 break;
9c2149c8 6559 default:
f31b035a 6560 goto cp0_unimplemented;
9c2149c8
TS
6561 }
6562 break;
6563 case 22:
d9bea114 6564 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6565 rn = "'Diagnostic"; /* implementation dependent */
6566 break;
9c2149c8
TS
6567 case 23:
6568 switch (sel) {
6569 case 0:
895c2d04 6570 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6571 rn = "Debug";
6572 break;
9c2149c8 6573 case 1:
895c2d04 6574// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6575 rn = "TraceControl";
6576// break;
9c2149c8 6577 case 2:
895c2d04 6578// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6579 rn = "TraceControl2";
6580// break;
9c2149c8 6581 case 3:
895c2d04 6582// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6583 rn = "UserTraceData";
6584// break;
9c2149c8 6585 case 4:
895c2d04 6586// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6587 rn = "TraceBPC";
6588// break;
9c2149c8 6589 default:
f31b035a 6590 goto cp0_unimplemented;
9c2149c8
TS
6591 }
6592 break;
6593 case 24:
6594 switch (sel) {
6595 case 0:
f0b3f3ae 6596 /* EJTAG support */
7db13fae 6597 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6598 rn = "DEPC";
6599 break;
9c2149c8 6600 default:
f31b035a 6601 goto cp0_unimplemented;
9c2149c8
TS
6602 }
6603 break;
6604 case 25:
6605 switch (sel) {
6606 case 0:
7db13fae 6607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6608 rn = "Performance0";
9c2149c8
TS
6609 break;
6610 case 1:
d9bea114 6611// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6612 rn = "Performance1";
6613// break;
9c2149c8 6614 case 2:
d9bea114 6615// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6616 rn = "Performance2";
6617// break;
9c2149c8 6618 case 3:
d9bea114 6619// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6620 rn = "Performance3";
6621// break;
9c2149c8 6622 case 4:
d9bea114 6623// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6624 rn = "Performance4";
6625// break;
9c2149c8 6626 case 5:
d9bea114 6627// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6628 rn = "Performance5";
6629// break;
9c2149c8 6630 case 6:
d9bea114 6631// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6632 rn = "Performance6";
6633// break;
9c2149c8 6634 case 7:
d9bea114 6635// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6636 rn = "Performance7";
6637// break;
9c2149c8 6638 default:
f31b035a 6639 goto cp0_unimplemented;
9c2149c8
TS
6640 }
6641 break;
6642 case 26:
d9bea114 6643 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6644 rn = "ECC";
6645 break;
9c2149c8
TS
6646 case 27:
6647 switch (sel) {
6648 /* ignored */
6649 case 0 ... 3:
d9bea114 6650 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6651 rn = "CacheErr";
6652 break;
9c2149c8 6653 default:
f31b035a 6654 goto cp0_unimplemented;
9c2149c8
TS
6655 }
6656 break;
6657 case 28:
6658 switch (sel) {
6659 case 0:
6660 case 2:
6661 case 4:
6662 case 6:
7db13fae 6663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6664 rn = "TagLo";
6665 break;
6666 case 1:
6667 case 3:
6668 case 5:
6669 case 7:
7db13fae 6670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6671 rn = "DataLo";
6672 break;
6673 default:
f31b035a 6674 goto cp0_unimplemented;
9c2149c8
TS
6675 }
6676 break;
6677 case 29:
6678 switch (sel) {
6679 case 0:
6680 case 2:
6681 case 4:
6682 case 6:
7db13fae 6683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6684 rn = "TagHi";
6685 break;
6686 case 1:
6687 case 3:
6688 case 5:
6689 case 7:
7db13fae 6690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6691 rn = "DataHi";
6692 break;
6693 default:
f31b035a 6694 goto cp0_unimplemented;
9c2149c8
TS
6695 }
6696 break;
6697 case 30:
6698 switch (sel) {
6699 case 0:
7db13fae 6700 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6701 rn = "ErrorEPC";
6702 break;
9c2149c8 6703 default:
f31b035a 6704 goto cp0_unimplemented;
9c2149c8
TS
6705 }
6706 break;
6707 case 31:
6708 switch (sel) {
6709 case 0:
f0b3f3ae 6710 /* EJTAG support */
7db13fae 6711 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6712 rn = "DESAVE";
6713 break;
e98c0d17 6714 case 2 ... 7:
f31b035a
LA
6715 CP0_CHECK(ctx->kscrexist & (1 << sel));
6716 tcg_gen_ld_tl(arg, cpu_env,
6717 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6718 rn = "KScratch";
e98c0d17 6719 break;
9c2149c8 6720 default:
f31b035a 6721 goto cp0_unimplemented;
9c2149c8
TS
6722 }
6723 break;
6724 default:
f31b035a 6725 goto cp0_unimplemented;
9c2149c8 6726 }
2abf314d 6727 (void)rn; /* avoid a compiler warning */
d12d51d5 6728 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6729 return;
6730
f31b035a 6731cp0_unimplemented:
d12d51d5 6732 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 6733 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
6734}
6735
d75c135e 6736static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6737{
6738 const char *rn = "invalid";
6739
e189e748 6740 if (sel != 0)
d75c135e 6741 check_insn(ctx, ISA_MIPS64);
e189e748 6742
2e70f6ef
PB
6743 if (use_icount)
6744 gen_io_start();
6745
9c2149c8
TS
6746 switch (reg) {
6747 case 0:
6748 switch (sel) {
6749 case 0:
895c2d04 6750 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6751 rn = "Index";
6752 break;
6753 case 1:
f31b035a 6754 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6755 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6756 rn = "MVPControl";
ead9360e 6757 break;
9c2149c8 6758 case 2:
f31b035a 6759 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6760 /* ignored */
9c2149c8 6761 rn = "MVPConf0";
ead9360e 6762 break;
9c2149c8 6763 case 3:
f31b035a 6764 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6765 /* ignored */
9c2149c8 6766 rn = "MVPConf1";
ead9360e 6767 break;
9c2149c8 6768 default:
f31b035a 6769 goto cp0_unimplemented;
9c2149c8
TS
6770 }
6771 break;
6772 case 1:
6773 switch (sel) {
6774 case 0:
2423f660 6775 /* ignored */
9c2149c8 6776 rn = "Random";
2423f660 6777 break;
9c2149c8 6778 case 1:
f31b035a 6779 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6780 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6781 rn = "VPEControl";
ead9360e 6782 break;
9c2149c8 6783 case 2:
f31b035a 6784 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6785 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6786 rn = "VPEConf0";
ead9360e 6787 break;
9c2149c8 6788 case 3:
f31b035a 6789 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6790 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6791 rn = "VPEConf1";
ead9360e 6792 break;
9c2149c8 6793 case 4:
f31b035a 6794 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6795 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6796 rn = "YQMask";
ead9360e 6797 break;
9c2149c8 6798 case 5:
f31b035a 6799 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6800 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6801 rn = "VPESchedule";
ead9360e 6802 break;
9c2149c8 6803 case 6:
f31b035a 6804 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6805 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6806 rn = "VPEScheFBack";
ead9360e 6807 break;
9c2149c8 6808 case 7:
f31b035a 6809 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6810 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6811 rn = "VPEOpt";
ead9360e 6812 break;
9c2149c8 6813 default:
f31b035a 6814 goto cp0_unimplemented;
9c2149c8
TS
6815 }
6816 break;
6817 case 2:
6818 switch (sel) {
6819 case 0:
7207c7f9 6820 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
6821 rn = "EntryLo0";
6822 break;
9c2149c8 6823 case 1:
f31b035a 6824 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6825 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6826 rn = "TCStatus";
ead9360e 6827 break;
9c2149c8 6828 case 2:
f31b035a 6829 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6830 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6831 rn = "TCBind";
ead9360e 6832 break;
9c2149c8 6833 case 3:
f31b035a 6834 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6835 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6836 rn = "TCRestart";
ead9360e 6837 break;
9c2149c8 6838 case 4:
f31b035a 6839 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6840 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6841 rn = "TCHalt";
ead9360e 6842 break;
9c2149c8 6843 case 5:
f31b035a 6844 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6845 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6846 rn = "TCContext";
ead9360e 6847 break;
9c2149c8 6848 case 6:
f31b035a 6849 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6850 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6851 rn = "TCSchedule";
ead9360e 6852 break;
9c2149c8 6853 case 7:
f31b035a 6854 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6855 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6856 rn = "TCScheFBack";
ead9360e 6857 break;
9c2149c8 6858 default:
f31b035a 6859 goto cp0_unimplemented;
9c2149c8
TS
6860 }
6861 break;
6862 case 3:
6863 switch (sel) {
6864 case 0:
7207c7f9 6865 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
6866 rn = "EntryLo1";
6867 break;
9c2149c8 6868 default:
f31b035a 6869 goto cp0_unimplemented;
876d4b07 6870 }
9c2149c8
TS
6871 break;
6872 case 4:
6873 switch (sel) {
6874 case 0:
895c2d04 6875 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6876 rn = "Context";
6877 break;
9c2149c8 6878 case 1:
895c2d04 6879// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6880 rn = "ContextConfig";
f31b035a 6881 goto cp0_unimplemented;
2423f660 6882// break;
d279279e 6883 case 2:
f31b035a
LA
6884 CP0_CHECK(ctx->ulri);
6885 tcg_gen_st_tl(arg, cpu_env,
6886 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6887 rn = "UserLocal";
d279279e 6888 break;
9c2149c8 6889 default:
f31b035a 6890 goto cp0_unimplemented;
876d4b07 6891 }
9c2149c8
TS
6892 break;
6893 case 5:
6894 switch (sel) {
6895 case 0:
895c2d04 6896 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6897 rn = "PageMask";
6898 break;
9c2149c8 6899 case 1:
d75c135e 6900 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6901 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6902 rn = "PageGrain";
6903 break;
9c2149c8 6904 default:
f31b035a 6905 goto cp0_unimplemented;
876d4b07 6906 }
9c2149c8
TS
6907 break;
6908 case 6:
6909 switch (sel) {
6910 case 0:
895c2d04 6911 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6912 rn = "Wired";
6913 break;
9c2149c8 6914 case 1:
d75c135e 6915 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6916 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6917 rn = "SRSConf0";
ead9360e 6918 break;
9c2149c8 6919 case 2:
d75c135e 6920 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6921 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6922 rn = "SRSConf1";
ead9360e 6923 break;
9c2149c8 6924 case 3:
d75c135e 6925 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6926 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6927 rn = "SRSConf2";
ead9360e 6928 break;
9c2149c8 6929 case 4:
d75c135e 6930 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6931 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6932 rn = "SRSConf3";
ead9360e 6933 break;
9c2149c8 6934 case 5:
d75c135e 6935 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6936 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6937 rn = "SRSConf4";
ead9360e 6938 break;
9c2149c8 6939 default:
f31b035a 6940 goto cp0_unimplemented;
876d4b07 6941 }
9c2149c8
TS
6942 break;
6943 case 7:
6944 switch (sel) {
6945 case 0:
d75c135e 6946 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6947 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6948 ctx->bstate = BS_STOP;
2423f660
TS
6949 rn = "HWREna";
6950 break;
9c2149c8 6951 default:
f31b035a 6952 goto cp0_unimplemented;
876d4b07 6953 }
9c2149c8
TS
6954 break;
6955 case 8:
aea14095
LA
6956 switch (sel) {
6957 case 0:
6958 /* ignored */
6959 rn = "BadVAddr";
6960 break;
6961 case 1:
6962 /* ignored */
6963 rn = "BadInstr";
6964 break;
6965 case 2:
6966 /* ignored */
6967 rn = "BadInstrP";
6968 break;
6969 default:
f31b035a 6970 goto cp0_unimplemented;
aea14095 6971 }
9c2149c8
TS
6972 break;
6973 case 9:
6974 switch (sel) {
6975 case 0:
895c2d04 6976 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6977 rn = "Count";
6978 break;
876d4b07 6979 /* 6,7 are implementation dependent */
9c2149c8 6980 default:
f31b035a 6981 goto cp0_unimplemented;
876d4b07
TS
6982 }
6983 /* Stop translation as we may have switched the execution mode */
6984 ctx->bstate = BS_STOP;
9c2149c8
TS
6985 break;
6986 case 10:
6987 switch (sel) {
6988 case 0:
895c2d04 6989 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6990 rn = "EntryHi";
6991 break;
9c2149c8 6992 default:
f31b035a 6993 goto cp0_unimplemented;
876d4b07 6994 }
9c2149c8
TS
6995 break;
6996 case 11:
6997 switch (sel) {
6998 case 0:
895c2d04 6999 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7000 rn = "Compare";
7001 break;
876d4b07 7002 /* 6,7 are implementation dependent */
9c2149c8 7003 default:
f31b035a 7004 goto cp0_unimplemented;
876d4b07 7005 }
de9a95f0
AJ
7006 /* Stop translation as we may have switched the execution mode */
7007 ctx->bstate = BS_STOP;
9c2149c8
TS
7008 break;
7009 case 12:
7010 switch (sel) {
7011 case 0:
867abc7e 7012 save_cpu_state(ctx, 1);
895c2d04 7013 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
7014 /* BS_STOP isn't good enough here, hflags may have changed. */
7015 gen_save_pc(ctx->pc + 4);
7016 ctx->bstate = BS_EXCP;
2423f660
TS
7017 rn = "Status";
7018 break;
9c2149c8 7019 case 1:
d75c135e 7020 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7021 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
7022 /* Stop translation as we may have switched the execution mode */
7023 ctx->bstate = BS_STOP;
2423f660
TS
7024 rn = "IntCtl";
7025 break;
9c2149c8 7026 case 2:
d75c135e 7027 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7028 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
7029 /* Stop translation as we may have switched the execution mode */
7030 ctx->bstate = BS_STOP;
2423f660
TS
7031 rn = "SRSCtl";
7032 break;
9c2149c8 7033 case 3:
d75c135e 7034 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7035 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
7036 /* Stop translation as we may have switched the execution mode */
7037 ctx->bstate = BS_STOP;
2423f660
TS
7038 rn = "SRSMap";
7039 break;
7040 default:
f31b035a 7041 goto cp0_unimplemented;
876d4b07 7042 }
9c2149c8
TS
7043 break;
7044 case 13:
7045 switch (sel) {
7046 case 0:
867abc7e 7047 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
7048 /* Mark as an IO operation because we may trigger a software
7049 interrupt. */
7050 if (use_icount) {
7051 gen_io_start();
7052 }
895c2d04 7053 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
7054 if (use_icount) {
7055 gen_io_end();
7056 }
7057 /* Stop translation as we may have triggered an intetrupt */
7058 ctx->bstate = BS_STOP;
2423f660
TS
7059 rn = "Cause";
7060 break;
9c2149c8 7061 default:
f31b035a 7062 goto cp0_unimplemented;
876d4b07 7063 }
9c2149c8
TS
7064 break;
7065 case 14:
7066 switch (sel) {
7067 case 0:
7db13fae 7068 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7069 rn = "EPC";
7070 break;
9c2149c8 7071 default:
f31b035a 7072 goto cp0_unimplemented;
876d4b07 7073 }
9c2149c8
TS
7074 break;
7075 case 15:
7076 switch (sel) {
7077 case 0:
2423f660
TS
7078 /* ignored */
7079 rn = "PRid";
7080 break;
9c2149c8 7081 case 1:
d75c135e 7082 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7083 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7084 rn = "EBase";
7085 break;
9c2149c8 7086 default:
f31b035a 7087 goto cp0_unimplemented;
876d4b07 7088 }
9c2149c8
TS
7089 break;
7090 case 16:
7091 switch (sel) {
7092 case 0:
895c2d04 7093 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7094 rn = "Config";
2423f660
TS
7095 /* Stop translation as we may have switched the execution mode */
7096 ctx->bstate = BS_STOP;
9c2149c8
TS
7097 break;
7098 case 1:
1fc7bf6e 7099 /* ignored, read only */
9c2149c8
TS
7100 rn = "Config1";
7101 break;
7102 case 2:
895c2d04 7103 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7104 rn = "Config2";
2423f660
TS
7105 /* Stop translation as we may have switched the execution mode */
7106 ctx->bstate = BS_STOP;
9c2149c8
TS
7107 break;
7108 case 3:
90f12d73 7109 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7110 rn = "Config3";
90f12d73
MR
7111 /* Stop translation as we may have switched the execution mode */
7112 ctx->bstate = BS_STOP;
9c2149c8 7113 break;
faf1f68b
LA
7114 case 4:
7115 /* currently ignored */
7116 rn = "Config4";
7117 break;
7118 case 5:
7119 gen_helper_mtc0_config5(cpu_env, arg);
7120 rn = "Config5";
7121 /* Stop translation as we may have switched the execution mode */
7122 ctx->bstate = BS_STOP;
7123 break;
9c2149c8
TS
7124 /* 6,7 are implementation dependent */
7125 default:
7126 rn = "Invalid config selector";
f31b035a 7127 goto cp0_unimplemented;
9c2149c8 7128 }
9c2149c8
TS
7129 break;
7130 case 17:
7131 switch (sel) {
7132 case 0:
895c2d04 7133 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7134 rn = "LLAddr";
7135 break;
9c2149c8 7136 default:
f31b035a 7137 goto cp0_unimplemented;
9c2149c8
TS
7138 }
7139 break;
7140 case 18:
7141 switch (sel) {
fd88b6ab 7142 case 0 ... 7:
895c2d04 7143 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7144 rn = "WatchLo";
7145 break;
9c2149c8 7146 default:
f31b035a 7147 goto cp0_unimplemented;
9c2149c8
TS
7148 }
7149 break;
7150 case 19:
7151 switch (sel) {
fd88b6ab 7152 case 0 ... 7:
895c2d04 7153 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7154 rn = "WatchHi";
7155 break;
9c2149c8 7156 default:
f31b035a 7157 goto cp0_unimplemented;
9c2149c8
TS
7158 }
7159 break;
7160 case 20:
7161 switch (sel) {
7162 case 0:
d75c135e 7163 check_insn(ctx, ISA_MIPS3);
895c2d04 7164 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7165 rn = "XContext";
7166 break;
9c2149c8 7167 default:
f31b035a 7168 goto cp0_unimplemented;
9c2149c8
TS
7169 }
7170 break;
7171 case 21:
7172 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7173 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7174 switch (sel) {
7175 case 0:
895c2d04 7176 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7177 rn = "Framemask";
7178 break;
9c2149c8 7179 default:
f31b035a 7180 goto cp0_unimplemented;
9c2149c8
TS
7181 }
7182 break;
7183 case 22:
7184 /* ignored */
7185 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7186 break;
9c2149c8
TS
7187 case 23:
7188 switch (sel) {
7189 case 0:
895c2d04 7190 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
7191 /* BS_STOP isn't good enough here, hflags may have changed. */
7192 gen_save_pc(ctx->pc + 4);
7193 ctx->bstate = BS_EXCP;
2423f660
TS
7194 rn = "Debug";
7195 break;
9c2149c8 7196 case 1:
895c2d04 7197// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
7198 /* Stop translation as we may have switched the execution mode */
7199 ctx->bstate = BS_STOP;
2423f660
TS
7200 rn = "TraceControl";
7201// break;
9c2149c8 7202 case 2:
895c2d04 7203// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
7204 /* Stop translation as we may have switched the execution mode */
7205 ctx->bstate = BS_STOP;
2423f660
TS
7206 rn = "TraceControl2";
7207// break;
9c2149c8 7208 case 3:
895c2d04 7209// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
7210 /* Stop translation as we may have switched the execution mode */
7211 ctx->bstate = BS_STOP;
2423f660
TS
7212 rn = "UserTraceData";
7213// break;
9c2149c8 7214 case 4:
895c2d04 7215// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
7216 /* Stop translation as we may have switched the execution mode */
7217 ctx->bstate = BS_STOP;
2423f660
TS
7218 rn = "TraceBPC";
7219// break;
9c2149c8 7220 default:
f31b035a 7221 goto cp0_unimplemented;
9c2149c8 7222 }
9c2149c8
TS
7223 break;
7224 case 24:
7225 switch (sel) {
7226 case 0:
f1aa6320 7227 /* EJTAG support */
7db13fae 7228 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7229 rn = "DEPC";
7230 break;
9c2149c8 7231 default:
f31b035a 7232 goto cp0_unimplemented;
9c2149c8
TS
7233 }
7234 break;
7235 case 25:
7236 switch (sel) {
7237 case 0:
895c2d04 7238 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7239 rn = "Performance0";
7240 break;
9c2149c8 7241 case 1:
895c2d04 7242// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
7243 rn = "Performance1";
7244// break;
9c2149c8 7245 case 2:
895c2d04 7246// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
7247 rn = "Performance2";
7248// break;
9c2149c8 7249 case 3:
895c2d04 7250// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
7251 rn = "Performance3";
7252// break;
9c2149c8 7253 case 4:
895c2d04 7254// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
7255 rn = "Performance4";
7256// break;
9c2149c8 7257 case 5:
895c2d04 7258// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
7259 rn = "Performance5";
7260// break;
9c2149c8 7261 case 6:
895c2d04 7262// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
7263 rn = "Performance6";
7264// break;
9c2149c8 7265 case 7:
895c2d04 7266// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
7267 rn = "Performance7";
7268// break;
9c2149c8 7269 default:
f31b035a 7270 goto cp0_unimplemented;
9c2149c8 7271 }
876d4b07 7272 break;
9c2149c8 7273 case 26:
876d4b07 7274 /* ignored */
9c2149c8 7275 rn = "ECC";
876d4b07 7276 break;
9c2149c8
TS
7277 case 27:
7278 switch (sel) {
7279 case 0 ... 3:
2423f660
TS
7280 /* ignored */
7281 rn = "CacheErr";
7282 break;
9c2149c8 7283 default:
f31b035a 7284 goto cp0_unimplemented;
9c2149c8 7285 }
876d4b07 7286 break;
9c2149c8
TS
7287 case 28:
7288 switch (sel) {
7289 case 0:
7290 case 2:
7291 case 4:
7292 case 6:
895c2d04 7293 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7294 rn = "TagLo";
7295 break;
7296 case 1:
7297 case 3:
7298 case 5:
7299 case 7:
895c2d04 7300 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7301 rn = "DataLo";
7302 break;
7303 default:
f31b035a 7304 goto cp0_unimplemented;
9c2149c8
TS
7305 }
7306 break;
7307 case 29:
7308 switch (sel) {
7309 case 0:
7310 case 2:
7311 case 4:
7312 case 6:
895c2d04 7313 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7314 rn = "TagHi";
7315 break;
7316 case 1:
7317 case 3:
7318 case 5:
7319 case 7:
895c2d04 7320 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7321 rn = "DataHi";
7322 break;
7323 default:
7324 rn = "invalid sel";
f31b035a 7325 goto cp0_unimplemented;
9c2149c8 7326 }
876d4b07 7327 break;
9c2149c8
TS
7328 case 30:
7329 switch (sel) {
7330 case 0:
7db13fae 7331 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7332 rn = "ErrorEPC";
7333 break;
9c2149c8 7334 default:
f31b035a 7335 goto cp0_unimplemented;
9c2149c8
TS
7336 }
7337 break;
7338 case 31:
7339 switch (sel) {
7340 case 0:
f1aa6320 7341 /* EJTAG support */
7db13fae 7342 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7343 rn = "DESAVE";
7344 break;
e98c0d17 7345 case 2 ... 7:
f31b035a
LA
7346 CP0_CHECK(ctx->kscrexist & (1 << sel));
7347 tcg_gen_st_tl(arg, cpu_env,
7348 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7349 rn = "KScratch";
e98c0d17 7350 break;
9c2149c8 7351 default:
f31b035a 7352 goto cp0_unimplemented;
9c2149c8 7353 }
876d4b07
TS
7354 /* Stop translation as we may have switched the execution mode */
7355 ctx->bstate = BS_STOP;
9c2149c8
TS
7356 break;
7357 default:
f31b035a 7358 goto cp0_unimplemented;
9c2149c8 7359 }
2abf314d 7360 (void)rn; /* avoid a compiler warning */
d12d51d5 7361 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7362 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
7363 if (use_icount) {
7364 gen_io_end();
7365 ctx->bstate = BS_STOP;
7366 }
9c2149c8
TS
7367 return;
7368
f31b035a 7369cp0_unimplemented:
d12d51d5 7370 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7371}
d26bc211 7372#endif /* TARGET_MIPS64 */
9c2149c8 7373
7db13fae 7374static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7375 int u, int sel, int h)
7376{
7377 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7378 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7379
7380 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7381 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7382 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7383 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7384 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7385 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7386 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7387 else if (u == 0) {
7388 switch (rt) {
5a25ce94
EI
7389 case 1:
7390 switch (sel) {
7391 case 1:
895c2d04 7392 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7393 break;
7394 case 2:
895c2d04 7395 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7396 break;
7397 default:
7398 goto die;
7399 break;
7400 }
7401 break;
ead9360e
TS
7402 case 2:
7403 switch (sel) {
7404 case 1:
895c2d04 7405 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7406 break;
7407 case 2:
895c2d04 7408 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7409 break;
7410 case 3:
895c2d04 7411 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7412 break;
7413 case 4:
895c2d04 7414 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7415 break;
7416 case 5:
895c2d04 7417 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7418 break;
7419 case 6:
895c2d04 7420 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7421 break;
7422 case 7:
895c2d04 7423 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7424 break;
7425 default:
d75c135e 7426 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7427 break;
7428 }
7429 break;
7430 case 10:
7431 switch (sel) {
7432 case 0:
895c2d04 7433 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7434 break;
7435 default:
d75c135e 7436 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7437 break;
7438 }
7439 case 12:
7440 switch (sel) {
7441 case 0:
895c2d04 7442 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7443 break;
7444 default:
d75c135e 7445 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7446 break;
7447 }
5a25ce94
EI
7448 case 13:
7449 switch (sel) {
7450 case 0:
895c2d04 7451 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7452 break;
7453 default:
7454 goto die;
7455 break;
7456 }
7457 break;
7458 case 14:
7459 switch (sel) {
7460 case 0:
895c2d04 7461 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7462 break;
7463 default:
7464 goto die;
7465 break;
7466 }
7467 break;
7468 case 15:
7469 switch (sel) {
7470 case 1:
895c2d04 7471 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7472 break;
7473 default:
7474 goto die;
7475 break;
7476 }
7477 break;
7478 case 16:
7479 switch (sel) {
7480 case 0 ... 7:
895c2d04 7481 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7482 break;
7483 default:
7484 goto die;
7485 break;
7486 }
7487 break;
ead9360e
TS
7488 case 23:
7489 switch (sel) {
7490 case 0:
895c2d04 7491 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7492 break;
7493 default:
d75c135e 7494 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7495 break;
7496 }
7497 break;
7498 default:
d75c135e 7499 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7500 }
7501 } else switch (sel) {
7502 /* GPR registers. */
7503 case 0:
895c2d04 7504 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7505 break;
7506 /* Auxiliary CPU registers */
7507 case 1:
7508 switch (rt) {
7509 case 0:
895c2d04 7510 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7511 break;
7512 case 1:
895c2d04 7513 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7514 break;
7515 case 2:
895c2d04 7516 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7517 break;
7518 case 4:
895c2d04 7519 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7520 break;
7521 case 5:
895c2d04 7522 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7523 break;
7524 case 6:
895c2d04 7525 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7526 break;
7527 case 8:
895c2d04 7528 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7529 break;
7530 case 9:
895c2d04 7531 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7532 break;
7533 case 10:
895c2d04 7534 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7535 break;
7536 case 12:
895c2d04 7537 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7538 break;
7539 case 13:
895c2d04 7540 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7541 break;
7542 case 14:
895c2d04 7543 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7544 break;
7545 case 16:
895c2d04 7546 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7547 break;
7548 default:
7549 goto die;
7550 }
7551 break;
7552 /* Floating point (COP1). */
7553 case 2:
7554 /* XXX: For now we support only a single FPU context. */
7555 if (h == 0) {
a7812ae4 7556 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7557
7558 gen_load_fpr32(fp0, rt);
7559 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7560 tcg_temp_free_i32(fp0);
ead9360e 7561 } else {
a7812ae4 7562 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7563
7f6613ce 7564 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7565 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7566 tcg_temp_free_i32(fp0);
ead9360e
TS
7567 }
7568 break;
7569 case 3:
7570 /* XXX: For now we support only a single FPU context. */
895c2d04 7571 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7572 break;
7573 /* COP2: Not implemented. */
7574 case 4:
7575 case 5:
7576 /* fall through */
7577 default:
7578 goto die;
7579 }
d12d51d5 7580 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7581 gen_store_gpr(t0, rd);
7582 tcg_temp_free(t0);
ead9360e
TS
7583 return;
7584
7585die:
1a3fd9c3 7586 tcg_temp_free(t0);
d12d51d5 7587 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7588 generate_exception(ctx, EXCP_RI);
7589}
7590
7db13fae 7591static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7592 int u, int sel, int h)
7593{
7594 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7595 TCGv t0 = tcg_temp_local_new();
ead9360e 7596
1a3fd9c3 7597 gen_load_gpr(t0, rt);
ead9360e 7598 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7599 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7600 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7601 /* NOP */ ;
7602 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7603 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7604 /* NOP */ ;
7605 else if (u == 0) {
7606 switch (rd) {
5a25ce94
EI
7607 case 1:
7608 switch (sel) {
7609 case 1:
895c2d04 7610 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7611 break;
7612 case 2:
895c2d04 7613 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7614 break;
7615 default:
7616 goto die;
7617 break;
7618 }
7619 break;
ead9360e
TS
7620 case 2:
7621 switch (sel) {
7622 case 1:
895c2d04 7623 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7624 break;
7625 case 2:
895c2d04 7626 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7627 break;
7628 case 3:
895c2d04 7629 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7630 break;
7631 case 4:
895c2d04 7632 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7633 break;
7634 case 5:
895c2d04 7635 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7636 break;
7637 case 6:
895c2d04 7638 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7639 break;
7640 case 7:
895c2d04 7641 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7642 break;
7643 default:
d75c135e 7644 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7645 break;
7646 }
7647 break;
7648 case 10:
7649 switch (sel) {
7650 case 0:
895c2d04 7651 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7652 break;
7653 default:
d75c135e 7654 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7655 break;
7656 }
7657 case 12:
7658 switch (sel) {
7659 case 0:
895c2d04 7660 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7661 break;
7662 default:
d75c135e 7663 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7664 break;
7665 }
5a25ce94
EI
7666 case 13:
7667 switch (sel) {
7668 case 0:
895c2d04 7669 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7670 break;
7671 default:
7672 goto die;
7673 break;
7674 }
7675 break;
7676 case 15:
7677 switch (sel) {
7678 case 1:
895c2d04 7679 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7680 break;
7681 default:
7682 goto die;
7683 break;
7684 }
7685 break;
ead9360e
TS
7686 case 23:
7687 switch (sel) {
7688 case 0:
895c2d04 7689 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7690 break;
7691 default:
d75c135e 7692 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7693 break;
7694 }
7695 break;
7696 default:
d75c135e 7697 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7698 }
7699 } else switch (sel) {
7700 /* GPR registers. */
7701 case 0:
895c2d04 7702 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7703 break;
7704 /* Auxiliary CPU registers */
7705 case 1:
7706 switch (rd) {
7707 case 0:
895c2d04 7708 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7709 break;
7710 case 1:
895c2d04 7711 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7712 break;
7713 case 2:
895c2d04 7714 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7715 break;
7716 case 4:
895c2d04 7717 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7718 break;
7719 case 5:
895c2d04 7720 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7721 break;
7722 case 6:
895c2d04 7723 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7724 break;
7725 case 8:
895c2d04 7726 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7727 break;
7728 case 9:
895c2d04 7729 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7730 break;
7731 case 10:
895c2d04 7732 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7733 break;
7734 case 12:
895c2d04 7735 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7736 break;
7737 case 13:
895c2d04 7738 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7739 break;
7740 case 14:
895c2d04 7741 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7742 break;
7743 case 16:
895c2d04 7744 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7745 break;
7746 default:
7747 goto die;
7748 }
7749 break;
7750 /* Floating point (COP1). */
7751 case 2:
7752 /* XXX: For now we support only a single FPU context. */
7753 if (h == 0) {
a7812ae4 7754 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7755
7756 tcg_gen_trunc_tl_i32(fp0, t0);
7757 gen_store_fpr32(fp0, rd);
a7812ae4 7758 tcg_temp_free_i32(fp0);
ead9360e 7759 } else {
a7812ae4 7760 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7761
7762 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7763 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7764 tcg_temp_free_i32(fp0);
ead9360e
TS
7765 }
7766 break;
7767 case 3:
7768 /* XXX: For now we support only a single FPU context. */
4cf8a45f 7769 save_cpu_state(ctx, 1);
736d120a
PJ
7770 {
7771 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7772
7773 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7774 tcg_temp_free_i32(fs_tmp);
7775 }
4cf8a45f
YK
7776 /* Stop translation as we may have changed hflags */
7777 ctx->bstate = BS_STOP;
ead9360e
TS
7778 break;
7779 /* COP2: Not implemented. */
7780 case 4:
7781 case 5:
7782 /* fall through */
7783 default:
7784 goto die;
7785 }
d12d51d5 7786 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7787 tcg_temp_free(t0);
ead9360e
TS
7788 return;
7789
7790die:
1a3fd9c3 7791 tcg_temp_free(t0);
d12d51d5 7792 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7793 generate_exception(ctx, EXCP_RI);
7794}
7795
7db13fae 7796static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7797{
287c4b84 7798 const char *opn = "ldst";
6af0bf9c 7799
2e15497c 7800 check_cp0_enabled(ctx);
6af0bf9c
FB
7801 switch (opc) {
7802 case OPC_MFC0:
7803 if (rt == 0) {
ead9360e 7804 /* Treat as NOP. */
6af0bf9c
FB
7805 return;
7806 }
d75c135e 7807 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7808 opn = "mfc0";
7809 break;
7810 case OPC_MTC0:
1a3fd9c3 7811 {
1fc7bf6e 7812 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7813
7814 gen_load_gpr(t0, rt);
d75c135e 7815 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7816 tcg_temp_free(t0);
7817 }
6af0bf9c
FB
7818 opn = "mtc0";
7819 break;
d26bc211 7820#if defined(TARGET_MIPS64)
9c2149c8 7821 case OPC_DMFC0:
d75c135e 7822 check_insn(ctx, ISA_MIPS3);
9c2149c8 7823 if (rt == 0) {
ead9360e 7824 /* Treat as NOP. */
9c2149c8
TS
7825 return;
7826 }
d75c135e 7827 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7828 opn = "dmfc0";
7829 break;
7830 case OPC_DMTC0:
d75c135e 7831 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7832 {
1fc7bf6e 7833 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7834
7835 gen_load_gpr(t0, rt);
d75c135e 7836 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7837 tcg_temp_free(t0);
7838 }
9c2149c8
TS
7839 opn = "dmtc0";
7840 break;
534ce69f 7841#endif
ead9360e 7842 case OPC_MFTR:
d75c135e 7843 check_insn(ctx, ASE_MT);
ead9360e
TS
7844 if (rd == 0) {
7845 /* Treat as NOP. */
7846 return;
7847 }
6c5c1e20 7848 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7849 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7850 opn = "mftr";
7851 break;
7852 case OPC_MTTR:
d75c135e 7853 check_insn(ctx, ASE_MT);
6c5c1e20 7854 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7855 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7856 opn = "mttr";
7857 break;
6af0bf9c 7858 case OPC_TLBWI:
6af0bf9c 7859 opn = "tlbwi";
c01fccd2 7860 if (!env->tlb->helper_tlbwi)
29929e34 7861 goto die;
895c2d04 7862 gen_helper_tlbwi(cpu_env);
6af0bf9c 7863 break;
9456c2fb
LA
7864 case OPC_TLBINV:
7865 opn = "tlbinv";
7866 if (ctx->ie >= 2) {
7867 if (!env->tlb->helper_tlbinv) {
7868 goto die;
7869 }
7870 gen_helper_tlbinv(cpu_env);
7871 } /* treat as nop if TLBINV not supported */
7872 break;
7873 case OPC_TLBINVF:
7874 opn = "tlbinvf";
7875 if (ctx->ie >= 2) {
7876 if (!env->tlb->helper_tlbinvf) {
7877 goto die;
7878 }
7879 gen_helper_tlbinvf(cpu_env);
7880 } /* treat as nop if TLBINV not supported */
7881 break;
6af0bf9c 7882 case OPC_TLBWR:
6af0bf9c 7883 opn = "tlbwr";
c01fccd2 7884 if (!env->tlb->helper_tlbwr)
29929e34 7885 goto die;
895c2d04 7886 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7887 break;
7888 case OPC_TLBP:
6af0bf9c 7889 opn = "tlbp";
c01fccd2 7890 if (!env->tlb->helper_tlbp)
29929e34 7891 goto die;
895c2d04 7892 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7893 break;
7894 case OPC_TLBR:
6af0bf9c 7895 opn = "tlbr";
c01fccd2 7896 if (!env->tlb->helper_tlbr)
29929e34 7897 goto die;
895c2d04 7898 gen_helper_tlbr(cpu_env);
6af0bf9c 7899 break;
6af0bf9c
FB
7900 case OPC_ERET:
7901 opn = "eret";
d75c135e 7902 check_insn(ctx, ISA_MIPS2);
339cd2a8
LA
7903 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7904 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7905 MIPS_DEBUG("CTI in delay / forbidden slot");
7906 goto die;
7907 }
895c2d04 7908 gen_helper_eret(cpu_env);
6af0bf9c
FB
7909 ctx->bstate = BS_EXCP;
7910 break;
7911 case OPC_DERET:
7912 opn = "deret";
d75c135e 7913 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
7914 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7915 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7916 MIPS_DEBUG("CTI in delay / forbidden slot");
7917 goto die;
7918 }
6af0bf9c 7919 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7920 MIPS_INVAL(opn);
6af0bf9c
FB
7921 generate_exception(ctx, EXCP_RI);
7922 } else {
895c2d04 7923 gen_helper_deret(cpu_env);
6af0bf9c
FB
7924 ctx->bstate = BS_EXCP;
7925 }
7926 break;
4ad40f36
FB
7927 case OPC_WAIT:
7928 opn = "wait";
d75c135e 7929 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
7930 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7931 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7932 MIPS_DEBUG("CTI in delay / forbidden slot");
7933 goto die;
7934 }
4ad40f36
FB
7935 /* If we get an exception, we want to restart at next instruction */
7936 ctx->pc += 4;
7937 save_cpu_state(ctx, 1);
7938 ctx->pc -= 4;
895c2d04 7939 gen_helper_wait(cpu_env);
4ad40f36
FB
7940 ctx->bstate = BS_EXCP;
7941 break;
6af0bf9c 7942 default:
29929e34 7943 die:
923617a3 7944 MIPS_INVAL(opn);
6af0bf9c
FB
7945 generate_exception(ctx, EXCP_RI);
7946 return;
7947 }
2abf314d 7948 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7949 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7950}
f1aa6320 7951#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7952
6ea83fed 7953/* CP1 Branches (before delay slot) */
d75c135e
AJ
7954static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7955 int32_t cc, int32_t offset)
6ea83fed
FB
7956{
7957 target_ulong btarget;
923617a3 7958 const char *opn = "cp1 cond branch";
a7812ae4 7959 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7960
339cd2a8
LA
7961 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7962 MIPS_DEBUG("CTI in delay / forbidden slot");
7963 generate_exception(ctx, EXCP_RI);
7964 goto out;
7965 }
7966
e189e748 7967 if (cc != 0)
d75c135e 7968 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7969
6ea83fed
FB
7970 btarget = ctx->pc + 4 + offset;
7971
7a387fff
TS
7972 switch (op) {
7973 case OPC_BC1F:
d94536f4
AJ
7974 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7975 tcg_gen_not_i32(t0, t0);
7976 tcg_gen_andi_i32(t0, t0, 1);
7977 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7978 opn = "bc1f";
6ea83fed 7979 goto not_likely;
7a387fff 7980 case OPC_BC1FL:
d94536f4
AJ
7981 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7982 tcg_gen_not_i32(t0, t0);
7983 tcg_gen_andi_i32(t0, t0, 1);
7984 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7985 opn = "bc1fl";
6ea83fed 7986 goto likely;
7a387fff 7987 case OPC_BC1T:
d94536f4
AJ
7988 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7989 tcg_gen_andi_i32(t0, t0, 1);
7990 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7991 opn = "bc1t";
5a5012ec 7992 goto not_likely;
7a387fff 7993 case OPC_BC1TL:
d94536f4
AJ
7994 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7995 tcg_gen_andi_i32(t0, t0, 1);
7996 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7997 opn = "bc1tl";
6ea83fed
FB
7998 likely:
7999 ctx->hflags |= MIPS_HFLAG_BL;
8000 break;
5a5012ec 8001 case OPC_BC1FANY2:
a16336e4 8002 {
d94536f4
AJ
8003 TCGv_i32 t1 = tcg_temp_new_i32();
8004 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8005 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8006 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8007 tcg_temp_free_i32(t1);
d94536f4
AJ
8008 tcg_gen_andi_i32(t0, t0, 1);
8009 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8010 }
fd4a04eb 8011 opn = "bc1any2f";
5a5012ec
TS
8012 goto not_likely;
8013 case OPC_BC1TANY2:
a16336e4 8014 {
d94536f4
AJ
8015 TCGv_i32 t1 = tcg_temp_new_i32();
8016 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8017 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8018 tcg_gen_or_i32(t0, t0, t1);
8019 tcg_temp_free_i32(t1);
8020 tcg_gen_andi_i32(t0, t0, 1);
8021 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8022 }
fd4a04eb 8023 opn = "bc1any2t";
5a5012ec
TS
8024 goto not_likely;
8025 case OPC_BC1FANY4:
a16336e4 8026 {
d94536f4
AJ
8027 TCGv_i32 t1 = tcg_temp_new_i32();
8028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8029 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8030 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8031 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8032 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8034 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8035 tcg_temp_free_i32(t1);
d94536f4
AJ
8036 tcg_gen_andi_i32(t0, t0, 1);
8037 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8038 }
fd4a04eb 8039 opn = "bc1any4f";
5a5012ec
TS
8040 goto not_likely;
8041 case OPC_BC1TANY4:
a16336e4 8042 {
d94536f4
AJ
8043 TCGv_i32 t1 = tcg_temp_new_i32();
8044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8045 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8046 tcg_gen_or_i32(t0, t0, t1);
8047 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8048 tcg_gen_or_i32(t0, t0, t1);
8049 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8050 tcg_gen_or_i32(t0, t0, t1);
8051 tcg_temp_free_i32(t1);
8052 tcg_gen_andi_i32(t0, t0, 1);
8053 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8054 }
fd4a04eb 8055 opn = "bc1any4t";
5a5012ec
TS
8056 not_likely:
8057 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8058 break;
8059 default:
923617a3 8060 MIPS_INVAL(opn);
e397ee33 8061 generate_exception (ctx, EXCP_RI);
6c5c1e20 8062 goto out;
6ea83fed 8063 }
2abf314d 8064 (void)opn; /* avoid a compiler warning */
923617a3 8065 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
8066 ctx->hflags, btarget);
8067 ctx->btarget = btarget;
b231c103 8068 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8069 out:
a7812ae4 8070 tcg_temp_free_i32(t0);
6ea83fed
FB
8071}
8072
31837be3
YK
8073/* R6 CP1 Branches */
8074static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8075 int32_t ft, int32_t offset)
8076{
8077 target_ulong btarget;
8078 const char *opn = "cp1 cond branch";
8079 TCGv_i64 t0 = tcg_temp_new_i64();
8080
8081 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8082#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
8083 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8084 "\n", ctx->pc);
31837be3
YK
8085#endif
8086 generate_exception(ctx, EXCP_RI);
8087 goto out;
8088 }
8089
8090 gen_load_fpr64(ctx, t0, ft);
8091 tcg_gen_andi_i64(t0, t0, 1);
8092
8093 btarget = addr_add(ctx, ctx->pc + 4, offset);
8094
8095 switch (op) {
8096 case OPC_BC1EQZ:
8097 tcg_gen_xori_i64(t0, t0, 1);
8098 opn = "bc1eqz";
8099 ctx->hflags |= MIPS_HFLAG_BC;
8100 break;
8101 case OPC_BC1NEZ:
8102 /* t0 already set */
8103 opn = "bc1nez";
8104 ctx->hflags |= MIPS_HFLAG_BC;
8105 break;
8106 default:
8107 MIPS_INVAL(opn);
8108 generate_exception(ctx, EXCP_RI);
8109 goto out;
8110 }
8111
8112 tcg_gen_trunc_i64_tl(bcond, t0);
8113
8114 (void)opn; /* avoid a compiler warning */
8115 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
8116 ctx->hflags, btarget);
8117 ctx->btarget = btarget;
85479575 8118 ctx->hflags |= MIPS_HFLAG_BDS32;
31837be3
YK
8119
8120out:
8121 tcg_temp_free_i64(t0);
8122}
8123
6af0bf9c 8124/* Coprocessor 1 (FPU) */
5a5012ec 8125
5a5012ec
TS
8126#define FOP(func, fmt) (((fmt) << 21) | (func))
8127
bf4120ad
NF
8128enum fopcode {
8129 OPC_ADD_S = FOP(0, FMT_S),
8130 OPC_SUB_S = FOP(1, FMT_S),
8131 OPC_MUL_S = FOP(2, FMT_S),
8132 OPC_DIV_S = FOP(3, FMT_S),
8133 OPC_SQRT_S = FOP(4, FMT_S),
8134 OPC_ABS_S = FOP(5, FMT_S),
8135 OPC_MOV_S = FOP(6, FMT_S),
8136 OPC_NEG_S = FOP(7, FMT_S),
8137 OPC_ROUND_L_S = FOP(8, FMT_S),
8138 OPC_TRUNC_L_S = FOP(9, FMT_S),
8139 OPC_CEIL_L_S = FOP(10, FMT_S),
8140 OPC_FLOOR_L_S = FOP(11, FMT_S),
8141 OPC_ROUND_W_S = FOP(12, FMT_S),
8142 OPC_TRUNC_W_S = FOP(13, FMT_S),
8143 OPC_CEIL_W_S = FOP(14, FMT_S),
8144 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8145 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8146 OPC_MOVCF_S = FOP(17, FMT_S),
8147 OPC_MOVZ_S = FOP(18, FMT_S),
8148 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8149 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8150 OPC_RECIP_S = FOP(21, FMT_S),
8151 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8152 OPC_SELNEZ_S = FOP(23, FMT_S),
8153 OPC_MADDF_S = FOP(24, FMT_S),
8154 OPC_MSUBF_S = FOP(25, FMT_S),
8155 OPC_RINT_S = FOP(26, FMT_S),
8156 OPC_CLASS_S = FOP(27, FMT_S),
8157 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8158 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8159 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8160 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8161 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8162 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8163 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8164 OPC_RSQRT2_S = FOP(31, FMT_S),
8165 OPC_CVT_D_S = FOP(33, FMT_S),
8166 OPC_CVT_W_S = FOP(36, FMT_S),
8167 OPC_CVT_L_S = FOP(37, FMT_S),
8168 OPC_CVT_PS_S = FOP(38, FMT_S),
8169 OPC_CMP_F_S = FOP (48, FMT_S),
8170 OPC_CMP_UN_S = FOP (49, FMT_S),
8171 OPC_CMP_EQ_S = FOP (50, FMT_S),
8172 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8173 OPC_CMP_OLT_S = FOP (52, FMT_S),
8174 OPC_CMP_ULT_S = FOP (53, FMT_S),
8175 OPC_CMP_OLE_S = FOP (54, FMT_S),
8176 OPC_CMP_ULE_S = FOP (55, FMT_S),
8177 OPC_CMP_SF_S = FOP (56, FMT_S),
8178 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8179 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8180 OPC_CMP_NGL_S = FOP (59, FMT_S),
8181 OPC_CMP_LT_S = FOP (60, FMT_S),
8182 OPC_CMP_NGE_S = FOP (61, FMT_S),
8183 OPC_CMP_LE_S = FOP (62, FMT_S),
8184 OPC_CMP_NGT_S = FOP (63, FMT_S),
8185
8186 OPC_ADD_D = FOP(0, FMT_D),
8187 OPC_SUB_D = FOP(1, FMT_D),
8188 OPC_MUL_D = FOP(2, FMT_D),
8189 OPC_DIV_D = FOP(3, FMT_D),
8190 OPC_SQRT_D = FOP(4, FMT_D),
8191 OPC_ABS_D = FOP(5, FMT_D),
8192 OPC_MOV_D = FOP(6, FMT_D),
8193 OPC_NEG_D = FOP(7, FMT_D),
8194 OPC_ROUND_L_D = FOP(8, FMT_D),
8195 OPC_TRUNC_L_D = FOP(9, FMT_D),
8196 OPC_CEIL_L_D = FOP(10, FMT_D),
8197 OPC_FLOOR_L_D = FOP(11, FMT_D),
8198 OPC_ROUND_W_D = FOP(12, FMT_D),
8199 OPC_TRUNC_W_D = FOP(13, FMT_D),
8200 OPC_CEIL_W_D = FOP(14, FMT_D),
8201 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8202 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8203 OPC_MOVCF_D = FOP(17, FMT_D),
8204 OPC_MOVZ_D = FOP(18, FMT_D),
8205 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8206 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8207 OPC_RECIP_D = FOP(21, FMT_D),
8208 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8209 OPC_SELNEZ_D = FOP(23, FMT_D),
8210 OPC_MADDF_D = FOP(24, FMT_D),
8211 OPC_MSUBF_D = FOP(25, FMT_D),
8212 OPC_RINT_D = FOP(26, FMT_D),
8213 OPC_CLASS_D = FOP(27, FMT_D),
8214 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8215 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8216 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8217 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8218 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8219 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8220 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8221 OPC_RSQRT2_D = FOP(31, FMT_D),
8222 OPC_CVT_S_D = FOP(32, FMT_D),
8223 OPC_CVT_W_D = FOP(36, FMT_D),
8224 OPC_CVT_L_D = FOP(37, FMT_D),
8225 OPC_CMP_F_D = FOP (48, FMT_D),
8226 OPC_CMP_UN_D = FOP (49, FMT_D),
8227 OPC_CMP_EQ_D = FOP (50, FMT_D),
8228 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8229 OPC_CMP_OLT_D = FOP (52, FMT_D),
8230 OPC_CMP_ULT_D = FOP (53, FMT_D),
8231 OPC_CMP_OLE_D = FOP (54, FMT_D),
8232 OPC_CMP_ULE_D = FOP (55, FMT_D),
8233 OPC_CMP_SF_D = FOP (56, FMT_D),
8234 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8235 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8236 OPC_CMP_NGL_D = FOP (59, FMT_D),
8237 OPC_CMP_LT_D = FOP (60, FMT_D),
8238 OPC_CMP_NGE_D = FOP (61, FMT_D),
8239 OPC_CMP_LE_D = FOP (62, FMT_D),
8240 OPC_CMP_NGT_D = FOP (63, FMT_D),
8241
8242 OPC_CVT_S_W = FOP(32, FMT_W),
8243 OPC_CVT_D_W = FOP(33, FMT_W),
8244 OPC_CVT_S_L = FOP(32, FMT_L),
8245 OPC_CVT_D_L = FOP(33, FMT_L),
8246 OPC_CVT_PS_PW = FOP(38, FMT_W),
8247
8248 OPC_ADD_PS = FOP(0, FMT_PS),
8249 OPC_SUB_PS = FOP(1, FMT_PS),
8250 OPC_MUL_PS = FOP(2, FMT_PS),
8251 OPC_DIV_PS = FOP(3, FMT_PS),
8252 OPC_ABS_PS = FOP(5, FMT_PS),
8253 OPC_MOV_PS = FOP(6, FMT_PS),
8254 OPC_NEG_PS = FOP(7, FMT_PS),
8255 OPC_MOVCF_PS = FOP(17, FMT_PS),
8256 OPC_MOVZ_PS = FOP(18, FMT_PS),
8257 OPC_MOVN_PS = FOP(19, FMT_PS),
8258 OPC_ADDR_PS = FOP(24, FMT_PS),
8259 OPC_MULR_PS = FOP(26, FMT_PS),
8260 OPC_RECIP2_PS = FOP(28, FMT_PS),
8261 OPC_RECIP1_PS = FOP(29, FMT_PS),
8262 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8263 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8264
8265 OPC_CVT_S_PU = FOP(32, FMT_PS),
8266 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8267 OPC_CVT_S_PL = FOP(40, FMT_PS),
8268 OPC_PLL_PS = FOP(44, FMT_PS),
8269 OPC_PLU_PS = FOP(45, FMT_PS),
8270 OPC_PUL_PS = FOP(46, FMT_PS),
8271 OPC_PUU_PS = FOP(47, FMT_PS),
8272 OPC_CMP_F_PS = FOP (48, FMT_PS),
8273 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8274 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8275 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8276 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8277 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8278 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8279 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8280 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8281 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8282 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8283 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8284 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8285 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8286 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8287 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8288};
8289
3f493883
YK
8290enum r6_f_cmp_op {
8291 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8292 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8293 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8294 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8295 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8296 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8297 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8298 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8299 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8300 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8301 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8302 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8303 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8304 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8305 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8306 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8307 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8308 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8309 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8310 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8311 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8312 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8313
8314 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8315 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8316 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8317 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8318 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8319 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8320 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8321 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8322 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8323 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8324 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8325 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8326 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8327 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8328 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8329 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8330 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8331 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8332 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8333 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8334 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8335 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8336};
7a387fff 8337static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8338{
923617a3 8339 const char *opn = "cp1 move";
72c3a3ee 8340 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8341
8342 switch (opc) {
8343 case OPC_MFC1:
b6d96bed 8344 {
a7812ae4 8345 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8346
8347 gen_load_fpr32(fp0, fs);
8348 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8349 tcg_temp_free_i32(fp0);
6958549d 8350 }
6c5c1e20 8351 gen_store_gpr(t0, rt);
6ea83fed
FB
8352 opn = "mfc1";
8353 break;
8354 case OPC_MTC1:
6c5c1e20 8355 gen_load_gpr(t0, rt);
b6d96bed 8356 {
a7812ae4 8357 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8358
8359 tcg_gen_trunc_tl_i32(fp0, t0);
8360 gen_store_fpr32(fp0, fs);
a7812ae4 8361 tcg_temp_free_i32(fp0);
6958549d 8362 }
6ea83fed
FB
8363 opn = "mtc1";
8364 break;
8365 case OPC_CFC1:
895c2d04 8366 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8367 gen_store_gpr(t0, rt);
6ea83fed
FB
8368 opn = "cfc1";
8369 break;
8370 case OPC_CTC1:
6c5c1e20 8371 gen_load_gpr(t0, rt);
4cf8a45f 8372 save_cpu_state(ctx, 1);
736d120a
PJ
8373 {
8374 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8375
8376 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8377 tcg_temp_free_i32(fs_tmp);
8378 }
4cf8a45f
YK
8379 /* Stop translation as we may have changed hflags */
8380 ctx->bstate = BS_STOP;
6ea83fed
FB
8381 opn = "ctc1";
8382 break;
72c3a3ee 8383#if defined(TARGET_MIPS64)
9c2149c8 8384 case OPC_DMFC1:
72c3a3ee 8385 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8386 gen_store_gpr(t0, rt);
5a5012ec
TS
8387 opn = "dmfc1";
8388 break;
9c2149c8 8389 case OPC_DMTC1:
6c5c1e20 8390 gen_load_gpr(t0, rt);
72c3a3ee 8391 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
8392 opn = "dmtc1";
8393 break;
72c3a3ee 8394#endif
5a5012ec 8395 case OPC_MFHC1:
b6d96bed 8396 {
a7812ae4 8397 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8398
7f6613ce 8399 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8400 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8401 tcg_temp_free_i32(fp0);
6958549d 8402 }
6c5c1e20 8403 gen_store_gpr(t0, rt);
5a5012ec
TS
8404 opn = "mfhc1";
8405 break;
8406 case OPC_MTHC1:
6c5c1e20 8407 gen_load_gpr(t0, rt);
b6d96bed 8408 {
a7812ae4 8409 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8410
8411 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8412 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8413 tcg_temp_free_i32(fp0);
6958549d 8414 }
5a5012ec
TS
8415 opn = "mthc1";
8416 break;
6ea83fed 8417 default:
923617a3 8418 MIPS_INVAL(opn);
e397ee33 8419 generate_exception (ctx, EXCP_RI);
6c5c1e20 8420 goto out;
6ea83fed 8421 }
2abf314d 8422 (void)opn; /* avoid a compiler warning */
6ea83fed 8423 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8424
8425 out:
8426 tcg_temp_free(t0);
6ea83fed
FB
8427}
8428
5a5012ec
TS
8429static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8430{
af58f9ca 8431 int l1;
e214b9bb 8432 TCGCond cond;
af58f9ca
AJ
8433 TCGv_i32 t0;
8434
8435 if (rd == 0) {
8436 /* Treat as NOP. */
8437 return;
8438 }
6ea83fed 8439
e214b9bb 8440 if (tf)
e214b9bb 8441 cond = TCG_COND_EQ;
27848470
TS
8442 else
8443 cond = TCG_COND_NE;
8444
af58f9ca
AJ
8445 l1 = gen_new_label();
8446 t0 = tcg_temp_new_i32();
fa31af0e 8447 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8448 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8449 tcg_temp_free_i32(t0);
af58f9ca
AJ
8450 if (rs == 0) {
8451 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8452 } else {
8453 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8454 }
e214b9bb 8455 gen_set_label(l1);
5a5012ec
TS
8456}
8457
b6d96bed 8458static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 8459{
a16336e4 8460 int cond;
cbc37b28 8461 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8462 int l1 = gen_new_label();
8463
a16336e4
TS
8464 if (tf)
8465 cond = TCG_COND_EQ;
8466 else
8467 cond = TCG_COND_NE;
8468
fa31af0e 8469 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8470 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8471 gen_load_fpr32(t0, fs);
8472 gen_store_fpr32(t0, fd);
a16336e4 8473 gen_set_label(l1);
cbc37b28 8474 tcg_temp_free_i32(t0);
5a5012ec 8475}
a16336e4 8476
b6d96bed 8477static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8478{
a16336e4 8479 int cond;
cbc37b28
AJ
8480 TCGv_i32 t0 = tcg_temp_new_i32();
8481 TCGv_i64 fp0;
a16336e4
TS
8482 int l1 = gen_new_label();
8483
a16336e4
TS
8484 if (tf)
8485 cond = TCG_COND_EQ;
8486 else
8487 cond = TCG_COND_NE;
8488
fa31af0e 8489 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8490 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8491 tcg_temp_free_i32(t0);
11f94258 8492 fp0 = tcg_temp_new_i64();
9bf3eb2c 8493 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8494 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8495 tcg_temp_free_i64(fp0);
cbc37b28 8496 gen_set_label(l1);
a16336e4
TS
8497}
8498
7f6613ce
PJ
8499static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8500 int cc, int tf)
a16336e4
TS
8501{
8502 int cond;
cbc37b28 8503 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8504 int l1 = gen_new_label();
8505 int l2 = gen_new_label();
8506
8507 if (tf)
8508 cond = TCG_COND_EQ;
8509 else
8510 cond = TCG_COND_NE;
8511
fa31af0e 8512 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8513 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8514 gen_load_fpr32(t0, fs);
8515 gen_store_fpr32(t0, fd);
a16336e4 8516 gen_set_label(l1);
9bf3eb2c 8517
fa31af0e 8518 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8519 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8520 gen_load_fpr32h(ctx, t0, fs);
8521 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8522 tcg_temp_free_i32(t0);
a16336e4 8523 gen_set_label(l2);
a16336e4
TS
8524}
8525
e7f16abb
LA
8526static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8527 int fs)
8528{
8529 TCGv_i32 t1 = tcg_const_i32(0);
8530 TCGv_i32 fp0 = tcg_temp_new_i32();
8531 TCGv_i32 fp1 = tcg_temp_new_i32();
8532 TCGv_i32 fp2 = tcg_temp_new_i32();
8533 gen_load_fpr32(fp0, fd);
8534 gen_load_fpr32(fp1, ft);
8535 gen_load_fpr32(fp2, fs);
8536
8537 switch (op1) {
8538 case OPC_SEL_S:
8539 tcg_gen_andi_i32(fp0, fp0, 1);
8540 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8541 break;
8542 case OPC_SELEQZ_S:
8543 tcg_gen_andi_i32(fp1, fp1, 1);
8544 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8545 break;
8546 case OPC_SELNEZ_S:
8547 tcg_gen_andi_i32(fp1, fp1, 1);
8548 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8549 break;
8550 default:
8551 MIPS_INVAL("gen_sel_s");
8552 generate_exception (ctx, EXCP_RI);
8553 break;
8554 }
8555
8556 gen_store_fpr32(fp0, fd);
8557 tcg_temp_free_i32(fp2);
8558 tcg_temp_free_i32(fp1);
8559 tcg_temp_free_i32(fp0);
8560 tcg_temp_free_i32(t1);
8561}
8562
8563static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8564 int fs)
8565{
8566 TCGv_i64 t1 = tcg_const_i64(0);
8567 TCGv_i64 fp0 = tcg_temp_new_i64();
8568 TCGv_i64 fp1 = tcg_temp_new_i64();
8569 TCGv_i64 fp2 = tcg_temp_new_i64();
8570 gen_load_fpr64(ctx, fp0, fd);
8571 gen_load_fpr64(ctx, fp1, ft);
8572 gen_load_fpr64(ctx, fp2, fs);
8573
8574 switch (op1) {
8575 case OPC_SEL_D:
8576 tcg_gen_andi_i64(fp0, fp0, 1);
8577 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8578 break;
8579 case OPC_SELEQZ_D:
8580 tcg_gen_andi_i64(fp1, fp1, 1);
8581 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8582 break;
8583 case OPC_SELNEZ_D:
8584 tcg_gen_andi_i64(fp1, fp1, 1);
8585 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8586 break;
8587 default:
8588 MIPS_INVAL("gen_sel_d");
8589 generate_exception (ctx, EXCP_RI);
8590 break;
8591 }
8592
8593 gen_store_fpr64(ctx, fp0, fd);
8594 tcg_temp_free_i64(fp2);
8595 tcg_temp_free_i64(fp1);
8596 tcg_temp_free_i64(fp0);
8597 tcg_temp_free_i64(t1);
8598}
6ea83fed 8599
bf4120ad 8600static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8601 int ft, int fs, int fd, int cc)
6ea83fed 8602{
923617a3 8603 const char *opn = "farith";
6ea83fed
FB
8604 const char *condnames[] = {
8605 "c.f",
8606 "c.un",
8607 "c.eq",
8608 "c.ueq",
8609 "c.olt",
8610 "c.ult",
8611 "c.ole",
8612 "c.ule",
8613 "c.sf",
8614 "c.ngle",
8615 "c.seq",
8616 "c.ngl",
8617 "c.lt",
8618 "c.nge",
8619 "c.le",
8620 "c.ngt",
8621 };
5a1e8ffb
TS
8622 const char *condnames_abs[] = {
8623 "cabs.f",
8624 "cabs.un",
8625 "cabs.eq",
8626 "cabs.ueq",
8627 "cabs.olt",
8628 "cabs.ult",
8629 "cabs.ole",
8630 "cabs.ule",
8631 "cabs.sf",
8632 "cabs.ngle",
8633 "cabs.seq",
8634 "cabs.ngl",
8635 "cabs.lt",
8636 "cabs.nge",
8637 "cabs.le",
8638 "cabs.ngt",
8639 };
8640 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8641 uint32_t func = ctx->opcode & 0x3f;
8642
bf4120ad
NF
8643 switch (op1) {
8644 case OPC_ADD_S:
b6d96bed 8645 {
a7812ae4
PB
8646 TCGv_i32 fp0 = tcg_temp_new_i32();
8647 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8648
8649 gen_load_fpr32(fp0, fs);
8650 gen_load_fpr32(fp1, ft);
895c2d04 8651 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8652 tcg_temp_free_i32(fp1);
b6d96bed 8653 gen_store_fpr32(fp0, fd);
a7812ae4 8654 tcg_temp_free_i32(fp0);
b6d96bed 8655 }
5a5012ec 8656 opn = "add.s";
5a1e8ffb 8657 optype = BINOP;
5a5012ec 8658 break;
bf4120ad 8659 case OPC_SUB_S:
b6d96bed 8660 {
a7812ae4
PB
8661 TCGv_i32 fp0 = tcg_temp_new_i32();
8662 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8663
8664 gen_load_fpr32(fp0, fs);
8665 gen_load_fpr32(fp1, ft);
895c2d04 8666 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8667 tcg_temp_free_i32(fp1);
b6d96bed 8668 gen_store_fpr32(fp0, fd);
a7812ae4 8669 tcg_temp_free_i32(fp0);
b6d96bed 8670 }
5a5012ec 8671 opn = "sub.s";
5a1e8ffb 8672 optype = BINOP;
5a5012ec 8673 break;
bf4120ad 8674 case OPC_MUL_S:
b6d96bed 8675 {
a7812ae4
PB
8676 TCGv_i32 fp0 = tcg_temp_new_i32();
8677 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8678
8679 gen_load_fpr32(fp0, fs);
8680 gen_load_fpr32(fp1, ft);
895c2d04 8681 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8682 tcg_temp_free_i32(fp1);
b6d96bed 8683 gen_store_fpr32(fp0, fd);
a7812ae4 8684 tcg_temp_free_i32(fp0);
b6d96bed 8685 }
5a5012ec 8686 opn = "mul.s";
5a1e8ffb 8687 optype = BINOP;
5a5012ec 8688 break;
bf4120ad 8689 case OPC_DIV_S:
b6d96bed 8690 {
a7812ae4
PB
8691 TCGv_i32 fp0 = tcg_temp_new_i32();
8692 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8693
8694 gen_load_fpr32(fp0, fs);
8695 gen_load_fpr32(fp1, ft);
895c2d04 8696 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8697 tcg_temp_free_i32(fp1);
b6d96bed 8698 gen_store_fpr32(fp0, fd);
a7812ae4 8699 tcg_temp_free_i32(fp0);
b6d96bed 8700 }
5a5012ec 8701 opn = "div.s";
5a1e8ffb 8702 optype = BINOP;
5a5012ec 8703 break;
bf4120ad 8704 case OPC_SQRT_S:
b6d96bed 8705 {
a7812ae4 8706 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8707
8708 gen_load_fpr32(fp0, fs);
895c2d04 8709 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 8710 gen_store_fpr32(fp0, fd);
a7812ae4 8711 tcg_temp_free_i32(fp0);
b6d96bed 8712 }
5a5012ec
TS
8713 opn = "sqrt.s";
8714 break;
bf4120ad 8715 case OPC_ABS_S:
b6d96bed 8716 {
a7812ae4 8717 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8718
8719 gen_load_fpr32(fp0, fs);
a7812ae4 8720 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 8721 gen_store_fpr32(fp0, fd);
a7812ae4 8722 tcg_temp_free_i32(fp0);
b6d96bed 8723 }
5a5012ec
TS
8724 opn = "abs.s";
8725 break;
bf4120ad 8726 case OPC_MOV_S:
b6d96bed 8727 {
a7812ae4 8728 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8729
8730 gen_load_fpr32(fp0, fs);
8731 gen_store_fpr32(fp0, fd);
a7812ae4 8732 tcg_temp_free_i32(fp0);
b6d96bed 8733 }
5a5012ec
TS
8734 opn = "mov.s";
8735 break;
bf4120ad 8736 case OPC_NEG_S:
b6d96bed 8737 {
a7812ae4 8738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8739
8740 gen_load_fpr32(fp0, fs);
a7812ae4 8741 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 8742 gen_store_fpr32(fp0, fd);
a7812ae4 8743 tcg_temp_free_i32(fp0);
b6d96bed 8744 }
5a5012ec
TS
8745 opn = "neg.s";
8746 break;
bf4120ad 8747 case OPC_ROUND_L_S:
5e755519 8748 check_cp1_64bitmode(ctx);
b6d96bed 8749 {
a7812ae4
PB
8750 TCGv_i32 fp32 = tcg_temp_new_i32();
8751 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8752
8753 gen_load_fpr32(fp32, fs);
895c2d04 8754 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8755 tcg_temp_free_i32(fp32);
b6d96bed 8756 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8757 tcg_temp_free_i64(fp64);
b6d96bed 8758 }
5a5012ec
TS
8759 opn = "round.l.s";
8760 break;
bf4120ad 8761 case OPC_TRUNC_L_S:
5e755519 8762 check_cp1_64bitmode(ctx);
b6d96bed 8763 {
a7812ae4
PB
8764 TCGv_i32 fp32 = tcg_temp_new_i32();
8765 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8766
8767 gen_load_fpr32(fp32, fs);
895c2d04 8768 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8769 tcg_temp_free_i32(fp32);
b6d96bed 8770 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8771 tcg_temp_free_i64(fp64);
b6d96bed 8772 }
5a5012ec
TS
8773 opn = "trunc.l.s";
8774 break;
bf4120ad 8775 case OPC_CEIL_L_S:
5e755519 8776 check_cp1_64bitmode(ctx);
b6d96bed 8777 {
a7812ae4
PB
8778 TCGv_i32 fp32 = tcg_temp_new_i32();
8779 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8780
8781 gen_load_fpr32(fp32, fs);
895c2d04 8782 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8783 tcg_temp_free_i32(fp32);
b6d96bed 8784 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8785 tcg_temp_free_i64(fp64);
b6d96bed 8786 }
5a5012ec
TS
8787 opn = "ceil.l.s";
8788 break;
bf4120ad 8789 case OPC_FLOOR_L_S:
5e755519 8790 check_cp1_64bitmode(ctx);
b6d96bed 8791 {
a7812ae4
PB
8792 TCGv_i32 fp32 = tcg_temp_new_i32();
8793 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8794
8795 gen_load_fpr32(fp32, fs);
895c2d04 8796 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8797 tcg_temp_free_i32(fp32);
b6d96bed 8798 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8799 tcg_temp_free_i64(fp64);
b6d96bed 8800 }
5a5012ec
TS
8801 opn = "floor.l.s";
8802 break;
bf4120ad 8803 case OPC_ROUND_W_S:
b6d96bed 8804 {
a7812ae4 8805 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8806
8807 gen_load_fpr32(fp0, fs);
895c2d04 8808 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 8809 gen_store_fpr32(fp0, fd);
a7812ae4 8810 tcg_temp_free_i32(fp0);
b6d96bed 8811 }
5a5012ec
TS
8812 opn = "round.w.s";
8813 break;
bf4120ad 8814 case OPC_TRUNC_W_S:
b6d96bed 8815 {
a7812ae4 8816 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8817
8818 gen_load_fpr32(fp0, fs);
895c2d04 8819 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 8820 gen_store_fpr32(fp0, fd);
a7812ae4 8821 tcg_temp_free_i32(fp0);
b6d96bed 8822 }
5a5012ec
TS
8823 opn = "trunc.w.s";
8824 break;
bf4120ad 8825 case OPC_CEIL_W_S:
b6d96bed 8826 {
a7812ae4 8827 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8828
8829 gen_load_fpr32(fp0, fs);
895c2d04 8830 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 8831 gen_store_fpr32(fp0, fd);
a7812ae4 8832 tcg_temp_free_i32(fp0);
b6d96bed 8833 }
5a5012ec
TS
8834 opn = "ceil.w.s";
8835 break;
bf4120ad 8836 case OPC_FLOOR_W_S:
b6d96bed 8837 {
a7812ae4 8838 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8839
8840 gen_load_fpr32(fp0, fs);
895c2d04 8841 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8842 gen_store_fpr32(fp0, fd);
a7812ae4 8843 tcg_temp_free_i32(fp0);
b6d96bed 8844 }
5a5012ec
TS
8845 opn = "floor.w.s";
8846 break;
e7f16abb
LA
8847 case OPC_SEL_S:
8848 check_insn(ctx, ISA_MIPS32R6);
8849 gen_sel_s(ctx, op1, fd, ft, fs);
8850 opn = "sel.s";
8851 break;
8852 case OPC_SELEQZ_S:
8853 check_insn(ctx, ISA_MIPS32R6);
8854 gen_sel_s(ctx, op1, fd, ft, fs);
8855 opn = "seleqz.s";
8856 break;
8857 case OPC_SELNEZ_S:
8858 check_insn(ctx, ISA_MIPS32R6);
8859 gen_sel_s(ctx, op1, fd, ft, fs);
8860 opn = "selnez.s";
8861 break;
bf4120ad 8862 case OPC_MOVCF_S:
fecd2646 8863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8864 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8865 opn = "movcf.s";
8866 break;
bf4120ad 8867 case OPC_MOVZ_S:
fecd2646 8868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8869 {
8870 int l1 = gen_new_label();
c9297f4d 8871 TCGv_i32 fp0;
a16336e4 8872
c9297f4d
AJ
8873 if (ft != 0) {
8874 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8875 }
8876 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8877 gen_load_fpr32(fp0, fs);
8878 gen_store_fpr32(fp0, fd);
a7812ae4 8879 tcg_temp_free_i32(fp0);
a16336e4
TS
8880 gen_set_label(l1);
8881 }
5a5012ec
TS
8882 opn = "movz.s";
8883 break;
bf4120ad 8884 case OPC_MOVN_S:
fecd2646 8885 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8886 {
8887 int l1 = gen_new_label();
c9297f4d
AJ
8888 TCGv_i32 fp0;
8889
8890 if (ft != 0) {
8891 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8892 fp0 = tcg_temp_new_i32();
8893 gen_load_fpr32(fp0, fs);
8894 gen_store_fpr32(fp0, fd);
8895 tcg_temp_free_i32(fp0);
8896 gen_set_label(l1);
8897 }
a16336e4 8898 }
5a5012ec
TS
8899 opn = "movn.s";
8900 break;
bf4120ad 8901 case OPC_RECIP_S:
b8aa4598 8902 check_cop1x(ctx);
b6d96bed 8903 {
a7812ae4 8904 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8905
8906 gen_load_fpr32(fp0, fs);
895c2d04 8907 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8908 gen_store_fpr32(fp0, fd);
a7812ae4 8909 tcg_temp_free_i32(fp0);
b6d96bed 8910 }
57fa1fb3
TS
8911 opn = "recip.s";
8912 break;
bf4120ad 8913 case OPC_RSQRT_S:
b8aa4598 8914 check_cop1x(ctx);
b6d96bed 8915 {
a7812ae4 8916 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8917
8918 gen_load_fpr32(fp0, fs);
895c2d04 8919 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8920 gen_store_fpr32(fp0, fd);
a7812ae4 8921 tcg_temp_free_i32(fp0);
b6d96bed 8922 }
57fa1fb3
TS
8923 opn = "rsqrt.s";
8924 break;
e7f16abb
LA
8925 case OPC_MADDF_S:
8926 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8927 {
a7812ae4
PB
8928 TCGv_i32 fp0 = tcg_temp_new_i32();
8929 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8930 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8931 gen_load_fpr32(fp0, fs);
d22d7289 8932 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8933 gen_load_fpr32(fp2, fd);
8934 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8935 gen_store_fpr32(fp2, fd);
8936 tcg_temp_free_i32(fp2);
a7812ae4 8937 tcg_temp_free_i32(fp1);
a7812ae4 8938 tcg_temp_free_i32(fp0);
e7f16abb 8939 opn = "maddf.s";
b6d96bed 8940 }
57fa1fb3 8941 break;
e7f16abb
LA
8942 case OPC_MSUBF_S:
8943 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8944 {
a7812ae4 8945 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8946 TCGv_i32 fp1 = tcg_temp_new_i32();
8947 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8948 gen_load_fpr32(fp0, fs);
e7f16abb
LA
8949 gen_load_fpr32(fp1, ft);
8950 gen_load_fpr32(fp2, fd);
8951 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8952 gen_store_fpr32(fp2, fd);
8953 tcg_temp_free_i32(fp2);
8954 tcg_temp_free_i32(fp1);
a7812ae4 8955 tcg_temp_free_i32(fp0);
e7f16abb 8956 opn = "msubf.s";
b6d96bed 8957 }
57fa1fb3 8958 break;
e7f16abb
LA
8959 case OPC_RINT_S:
8960 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8961 {
a7812ae4 8962 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8963 gen_load_fpr32(fp0, fs);
e7f16abb 8964 gen_helper_float_rint_s(fp0, cpu_env, fp0);
b6d96bed 8965 gen_store_fpr32(fp0, fd);
a7812ae4 8966 tcg_temp_free_i32(fp0);
e7f16abb 8967 opn = "rint.s";
b6d96bed 8968 }
57fa1fb3 8969 break;
e7f16abb
LA
8970 case OPC_CLASS_S:
8971 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8972 {
e7f16abb
LA
8973 TCGv_i32 fp0 = tcg_temp_new_i32();
8974 gen_load_fpr32(fp0, fs);
8975 gen_helper_float_class_s(fp0, fp0);
8976 gen_store_fpr32(fp0, fd);
8977 tcg_temp_free_i32(fp0);
8978 opn = "class.s";
8979 }
8980 break;
8981 case OPC_MIN_S: /* OPC_RECIP2_S */
8982 if (ctx->insn_flags & ISA_MIPS32R6) {
8983 /* OPC_MIN_S */
a7812ae4
PB
8984 TCGv_i32 fp0 = tcg_temp_new_i32();
8985 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb
LA
8986 TCGv_i32 fp2 = tcg_temp_new_i32();
8987 gen_load_fpr32(fp0, fs);
8988 gen_load_fpr32(fp1, ft);
8989 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8990 gen_store_fpr32(fp2, fd);
8991 tcg_temp_free_i32(fp2);
8992 tcg_temp_free_i32(fp1);
8993 tcg_temp_free_i32(fp0);
8994 opn = "min.s";
8995 } else {
8996 /* OPC_RECIP2_S */
8997 check_cp1_64bitmode(ctx);
8998 {
8999 TCGv_i32 fp0 = tcg_temp_new_i32();
9000 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9001
e7f16abb
LA
9002 gen_load_fpr32(fp0, fs);
9003 gen_load_fpr32(fp1, ft);
9004 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9005 tcg_temp_free_i32(fp1);
9006 gen_store_fpr32(fp0, fd);
9007 tcg_temp_free_i32(fp0);
9008 }
9009 opn = "recip2.s";
9010 }
9011 break;
9012 case OPC_MINA_S: /* OPC_RECIP1_S */
9013 if (ctx->insn_flags & ISA_MIPS32R6) {
9014 /* OPC_MINA_S */
9015 TCGv_i32 fp0 = tcg_temp_new_i32();
9016 TCGv_i32 fp1 = tcg_temp_new_i32();
9017 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9018 gen_load_fpr32(fp0, fs);
9019 gen_load_fpr32(fp1, ft);
e7f16abb
LA
9020 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9021 gen_store_fpr32(fp2, fd);
9022 tcg_temp_free_i32(fp2);
9023 tcg_temp_free_i32(fp1);
9024 tcg_temp_free_i32(fp0);
9025 opn = "mina.s";
9026 } else {
9027 /* OPC_RECIP1_S */
9028 check_cp1_64bitmode(ctx);
9029 {
9030 TCGv_i32 fp0 = tcg_temp_new_i32();
9031
9032 gen_load_fpr32(fp0, fs);
9033 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9034 gen_store_fpr32(fp0, fd);
9035 tcg_temp_free_i32(fp0);
9036 }
9037 opn = "recip1.s";
9038 }
9039 break;
9040 case OPC_MAX_S: /* OPC_RSQRT1_S */
9041 if (ctx->insn_flags & ISA_MIPS32R6) {
9042 /* OPC_MAX_S */
9043 TCGv_i32 fp0 = tcg_temp_new_i32();
9044 TCGv_i32 fp1 = tcg_temp_new_i32();
9045 gen_load_fpr32(fp0, fs);
9046 gen_load_fpr32(fp1, ft);
9047 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9048 gen_store_fpr32(fp1, fd);
9049 tcg_temp_free_i32(fp1);
9050 tcg_temp_free_i32(fp0);
9051 opn = "max.s";
9052 } else {
9053 /* OPC_RSQRT1_S */
9054 check_cp1_64bitmode(ctx);
9055 {
9056 TCGv_i32 fp0 = tcg_temp_new_i32();
9057
9058 gen_load_fpr32(fp0, fs);
9059 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9060 gen_store_fpr32(fp0, fd);
9061 tcg_temp_free_i32(fp0);
9062 }
9063 opn = "rsqrt1.s";
9064 }
9065 break;
9066 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9067 if (ctx->insn_flags & ISA_MIPS32R6) {
9068 /* OPC_MAXA_S */
9069 TCGv_i32 fp0 = tcg_temp_new_i32();
9070 TCGv_i32 fp1 = tcg_temp_new_i32();
9071 gen_load_fpr32(fp0, fs);
9072 gen_load_fpr32(fp1, ft);
9073 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9074 gen_store_fpr32(fp1, fd);
a7812ae4 9075 tcg_temp_free_i32(fp1);
a7812ae4 9076 tcg_temp_free_i32(fp0);
e7f16abb
LA
9077 opn = "maxa.s";
9078 } else {
9079 /* OPC_RSQRT2_S */
9080 check_cp1_64bitmode(ctx);
9081 {
9082 TCGv_i32 fp0 = tcg_temp_new_i32();
9083 TCGv_i32 fp1 = tcg_temp_new_i32();
9084
9085 gen_load_fpr32(fp0, fs);
9086 gen_load_fpr32(fp1, ft);
9087 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9088 tcg_temp_free_i32(fp1);
9089 gen_store_fpr32(fp0, fd);
9090 tcg_temp_free_i32(fp0);
9091 }
9092 opn = "rsqrt2.s";
b6d96bed 9093 }
57fa1fb3 9094 break;
bf4120ad 9095 case OPC_CVT_D_S:
5e755519 9096 check_cp1_registers(ctx, fd);
b6d96bed 9097 {
a7812ae4
PB
9098 TCGv_i32 fp32 = tcg_temp_new_i32();
9099 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9100
9101 gen_load_fpr32(fp32, fs);
895c2d04 9102 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9103 tcg_temp_free_i32(fp32);
b6d96bed 9104 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9105 tcg_temp_free_i64(fp64);
b6d96bed 9106 }
5a5012ec
TS
9107 opn = "cvt.d.s";
9108 break;
bf4120ad 9109 case OPC_CVT_W_S:
b6d96bed 9110 {
a7812ae4 9111 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9112
9113 gen_load_fpr32(fp0, fs);
895c2d04 9114 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 9115 gen_store_fpr32(fp0, fd);
a7812ae4 9116 tcg_temp_free_i32(fp0);
b6d96bed 9117 }
5a5012ec
TS
9118 opn = "cvt.w.s";
9119 break;
bf4120ad 9120 case OPC_CVT_L_S:
5e755519 9121 check_cp1_64bitmode(ctx);
b6d96bed 9122 {
a7812ae4
PB
9123 TCGv_i32 fp32 = tcg_temp_new_i32();
9124 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9125
9126 gen_load_fpr32(fp32, fs);
895c2d04 9127 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 9128 tcg_temp_free_i32(fp32);
b6d96bed 9129 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9130 tcg_temp_free_i64(fp64);
b6d96bed 9131 }
5a5012ec
TS
9132 opn = "cvt.l.s";
9133 break;
bf4120ad 9134 case OPC_CVT_PS_S:
fecd2646 9135 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9136 check_cp1_64bitmode(ctx);
b6d96bed 9137 {
a7812ae4
PB
9138 TCGv_i64 fp64 = tcg_temp_new_i64();
9139 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9140 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
9141
9142 gen_load_fpr32(fp32_0, fs);
9143 gen_load_fpr32(fp32_1, ft);
13d24f49 9144 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9145 tcg_temp_free_i32(fp32_1);
9146 tcg_temp_free_i32(fp32_0);
36aa55dc 9147 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9148 tcg_temp_free_i64(fp64);
b6d96bed 9149 }
5a5012ec
TS
9150 opn = "cvt.ps.s";
9151 break;
bf4120ad
NF
9152 case OPC_CMP_F_S:
9153 case OPC_CMP_UN_S:
9154 case OPC_CMP_EQ_S:
9155 case OPC_CMP_UEQ_S:
9156 case OPC_CMP_OLT_S:
9157 case OPC_CMP_ULT_S:
9158 case OPC_CMP_OLE_S:
9159 case OPC_CMP_ULE_S:
9160 case OPC_CMP_SF_S:
9161 case OPC_CMP_NGLE_S:
9162 case OPC_CMP_SEQ_S:
9163 case OPC_CMP_NGL_S:
9164 case OPC_CMP_LT_S:
9165 case OPC_CMP_NGE_S:
9166 case OPC_CMP_LE_S:
9167 case OPC_CMP_NGT_S:
fecd2646 9168 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9169 if (ctx->opcode & (1 << 6)) {
9170 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9171 opn = condnames_abs[func-48];
9172 } else {
9173 gen_cmp_s(ctx, func-48, ft, fs, cc);
9174 opn = condnames[func-48];
5a1e8ffb 9175 }
5a5012ec 9176 break;
bf4120ad 9177 case OPC_ADD_D:
5e755519 9178 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9179 {
a7812ae4
PB
9180 TCGv_i64 fp0 = tcg_temp_new_i64();
9181 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9182
9183 gen_load_fpr64(ctx, fp0, fs);
9184 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9185 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9186 tcg_temp_free_i64(fp1);
b6d96bed 9187 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9188 tcg_temp_free_i64(fp0);
b6d96bed 9189 }
6ea83fed 9190 opn = "add.d";
5a1e8ffb 9191 optype = BINOP;
6ea83fed 9192 break;
bf4120ad 9193 case OPC_SUB_D:
5e755519 9194 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9195 {
a7812ae4
PB
9196 TCGv_i64 fp0 = tcg_temp_new_i64();
9197 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9198
9199 gen_load_fpr64(ctx, fp0, fs);
9200 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9201 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9202 tcg_temp_free_i64(fp1);
b6d96bed 9203 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9204 tcg_temp_free_i64(fp0);
b6d96bed 9205 }
6ea83fed 9206 opn = "sub.d";
5a1e8ffb 9207 optype = BINOP;
6ea83fed 9208 break;
bf4120ad 9209 case OPC_MUL_D:
5e755519 9210 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9211 {
a7812ae4
PB
9212 TCGv_i64 fp0 = tcg_temp_new_i64();
9213 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9214
9215 gen_load_fpr64(ctx, fp0, fs);
9216 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9217 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9218 tcg_temp_free_i64(fp1);
b6d96bed 9219 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9220 tcg_temp_free_i64(fp0);
b6d96bed 9221 }
6ea83fed 9222 opn = "mul.d";
5a1e8ffb 9223 optype = BINOP;
6ea83fed 9224 break;
bf4120ad 9225 case OPC_DIV_D:
5e755519 9226 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9227 {
a7812ae4
PB
9228 TCGv_i64 fp0 = tcg_temp_new_i64();
9229 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9230
9231 gen_load_fpr64(ctx, fp0, fs);
9232 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9233 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9234 tcg_temp_free_i64(fp1);
b6d96bed 9235 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9236 tcg_temp_free_i64(fp0);
b6d96bed 9237 }
6ea83fed 9238 opn = "div.d";
5a1e8ffb 9239 optype = BINOP;
6ea83fed 9240 break;
bf4120ad 9241 case OPC_SQRT_D:
5e755519 9242 check_cp1_registers(ctx, fs | fd);
b6d96bed 9243 {
a7812ae4 9244 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9245
9246 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9247 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9248 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9249 tcg_temp_free_i64(fp0);
b6d96bed 9250 }
6ea83fed
FB
9251 opn = "sqrt.d";
9252 break;
bf4120ad 9253 case OPC_ABS_D:
5e755519 9254 check_cp1_registers(ctx, fs | fd);
b6d96bed 9255 {
a7812ae4 9256 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9257
9258 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9259 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 9260 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9261 tcg_temp_free_i64(fp0);
b6d96bed 9262 }
6ea83fed
FB
9263 opn = "abs.d";
9264 break;
bf4120ad 9265 case OPC_MOV_D:
5e755519 9266 check_cp1_registers(ctx, fs | fd);
b6d96bed 9267 {
a7812ae4 9268 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9269
9270 gen_load_fpr64(ctx, fp0, fs);
9271 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9272 tcg_temp_free_i64(fp0);
b6d96bed 9273 }
6ea83fed
FB
9274 opn = "mov.d";
9275 break;
bf4120ad 9276 case OPC_NEG_D:
5e755519 9277 check_cp1_registers(ctx, fs | fd);
b6d96bed 9278 {
a7812ae4 9279 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9280
9281 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9282 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 9283 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9284 tcg_temp_free_i64(fp0);
b6d96bed 9285 }
6ea83fed
FB
9286 opn = "neg.d";
9287 break;
bf4120ad 9288 case OPC_ROUND_L_D:
5e755519 9289 check_cp1_64bitmode(ctx);
b6d96bed 9290 {
a7812ae4 9291 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9292
9293 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9294 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 9295 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9296 tcg_temp_free_i64(fp0);
b6d96bed 9297 }
5a5012ec
TS
9298 opn = "round.l.d";
9299 break;
bf4120ad 9300 case OPC_TRUNC_L_D:
5e755519 9301 check_cp1_64bitmode(ctx);
b6d96bed 9302 {
a7812ae4 9303 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9304
9305 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9306 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 9307 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9308 tcg_temp_free_i64(fp0);
b6d96bed 9309 }
5a5012ec
TS
9310 opn = "trunc.l.d";
9311 break;
bf4120ad 9312 case OPC_CEIL_L_D:
5e755519 9313 check_cp1_64bitmode(ctx);
b6d96bed 9314 {
a7812ae4 9315 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9316
9317 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9318 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 9319 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9320 tcg_temp_free_i64(fp0);
b6d96bed 9321 }
5a5012ec
TS
9322 opn = "ceil.l.d";
9323 break;
bf4120ad 9324 case OPC_FLOOR_L_D:
5e755519 9325 check_cp1_64bitmode(ctx);
b6d96bed 9326 {
a7812ae4 9327 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9328
9329 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9330 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 9331 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9332 tcg_temp_free_i64(fp0);
b6d96bed 9333 }
5a5012ec
TS
9334 opn = "floor.l.d";
9335 break;
bf4120ad 9336 case OPC_ROUND_W_D:
5e755519 9337 check_cp1_registers(ctx, fs);
b6d96bed 9338 {
a7812ae4
PB
9339 TCGv_i32 fp32 = tcg_temp_new_i32();
9340 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9341
9342 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9343 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 9344 tcg_temp_free_i64(fp64);
b6d96bed 9345 gen_store_fpr32(fp32, fd);
a7812ae4 9346 tcg_temp_free_i32(fp32);
b6d96bed 9347 }
6ea83fed
FB
9348 opn = "round.w.d";
9349 break;
bf4120ad 9350 case OPC_TRUNC_W_D:
5e755519 9351 check_cp1_registers(ctx, fs);
b6d96bed 9352 {
a7812ae4
PB
9353 TCGv_i32 fp32 = tcg_temp_new_i32();
9354 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9355
9356 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9357 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 9358 tcg_temp_free_i64(fp64);
b6d96bed 9359 gen_store_fpr32(fp32, fd);
a7812ae4 9360 tcg_temp_free_i32(fp32);
b6d96bed 9361 }
6ea83fed
FB
9362 opn = "trunc.w.d";
9363 break;
bf4120ad 9364 case OPC_CEIL_W_D:
5e755519 9365 check_cp1_registers(ctx, fs);
b6d96bed 9366 {
a7812ae4
PB
9367 TCGv_i32 fp32 = tcg_temp_new_i32();
9368 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9369
9370 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9371 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 9372 tcg_temp_free_i64(fp64);
b6d96bed 9373 gen_store_fpr32(fp32, fd);
a7812ae4 9374 tcg_temp_free_i32(fp32);
b6d96bed 9375 }
6ea83fed
FB
9376 opn = "ceil.w.d";
9377 break;
bf4120ad 9378 case OPC_FLOOR_W_D:
5e755519 9379 check_cp1_registers(ctx, fs);
b6d96bed 9380 {
a7812ae4
PB
9381 TCGv_i32 fp32 = tcg_temp_new_i32();
9382 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9383
9384 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9385 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 9386 tcg_temp_free_i64(fp64);
b6d96bed 9387 gen_store_fpr32(fp32, fd);
a7812ae4 9388 tcg_temp_free_i32(fp32);
b6d96bed 9389 }
7a387fff 9390 opn = "floor.w.d";
6ea83fed 9391 break;
e7f16abb
LA
9392 case OPC_SEL_D:
9393 check_insn(ctx, ISA_MIPS32R6);
9394 gen_sel_d(ctx, op1, fd, ft, fs);
9395 opn = "sel.d";
9396 break;
9397 case OPC_SELEQZ_D:
9398 check_insn(ctx, ISA_MIPS32R6);
9399 gen_sel_d(ctx, op1, fd, ft, fs);
9400 opn = "seleqz.d";
9401 break;
9402 case OPC_SELNEZ_D:
9403 check_insn(ctx, ISA_MIPS32R6);
9404 gen_sel_d(ctx, op1, fd, ft, fs);
9405 opn = "selnez.d";
9406 break;
bf4120ad 9407 case OPC_MOVCF_D:
fecd2646 9408 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9409 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9410 opn = "movcf.d";
dd016883 9411 break;
bf4120ad 9412 case OPC_MOVZ_D:
fecd2646 9413 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9414 {
9415 int l1 = gen_new_label();
c9297f4d 9416 TCGv_i64 fp0;
a16336e4 9417
c9297f4d
AJ
9418 if (ft != 0) {
9419 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9420 }
9421 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9422 gen_load_fpr64(ctx, fp0, fs);
9423 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9424 tcg_temp_free_i64(fp0);
a16336e4
TS
9425 gen_set_label(l1);
9426 }
5a5012ec
TS
9427 opn = "movz.d";
9428 break;
bf4120ad 9429 case OPC_MOVN_D:
fecd2646 9430 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9431 {
9432 int l1 = gen_new_label();
c9297f4d
AJ
9433 TCGv_i64 fp0;
9434
9435 if (ft != 0) {
9436 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9437 fp0 = tcg_temp_new_i64();
9438 gen_load_fpr64(ctx, fp0, fs);
9439 gen_store_fpr64(ctx, fp0, fd);
9440 tcg_temp_free_i64(fp0);
9441 gen_set_label(l1);
9442 }
a16336e4 9443 }
5a5012ec 9444 opn = "movn.d";
6ea83fed 9445 break;
bf4120ad 9446 case OPC_RECIP_D:
b8aa4598 9447 check_cp1_64bitmode(ctx);
b6d96bed 9448 {
a7812ae4 9449 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9450
9451 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9452 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9453 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9454 tcg_temp_free_i64(fp0);
b6d96bed 9455 }
57fa1fb3
TS
9456 opn = "recip.d";
9457 break;
bf4120ad 9458 case OPC_RSQRT_D:
b8aa4598 9459 check_cp1_64bitmode(ctx);
b6d96bed 9460 {
a7812ae4 9461 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9462
9463 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9464 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9465 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9466 tcg_temp_free_i64(fp0);
b6d96bed 9467 }
57fa1fb3
TS
9468 opn = "rsqrt.d";
9469 break;
e7f16abb
LA
9470 case OPC_MADDF_D:
9471 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9472 {
a7812ae4
PB
9473 TCGv_i64 fp0 = tcg_temp_new_i64();
9474 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9475 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9476 gen_load_fpr64(ctx, fp0, fs);
9477 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9478 gen_load_fpr64(ctx, fp2, fd);
9479 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9480 gen_store_fpr64(ctx, fp2, fd);
9481 tcg_temp_free_i64(fp2);
a7812ae4 9482 tcg_temp_free_i64(fp1);
a7812ae4 9483 tcg_temp_free_i64(fp0);
e7f16abb 9484 opn = "maddf.d";
b6d96bed 9485 }
57fa1fb3 9486 break;
e7f16abb
LA
9487 case OPC_MSUBF_D:
9488 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9489 {
a7812ae4 9490 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9491 TCGv_i64 fp1 = tcg_temp_new_i64();
9492 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9493 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9494 gen_load_fpr64(ctx, fp1, ft);
9495 gen_load_fpr64(ctx, fp2, fd);
9496 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9497 gen_store_fpr64(ctx, fp2, fd);
9498 tcg_temp_free_i64(fp2);
9499 tcg_temp_free_i64(fp1);
a7812ae4 9500 tcg_temp_free_i64(fp0);
e7f16abb 9501 opn = "msubf.d";
b6d96bed 9502 }
57fa1fb3 9503 break;
e7f16abb
LA
9504 case OPC_RINT_D:
9505 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9506 {
a7812ae4 9507 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9508 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9509 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9510 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9511 tcg_temp_free_i64(fp0);
e7f16abb 9512 opn = "rint.d";
b6d96bed 9513 }
57fa1fb3 9514 break;
e7f16abb
LA
9515 case OPC_CLASS_D:
9516 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9517 {
e7f16abb
LA
9518 TCGv_i64 fp0 = tcg_temp_new_i64();
9519 gen_load_fpr64(ctx, fp0, fs);
9520 gen_helper_float_class_d(fp0, fp0);
9521 gen_store_fpr64(ctx, fp0, fd);
9522 tcg_temp_free_i64(fp0);
9523 opn = "class.d";
9524 }
9525 break;
9526 case OPC_MIN_D: /* OPC_RECIP2_D */
9527 if (ctx->insn_flags & ISA_MIPS32R6) {
9528 /* OPC_MIN_D */
a7812ae4
PB
9529 TCGv_i64 fp0 = tcg_temp_new_i64();
9530 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9531 gen_load_fpr64(ctx, fp0, fs);
9532 gen_load_fpr64(ctx, fp1, ft);
9533 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9534 gen_store_fpr64(ctx, fp1, fd);
9535 tcg_temp_free_i64(fp1);
9536 tcg_temp_free_i64(fp0);
9537 opn = "min.d";
9538 } else {
9539 /* OPC_RECIP2_D */
9540 check_cp1_64bitmode(ctx);
9541 {
9542 TCGv_i64 fp0 = tcg_temp_new_i64();
9543 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9544
e7f16abb
LA
9545 gen_load_fpr64(ctx, fp0, fs);
9546 gen_load_fpr64(ctx, fp1, ft);
9547 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9548 tcg_temp_free_i64(fp1);
9549 gen_store_fpr64(ctx, fp0, fd);
9550 tcg_temp_free_i64(fp0);
9551 }
9552 opn = "recip2.d";
9553 }
9554 break;
9555 case OPC_MINA_D: /* OPC_RECIP1_D */
9556 if (ctx->insn_flags & ISA_MIPS32R6) {
9557 /* OPC_MINA_D */
9558 TCGv_i64 fp0 = tcg_temp_new_i64();
9559 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9560 gen_load_fpr64(ctx, fp0, fs);
9561 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9562 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9563 gen_store_fpr64(ctx, fp1, fd);
9564 tcg_temp_free_i64(fp1);
9565 tcg_temp_free_i64(fp0);
9566 opn = "mina.d";
9567 } else {
9568 /* OPC_RECIP1_D */
9569 check_cp1_64bitmode(ctx);
9570 {
9571 TCGv_i64 fp0 = tcg_temp_new_i64();
9572
9573 gen_load_fpr64(ctx, fp0, fs);
9574 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9575 gen_store_fpr64(ctx, fp0, fd);
9576 tcg_temp_free_i64(fp0);
9577 }
9578 opn = "recip1.d";
9579 }
9580 break;
9581 case OPC_MAX_D: /* OPC_RSQRT1_D */
9582 if (ctx->insn_flags & ISA_MIPS32R6) {
9583 /* OPC_MAX_D */
9584 TCGv_i64 fp0 = tcg_temp_new_i64();
9585 TCGv_i64 fp1 = tcg_temp_new_i64();
9586 gen_load_fpr64(ctx, fp0, fs);
9587 gen_load_fpr64(ctx, fp1, ft);
9588 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9589 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9590 tcg_temp_free_i64(fp1);
a7812ae4 9591 tcg_temp_free_i64(fp0);
e7f16abb
LA
9592 opn = "max.d";
9593 } else {
9594 /* OPC_RSQRT1_D */
9595 check_cp1_64bitmode(ctx);
9596 {
9597 TCGv_i64 fp0 = tcg_temp_new_i64();
9598
9599 gen_load_fpr64(ctx, fp0, fs);
9600 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9601 gen_store_fpr64(ctx, fp0, fd);
9602 tcg_temp_free_i64(fp0);
9603 }
9604 opn = "rsqrt1.d";
9605 }
9606 break;
9607 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9608 if (ctx->insn_flags & ISA_MIPS32R6) {
9609 /* OPC_MAXA_D */
9610 TCGv_i64 fp0 = tcg_temp_new_i64();
9611 TCGv_i64 fp1 = tcg_temp_new_i64();
9612 gen_load_fpr64(ctx, fp0, fs);
9613 gen_load_fpr64(ctx, fp1, ft);
9614 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9615 gen_store_fpr64(ctx, fp1, fd);
9616 tcg_temp_free_i64(fp1);
9617 tcg_temp_free_i64(fp0);
9618 opn = "maxa.d";
9619 } else {
9620 /* OPC_RSQRT2_D */
9621 check_cp1_64bitmode(ctx);
9622 {
9623 TCGv_i64 fp0 = tcg_temp_new_i64();
9624 TCGv_i64 fp1 = tcg_temp_new_i64();
9625
9626 gen_load_fpr64(ctx, fp0, fs);
9627 gen_load_fpr64(ctx, fp1, ft);
9628 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9629 tcg_temp_free_i64(fp1);
9630 gen_store_fpr64(ctx, fp0, fd);
9631 tcg_temp_free_i64(fp0);
9632 }
9633 opn = "rsqrt2.d";
b6d96bed 9634 }
57fa1fb3 9635 break;
bf4120ad
NF
9636 case OPC_CMP_F_D:
9637 case OPC_CMP_UN_D:
9638 case OPC_CMP_EQ_D:
9639 case OPC_CMP_UEQ_D:
9640 case OPC_CMP_OLT_D:
9641 case OPC_CMP_ULT_D:
9642 case OPC_CMP_OLE_D:
9643 case OPC_CMP_ULE_D:
9644 case OPC_CMP_SF_D:
9645 case OPC_CMP_NGLE_D:
9646 case OPC_CMP_SEQ_D:
9647 case OPC_CMP_NGL_D:
9648 case OPC_CMP_LT_D:
9649 case OPC_CMP_NGE_D:
9650 case OPC_CMP_LE_D:
9651 case OPC_CMP_NGT_D:
fecd2646 9652 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9653 if (ctx->opcode & (1 << 6)) {
9654 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9655 opn = condnames_abs[func-48];
9656 } else {
9657 gen_cmp_d(ctx, func-48, ft, fs, cc);
9658 opn = condnames[func-48];
5a1e8ffb 9659 }
6ea83fed 9660 break;
bf4120ad 9661 case OPC_CVT_S_D:
5e755519 9662 check_cp1_registers(ctx, fs);
b6d96bed 9663 {
a7812ae4
PB
9664 TCGv_i32 fp32 = tcg_temp_new_i32();
9665 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9666
9667 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9668 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9669 tcg_temp_free_i64(fp64);
b6d96bed 9670 gen_store_fpr32(fp32, fd);
a7812ae4 9671 tcg_temp_free_i32(fp32);
b6d96bed 9672 }
5a5012ec
TS
9673 opn = "cvt.s.d";
9674 break;
bf4120ad 9675 case OPC_CVT_W_D:
5e755519 9676 check_cp1_registers(ctx, fs);
b6d96bed 9677 {
a7812ae4
PB
9678 TCGv_i32 fp32 = tcg_temp_new_i32();
9679 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9680
9681 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9682 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9683 tcg_temp_free_i64(fp64);
b6d96bed 9684 gen_store_fpr32(fp32, fd);
a7812ae4 9685 tcg_temp_free_i32(fp32);
b6d96bed 9686 }
5a5012ec
TS
9687 opn = "cvt.w.d";
9688 break;
bf4120ad 9689 case OPC_CVT_L_D:
5e755519 9690 check_cp1_64bitmode(ctx);
b6d96bed 9691 {
a7812ae4 9692 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9693
9694 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9695 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9696 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9697 tcg_temp_free_i64(fp0);
b6d96bed 9698 }
5a5012ec
TS
9699 opn = "cvt.l.d";
9700 break;
bf4120ad 9701 case OPC_CVT_S_W:
b6d96bed 9702 {
a7812ae4 9703 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9704
9705 gen_load_fpr32(fp0, fs);
895c2d04 9706 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 9707 gen_store_fpr32(fp0, fd);
a7812ae4 9708 tcg_temp_free_i32(fp0);
b6d96bed 9709 }
5a5012ec 9710 opn = "cvt.s.w";
6ea83fed 9711 break;
bf4120ad 9712 case OPC_CVT_D_W:
5e755519 9713 check_cp1_registers(ctx, fd);
b6d96bed 9714 {
a7812ae4
PB
9715 TCGv_i32 fp32 = tcg_temp_new_i32();
9716 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9717
9718 gen_load_fpr32(fp32, fs);
895c2d04 9719 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9720 tcg_temp_free_i32(fp32);
b6d96bed 9721 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9722 tcg_temp_free_i64(fp64);
b6d96bed 9723 }
5a5012ec
TS
9724 opn = "cvt.d.w";
9725 break;
bf4120ad 9726 case OPC_CVT_S_L:
5e755519 9727 check_cp1_64bitmode(ctx);
b6d96bed 9728 {
a7812ae4
PB
9729 TCGv_i32 fp32 = tcg_temp_new_i32();
9730 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9731
9732 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9733 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9734 tcg_temp_free_i64(fp64);
b6d96bed 9735 gen_store_fpr32(fp32, fd);
a7812ae4 9736 tcg_temp_free_i32(fp32);
b6d96bed 9737 }
5a5012ec
TS
9738 opn = "cvt.s.l";
9739 break;
bf4120ad 9740 case OPC_CVT_D_L:
5e755519 9741 check_cp1_64bitmode(ctx);
b6d96bed 9742 {
a7812ae4 9743 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9744
9745 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9746 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9747 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9748 tcg_temp_free_i64(fp0);
b6d96bed 9749 }
5a5012ec
TS
9750 opn = "cvt.d.l";
9751 break;
bf4120ad 9752 case OPC_CVT_PS_PW:
fecd2646 9753 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9754 check_cp1_64bitmode(ctx);
b6d96bed 9755 {
a7812ae4 9756 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9757
9758 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9759 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9760 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9761 tcg_temp_free_i64(fp0);
b6d96bed 9762 }
5a5012ec
TS
9763 opn = "cvt.ps.pw";
9764 break;
bf4120ad 9765 case OPC_ADD_PS:
5e755519 9766 check_cp1_64bitmode(ctx);
b6d96bed 9767 {
a7812ae4
PB
9768 TCGv_i64 fp0 = tcg_temp_new_i64();
9769 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9770
9771 gen_load_fpr64(ctx, fp0, fs);
9772 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9773 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9774 tcg_temp_free_i64(fp1);
b6d96bed 9775 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9776 tcg_temp_free_i64(fp0);
b6d96bed 9777 }
5a5012ec 9778 opn = "add.ps";
6ea83fed 9779 break;
bf4120ad 9780 case OPC_SUB_PS:
5e755519 9781 check_cp1_64bitmode(ctx);
b6d96bed 9782 {
a7812ae4
PB
9783 TCGv_i64 fp0 = tcg_temp_new_i64();
9784 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9785
9786 gen_load_fpr64(ctx, fp0, fs);
9787 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9788 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9789 tcg_temp_free_i64(fp1);
b6d96bed 9790 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9791 tcg_temp_free_i64(fp0);
b6d96bed 9792 }
5a5012ec 9793 opn = "sub.ps";
6ea83fed 9794 break;
bf4120ad 9795 case OPC_MUL_PS:
5e755519 9796 check_cp1_64bitmode(ctx);
b6d96bed 9797 {
a7812ae4
PB
9798 TCGv_i64 fp0 = tcg_temp_new_i64();
9799 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9800
9801 gen_load_fpr64(ctx, fp0, fs);
9802 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9803 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9804 tcg_temp_free_i64(fp1);
b6d96bed 9805 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9806 tcg_temp_free_i64(fp0);
b6d96bed 9807 }
5a5012ec 9808 opn = "mul.ps";
6ea83fed 9809 break;
bf4120ad 9810 case OPC_ABS_PS:
5e755519 9811 check_cp1_64bitmode(ctx);
b6d96bed 9812 {
a7812ae4 9813 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9814
9815 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9816 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9817 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9818 tcg_temp_free_i64(fp0);
b6d96bed 9819 }
5a5012ec 9820 opn = "abs.ps";
6ea83fed 9821 break;
bf4120ad 9822 case OPC_MOV_PS:
5e755519 9823 check_cp1_64bitmode(ctx);
b6d96bed 9824 {
a7812ae4 9825 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9826
9827 gen_load_fpr64(ctx, fp0, fs);
9828 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9829 tcg_temp_free_i64(fp0);
b6d96bed 9830 }
5a5012ec 9831 opn = "mov.ps";
6ea83fed 9832 break;
bf4120ad 9833 case OPC_NEG_PS:
5e755519 9834 check_cp1_64bitmode(ctx);
b6d96bed 9835 {
a7812ae4 9836 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9837
9838 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9839 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9840 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9841 tcg_temp_free_i64(fp0);
b6d96bed 9842 }
5a5012ec 9843 opn = "neg.ps";
6ea83fed 9844 break;
bf4120ad 9845 case OPC_MOVCF_PS:
5e755519 9846 check_cp1_64bitmode(ctx);
7f6613ce 9847 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9848 opn = "movcf.ps";
6ea83fed 9849 break;
bf4120ad 9850 case OPC_MOVZ_PS:
5e755519 9851 check_cp1_64bitmode(ctx);
a16336e4
TS
9852 {
9853 int l1 = gen_new_label();
30a3848b 9854 TCGv_i64 fp0;
a16336e4 9855
c9297f4d
AJ
9856 if (ft != 0)
9857 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9858 fp0 = tcg_temp_new_i64();
9859 gen_load_fpr64(ctx, fp0, fs);
9860 gen_store_fpr64(ctx, fp0, fd);
9861 tcg_temp_free_i64(fp0);
a16336e4
TS
9862 gen_set_label(l1);
9863 }
5a5012ec 9864 opn = "movz.ps";
6ea83fed 9865 break;
bf4120ad 9866 case OPC_MOVN_PS:
5e755519 9867 check_cp1_64bitmode(ctx);
a16336e4
TS
9868 {
9869 int l1 = gen_new_label();
30a3848b 9870 TCGv_i64 fp0;
c9297f4d
AJ
9871
9872 if (ft != 0) {
9873 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9874 fp0 = tcg_temp_new_i64();
9875 gen_load_fpr64(ctx, fp0, fs);
9876 gen_store_fpr64(ctx, fp0, fd);
9877 tcg_temp_free_i64(fp0);
9878 gen_set_label(l1);
9879 }
a16336e4 9880 }
5a5012ec 9881 opn = "movn.ps";
6ea83fed 9882 break;
bf4120ad 9883 case OPC_ADDR_PS:
5e755519 9884 check_cp1_64bitmode(ctx);
b6d96bed 9885 {
a7812ae4
PB
9886 TCGv_i64 fp0 = tcg_temp_new_i64();
9887 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9888
9889 gen_load_fpr64(ctx, fp0, ft);
9890 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9891 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9892 tcg_temp_free_i64(fp1);
b6d96bed 9893 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9894 tcg_temp_free_i64(fp0);
b6d96bed 9895 }
fbcc6828
TS
9896 opn = "addr.ps";
9897 break;
bf4120ad 9898 case OPC_MULR_PS:
5e755519 9899 check_cp1_64bitmode(ctx);
b6d96bed 9900 {
a7812ae4
PB
9901 TCGv_i64 fp0 = tcg_temp_new_i64();
9902 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9903
9904 gen_load_fpr64(ctx, fp0, ft);
9905 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9906 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9907 tcg_temp_free_i64(fp1);
b6d96bed 9908 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9909 tcg_temp_free_i64(fp0);
b6d96bed 9910 }
57fa1fb3
TS
9911 opn = "mulr.ps";
9912 break;
bf4120ad 9913 case OPC_RECIP2_PS:
5e755519 9914 check_cp1_64bitmode(ctx);
b6d96bed 9915 {
a7812ae4
PB
9916 TCGv_i64 fp0 = tcg_temp_new_i64();
9917 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9918
9919 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9920 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9921 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9922 tcg_temp_free_i64(fp1);
b6d96bed 9923 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9924 tcg_temp_free_i64(fp0);
b6d96bed 9925 }
57fa1fb3
TS
9926 opn = "recip2.ps";
9927 break;
bf4120ad 9928 case OPC_RECIP1_PS:
5e755519 9929 check_cp1_64bitmode(ctx);
b6d96bed 9930 {
a7812ae4 9931 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9932
9933 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9934 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9935 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9936 tcg_temp_free_i64(fp0);
b6d96bed 9937 }
57fa1fb3
TS
9938 opn = "recip1.ps";
9939 break;
bf4120ad 9940 case OPC_RSQRT1_PS:
5e755519 9941 check_cp1_64bitmode(ctx);
b6d96bed 9942 {
a7812ae4 9943 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9944
9945 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9946 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9947 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9948 tcg_temp_free_i64(fp0);
b6d96bed 9949 }
57fa1fb3
TS
9950 opn = "rsqrt1.ps";
9951 break;
bf4120ad 9952 case OPC_RSQRT2_PS:
5e755519 9953 check_cp1_64bitmode(ctx);
b6d96bed 9954 {
a7812ae4
PB
9955 TCGv_i64 fp0 = tcg_temp_new_i64();
9956 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9957
9958 gen_load_fpr64(ctx, fp0, fs);
9959 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9960 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9961 tcg_temp_free_i64(fp1);
b6d96bed 9962 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9963 tcg_temp_free_i64(fp0);
b6d96bed 9964 }
57fa1fb3
TS
9965 opn = "rsqrt2.ps";
9966 break;
bf4120ad 9967 case OPC_CVT_S_PU:
5e755519 9968 check_cp1_64bitmode(ctx);
b6d96bed 9969 {
a7812ae4 9970 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9971
7f6613ce 9972 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9973 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 9974 gen_store_fpr32(fp0, fd);
a7812ae4 9975 tcg_temp_free_i32(fp0);
b6d96bed 9976 }
5a5012ec 9977 opn = "cvt.s.pu";
dd016883 9978 break;
bf4120ad 9979 case OPC_CVT_PW_PS:
5e755519 9980 check_cp1_64bitmode(ctx);
b6d96bed 9981 {
a7812ae4 9982 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9983
9984 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9985 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9986 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9987 tcg_temp_free_i64(fp0);
b6d96bed 9988 }
5a5012ec 9989 opn = "cvt.pw.ps";
6ea83fed 9990 break;
bf4120ad 9991 case OPC_CVT_S_PL:
5e755519 9992 check_cp1_64bitmode(ctx);
b6d96bed 9993 {
a7812ae4 9994 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9995
9996 gen_load_fpr32(fp0, fs);
895c2d04 9997 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 9998 gen_store_fpr32(fp0, fd);
a7812ae4 9999 tcg_temp_free_i32(fp0);
b6d96bed 10000 }
5a5012ec 10001 opn = "cvt.s.pl";
6ea83fed 10002 break;
bf4120ad 10003 case OPC_PLL_PS:
5e755519 10004 check_cp1_64bitmode(ctx);
b6d96bed 10005 {
a7812ae4
PB
10006 TCGv_i32 fp0 = tcg_temp_new_i32();
10007 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
10008
10009 gen_load_fpr32(fp0, fs);
10010 gen_load_fpr32(fp1, ft);
7f6613ce 10011 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 10012 gen_store_fpr32(fp1, fd);
a7812ae4
PB
10013 tcg_temp_free_i32(fp0);
10014 tcg_temp_free_i32(fp1);
b6d96bed 10015 }
5a5012ec 10016 opn = "pll.ps";
6ea83fed 10017 break;
bf4120ad 10018 case OPC_PLU_PS:
5e755519 10019 check_cp1_64bitmode(ctx);
b6d96bed 10020 {
a7812ae4
PB
10021 TCGv_i32 fp0 = tcg_temp_new_i32();
10022 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
10023
10024 gen_load_fpr32(fp0, fs);
7f6613ce 10025 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10026 gen_store_fpr32(fp1, fd);
7f6613ce 10027 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10028 tcg_temp_free_i32(fp0);
10029 tcg_temp_free_i32(fp1);
b6d96bed 10030 }
5a5012ec
TS
10031 opn = "plu.ps";
10032 break;
bf4120ad 10033 case OPC_PUL_PS:
5e755519 10034 check_cp1_64bitmode(ctx);
b6d96bed 10035 {
a7812ae4
PB
10036 TCGv_i32 fp0 = tcg_temp_new_i32();
10037 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10038
7f6613ce 10039 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
10040 gen_load_fpr32(fp1, ft);
10041 gen_store_fpr32(fp1, fd);
7f6613ce 10042 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10043 tcg_temp_free_i32(fp0);
10044 tcg_temp_free_i32(fp1);
b6d96bed 10045 }
5a5012ec
TS
10046 opn = "pul.ps";
10047 break;
bf4120ad 10048 case OPC_PUU_PS:
5e755519 10049 check_cp1_64bitmode(ctx);
b6d96bed 10050 {
a7812ae4
PB
10051 TCGv_i32 fp0 = tcg_temp_new_i32();
10052 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10053
7f6613ce
PJ
10054 gen_load_fpr32h(ctx, fp0, fs);
10055 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 10056 gen_store_fpr32(fp1, fd);
7f6613ce 10057 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10058 tcg_temp_free_i32(fp0);
10059 tcg_temp_free_i32(fp1);
b6d96bed 10060 }
5a5012ec
TS
10061 opn = "puu.ps";
10062 break;
bf4120ad
NF
10063 case OPC_CMP_F_PS:
10064 case OPC_CMP_UN_PS:
10065 case OPC_CMP_EQ_PS:
10066 case OPC_CMP_UEQ_PS:
10067 case OPC_CMP_OLT_PS:
10068 case OPC_CMP_ULT_PS:
10069 case OPC_CMP_OLE_PS:
10070 case OPC_CMP_ULE_PS:
10071 case OPC_CMP_SF_PS:
10072 case OPC_CMP_NGLE_PS:
10073 case OPC_CMP_SEQ_PS:
10074 case OPC_CMP_NGL_PS:
10075 case OPC_CMP_LT_PS:
10076 case OPC_CMP_NGE_PS:
10077 case OPC_CMP_LE_PS:
10078 case OPC_CMP_NGT_PS:
8153667c
NF
10079 if (ctx->opcode & (1 << 6)) {
10080 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10081 opn = condnames_abs[func-48];
10082 } else {
10083 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10084 opn = condnames[func-48];
5a1e8ffb 10085 }
6ea83fed 10086 break;
5a5012ec 10087 default:
923617a3 10088 MIPS_INVAL(opn);
e397ee33 10089 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
10090 return;
10091 }
2abf314d 10092 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
10093 switch (optype) {
10094 case BINOP:
6ea83fed 10095 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
10096 break;
10097 case CMPOP:
10098 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
10099 break;
10100 default:
6ea83fed 10101 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
10102 break;
10103 }
6ea83fed 10104}
6af0bf9c 10105
5a5012ec 10106/* Coprocessor 3 (FPU) */
5e755519
TS
10107static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10108 int fd, int fs, int base, int index)
7a387fff 10109{
923617a3 10110 const char *opn = "extended float load/store";
93b12ccc 10111 int store = 0;
4e2474d6 10112 TCGv t0 = tcg_temp_new();
7a387fff 10113
93b12ccc 10114 if (base == 0) {
6c5c1e20 10115 gen_load_gpr(t0, index);
93b12ccc 10116 } else if (index == 0) {
6c5c1e20 10117 gen_load_gpr(t0, base);
93b12ccc 10118 } else {
05168674 10119 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10120 }
5a5012ec 10121 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10122 memory access. */
5a5012ec
TS
10123 switch (opc) {
10124 case OPC_LWXC1:
8c0ab41f 10125 check_cop1x(ctx);
b6d96bed 10126 {
a7812ae4 10127 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10128
5f68f5ae 10129 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10130 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 10131 gen_store_fpr32(fp0, fd);
a7812ae4 10132 tcg_temp_free_i32(fp0);
b6d96bed 10133 }
5a5012ec
TS
10134 opn = "lwxc1";
10135 break;
10136 case OPC_LDXC1:
8c0ab41f
AJ
10137 check_cop1x(ctx);
10138 check_cp1_registers(ctx, fd);
b6d96bed 10139 {
a7812ae4 10140 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10141 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10142 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10143 tcg_temp_free_i64(fp0);
b6d96bed 10144 }
5a5012ec
TS
10145 opn = "ldxc1";
10146 break;
10147 case OPC_LUXC1:
8c0ab41f 10148 check_cp1_64bitmode(ctx);
6c5c1e20 10149 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10150 {
a7812ae4 10151 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10152
5f68f5ae 10153 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10154 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10155 tcg_temp_free_i64(fp0);
b6d96bed 10156 }
5a5012ec
TS
10157 opn = "luxc1";
10158 break;
10159 case OPC_SWXC1:
8c0ab41f 10160 check_cop1x(ctx);
b6d96bed 10161 {
a7812ae4 10162 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10163 gen_load_fpr32(fp0, fs);
5f68f5ae 10164 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10165 tcg_temp_free_i32(fp0);
b6d96bed 10166 }
5a5012ec 10167 opn = "swxc1";
93b12ccc 10168 store = 1;
5a5012ec
TS
10169 break;
10170 case OPC_SDXC1:
8c0ab41f
AJ
10171 check_cop1x(ctx);
10172 check_cp1_registers(ctx, fs);
b6d96bed 10173 {
a7812ae4 10174 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10175 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10176 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10177 tcg_temp_free_i64(fp0);
b6d96bed 10178 }
5a5012ec 10179 opn = "sdxc1";
93b12ccc 10180 store = 1;
5a5012ec
TS
10181 break;
10182 case OPC_SUXC1:
8c0ab41f 10183 check_cp1_64bitmode(ctx);
6c5c1e20 10184 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10185 {
a7812ae4 10186 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10187 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10188 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10189 tcg_temp_free_i64(fp0);
b6d96bed 10190 }
5a5012ec 10191 opn = "suxc1";
93b12ccc 10192 store = 1;
5a5012ec 10193 break;
5a5012ec 10194 }
6c5c1e20 10195 tcg_temp_free(t0);
2abf314d 10196 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
10197 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
10198 regnames[index], regnames[base]);
5a5012ec
TS
10199}
10200
5e755519
TS
10201static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10202 int fd, int fr, int fs, int ft)
5a5012ec 10203{
923617a3 10204 const char *opn = "flt3_arith";
5a5012ec 10205
5a5012ec
TS
10206 switch (opc) {
10207 case OPC_ALNV_PS:
b8aa4598 10208 check_cp1_64bitmode(ctx);
a16336e4 10209 {
a7812ae4 10210 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10211 TCGv_i32 fp = tcg_temp_new_i32();
10212 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
10213 int l1 = gen_new_label();
10214 int l2 = gen_new_label();
10215
6c5c1e20
TS
10216 gen_load_gpr(t0, fr);
10217 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10218
10219 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 10220 gen_load_fpr32(fp, fs);
7f6613ce 10221 gen_load_fpr32h(ctx, fph, fs);
c905fdac 10222 gen_store_fpr32(fp, fd);
7f6613ce 10223 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10224 tcg_gen_br(l2);
10225 gen_set_label(l1);
6c5c1e20
TS
10226 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10227 tcg_temp_free(t0);
a16336e4 10228#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 10229 gen_load_fpr32(fp, fs);
7f6613ce
PJ
10230 gen_load_fpr32h(ctx, fph, ft);
10231 gen_store_fpr32h(ctx, fp, fd);
c905fdac 10232 gen_store_fpr32(fph, fd);
a16336e4 10233#else
7f6613ce 10234 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
10235 gen_load_fpr32(fp, ft);
10236 gen_store_fpr32(fph, fd);
7f6613ce 10237 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10238#endif
10239 gen_set_label(l2);
c905fdac
AJ
10240 tcg_temp_free_i32(fp);
10241 tcg_temp_free_i32(fph);
a16336e4 10242 }
5a5012ec
TS
10243 opn = "alnv.ps";
10244 break;
10245 case OPC_MADD_S:
b8aa4598 10246 check_cop1x(ctx);
b6d96bed 10247 {
a7812ae4
PB
10248 TCGv_i32 fp0 = tcg_temp_new_i32();
10249 TCGv_i32 fp1 = tcg_temp_new_i32();
10250 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10251
10252 gen_load_fpr32(fp0, fs);
10253 gen_load_fpr32(fp1, ft);
10254 gen_load_fpr32(fp2, fr);
b3d6cd44 10255 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10256 tcg_temp_free_i32(fp0);
10257 tcg_temp_free_i32(fp1);
b6d96bed 10258 gen_store_fpr32(fp2, fd);
a7812ae4 10259 tcg_temp_free_i32(fp2);
b6d96bed 10260 }
5a5012ec
TS
10261 opn = "madd.s";
10262 break;
10263 case OPC_MADD_D:
b8aa4598
TS
10264 check_cop1x(ctx);
10265 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10266 {
a7812ae4
PB
10267 TCGv_i64 fp0 = tcg_temp_new_i64();
10268 TCGv_i64 fp1 = tcg_temp_new_i64();
10269 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10270
10271 gen_load_fpr64(ctx, fp0, fs);
10272 gen_load_fpr64(ctx, fp1, ft);
10273 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10274 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10275 tcg_temp_free_i64(fp0);
10276 tcg_temp_free_i64(fp1);
b6d96bed 10277 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10278 tcg_temp_free_i64(fp2);
b6d96bed 10279 }
5a5012ec
TS
10280 opn = "madd.d";
10281 break;
10282 case OPC_MADD_PS:
b8aa4598 10283 check_cp1_64bitmode(ctx);
b6d96bed 10284 {
a7812ae4
PB
10285 TCGv_i64 fp0 = tcg_temp_new_i64();
10286 TCGv_i64 fp1 = tcg_temp_new_i64();
10287 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10288
10289 gen_load_fpr64(ctx, fp0, fs);
10290 gen_load_fpr64(ctx, fp1, ft);
10291 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10292 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10293 tcg_temp_free_i64(fp0);
10294 tcg_temp_free_i64(fp1);
b6d96bed 10295 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10296 tcg_temp_free_i64(fp2);
b6d96bed 10297 }
5a5012ec
TS
10298 opn = "madd.ps";
10299 break;
10300 case OPC_MSUB_S:
b8aa4598 10301 check_cop1x(ctx);
b6d96bed 10302 {
a7812ae4
PB
10303 TCGv_i32 fp0 = tcg_temp_new_i32();
10304 TCGv_i32 fp1 = tcg_temp_new_i32();
10305 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10306
10307 gen_load_fpr32(fp0, fs);
10308 gen_load_fpr32(fp1, ft);
10309 gen_load_fpr32(fp2, fr);
b3d6cd44 10310 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10311 tcg_temp_free_i32(fp0);
10312 tcg_temp_free_i32(fp1);
b6d96bed 10313 gen_store_fpr32(fp2, fd);
a7812ae4 10314 tcg_temp_free_i32(fp2);
b6d96bed 10315 }
5a5012ec
TS
10316 opn = "msub.s";
10317 break;
10318 case OPC_MSUB_D:
b8aa4598
TS
10319 check_cop1x(ctx);
10320 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10321 {
a7812ae4
PB
10322 TCGv_i64 fp0 = tcg_temp_new_i64();
10323 TCGv_i64 fp1 = tcg_temp_new_i64();
10324 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10325
10326 gen_load_fpr64(ctx, fp0, fs);
10327 gen_load_fpr64(ctx, fp1, ft);
10328 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10329 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10330 tcg_temp_free_i64(fp0);
10331 tcg_temp_free_i64(fp1);
b6d96bed 10332 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10333 tcg_temp_free_i64(fp2);
b6d96bed 10334 }
5a5012ec
TS
10335 opn = "msub.d";
10336 break;
10337 case OPC_MSUB_PS:
b8aa4598 10338 check_cp1_64bitmode(ctx);
b6d96bed 10339 {
a7812ae4
PB
10340 TCGv_i64 fp0 = tcg_temp_new_i64();
10341 TCGv_i64 fp1 = tcg_temp_new_i64();
10342 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10343
10344 gen_load_fpr64(ctx, fp0, fs);
10345 gen_load_fpr64(ctx, fp1, ft);
10346 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10347 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10348 tcg_temp_free_i64(fp0);
10349 tcg_temp_free_i64(fp1);
b6d96bed 10350 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10351 tcg_temp_free_i64(fp2);
b6d96bed 10352 }
5a5012ec
TS
10353 opn = "msub.ps";
10354 break;
10355 case OPC_NMADD_S:
b8aa4598 10356 check_cop1x(ctx);
b6d96bed 10357 {
a7812ae4
PB
10358 TCGv_i32 fp0 = tcg_temp_new_i32();
10359 TCGv_i32 fp1 = tcg_temp_new_i32();
10360 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10361
10362 gen_load_fpr32(fp0, fs);
10363 gen_load_fpr32(fp1, ft);
10364 gen_load_fpr32(fp2, fr);
b3d6cd44 10365 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10366 tcg_temp_free_i32(fp0);
10367 tcg_temp_free_i32(fp1);
b6d96bed 10368 gen_store_fpr32(fp2, fd);
a7812ae4 10369 tcg_temp_free_i32(fp2);
b6d96bed 10370 }
5a5012ec
TS
10371 opn = "nmadd.s";
10372 break;
10373 case OPC_NMADD_D:
b8aa4598
TS
10374 check_cop1x(ctx);
10375 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10376 {
a7812ae4
PB
10377 TCGv_i64 fp0 = tcg_temp_new_i64();
10378 TCGv_i64 fp1 = tcg_temp_new_i64();
10379 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10380
10381 gen_load_fpr64(ctx, fp0, fs);
10382 gen_load_fpr64(ctx, fp1, ft);
10383 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10384 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10385 tcg_temp_free_i64(fp0);
10386 tcg_temp_free_i64(fp1);
b6d96bed 10387 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10388 tcg_temp_free_i64(fp2);
b6d96bed 10389 }
5a5012ec
TS
10390 opn = "nmadd.d";
10391 break;
10392 case OPC_NMADD_PS:
b8aa4598 10393 check_cp1_64bitmode(ctx);
b6d96bed 10394 {
a7812ae4
PB
10395 TCGv_i64 fp0 = tcg_temp_new_i64();
10396 TCGv_i64 fp1 = tcg_temp_new_i64();
10397 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10398
10399 gen_load_fpr64(ctx, fp0, fs);
10400 gen_load_fpr64(ctx, fp1, ft);
10401 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10402 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10403 tcg_temp_free_i64(fp0);
10404 tcg_temp_free_i64(fp1);
b6d96bed 10405 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10406 tcg_temp_free_i64(fp2);
b6d96bed 10407 }
5a5012ec
TS
10408 opn = "nmadd.ps";
10409 break;
10410 case OPC_NMSUB_S:
b8aa4598 10411 check_cop1x(ctx);
b6d96bed 10412 {
a7812ae4
PB
10413 TCGv_i32 fp0 = tcg_temp_new_i32();
10414 TCGv_i32 fp1 = tcg_temp_new_i32();
10415 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10416
10417 gen_load_fpr32(fp0, fs);
10418 gen_load_fpr32(fp1, ft);
10419 gen_load_fpr32(fp2, fr);
b3d6cd44 10420 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10421 tcg_temp_free_i32(fp0);
10422 tcg_temp_free_i32(fp1);
b6d96bed 10423 gen_store_fpr32(fp2, fd);
a7812ae4 10424 tcg_temp_free_i32(fp2);
b6d96bed 10425 }
5a5012ec
TS
10426 opn = "nmsub.s";
10427 break;
10428 case OPC_NMSUB_D:
b8aa4598
TS
10429 check_cop1x(ctx);
10430 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10431 {
a7812ae4
PB
10432 TCGv_i64 fp0 = tcg_temp_new_i64();
10433 TCGv_i64 fp1 = tcg_temp_new_i64();
10434 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10435
10436 gen_load_fpr64(ctx, fp0, fs);
10437 gen_load_fpr64(ctx, fp1, ft);
10438 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10439 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10440 tcg_temp_free_i64(fp0);
10441 tcg_temp_free_i64(fp1);
b6d96bed 10442 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10443 tcg_temp_free_i64(fp2);
b6d96bed 10444 }
5a5012ec
TS
10445 opn = "nmsub.d";
10446 break;
10447 case OPC_NMSUB_PS:
b8aa4598 10448 check_cp1_64bitmode(ctx);
b6d96bed 10449 {
a7812ae4
PB
10450 TCGv_i64 fp0 = tcg_temp_new_i64();
10451 TCGv_i64 fp1 = tcg_temp_new_i64();
10452 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10453
10454 gen_load_fpr64(ctx, fp0, fs);
10455 gen_load_fpr64(ctx, fp1, ft);
10456 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10457 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10458 tcg_temp_free_i64(fp0);
10459 tcg_temp_free_i64(fp1);
b6d96bed 10460 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10461 tcg_temp_free_i64(fp2);
b6d96bed 10462 }
5a5012ec
TS
10463 opn = "nmsub.ps";
10464 break;
923617a3
TS
10465 default:
10466 MIPS_INVAL(opn);
5a5012ec
TS
10467 generate_exception (ctx, EXCP_RI);
10468 return;
10469 }
2abf314d 10470 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10471 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10472 fregnames[fs], fregnames[ft]);
7a387fff
TS
10473}
10474
d75c135e 10475static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10476{
10477 TCGv t0;
10478
b3167288
RH
10479#if !defined(CONFIG_USER_ONLY)
10480 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10481 Therefore only check the ISA in system mode. */
d75c135e 10482 check_insn(ctx, ISA_MIPS32R2);
b3167288 10483#endif
26ebe468
NF
10484 t0 = tcg_temp_new();
10485
10486 switch (rd) {
10487 case 0:
10488 save_cpu_state(ctx, 1);
895c2d04 10489 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10490 gen_store_gpr(t0, rt);
10491 break;
10492 case 1:
10493 save_cpu_state(ctx, 1);
895c2d04 10494 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10495 gen_store_gpr(t0, rt);
10496 break;
10497 case 2:
10498 save_cpu_state(ctx, 1);
895c2d04 10499 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10500 gen_store_gpr(t0, rt);
10501 break;
10502 case 3:
10503 save_cpu_state(ctx, 1);
895c2d04 10504 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10505 gen_store_gpr(t0, rt);
10506 break;
10507 case 29:
10508#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10509 tcg_gen_ld_tl(t0, cpu_env,
10510 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10511 gen_store_gpr(t0, rt);
10512 break;
10513#else
d279279e
PJ
10514 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10515 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10516 tcg_gen_ld_tl(t0, cpu_env,
10517 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10518 gen_store_gpr(t0, rt);
10519 } else {
10520 generate_exception(ctx, EXCP_RI);
10521 }
10522 break;
26ebe468
NF
10523#endif
10524 default: /* Invalid */
10525 MIPS_INVAL("rdhwr");
10526 generate_exception(ctx, EXCP_RI);
10527 break;
10528 }
10529 tcg_temp_free(t0);
10530}
10531
31837be3 10532static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10533{
10534 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10535 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
10536 /* Branches completion */
10537 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10538 ctx->bstate = BS_BRANCH;
10539 save_cpu_state(ctx, 0);
10540 /* FIXME: Need to clear can_do_io. */
364d4831 10541 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8
LA
10542 case MIPS_HFLAG_FBNSLOT:
10543 MIPS_DEBUG("forbidden slot");
10544 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10545 break;
c9602061
NF
10546 case MIPS_HFLAG_B:
10547 /* unconditional branch */
10548 MIPS_DEBUG("unconditional branch");
364d4831
NF
10549 if (proc_hflags & MIPS_HFLAG_BX) {
10550 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10551 }
c9602061
NF
10552 gen_goto_tb(ctx, 0, ctx->btarget);
10553 break;
10554 case MIPS_HFLAG_BL:
10555 /* blikely taken case */
10556 MIPS_DEBUG("blikely branch taken");
10557 gen_goto_tb(ctx, 0, ctx->btarget);
10558 break;
10559 case MIPS_HFLAG_BC:
10560 /* Conditional branch */
10561 MIPS_DEBUG("conditional branch");
10562 {
10563 int l1 = gen_new_label();
10564
10565 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10566 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10567 gen_set_label(l1);
10568 gen_goto_tb(ctx, 0, ctx->btarget);
10569 }
10570 break;
10571 case MIPS_HFLAG_BR:
10572 /* unconditional branch to register */
10573 MIPS_DEBUG("branch to register");
d75c135e 10574 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10575 TCGv t0 = tcg_temp_new();
10576 TCGv_i32 t1 = tcg_temp_new_i32();
10577
10578 tcg_gen_andi_tl(t0, btarget, 0x1);
10579 tcg_gen_trunc_tl_i32(t1, t0);
10580 tcg_temp_free(t0);
10581 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10582 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10583 tcg_gen_or_i32(hflags, hflags, t1);
10584 tcg_temp_free_i32(t1);
10585
10586 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10587 } else {
10588 tcg_gen_mov_tl(cpu_PC, btarget);
10589 }
c9602061
NF
10590 if (ctx->singlestep_enabled) {
10591 save_cpu_state(ctx, 0);
895c2d04 10592 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10593 }
10594 tcg_gen_exit_tb(0);
10595 break;
10596 default:
10597 MIPS_DEBUG("unknown branch");
10598 break;
10599 }
10600 }
10601}
10602
7a387fff 10603/* ISA extensions (ASEs) */
6af0bf9c 10604/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10605
10606/* MIPS16 major opcodes */
10607enum {
10608 M16_OPC_ADDIUSP = 0x00,
10609 M16_OPC_ADDIUPC = 0x01,
10610 M16_OPC_B = 0x02,
10611 M16_OPC_JAL = 0x03,
10612 M16_OPC_BEQZ = 0x04,
10613 M16_OPC_BNEQZ = 0x05,
10614 M16_OPC_SHIFT = 0x06,
10615 M16_OPC_LD = 0x07,
10616 M16_OPC_RRIA = 0x08,
10617 M16_OPC_ADDIU8 = 0x09,
10618 M16_OPC_SLTI = 0x0a,
10619 M16_OPC_SLTIU = 0x0b,
10620 M16_OPC_I8 = 0x0c,
10621 M16_OPC_LI = 0x0d,
10622 M16_OPC_CMPI = 0x0e,
10623 M16_OPC_SD = 0x0f,
10624 M16_OPC_LB = 0x10,
10625 M16_OPC_LH = 0x11,
10626 M16_OPC_LWSP = 0x12,
10627 M16_OPC_LW = 0x13,
10628 M16_OPC_LBU = 0x14,
10629 M16_OPC_LHU = 0x15,
10630 M16_OPC_LWPC = 0x16,
10631 M16_OPC_LWU = 0x17,
10632 M16_OPC_SB = 0x18,
10633 M16_OPC_SH = 0x19,
10634 M16_OPC_SWSP = 0x1a,
10635 M16_OPC_SW = 0x1b,
10636 M16_OPC_RRR = 0x1c,
10637 M16_OPC_RR = 0x1d,
10638 M16_OPC_EXTEND = 0x1e,
10639 M16_OPC_I64 = 0x1f
10640};
10641
10642/* I8 funct field */
10643enum {
10644 I8_BTEQZ = 0x0,
10645 I8_BTNEZ = 0x1,
10646 I8_SWRASP = 0x2,
10647 I8_ADJSP = 0x3,
10648 I8_SVRS = 0x4,
10649 I8_MOV32R = 0x5,
10650 I8_MOVR32 = 0x7
10651};
10652
10653/* RRR f field */
10654enum {
10655 RRR_DADDU = 0x0,
10656 RRR_ADDU = 0x1,
10657 RRR_DSUBU = 0x2,
10658 RRR_SUBU = 0x3
10659};
10660
10661/* RR funct field */
10662enum {
10663 RR_JR = 0x00,
10664 RR_SDBBP = 0x01,
10665 RR_SLT = 0x02,
10666 RR_SLTU = 0x03,
10667 RR_SLLV = 0x04,
10668 RR_BREAK = 0x05,
10669 RR_SRLV = 0x06,
10670 RR_SRAV = 0x07,
10671 RR_DSRL = 0x08,
10672 RR_CMP = 0x0a,
10673 RR_NEG = 0x0b,
10674 RR_AND = 0x0c,
10675 RR_OR = 0x0d,
10676 RR_XOR = 0x0e,
10677 RR_NOT = 0x0f,
10678 RR_MFHI = 0x10,
10679 RR_CNVT = 0x11,
10680 RR_MFLO = 0x12,
10681 RR_DSRA = 0x13,
10682 RR_DSLLV = 0x14,
10683 RR_DSRLV = 0x16,
10684 RR_DSRAV = 0x17,
10685 RR_MULT = 0x18,
10686 RR_MULTU = 0x19,
10687 RR_DIV = 0x1a,
10688 RR_DIVU = 0x1b,
10689 RR_DMULT = 0x1c,
10690 RR_DMULTU = 0x1d,
10691 RR_DDIV = 0x1e,
10692 RR_DDIVU = 0x1f
10693};
10694
10695/* I64 funct field */
10696enum {
10697 I64_LDSP = 0x0,
10698 I64_SDSP = 0x1,
10699 I64_SDRASP = 0x2,
10700 I64_DADJSP = 0x3,
10701 I64_LDPC = 0x4,
364d4831 10702 I64_DADDIU5 = 0x5,
6ea219d0
NF
10703 I64_DADDIUPC = 0x6,
10704 I64_DADDIUSP = 0x7
10705};
10706
10707/* RR ry field for CNVT */
10708enum {
10709 RR_RY_CNVT_ZEB = 0x0,
10710 RR_RY_CNVT_ZEH = 0x1,
10711 RR_RY_CNVT_ZEW = 0x2,
10712 RR_RY_CNVT_SEB = 0x4,
10713 RR_RY_CNVT_SEH = 0x5,
10714 RR_RY_CNVT_SEW = 0x6,
10715};
10716
364d4831
NF
10717static int xlat (int r)
10718{
10719 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10720
10721 return map[r];
10722}
10723
10724static void gen_mips16_save (DisasContext *ctx,
10725 int xsregs, int aregs,
10726 int do_ra, int do_s0, int do_s1,
10727 int framesize)
10728{
10729 TCGv t0 = tcg_temp_new();
10730 TCGv t1 = tcg_temp_new();
10731 int args, astatic;
10732
10733 switch (aregs) {
10734 case 0:
10735 case 1:
10736 case 2:
10737 case 3:
10738 case 11:
10739 args = 0;
10740 break;
10741 case 4:
10742 case 5:
10743 case 6:
10744 case 7:
10745 args = 1;
10746 break;
10747 case 8:
10748 case 9:
10749 case 10:
10750 args = 2;
10751 break;
10752 case 12:
10753 case 13:
10754 args = 3;
10755 break;
10756 case 14:
10757 args = 4;
10758 break;
10759 default:
10760 generate_exception(ctx, EXCP_RI);
10761 return;
10762 }
10763
10764 switch (args) {
10765 case 4:
10766 gen_base_offset_addr(ctx, t0, 29, 12);
10767 gen_load_gpr(t1, 7);
5f68f5ae 10768 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10769 /* Fall through */
10770 case 3:
10771 gen_base_offset_addr(ctx, t0, 29, 8);
10772 gen_load_gpr(t1, 6);
5f68f5ae 10773 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10774 /* Fall through */
10775 case 2:
10776 gen_base_offset_addr(ctx, t0, 29, 4);
10777 gen_load_gpr(t1, 5);
5f68f5ae 10778 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10779 /* Fall through */
10780 case 1:
10781 gen_base_offset_addr(ctx, t0, 29, 0);
10782 gen_load_gpr(t1, 4);
5f68f5ae 10783 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10784 }
10785
10786 gen_load_gpr(t0, 29);
10787
5f68f5ae
AJ
10788#define DECR_AND_STORE(reg) do { \
10789 tcg_gen_subi_tl(t0, t0, 4); \
10790 gen_load_gpr(t1, reg); \
10791 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10792 } while (0)
10793
10794 if (do_ra) {
10795 DECR_AND_STORE(31);
10796 }
10797
10798 switch (xsregs) {
10799 case 7:
10800 DECR_AND_STORE(30);
10801 /* Fall through */
10802 case 6:
10803 DECR_AND_STORE(23);
10804 /* Fall through */
10805 case 5:
10806 DECR_AND_STORE(22);
10807 /* Fall through */
10808 case 4:
10809 DECR_AND_STORE(21);
10810 /* Fall through */
10811 case 3:
10812 DECR_AND_STORE(20);
10813 /* Fall through */
10814 case 2:
10815 DECR_AND_STORE(19);
10816 /* Fall through */
10817 case 1:
10818 DECR_AND_STORE(18);
10819 }
10820
10821 if (do_s1) {
10822 DECR_AND_STORE(17);
10823 }
10824 if (do_s0) {
10825 DECR_AND_STORE(16);
10826 }
10827
10828 switch (aregs) {
10829 case 0:
10830 case 4:
10831 case 8:
10832 case 12:
10833 case 14:
10834 astatic = 0;
10835 break;
10836 case 1:
10837 case 5:
10838 case 9:
10839 case 13:
10840 astatic = 1;
10841 break;
10842 case 2:
10843 case 6:
10844 case 10:
10845 astatic = 2;
10846 break;
10847 case 3:
10848 case 7:
10849 astatic = 3;
10850 break;
10851 case 11:
10852 astatic = 4;
10853 break;
10854 default:
10855 generate_exception(ctx, EXCP_RI);
10856 return;
10857 }
10858
10859 if (astatic > 0) {
10860 DECR_AND_STORE(7);
10861 if (astatic > 1) {
10862 DECR_AND_STORE(6);
10863 if (astatic > 2) {
10864 DECR_AND_STORE(5);
10865 if (astatic > 3) {
10866 DECR_AND_STORE(4);
10867 }
10868 }
10869 }
10870 }
10871#undef DECR_AND_STORE
10872
10873 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10874 tcg_temp_free(t0);
10875 tcg_temp_free(t1);
10876}
10877
10878static void gen_mips16_restore (DisasContext *ctx,
10879 int xsregs, int aregs,
10880 int do_ra, int do_s0, int do_s1,
10881 int framesize)
10882{
10883 int astatic;
10884 TCGv t0 = tcg_temp_new();
10885 TCGv t1 = tcg_temp_new();
10886
10887 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
10888
5f68f5ae
AJ
10889#define DECR_AND_LOAD(reg) do { \
10890 tcg_gen_subi_tl(t0, t0, 4); \
10891 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10892 gen_store_gpr(t1, reg); \
364d4831
NF
10893 } while (0)
10894
10895 if (do_ra) {
10896 DECR_AND_LOAD(31);
10897 }
10898
10899 switch (xsregs) {
10900 case 7:
10901 DECR_AND_LOAD(30);
10902 /* Fall through */
10903 case 6:
10904 DECR_AND_LOAD(23);
10905 /* Fall through */
10906 case 5:
10907 DECR_AND_LOAD(22);
10908 /* Fall through */
10909 case 4:
10910 DECR_AND_LOAD(21);
10911 /* Fall through */
10912 case 3:
10913 DECR_AND_LOAD(20);
10914 /* Fall through */
10915 case 2:
10916 DECR_AND_LOAD(19);
10917 /* Fall through */
10918 case 1:
10919 DECR_AND_LOAD(18);
10920 }
10921
10922 if (do_s1) {
10923 DECR_AND_LOAD(17);
10924 }
10925 if (do_s0) {
10926 DECR_AND_LOAD(16);
10927 }
10928
10929 switch (aregs) {
10930 case 0:
10931 case 4:
10932 case 8:
10933 case 12:
10934 case 14:
10935 astatic = 0;
10936 break;
10937 case 1:
10938 case 5:
10939 case 9:
10940 case 13:
10941 astatic = 1;
10942 break;
10943 case 2:
10944 case 6:
10945 case 10:
10946 astatic = 2;
10947 break;
10948 case 3:
10949 case 7:
10950 astatic = 3;
10951 break;
10952 case 11:
10953 astatic = 4;
10954 break;
10955 default:
10956 generate_exception(ctx, EXCP_RI);
10957 return;
10958 }
10959
10960 if (astatic > 0) {
10961 DECR_AND_LOAD(7);
10962 if (astatic > 1) {
10963 DECR_AND_LOAD(6);
10964 if (astatic > 2) {
10965 DECR_AND_LOAD(5);
10966 if (astatic > 3) {
10967 DECR_AND_LOAD(4);
10968 }
10969 }
10970 }
10971 }
10972#undef DECR_AND_LOAD
10973
10974 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10975 tcg_temp_free(t0);
10976 tcg_temp_free(t1);
10977}
10978
10979static void gen_addiupc (DisasContext *ctx, int rx, int imm,
10980 int is_64_bit, int extended)
10981{
10982 TCGv t0;
10983
10984 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10985 generate_exception(ctx, EXCP_RI);
10986 return;
10987 }
10988
10989 t0 = tcg_temp_new();
10990
10991 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
10992 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
10993 if (!is_64_bit) {
10994 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10995 }
10996
10997 tcg_temp_free(t0);
10998}
10999
11000#if defined(TARGET_MIPS64)
d75c135e 11001static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11002 int ry, int funct, int16_t offset,
11003 int extended)
11004{
11005 switch (funct) {
11006 case I64_LDSP:
d9224450 11007 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11008 check_mips_64(ctx);
11009 offset = extended ? offset : offset << 3;
d75c135e 11010 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11011 break;
11012 case I64_SDSP:
d9224450 11013 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11014 check_mips_64(ctx);
11015 offset = extended ? offset : offset << 3;
5c13fdfd 11016 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11017 break;
11018 case I64_SDRASP:
d9224450 11019 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11020 check_mips_64(ctx);
11021 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11022 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11023 break;
11024 case I64_DADJSP:
d9224450 11025 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11026 check_mips_64(ctx);
11027 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11028 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11029 break;
11030 case I64_LDPC:
d9224450
MR
11031 check_insn(ctx, ISA_MIPS3);
11032 check_mips_64(ctx);
364d4831
NF
11033 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11034 generate_exception(ctx, EXCP_RI);
11035 } else {
11036 offset = extended ? offset : offset << 3;
d75c135e 11037 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11038 }
11039 break;
11040 case I64_DADDIU5:
d9224450 11041 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11042 check_mips_64(ctx);
11043 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11044 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11045 break;
11046 case I64_DADDIUPC:
d9224450 11047 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11048 check_mips_64(ctx);
11049 offset = extended ? offset : offset << 2;
11050 gen_addiupc(ctx, ry, offset, 1, extended);
11051 break;
11052 case I64_DADDIUSP:
d9224450 11053 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11054 check_mips_64(ctx);
11055 offset = extended ? offset : offset << 2;
d75c135e 11056 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11057 break;
11058 }
11059}
11060#endif
11061
240ce26a 11062static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11063{
895c2d04 11064 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11065 int op, rx, ry, funct, sa;
11066 int16_t imm, offset;
11067
11068 ctx->opcode = (ctx->opcode << 16) | extend;
11069 op = (ctx->opcode >> 11) & 0x1f;
11070 sa = (ctx->opcode >> 22) & 0x1f;
11071 funct = (ctx->opcode >> 8) & 0x7;
11072 rx = xlat((ctx->opcode >> 8) & 0x7);
11073 ry = xlat((ctx->opcode >> 5) & 0x7);
11074 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11075 | ((ctx->opcode >> 21) & 0x3f) << 5
11076 | (ctx->opcode & 0x1f));
11077
11078 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11079 counterparts. */
11080 switch (op) {
11081 case M16_OPC_ADDIUSP:
d75c135e 11082 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11083 break;
11084 case M16_OPC_ADDIUPC:
11085 gen_addiupc(ctx, rx, imm, 0, 1);
11086 break;
11087 case M16_OPC_B:
b231c103 11088 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11089 /* No delay slot, so just process as a normal instruction */
11090 break;
11091 case M16_OPC_BEQZ:
b231c103 11092 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11093 /* No delay slot, so just process as a normal instruction */
11094 break;
11095 case M16_OPC_BNEQZ:
b231c103 11096 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11097 /* No delay slot, so just process as a normal instruction */
11098 break;
11099 case M16_OPC_SHIFT:
11100 switch (ctx->opcode & 0x3) {
11101 case 0x0:
d75c135e 11102 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11103 break;
11104 case 0x1:
11105#if defined(TARGET_MIPS64)
11106 check_mips_64(ctx);
d75c135e 11107 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11108#else
11109 generate_exception(ctx, EXCP_RI);
11110#endif
11111 break;
11112 case 0x2:
d75c135e 11113 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11114 break;
11115 case 0x3:
d75c135e 11116 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11117 break;
11118 }
11119 break;
11120#if defined(TARGET_MIPS64)
11121 case M16_OPC_LD:
d9224450 11122 check_insn(ctx, ISA_MIPS3);
d75de749 11123 check_mips_64(ctx);
d75c135e 11124 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11125 break;
11126#endif
11127 case M16_OPC_RRIA:
11128 imm = ctx->opcode & 0xf;
11129 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11130 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11131 imm = (int16_t) (imm << 1) >> 1;
11132 if ((ctx->opcode >> 4) & 0x1) {
11133#if defined(TARGET_MIPS64)
11134 check_mips_64(ctx);
d75c135e 11135 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11136#else
11137 generate_exception(ctx, EXCP_RI);
11138#endif
11139 } else {
d75c135e 11140 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11141 }
11142 break;
11143 case M16_OPC_ADDIU8:
d75c135e 11144 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11145 break;
11146 case M16_OPC_SLTI:
d75c135e 11147 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11148 break;
11149 case M16_OPC_SLTIU:
d75c135e 11150 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11151 break;
11152 case M16_OPC_I8:
11153 switch (funct) {
11154 case I8_BTEQZ:
b231c103 11155 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11156 break;
11157 case I8_BTNEZ:
b231c103 11158 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11159 break;
11160 case I8_SWRASP:
5c13fdfd 11161 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11162 break;
11163 case I8_ADJSP:
d75c135e 11164 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11165 break;
11166 case I8_SVRS:
d9224450 11167 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11168 {
11169 int xsregs = (ctx->opcode >> 24) & 0x7;
11170 int aregs = (ctx->opcode >> 16) & 0xf;
11171 int do_ra = (ctx->opcode >> 6) & 0x1;
11172 int do_s0 = (ctx->opcode >> 5) & 0x1;
11173 int do_s1 = (ctx->opcode >> 4) & 0x1;
11174 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11175 | (ctx->opcode & 0xf)) << 3;
11176
11177 if (ctx->opcode & (1 << 7)) {
11178 gen_mips16_save(ctx, xsregs, aregs,
11179 do_ra, do_s0, do_s1,
11180 framesize);
11181 } else {
11182 gen_mips16_restore(ctx, xsregs, aregs,
11183 do_ra, do_s0, do_s1,
11184 framesize);
11185 }
11186 }
11187 break;
11188 default:
11189 generate_exception(ctx, EXCP_RI);
11190 break;
11191 }
11192 break;
11193 case M16_OPC_LI:
11194 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11195 break;
11196 case M16_OPC_CMPI:
11197 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11198 break;
11199#if defined(TARGET_MIPS64)
11200 case M16_OPC_SD:
d9224450
MR
11201 check_insn(ctx, ISA_MIPS3);
11202 check_mips_64(ctx);
5c13fdfd 11203 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11204 break;
11205#endif
11206 case M16_OPC_LB:
d75c135e 11207 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11208 break;
11209 case M16_OPC_LH:
d75c135e 11210 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11211 break;
11212 case M16_OPC_LWSP:
d75c135e 11213 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11214 break;
11215 case M16_OPC_LW:
d75c135e 11216 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11217 break;
11218 case M16_OPC_LBU:
d75c135e 11219 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11220 break;
11221 case M16_OPC_LHU:
d75c135e 11222 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11223 break;
11224 case M16_OPC_LWPC:
d75c135e 11225 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11226 break;
11227#if defined(TARGET_MIPS64)
11228 case M16_OPC_LWU:
d9224450
MR
11229 check_insn(ctx, ISA_MIPS3);
11230 check_mips_64(ctx);
d75c135e 11231 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11232 break;
11233#endif
11234 case M16_OPC_SB:
5c13fdfd 11235 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11236 break;
11237 case M16_OPC_SH:
5c13fdfd 11238 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11239 break;
11240 case M16_OPC_SWSP:
5c13fdfd 11241 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11242 break;
11243 case M16_OPC_SW:
5c13fdfd 11244 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11245 break;
11246#if defined(TARGET_MIPS64)
11247 case M16_OPC_I64:
d75c135e 11248 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11249 break;
11250#endif
11251 default:
11252 generate_exception(ctx, EXCP_RI);
11253 break;
11254 }
11255
11256 return 4;
11257}
11258
240ce26a 11259static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11260{
11261 int rx, ry;
11262 int sa;
11263 int op, cnvt_op, op1, offset;
11264 int funct;
11265 int n_bytes;
11266
11267 op = (ctx->opcode >> 11) & 0x1f;
11268 sa = (ctx->opcode >> 2) & 0x7;
11269 sa = sa == 0 ? 8 : sa;
11270 rx = xlat((ctx->opcode >> 8) & 0x7);
11271 cnvt_op = (ctx->opcode >> 5) & 0x7;
11272 ry = xlat((ctx->opcode >> 5) & 0x7);
11273 op1 = offset = ctx->opcode & 0x1f;
11274
11275 n_bytes = 2;
11276
11277 switch (op) {
11278 case M16_OPC_ADDIUSP:
11279 {
11280 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11281
d75c135e 11282 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11283 }
11284 break;
11285 case M16_OPC_ADDIUPC:
11286 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11287 break;
11288 case M16_OPC_B:
11289 offset = (ctx->opcode & 0x7ff) << 1;
11290 offset = (int16_t)(offset << 4) >> 4;
b231c103 11291 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11292 /* No delay slot, so just process as a normal instruction */
11293 break;
11294 case M16_OPC_JAL:
895c2d04 11295 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
11296 offset = (((ctx->opcode & 0x1f) << 21)
11297 | ((ctx->opcode >> 5) & 0x1f) << 16
11298 | offset) << 2;
b231c103
YK
11299 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11300 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11301 n_bytes = 4;
364d4831
NF
11302 break;
11303 case M16_OPC_BEQZ:
b231c103
YK
11304 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11305 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11306 /* No delay slot, so just process as a normal instruction */
11307 break;
11308 case M16_OPC_BNEQZ:
b231c103
YK
11309 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11310 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11311 /* No delay slot, so just process as a normal instruction */
11312 break;
11313 case M16_OPC_SHIFT:
11314 switch (ctx->opcode & 0x3) {
11315 case 0x0:
d75c135e 11316 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11317 break;
11318 case 0x1:
11319#if defined(TARGET_MIPS64)
d9224450 11320 check_insn(ctx, ISA_MIPS3);
364d4831 11321 check_mips_64(ctx);
d75c135e 11322 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
11323#else
11324 generate_exception(ctx, EXCP_RI);
11325#endif
11326 break;
11327 case 0x2:
d75c135e 11328 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11329 break;
11330 case 0x3:
d75c135e 11331 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11332 break;
11333 }
11334 break;
11335#if defined(TARGET_MIPS64)
11336 case M16_OPC_LD:
d9224450 11337 check_insn(ctx, ISA_MIPS3);
364d4831 11338 check_mips_64(ctx);
d75c135e 11339 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11340 break;
11341#endif
11342 case M16_OPC_RRIA:
11343 {
11344 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11345
11346 if ((ctx->opcode >> 4) & 1) {
11347#if defined(TARGET_MIPS64)
d9224450 11348 check_insn(ctx, ISA_MIPS3);
364d4831 11349 check_mips_64(ctx);
d75c135e 11350 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
11351#else
11352 generate_exception(ctx, EXCP_RI);
11353#endif
11354 } else {
d75c135e 11355 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11356 }
11357 }
11358 break;
11359 case M16_OPC_ADDIU8:
11360 {
11361 int16_t imm = (int8_t) ctx->opcode;
11362
d75c135e 11363 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11364 }
11365 break;
11366 case M16_OPC_SLTI:
11367 {
11368 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11369 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11370 }
11371 break;
11372 case M16_OPC_SLTIU:
11373 {
11374 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11375 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11376 }
11377 break;
11378 case M16_OPC_I8:
11379 {
11380 int reg32;
11381
11382 funct = (ctx->opcode >> 8) & 0x7;
11383 switch (funct) {
11384 case I8_BTEQZ:
11385 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11386 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11387 break;
11388 case I8_BTNEZ:
11389 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11390 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11391 break;
11392 case I8_SWRASP:
5c13fdfd 11393 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11394 break;
11395 case I8_ADJSP:
d75c135e 11396 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11397 ((int8_t)ctx->opcode) << 3);
11398 break;
11399 case I8_SVRS:
d9224450 11400 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11401 {
11402 int do_ra = ctx->opcode & (1 << 6);
11403 int do_s0 = ctx->opcode & (1 << 5);
11404 int do_s1 = ctx->opcode & (1 << 4);
11405 int framesize = ctx->opcode & 0xf;
11406
11407 if (framesize == 0) {
11408 framesize = 128;
11409 } else {
11410 framesize = framesize << 3;
11411 }
11412
11413 if (ctx->opcode & (1 << 7)) {
11414 gen_mips16_save(ctx, 0, 0,
11415 do_ra, do_s0, do_s1, framesize);
11416 } else {
11417 gen_mips16_restore(ctx, 0, 0,
11418 do_ra, do_s0, do_s1, framesize);
11419 }
11420 }
11421 break;
11422 case I8_MOV32R:
11423 {
11424 int rz = xlat(ctx->opcode & 0x7);
11425
11426 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11427 ((ctx->opcode >> 5) & 0x7);
d75c135e 11428 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11429 }
11430 break;
11431 case I8_MOVR32:
11432 reg32 = ctx->opcode & 0x1f;
d75c135e 11433 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11434 break;
11435 default:
11436 generate_exception(ctx, EXCP_RI);
11437 break;
11438 }
11439 }
11440 break;
11441 case M16_OPC_LI:
11442 {
11443 int16_t imm = (uint8_t) ctx->opcode;
11444
d75c135e 11445 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11446 }
11447 break;
11448 case M16_OPC_CMPI:
11449 {
11450 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11451 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11452 }
11453 break;
11454#if defined(TARGET_MIPS64)
11455 case M16_OPC_SD:
d9224450 11456 check_insn(ctx, ISA_MIPS3);
364d4831 11457 check_mips_64(ctx);
5c13fdfd 11458 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11459 break;
11460#endif
11461 case M16_OPC_LB:
d75c135e 11462 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11463 break;
11464 case M16_OPC_LH:
d75c135e 11465 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11466 break;
11467 case M16_OPC_LWSP:
d75c135e 11468 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11469 break;
11470 case M16_OPC_LW:
d75c135e 11471 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11472 break;
11473 case M16_OPC_LBU:
d75c135e 11474 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11475 break;
11476 case M16_OPC_LHU:
d75c135e 11477 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11478 break;
11479 case M16_OPC_LWPC:
d75c135e 11480 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11481 break;
11482#if defined (TARGET_MIPS64)
11483 case M16_OPC_LWU:
d9224450 11484 check_insn(ctx, ISA_MIPS3);
364d4831 11485 check_mips_64(ctx);
d75c135e 11486 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11487 break;
11488#endif
11489 case M16_OPC_SB:
5c13fdfd 11490 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11491 break;
11492 case M16_OPC_SH:
5c13fdfd 11493 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11494 break;
11495 case M16_OPC_SWSP:
5c13fdfd 11496 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11497 break;
11498 case M16_OPC_SW:
5c13fdfd 11499 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11500 break;
11501 case M16_OPC_RRR:
11502 {
11503 int rz = xlat((ctx->opcode >> 2) & 0x7);
11504 int mips32_op;
11505
11506 switch (ctx->opcode & 0x3) {
11507 case RRR_ADDU:
11508 mips32_op = OPC_ADDU;
11509 break;
11510 case RRR_SUBU:
11511 mips32_op = OPC_SUBU;
11512 break;
11513#if defined(TARGET_MIPS64)
11514 case RRR_DADDU:
11515 mips32_op = OPC_DADDU;
d9224450 11516 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11517 check_mips_64(ctx);
11518 break;
11519 case RRR_DSUBU:
11520 mips32_op = OPC_DSUBU;
d9224450 11521 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11522 check_mips_64(ctx);
11523 break;
11524#endif
11525 default:
11526 generate_exception(ctx, EXCP_RI);
11527 goto done;
11528 }
11529
d75c135e 11530 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11531 done:
11532 ;
11533 }
11534 break;
11535 case M16_OPC_RR:
11536 switch (op1) {
11537 case RR_JR:
11538 {
11539 int nd = (ctx->opcode >> 7) & 0x1;
11540 int link = (ctx->opcode >> 6) & 0x1;
11541 int ra = (ctx->opcode >> 5) & 0x1;
11542
d9224450
MR
11543 if (nd) {
11544 check_insn(ctx, ISA_MIPS32);
11545 }
11546
364d4831 11547 if (link) {
b231c103 11548 op = OPC_JALR;
364d4831
NF
11549 } else {
11550 op = OPC_JR;
11551 }
11552
b231c103
YK
11553 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11554 (nd ? 0 : 2));
364d4831
NF
11555 }
11556 break;
11557 case RR_SDBBP:
11558 /* XXX: not clear which exception should be raised
11559 * when in debug mode...
11560 */
d75c135e 11561 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11562 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11563 generate_exception(ctx, EXCP_DBp);
11564 } else {
11565 generate_exception(ctx, EXCP_DBp);
11566 }
11567 break;
11568 case RR_SLT:
d75c135e 11569 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11570 break;
11571 case RR_SLTU:
d75c135e 11572 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11573 break;
11574 case RR_BREAK:
11575 generate_exception(ctx, EXCP_BREAK);
11576 break;
11577 case RR_SLLV:
d75c135e 11578 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11579 break;
11580 case RR_SRLV:
d75c135e 11581 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11582 break;
11583 case RR_SRAV:
d75c135e 11584 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11585 break;
11586#if defined (TARGET_MIPS64)
11587 case RR_DSRL:
d9224450 11588 check_insn(ctx, ISA_MIPS3);
364d4831 11589 check_mips_64(ctx);
d75c135e 11590 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11591 break;
11592#endif
11593 case RR_CMP:
d75c135e 11594 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11595 break;
11596 case RR_NEG:
d75c135e 11597 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11598 break;
11599 case RR_AND:
d75c135e 11600 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11601 break;
11602 case RR_OR:
d75c135e 11603 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11604 break;
11605 case RR_XOR:
d75c135e 11606 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11607 break;
11608 case RR_NOT:
d75c135e 11609 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11610 break;
11611 case RR_MFHI:
26135ead 11612 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11613 break;
11614 case RR_CNVT:
d9224450 11615 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11616 switch (cnvt_op) {
11617 case RR_RY_CNVT_ZEB:
11618 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11619 break;
11620 case RR_RY_CNVT_ZEH:
11621 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11622 break;
11623 case RR_RY_CNVT_SEB:
11624 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11625 break;
11626 case RR_RY_CNVT_SEH:
11627 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11628 break;
11629#if defined (TARGET_MIPS64)
11630 case RR_RY_CNVT_ZEW:
d9224450 11631 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11632 check_mips_64(ctx);
11633 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11634 break;
11635 case RR_RY_CNVT_SEW:
d9224450 11636 check_insn(ctx, ISA_MIPS64);
364d4831
NF
11637 check_mips_64(ctx);
11638 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11639 break;
11640#endif
11641 default:
11642 generate_exception(ctx, EXCP_RI);
11643 break;
11644 }
11645 break;
11646 case RR_MFLO:
26135ead 11647 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11648 break;
11649#if defined (TARGET_MIPS64)
11650 case RR_DSRA:
d9224450 11651 check_insn(ctx, ISA_MIPS3);
364d4831 11652 check_mips_64(ctx);
d75c135e 11653 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11654 break;
11655 case RR_DSLLV:
d9224450 11656 check_insn(ctx, ISA_MIPS3);
364d4831 11657 check_mips_64(ctx);
d75c135e 11658 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11659 break;
11660 case RR_DSRLV:
d9224450 11661 check_insn(ctx, ISA_MIPS3);
364d4831 11662 check_mips_64(ctx);
d75c135e 11663 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11664 break;
11665 case RR_DSRAV:
d9224450 11666 check_insn(ctx, ISA_MIPS3);
364d4831 11667 check_mips_64(ctx);
d75c135e 11668 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11669 break;
11670#endif
11671 case RR_MULT:
26135ead 11672 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11673 break;
11674 case RR_MULTU:
26135ead 11675 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11676 break;
11677 case RR_DIV:
26135ead 11678 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11679 break;
11680 case RR_DIVU:
26135ead 11681 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11682 break;
11683#if defined (TARGET_MIPS64)
11684 case RR_DMULT:
d9224450 11685 check_insn(ctx, ISA_MIPS3);
364d4831 11686 check_mips_64(ctx);
26135ead 11687 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11688 break;
11689 case RR_DMULTU:
d9224450 11690 check_insn(ctx, ISA_MIPS3);
364d4831 11691 check_mips_64(ctx);
26135ead 11692 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11693 break;
11694 case RR_DDIV:
d9224450 11695 check_insn(ctx, ISA_MIPS3);
364d4831 11696 check_mips_64(ctx);
26135ead 11697 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11698 break;
11699 case RR_DDIVU:
d9224450 11700 check_insn(ctx, ISA_MIPS3);
364d4831 11701 check_mips_64(ctx);
26135ead 11702 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11703 break;
11704#endif
11705 default:
11706 generate_exception(ctx, EXCP_RI);
11707 break;
11708 }
11709 break;
11710 case M16_OPC_EXTEND:
240ce26a 11711 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11712 n_bytes = 4;
11713 break;
11714#if defined(TARGET_MIPS64)
11715 case M16_OPC_I64:
11716 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11717 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11718 break;
11719#endif
11720 default:
11721 generate_exception(ctx, EXCP_RI);
11722 break;
11723 }
11724
11725 return n_bytes;
11726}
11727
211da992 11728/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11729
211da992
CWR
11730/*
11731 * microMIPS32/microMIPS64 major opcodes
11732 *
11733 * 1. MIPS Architecture for Programmers Volume II-B:
11734 * The microMIPS32 Instruction Set (Revision 3.05)
11735 *
11736 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11737 *
11738 * 2. MIPS Architecture For Programmers Volume II-A:
11739 * The MIPS64 Instruction Set (Revision 3.51)
11740 */
6af0bf9c 11741
3c824109
NF
11742enum {
11743 POOL32A = 0x00,
11744 POOL16A = 0x01,
11745 LBU16 = 0x02,
11746 MOVE16 = 0x03,
11747 ADDI32 = 0x04,
11748 LBU32 = 0x05,
11749 SB32 = 0x06,
11750 LB32 = 0x07,
11751
11752 POOL32B = 0x08,
11753 POOL16B = 0x09,
11754 LHU16 = 0x0a,
11755 ANDI16 = 0x0b,
11756 ADDIU32 = 0x0c,
11757 LHU32 = 0x0d,
11758 SH32 = 0x0e,
11759 LH32 = 0x0f,
11760
11761 POOL32I = 0x10,
11762 POOL16C = 0x11,
11763 LWSP16 = 0x12,
11764 POOL16D = 0x13,
11765 ORI32 = 0x14,
11766 POOL32F = 0x15,
211da992
CWR
11767 POOL32S = 0x16, /* MIPS64 */
11768 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11769
211da992 11770 /* 0x1f is reserved */
3c824109
NF
11771 POOL32C = 0x18,
11772 LWGP16 = 0x19,
11773 LW16 = 0x1a,
11774 POOL16E = 0x1b,
11775 XORI32 = 0x1c,
11776 JALS32 = 0x1d,
11777 ADDIUPC = 0x1e,
3c824109
NF
11778
11779 /* 0x20 is reserved */
11780 RES_20 = 0x20,
11781 POOL16F = 0x21,
11782 SB16 = 0x22,
11783 BEQZ16 = 0x23,
11784 SLTI32 = 0x24,
11785 BEQ32 = 0x25,
11786 SWC132 = 0x26,
11787 LWC132 = 0x27,
11788
11789 /* 0x28 and 0x29 are reserved */
11790 RES_28 = 0x28,
11791 RES_29 = 0x29,
11792 SH16 = 0x2a,
11793 BNEZ16 = 0x2b,
11794 SLTIU32 = 0x2c,
11795 BNE32 = 0x2d,
11796 SDC132 = 0x2e,
11797 LDC132 = 0x2f,
11798
11799 /* 0x30 and 0x31 are reserved */
11800 RES_30 = 0x30,
11801 RES_31 = 0x31,
11802 SWSP16 = 0x32,
11803 B16 = 0x33,
11804 ANDI32 = 0x34,
11805 J32 = 0x35,
211da992
CWR
11806 SD32 = 0x36, /* MIPS64 */
11807 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11808
11809 /* 0x38 and 0x39 are reserved */
11810 RES_38 = 0x38,
11811 RES_39 = 0x39,
11812 SW16 = 0x3a,
11813 LI16 = 0x3b,
11814 JALX32 = 0x3c,
11815 JAL32 = 0x3d,
11816 SW32 = 0x3e,
11817 LW32 = 0x3f
11818};
11819
11820/* POOL32A encoding of minor opcode field */
11821
11822enum {
11823 /* These opcodes are distinguished only by bits 9..6; those bits are
11824 * what are recorded below. */
11825 SLL32 = 0x0,
11826 SRL32 = 0x1,
11827 SRA = 0x2,
11828 ROTR = 0x3,
11829
11830 SLLV = 0x0,
11831 SRLV = 0x1,
11832 SRAV = 0x2,
11833 ROTRV = 0x3,
11834 ADD = 0x4,
11835 ADDU32 = 0x5,
11836 SUB = 0x6,
11837 SUBU32 = 0x7,
11838 MUL = 0x8,
11839 AND = 0x9,
11840 OR32 = 0xa,
11841 NOR = 0xb,
11842 XOR32 = 0xc,
11843 SLT = 0xd,
11844 SLTU = 0xe,
11845
11846 MOVN = 0x0,
11847 MOVZ = 0x1,
11848 LWXS = 0x4,
11849
11850 /* The following can be distinguished by their lower 6 bits. */
11851 INS = 0x0c,
11852 EXT = 0x2c,
11853 POOL32AXF = 0x3c
11854};
11855
11856/* POOL32AXF encoding of minor opcode field extension */
11857
d132c79f
CWR
11858/*
11859 * 1. MIPS Architecture for Programmers Volume II-B:
11860 * The microMIPS32 Instruction Set (Revision 3.05)
11861 *
11862 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11863 *
11864 * 2. MIPS Architecture for Programmers VolumeIV-e:
11865 * The MIPS DSP Application-Specific Extension
11866 * to the microMIPS32 Architecture (Revision 2.34)
11867 *
11868 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11869 */
11870
3c824109
NF
11871enum {
11872 /* bits 11..6 */
11873 TEQ = 0x00,
11874 TGE = 0x08,
11875 TGEU = 0x10,
11876 TLT = 0x20,
11877 TLTU = 0x28,
11878 TNE = 0x30,
11879
11880 MFC0 = 0x03,
11881 MTC0 = 0x0b,
11882
d132c79f
CWR
11883 /* begin of microMIPS32 DSP */
11884
3c824109
NF
11885 /* bits 13..12 for 0x01 */
11886 MFHI_ACC = 0x0,
11887 MFLO_ACC = 0x1,
11888 MTHI_ACC = 0x2,
11889 MTLO_ACC = 0x3,
11890
11891 /* bits 13..12 for 0x2a */
11892 MADD_ACC = 0x0,
11893 MADDU_ACC = 0x1,
11894 MSUB_ACC = 0x2,
11895 MSUBU_ACC = 0x3,
11896
11897 /* bits 13..12 for 0x32 */
11898 MULT_ACC = 0x0,
6801038b 11899 MULTU_ACC = 0x1,
3c824109 11900
d132c79f
CWR
11901 /* end of microMIPS32 DSP */
11902
3c824109
NF
11903 /* bits 15..12 for 0x2c */
11904 SEB = 0x2,
11905 SEH = 0x3,
11906 CLO = 0x4,
11907 CLZ = 0x5,
11908 RDHWR = 0x6,
11909 WSBH = 0x7,
11910 MULT = 0x8,
11911 MULTU = 0x9,
11912 DIV = 0xa,
11913 DIVU = 0xb,
11914 MADD = 0xc,
11915 MADDU = 0xd,
11916 MSUB = 0xe,
11917 MSUBU = 0xf,
11918
11919 /* bits 15..12 for 0x34 */
11920 MFC2 = 0x4,
11921 MTC2 = 0x5,
11922 MFHC2 = 0x8,
11923 MTHC2 = 0x9,
11924 CFC2 = 0xc,
11925 CTC2 = 0xd,
11926
11927 /* bits 15..12 for 0x3c */
11928 JALR = 0x0,
11929 JR = 0x0, /* alias */
11930 JALR_HB = 0x1,
11931 JALRS = 0x4,
11932 JALRS_HB = 0x5,
11933
11934 /* bits 15..12 for 0x05 */
11935 RDPGPR = 0xe,
11936 WRPGPR = 0xf,
11937
11938 /* bits 15..12 for 0x0d */
11939 TLBP = 0x0,
11940 TLBR = 0x1,
11941 TLBWI = 0x2,
11942 TLBWR = 0x3,
11943 WAIT = 0x9,
11944 IRET = 0xd,
11945 DERET = 0xe,
11946 ERET = 0xf,
11947
11948 /* bits 15..12 for 0x15 */
11949 DMT = 0x0,
11950 DVPE = 0x1,
11951 EMT = 0x2,
11952 EVPE = 0x3,
11953
11954 /* bits 15..12 for 0x1d */
11955 DI = 0x4,
11956 EI = 0x5,
11957
11958 /* bits 15..12 for 0x2d */
11959 SYNC = 0x6,
11960 SYSCALL = 0x8,
11961 SDBBP = 0xd,
11962
11963 /* bits 15..12 for 0x35 */
11964 MFHI32 = 0x0,
11965 MFLO32 = 0x1,
11966 MTHI32 = 0x2,
11967 MTLO32 = 0x3,
11968};
11969
11970/* POOL32B encoding of minor opcode field (bits 15..12) */
11971
11972enum {
11973 LWC2 = 0x0,
11974 LWP = 0x1,
11975 LDP = 0x4,
11976 LWM32 = 0x5,
11977 CACHE = 0x6,
11978 LDM = 0x7,
11979 SWC2 = 0x8,
11980 SWP = 0x9,
11981 SDP = 0xc,
11982 SWM32 = 0xd,
11983 SDM = 0xf
11984};
11985
11986/* POOL32C encoding of minor opcode field (bits 15..12) */
11987
11988enum {
11989 LWL = 0x0,
11990 SWL = 0x8,
11991 LWR = 0x1,
11992 SWR = 0x9,
11993 PREF = 0x2,
11994 /* 0xa is reserved */
11995 LL = 0x3,
11996 SC = 0xb,
11997 LDL = 0x4,
11998 SDL = 0xc,
11999 LDR = 0x5,
12000 SDR = 0xd,
12001 /* 0x6 is reserved */
12002 LWU = 0xe,
12003 LLD = 0x7,
12004 SCD = 0xf
12005};
12006
12007/* POOL32F encoding of minor opcode field (bits 5..0) */
12008
12009enum {
12010 /* These are the bit 7..6 values */
12011 ADD_FMT = 0x0,
12012 MOVN_FMT = 0x0,
12013
12014 SUB_FMT = 0x1,
12015 MOVZ_FMT = 0x1,
12016
12017 MUL_FMT = 0x2,
12018
12019 DIV_FMT = 0x3,
12020
12021 /* These are the bit 8..6 values */
12022 RSQRT2_FMT = 0x0,
12023 MOVF_FMT = 0x0,
12024
12025 LWXC1 = 0x1,
12026 MOVT_FMT = 0x1,
12027
12028 PLL_PS = 0x2,
12029 SWXC1 = 0x2,
12030
12031 PLU_PS = 0x3,
12032 LDXC1 = 0x3,
12033
12034 PUL_PS = 0x4,
12035 SDXC1 = 0x4,
12036 RECIP2_FMT = 0x4,
12037
12038 PUU_PS = 0x5,
12039 LUXC1 = 0x5,
12040
12041 CVT_PS_S = 0x6,
12042 SUXC1 = 0x6,
12043 ADDR_PS = 0x6,
12044 PREFX = 0x6,
12045
12046 MULR_PS = 0x7,
12047
12048 MADD_S = 0x01,
12049 MADD_D = 0x09,
12050 MADD_PS = 0x11,
12051 ALNV_PS = 0x19,
12052 MSUB_S = 0x21,
12053 MSUB_D = 0x29,
12054 MSUB_PS = 0x31,
12055
12056 NMADD_S = 0x02,
12057 NMADD_D = 0x0a,
12058 NMADD_PS = 0x12,
12059 NMSUB_S = 0x22,
12060 NMSUB_D = 0x2a,
12061 NMSUB_PS = 0x32,
12062
12063 POOL32FXF = 0x3b,
12064
12065 CABS_COND_FMT = 0x1c, /* MIPS3D */
12066 C_COND_FMT = 0x3c
12067};
12068
12069/* POOL32Fxf encoding of minor opcode extension field */
12070
12071enum {
12072 CVT_L = 0x04,
12073 RSQRT_FMT = 0x08,
12074 FLOOR_L = 0x0c,
12075 CVT_PW_PS = 0x1c,
12076 CVT_W = 0x24,
12077 SQRT_FMT = 0x28,
12078 FLOOR_W = 0x2c,
12079 CVT_PS_PW = 0x3c,
12080 CFC1 = 0x40,
12081 RECIP_FMT = 0x48,
12082 CEIL_L = 0x4c,
12083 CTC1 = 0x60,
12084 CEIL_W = 0x6c,
12085 MFC1 = 0x80,
12086 CVT_S_PL = 0x84,
12087 TRUNC_L = 0x8c,
12088 MTC1 = 0xa0,
12089 CVT_S_PU = 0xa4,
12090 TRUNC_W = 0xac,
12091 MFHC1 = 0xc0,
12092 ROUND_L = 0xcc,
12093 MTHC1 = 0xe0,
12094 ROUND_W = 0xec,
12095
12096 MOV_FMT = 0x01,
12097 MOVF = 0x05,
12098 ABS_FMT = 0x0d,
12099 RSQRT1_FMT = 0x1d,
12100 MOVT = 0x25,
12101 NEG_FMT = 0x2d,
12102 CVT_D = 0x4d,
12103 RECIP1_FMT = 0x5d,
12104 CVT_S = 0x6d
12105};
12106
12107/* POOL32I encoding of minor opcode field (bits 25..21) */
12108
12109enum {
12110 BLTZ = 0x00,
12111 BLTZAL = 0x01,
12112 BGEZ = 0x02,
12113 BGEZAL = 0x03,
12114 BLEZ = 0x04,
12115 BNEZC = 0x05,
12116 BGTZ = 0x06,
12117 BEQZC = 0x07,
12118 TLTI = 0x08,
12119 TGEI = 0x09,
12120 TLTIU = 0x0a,
12121 TGEIU = 0x0b,
12122 TNEI = 0x0c,
12123 LUI = 0x0d,
12124 TEQI = 0x0e,
12125 SYNCI = 0x10,
12126 BLTZALS = 0x11,
12127 BGEZALS = 0x13,
12128 BC2F = 0x14,
12129 BC2T = 0x15,
12130 BPOSGE64 = 0x1a,
12131 BPOSGE32 = 0x1b,
12132 /* These overlap and are distinguished by bit16 of the instruction */
12133 BC1F = 0x1c,
12134 BC1T = 0x1d,
12135 BC1ANY2F = 0x1c,
12136 BC1ANY2T = 0x1d,
12137 BC1ANY4F = 0x1e,
12138 BC1ANY4T = 0x1f
12139};
12140
12141/* POOL16A encoding of minor opcode field */
12142
12143enum {
12144 ADDU16 = 0x0,
12145 SUBU16 = 0x1
12146};
12147
12148/* POOL16B encoding of minor opcode field */
12149
12150enum {
12151 SLL16 = 0x0,
12152 SRL16 = 0x1
12153};
12154
12155/* POOL16C encoding of minor opcode field */
12156
12157enum {
12158 NOT16 = 0x00,
12159 XOR16 = 0x04,
12160 AND16 = 0x08,
12161 OR16 = 0x0c,
12162 LWM16 = 0x10,
12163 SWM16 = 0x14,
12164 JR16 = 0x18,
12165 JRC16 = 0x1a,
12166 JALR16 = 0x1c,
12167 JALR16S = 0x1e,
12168 MFHI16 = 0x20,
12169 MFLO16 = 0x24,
12170 BREAK16 = 0x28,
12171 SDBBP16 = 0x2c,
12172 JRADDIUSP = 0x30
12173};
12174
12175/* POOL16D encoding of minor opcode field */
12176
12177enum {
12178 ADDIUS5 = 0x0,
12179 ADDIUSP = 0x1
12180};
12181
12182/* POOL16E encoding of minor opcode field */
12183
12184enum {
12185 ADDIUR2 = 0x0,
12186 ADDIUR1SP = 0x1
12187};
12188
12189static int mmreg (int r)
12190{
12191 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12192
12193 return map[r];
12194}
12195
12196/* Used for 16-bit store instructions. */
12197static int mmreg2 (int r)
12198{
12199 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12200
12201 return map[r];
12202}
12203
12204#define uMIPS_RD(op) ((op >> 7) & 0x7)
12205#define uMIPS_RS(op) ((op >> 4) & 0x7)
12206#define uMIPS_RS2(op) uMIPS_RS(op)
12207#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12208#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12209#define uMIPS_RS5(op) (op & 0x1f)
12210
12211/* Signed immediate */
12212#define SIMM(op, start, width) \
12213 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12214 << (32-width)) \
12215 >> (32-width))
12216/* Zero-extended immediate */
12217#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12218
d75c135e 12219static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12220{
12221 int rd = mmreg(uMIPS_RD(ctx->opcode));
12222
d75c135e 12223 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12224}
12225
d75c135e 12226static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12227{
12228 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12229 int rd = mmreg(uMIPS_RD(ctx->opcode));
12230 int rs = mmreg(uMIPS_RS(ctx->opcode));
12231
d75c135e 12232 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12233}
12234
d75c135e 12235static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12236{
12237 int encoded = ZIMM(ctx->opcode, 1, 9);
12238 int decoded;
12239
12240 if (encoded <= 1) {
12241 decoded = 256 + encoded;
12242 } else if (encoded <= 255) {
12243 decoded = encoded;
12244 } else if (encoded <= 509) {
12245 decoded = encoded - 512;
12246 } else {
12247 decoded = encoded - 768;
12248 }
12249
d75c135e 12250 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12251}
12252
d75c135e 12253static void gen_addius5(DisasContext *ctx)
3c824109
NF
12254{
12255 int imm = SIMM(ctx->opcode, 1, 4);
12256 int rd = (ctx->opcode >> 5) & 0x1f;
12257
d75c135e 12258 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12259}
12260
d75c135e 12261static void gen_andi16(DisasContext *ctx)
3c824109
NF
12262{
12263 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12264 31, 32, 63, 64, 255, 32768, 65535 };
12265 int rd = mmreg(uMIPS_RD(ctx->opcode));
12266 int rs = mmreg(uMIPS_RS(ctx->opcode));
12267 int encoded = ZIMM(ctx->opcode, 0, 4);
12268
d75c135e 12269 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12270}
12271
12272static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12273 int base, int16_t offset)
12274{
e1050a76 12275 const char *opn = "ldst_multiple";
3c824109
NF
12276 TCGv t0, t1;
12277 TCGv_i32 t2;
12278
12279 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12280 generate_exception(ctx, EXCP_RI);
12281 return;
12282 }
12283
12284 t0 = tcg_temp_new();
12285
12286 gen_base_offset_addr(ctx, t0, base, offset);
12287
12288 t1 = tcg_const_tl(reglist);
12289 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12290
3c824109
NF
12291 save_cpu_state(ctx, 1);
12292 switch (opc) {
12293 case LWM32:
895c2d04 12294 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 12295 opn = "lwm";
3c824109
NF
12296 break;
12297 case SWM32:
895c2d04 12298 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 12299 opn = "swm";
3c824109
NF
12300 break;
12301#ifdef TARGET_MIPS64
12302 case LDM:
895c2d04 12303 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 12304 opn = "ldm";
3c824109
NF
12305 break;
12306 case SDM:
895c2d04 12307 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 12308 opn = "sdm";
3c824109 12309 break;
6af0bf9c 12310#endif
3c824109 12311 }
e1050a76 12312 (void)opn;
3c824109
NF
12313 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
12314 tcg_temp_free(t0);
33087598 12315 tcg_temp_free(t1);
3c824109
NF
12316 tcg_temp_free_i32(t2);
12317}
6af0bf9c 12318
3c824109 12319
240ce26a 12320static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12321{
3c824109
NF
12322 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12323 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12324
3c824109
NF
12325 switch (((ctx->opcode) >> 4) & 0x3f) {
12326 case NOT16 + 0:
12327 case NOT16 + 1:
12328 case NOT16 + 2:
12329 case NOT16 + 3:
d75c135e 12330 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12331 break;
12332 case XOR16 + 0:
12333 case XOR16 + 1:
12334 case XOR16 + 2:
12335 case XOR16 + 3:
d75c135e 12336 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
12337 break;
12338 case AND16 + 0:
12339 case AND16 + 1:
12340 case AND16 + 2:
12341 case AND16 + 3:
d75c135e 12342 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
12343 break;
12344 case OR16 + 0:
12345 case OR16 + 1:
12346 case OR16 + 2:
12347 case OR16 + 3:
d75c135e 12348 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
12349 break;
12350 case LWM16 + 0:
12351 case LWM16 + 1:
12352 case LWM16 + 2:
12353 case LWM16 + 3:
12354 {
12355 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12356 int offset = ZIMM(ctx->opcode, 0, 4);
12357
12358 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12359 29, offset << 2);
12360 }
12361 break;
12362 case SWM16 + 0:
12363 case SWM16 + 1:
12364 case SWM16 + 2:
12365 case SWM16 + 3:
12366 {
12367 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12368 int offset = ZIMM(ctx->opcode, 0, 4);
12369
12370 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12371 29, offset << 2);
12372 }
12373 break;
12374 case JR16 + 0:
12375 case JR16 + 1:
12376 {
12377 int reg = ctx->opcode & 0x1f;
12378
b231c103 12379 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 12380 }
3c824109
NF
12381 break;
12382 case JRC16 + 0:
12383 case JRC16 + 1:
12384 {
12385 int reg = ctx->opcode & 0x1f;
b231c103 12386 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
12387 /* Let normal delay slot handling in our caller take us
12388 to the branch target. */
12389 }
12390 break;
12391 case JALR16 + 0:
12392 case JALR16 + 1:
b231c103
YK
12393 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12394 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12395 break;
3c824109
NF
12396 case JALR16S + 0:
12397 case JALR16S + 1:
b231c103
YK
12398 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12399 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12400 break;
12401 case MFHI16 + 0:
12402 case MFHI16 + 1:
26135ead 12403 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12404 break;
12405 case MFLO16 + 0:
12406 case MFLO16 + 1:
26135ead 12407 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
12408 break;
12409 case BREAK16:
12410 generate_exception(ctx, EXCP_BREAK);
12411 break;
12412 case SDBBP16:
12413 /* XXX: not clear which exception should be raised
12414 * when in debug mode...
12415 */
d75c135e 12416 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12417 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12418 generate_exception(ctx, EXCP_DBp);
12419 } else {
12420 generate_exception(ctx, EXCP_DBp);
12421 }
12422 break;
12423 case JRADDIUSP + 0:
12424 case JRADDIUSP + 1:
12425 {
12426 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 12427 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 12428 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
12429 /* Let normal delay slot handling in our caller take us
12430 to the branch target. */
12431 }
12432 break;
12433 default:
12434 generate_exception(ctx, EXCP_RI);
12435 break;
12436 }
12437}
12438
12439static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12440{
12441 TCGv t0 = tcg_temp_new();
12442 TCGv t1 = tcg_temp_new();
12443
12444 gen_load_gpr(t0, base);
12445
12446 if (index != 0) {
12447 gen_load_gpr(t1, index);
12448 tcg_gen_shli_tl(t1, t1, 2);
12449 gen_op_addr_add(ctx, t0, t1, t0);
12450 }
12451
5f68f5ae 12452 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12453 gen_store_gpr(t1, rd);
12454
12455 tcg_temp_free(t0);
12456 tcg_temp_free(t1);
12457}
12458
12459static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12460 int base, int16_t offset)
12461{
12462 const char *opn = "ldst_pair";
12463 TCGv t0, t1;
12464
36c6711b 12465 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12466 generate_exception(ctx, EXCP_RI);
d796321b
FB
12467 return;
12468 }
12469
3c824109
NF
12470 t0 = tcg_temp_new();
12471 t1 = tcg_temp_new();
8e9ade68 12472
3c824109
NF
12473 gen_base_offset_addr(ctx, t0, base, offset);
12474
12475 switch (opc) {
12476 case LWP:
36c6711b
EJ
12477 if (rd == base) {
12478 generate_exception(ctx, EXCP_RI);
12479 return;
12480 }
5f68f5ae 12481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12482 gen_store_gpr(t1, rd);
12483 tcg_gen_movi_tl(t1, 4);
12484 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12485 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12486 gen_store_gpr(t1, rd+1);
12487 opn = "lwp";
12488 break;
12489 case SWP:
3c824109 12490 gen_load_gpr(t1, rd);
5f68f5ae 12491 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12492 tcg_gen_movi_tl(t1, 4);
12493 gen_op_addr_add(ctx, t0, t0, t1);
12494 gen_load_gpr(t1, rd+1);
5f68f5ae 12495 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12496 opn = "swp";
12497 break;
12498#ifdef TARGET_MIPS64
12499 case LDP:
36c6711b
EJ
12500 if (rd == base) {
12501 generate_exception(ctx, EXCP_RI);
12502 return;
12503 }
5f68f5ae 12504 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12505 gen_store_gpr(t1, rd);
12506 tcg_gen_movi_tl(t1, 8);
12507 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12508 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12509 gen_store_gpr(t1, rd+1);
12510 opn = "ldp";
12511 break;
12512 case SDP:
3c824109 12513 gen_load_gpr(t1, rd);
5f68f5ae 12514 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12515 tcg_gen_movi_tl(t1, 8);
12516 gen_op_addr_add(ctx, t0, t0, t1);
12517 gen_load_gpr(t1, rd+1);
5f68f5ae 12518 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12519 opn = "sdp";
12520 break;
12521#endif
6af0bf9c 12522 }
2abf314d 12523 (void)opn; /* avoid a compiler warning */
3c824109
NF
12524 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12525 tcg_temp_free(t0);
12526 tcg_temp_free(t1);
12527}
618b0fe9 12528
240ce26a 12529static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12530{
12531 int extension = (ctx->opcode >> 6) & 0x3f;
12532 int minor = (ctx->opcode >> 12) & 0xf;
12533 uint32_t mips32_op;
12534
12535 switch (extension) {
12536 case TEQ:
12537 mips32_op = OPC_TEQ;
12538 goto do_trap;
12539 case TGE:
12540 mips32_op = OPC_TGE;
12541 goto do_trap;
12542 case TGEU:
12543 mips32_op = OPC_TGEU;
12544 goto do_trap;
12545 case TLT:
12546 mips32_op = OPC_TLT;
12547 goto do_trap;
12548 case TLTU:
12549 mips32_op = OPC_TLTU;
12550 goto do_trap;
12551 case TNE:
12552 mips32_op = OPC_TNE;
12553 do_trap:
12554 gen_trap(ctx, mips32_op, rs, rt, -1);
12555 break;
12556#ifndef CONFIG_USER_ONLY
12557 case MFC0:
12558 case MFC0 + 32:
2e15497c 12559 check_cp0_enabled(ctx);
3c824109
NF
12560 if (rt == 0) {
12561 /* Treat as NOP. */
12562 break;
12563 }
d75c135e 12564 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12565 break;
12566 case MTC0:
12567 case MTC0 + 32:
2e15497c 12568 check_cp0_enabled(ctx);
3c824109
NF
12569 {
12570 TCGv t0 = tcg_temp_new();
618b0fe9 12571
3c824109 12572 gen_load_gpr(t0, rt);
d75c135e 12573 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12574 tcg_temp_free(t0);
12575 }
12576 break;
12577#endif
a1fc6246
LA
12578 case 0x2a:
12579 switch (minor & 3) {
12580 case MADD_ACC:
12581 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12582 break;
12583 case MADDU_ACC:
12584 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12585 break;
12586 case MSUB_ACC:
12587 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12588 break;
12589 case MSUBU_ACC:
12590 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12591 break;
12592 default:
12593 goto pool32axf_invalid;
12594 }
12595 break;
12596 case 0x32:
12597 switch (minor & 3) {
12598 case MULT_ACC:
12599 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12600 break;
12601 case MULTU_ACC:
12602 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12603 break;
12604 default:
12605 goto pool32axf_invalid;
12606 }
12607 break;
3c824109
NF
12608 case 0x2c:
12609 switch (minor) {
12610 case SEB:
12611 gen_bshfl(ctx, OPC_SEB, rs, rt);
12612 break;
12613 case SEH:
12614 gen_bshfl(ctx, OPC_SEH, rs, rt);
12615 break;
12616 case CLO:
12617 mips32_op = OPC_CLO;
12618 goto do_cl;
12619 case CLZ:
12620 mips32_op = OPC_CLZ;
12621 do_cl:
d75c135e 12622 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12623 gen_cl(ctx, mips32_op, rt, rs);
12624 break;
12625 case RDHWR:
d75c135e 12626 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12627 break;
12628 case WSBH:
12629 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12630 break;
12631 case MULT:
12632 mips32_op = OPC_MULT;
26135ead 12633 goto do_mul;
3c824109
NF
12634 case MULTU:
12635 mips32_op = OPC_MULTU;
26135ead 12636 goto do_mul;
3c824109
NF
12637 case DIV:
12638 mips32_op = OPC_DIV;
26135ead 12639 goto do_div;
3c824109
NF
12640 case DIVU:
12641 mips32_op = OPC_DIVU;
26135ead
RS
12642 goto do_div;
12643 do_div:
12644 check_insn(ctx, ISA_MIPS32);
12645 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12646 break;
3c824109
NF
12647 case MADD:
12648 mips32_op = OPC_MADD;
26135ead 12649 goto do_mul;
3c824109
NF
12650 case MADDU:
12651 mips32_op = OPC_MADDU;
26135ead 12652 goto do_mul;
3c824109
NF
12653 case MSUB:
12654 mips32_op = OPC_MSUB;
26135ead 12655 goto do_mul;
3c824109
NF
12656 case MSUBU:
12657 mips32_op = OPC_MSUBU;
26135ead 12658 do_mul:
d75c135e 12659 check_insn(ctx, ISA_MIPS32);
a1fc6246 12660 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12661 break;
12662 default:
12663 goto pool32axf_invalid;
12664 }
12665 break;
12666 case 0x34:
12667 switch (minor) {
12668 case MFC2:
12669 case MTC2:
12670 case MFHC2:
12671 case MTHC2:
12672 case CFC2:
12673 case CTC2:
12674 generate_exception_err(ctx, EXCP_CpU, 2);
12675 break;
12676 default:
12677 goto pool32axf_invalid;
12678 }
12679 break;
12680 case 0x3c:
12681 switch (minor) {
12682 case JALR:
12683 case JALR_HB:
b231c103
YK
12684 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12685 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12686 break;
12687 case JALRS:
12688 case JALRS_HB:
b231c103
YK
12689 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12690 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12691 break;
12692 default:
12693 goto pool32axf_invalid;
12694 }
12695 break;
12696 case 0x05:
12697 switch (minor) {
12698 case RDPGPR:
2e15497c 12699 check_cp0_enabled(ctx);
d75c135e 12700 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12701 gen_load_srsgpr(rt, rs);
12702 break;
12703 case WRPGPR:
2e15497c 12704 check_cp0_enabled(ctx);
d75c135e 12705 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12706 gen_store_srsgpr(rt, rs);
12707 break;
12708 default:
12709 goto pool32axf_invalid;
12710 }
12711 break;
12712#ifndef CONFIG_USER_ONLY
12713 case 0x0d:
12714 switch (minor) {
12715 case TLBP:
12716 mips32_op = OPC_TLBP;
12717 goto do_cp0;
12718 case TLBR:
12719 mips32_op = OPC_TLBR;
12720 goto do_cp0;
12721 case TLBWI:
12722 mips32_op = OPC_TLBWI;
12723 goto do_cp0;
12724 case TLBWR:
12725 mips32_op = OPC_TLBWR;
12726 goto do_cp0;
12727 case WAIT:
12728 mips32_op = OPC_WAIT;
12729 goto do_cp0;
12730 case DERET:
12731 mips32_op = OPC_DERET;
12732 goto do_cp0;
12733 case ERET:
12734 mips32_op = OPC_ERET;
12735 do_cp0:
12736 gen_cp0(env, ctx, mips32_op, rt, rs);
12737 break;
12738 default:
12739 goto pool32axf_invalid;
12740 }
12741 break;
12742 case 0x1d:
12743 switch (minor) {
12744 case DI:
2e15497c 12745 check_cp0_enabled(ctx);
3c824109
NF
12746 {
12747 TCGv t0 = tcg_temp_new();
12748
12749 save_cpu_state(ctx, 1);
895c2d04 12750 gen_helper_di(t0, cpu_env);
3c824109
NF
12751 gen_store_gpr(t0, rs);
12752 /* Stop translation as we may have switched the execution mode */
12753 ctx->bstate = BS_STOP;
12754 tcg_temp_free(t0);
12755 }
12756 break;
12757 case EI:
2e15497c 12758 check_cp0_enabled(ctx);
3c824109
NF
12759 {
12760 TCGv t0 = tcg_temp_new();
12761
12762 save_cpu_state(ctx, 1);
895c2d04 12763 gen_helper_ei(t0, cpu_env);
3c824109
NF
12764 gen_store_gpr(t0, rs);
12765 /* Stop translation as we may have switched the execution mode */
12766 ctx->bstate = BS_STOP;
12767 tcg_temp_free(t0);
12768 }
12769 break;
12770 default:
12771 goto pool32axf_invalid;
12772 }
12773 break;
12774#endif
12775 case 0x2d:
12776 switch (minor) {
12777 case SYNC:
12778 /* NOP */
12779 break;
12780 case SYSCALL:
12781 generate_exception(ctx, EXCP_SYSCALL);
12782 ctx->bstate = BS_STOP;
12783 break;
12784 case SDBBP:
d75c135e 12785 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12786 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12787 generate_exception(ctx, EXCP_DBp);
12788 } else {
12789 generate_exception(ctx, EXCP_DBp);
12790 }
12791 break;
12792 default:
12793 goto pool32axf_invalid;
12794 }
12795 break;
a1fc6246 12796 case 0x01:
26135ead 12797 switch (minor & 3) {
a1fc6246 12798 case MFHI_ACC:
26135ead 12799 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12800 break;
a1fc6246 12801 case MFLO_ACC:
26135ead 12802 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12803 break;
a1fc6246 12804 case MTHI_ACC:
26135ead 12805 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12806 break;
a1fc6246 12807 case MTLO_ACC:
26135ead 12808 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12809 break;
12810 default:
12811 goto pool32axf_invalid;
12812 }
12813 break;
a1fc6246
LA
12814 case 0x35:
12815 switch (minor) {
12816 case MFHI32:
12817 gen_HILO(ctx, OPC_MFHI, 0, rs);
12818 break;
12819 case MFLO32:
12820 gen_HILO(ctx, OPC_MFLO, 0, rs);
12821 break;
12822 case MTHI32:
12823 gen_HILO(ctx, OPC_MTHI, 0, rs);
12824 break;
12825 case MTLO32:
12826 gen_HILO(ctx, OPC_MTLO, 0, rs);
12827 break;
12828 default:
12829 goto pool32axf_invalid;
12830 }
12831 break;
3c824109
NF
12832 default:
12833 pool32axf_invalid:
12834 MIPS_INVAL("pool32axf");
12835 generate_exception(ctx, EXCP_RI);
12836 break;
12837 }
12838}
12839
12840/* Values for microMIPS fmt field. Variable-width, depending on which
12841 formats the instruction supports. */
12842
12843enum {
12844 FMT_SD_S = 0,
12845 FMT_SD_D = 1,
12846
12847 FMT_SDPS_S = 0,
12848 FMT_SDPS_D = 1,
12849 FMT_SDPS_PS = 2,
12850
12851 FMT_SWL_S = 0,
12852 FMT_SWL_W = 1,
12853 FMT_SWL_L = 2,
12854
12855 FMT_DWL_D = 0,
12856 FMT_DWL_W = 1,
12857 FMT_DWL_L = 2
12858};
12859
d75c135e 12860static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12861{
12862 int extension = (ctx->opcode >> 6) & 0x3ff;
12863 uint32_t mips32_op;
12864
12865#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12866#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12867#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12868
12869 switch (extension) {
12870 case FLOAT_1BIT_FMT(CFC1, 0):
12871 mips32_op = OPC_CFC1;
12872 goto do_cp1;
12873 case FLOAT_1BIT_FMT(CTC1, 0):
12874 mips32_op = OPC_CTC1;
12875 goto do_cp1;
12876 case FLOAT_1BIT_FMT(MFC1, 0):
12877 mips32_op = OPC_MFC1;
12878 goto do_cp1;
12879 case FLOAT_1BIT_FMT(MTC1, 0):
12880 mips32_op = OPC_MTC1;
12881 goto do_cp1;
12882 case FLOAT_1BIT_FMT(MFHC1, 0):
12883 mips32_op = OPC_MFHC1;
12884 goto do_cp1;
12885 case FLOAT_1BIT_FMT(MTHC1, 0):
12886 mips32_op = OPC_MTHC1;
12887 do_cp1:
12888 gen_cp1(ctx, mips32_op, rt, rs);
12889 break;
12890
12891 /* Reciprocal square root */
12892 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12893 mips32_op = OPC_RSQRT_S;
12894 goto do_unaryfp;
12895 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12896 mips32_op = OPC_RSQRT_D;
12897 goto do_unaryfp;
12898
12899 /* Square root */
12900 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12901 mips32_op = OPC_SQRT_S;
12902 goto do_unaryfp;
12903 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12904 mips32_op = OPC_SQRT_D;
12905 goto do_unaryfp;
12906
12907 /* Reciprocal */
12908 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12909 mips32_op = OPC_RECIP_S;
12910 goto do_unaryfp;
12911 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12912 mips32_op = OPC_RECIP_D;
12913 goto do_unaryfp;
12914
12915 /* Floor */
12916 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12917 mips32_op = OPC_FLOOR_L_S;
12918 goto do_unaryfp;
12919 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12920 mips32_op = OPC_FLOOR_L_D;
12921 goto do_unaryfp;
12922 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12923 mips32_op = OPC_FLOOR_W_S;
12924 goto do_unaryfp;
12925 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12926 mips32_op = OPC_FLOOR_W_D;
12927 goto do_unaryfp;
12928
12929 /* Ceiling */
12930 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12931 mips32_op = OPC_CEIL_L_S;
12932 goto do_unaryfp;
12933 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12934 mips32_op = OPC_CEIL_L_D;
12935 goto do_unaryfp;
12936 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12937 mips32_op = OPC_CEIL_W_S;
12938 goto do_unaryfp;
12939 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12940 mips32_op = OPC_CEIL_W_D;
12941 goto do_unaryfp;
12942
12943 /* Truncation */
12944 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12945 mips32_op = OPC_TRUNC_L_S;
12946 goto do_unaryfp;
12947 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12948 mips32_op = OPC_TRUNC_L_D;
12949 goto do_unaryfp;
12950 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12951 mips32_op = OPC_TRUNC_W_S;
12952 goto do_unaryfp;
12953 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12954 mips32_op = OPC_TRUNC_W_D;
12955 goto do_unaryfp;
12956
12957 /* Round */
12958 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12959 mips32_op = OPC_ROUND_L_S;
12960 goto do_unaryfp;
12961 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12962 mips32_op = OPC_ROUND_L_D;
12963 goto do_unaryfp;
12964 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12965 mips32_op = OPC_ROUND_W_S;
12966 goto do_unaryfp;
12967 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12968 mips32_op = OPC_ROUND_W_D;
12969 goto do_unaryfp;
12970
12971 /* Integer to floating-point conversion */
12972 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12973 mips32_op = OPC_CVT_L_S;
12974 goto do_unaryfp;
12975 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12976 mips32_op = OPC_CVT_L_D;
12977 goto do_unaryfp;
12978 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
12979 mips32_op = OPC_CVT_W_S;
12980 goto do_unaryfp;
12981 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
12982 mips32_op = OPC_CVT_W_D;
12983 goto do_unaryfp;
12984
12985 /* Paired-foo conversions */
12986 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
12987 mips32_op = OPC_CVT_S_PL;
12988 goto do_unaryfp;
12989 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
12990 mips32_op = OPC_CVT_S_PU;
12991 goto do_unaryfp;
12992 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
12993 mips32_op = OPC_CVT_PW_PS;
12994 goto do_unaryfp;
12995 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
12996 mips32_op = OPC_CVT_PS_PW;
12997 goto do_unaryfp;
12998
12999 /* Floating-point moves */
13000 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13001 mips32_op = OPC_MOV_S;
13002 goto do_unaryfp;
13003 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13004 mips32_op = OPC_MOV_D;
13005 goto do_unaryfp;
13006 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13007 mips32_op = OPC_MOV_PS;
13008 goto do_unaryfp;
13009
13010 /* Absolute value */
13011 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13012 mips32_op = OPC_ABS_S;
13013 goto do_unaryfp;
13014 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13015 mips32_op = OPC_ABS_D;
13016 goto do_unaryfp;
13017 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13018 mips32_op = OPC_ABS_PS;
13019 goto do_unaryfp;
13020
13021 /* Negation */
13022 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13023 mips32_op = OPC_NEG_S;
13024 goto do_unaryfp;
13025 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13026 mips32_op = OPC_NEG_D;
13027 goto do_unaryfp;
13028 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13029 mips32_op = OPC_NEG_PS;
13030 goto do_unaryfp;
13031
13032 /* Reciprocal square root step */
13033 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13034 mips32_op = OPC_RSQRT1_S;
13035 goto do_unaryfp;
13036 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13037 mips32_op = OPC_RSQRT1_D;
13038 goto do_unaryfp;
13039 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13040 mips32_op = OPC_RSQRT1_PS;
13041 goto do_unaryfp;
13042
13043 /* Reciprocal step */
13044 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13045 mips32_op = OPC_RECIP1_S;
13046 goto do_unaryfp;
13047 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13048 mips32_op = OPC_RECIP1_S;
13049 goto do_unaryfp;
13050 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13051 mips32_op = OPC_RECIP1_PS;
13052 goto do_unaryfp;
13053
13054 /* Conversions from double */
13055 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13056 mips32_op = OPC_CVT_D_S;
13057 goto do_unaryfp;
13058 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13059 mips32_op = OPC_CVT_D_W;
13060 goto do_unaryfp;
13061 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13062 mips32_op = OPC_CVT_D_L;
13063 goto do_unaryfp;
13064
13065 /* Conversions from single */
13066 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13067 mips32_op = OPC_CVT_S_D;
13068 goto do_unaryfp;
13069 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13070 mips32_op = OPC_CVT_S_W;
13071 goto do_unaryfp;
13072 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13073 mips32_op = OPC_CVT_S_L;
13074 do_unaryfp:
13075 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13076 break;
13077
13078 /* Conditional moves on floating-point codes */
13079 case COND_FLOAT_MOV(MOVT, 0):
13080 case COND_FLOAT_MOV(MOVT, 1):
13081 case COND_FLOAT_MOV(MOVT, 2):
13082 case COND_FLOAT_MOV(MOVT, 3):
13083 case COND_FLOAT_MOV(MOVT, 4):
13084 case COND_FLOAT_MOV(MOVT, 5):
13085 case COND_FLOAT_MOV(MOVT, 6):
13086 case COND_FLOAT_MOV(MOVT, 7):
13087 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13088 break;
13089 case COND_FLOAT_MOV(MOVF, 0):
13090 case COND_FLOAT_MOV(MOVF, 1):
13091 case COND_FLOAT_MOV(MOVF, 2):
13092 case COND_FLOAT_MOV(MOVF, 3):
13093 case COND_FLOAT_MOV(MOVF, 4):
13094 case COND_FLOAT_MOV(MOVF, 5):
13095 case COND_FLOAT_MOV(MOVF, 6):
13096 case COND_FLOAT_MOV(MOVF, 7):
13097 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13098 break;
13099 default:
13100 MIPS_INVAL("pool32fxf");
13101 generate_exception(ctx, EXCP_RI);
13102 break;
13103 }
13104}
13105
7db13fae 13106static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 13107 uint16_t insn_hw1)
3c824109
NF
13108{
13109 int32_t offset;
13110 uint16_t insn;
13111 int rt, rs, rd, rr;
13112 int16_t imm;
13113 uint32_t op, minor, mips32_op;
13114 uint32_t cond, fmt, cc;
13115
895c2d04 13116 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
13117 ctx->opcode = (ctx->opcode << 16) | insn;
13118
13119 rt = (ctx->opcode >> 21) & 0x1f;
13120 rs = (ctx->opcode >> 16) & 0x1f;
13121 rd = (ctx->opcode >> 11) & 0x1f;
13122 rr = (ctx->opcode >> 6) & 0x1f;
13123 imm = (int16_t) ctx->opcode;
13124
13125 op = (ctx->opcode >> 26) & 0x3f;
13126 switch (op) {
13127 case POOL32A:
13128 minor = ctx->opcode & 0x3f;
13129 switch (minor) {
13130 case 0x00:
13131 minor = (ctx->opcode >> 6) & 0xf;
13132 switch (minor) {
13133 case SLL32:
13134 mips32_op = OPC_SLL;
13135 goto do_shifti;
13136 case SRA:
13137 mips32_op = OPC_SRA;
13138 goto do_shifti;
13139 case SRL32:
13140 mips32_op = OPC_SRL;
13141 goto do_shifti;
13142 case ROTR:
13143 mips32_op = OPC_ROTR;
13144 do_shifti:
d75c135e 13145 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
13146 break;
13147 default:
13148 goto pool32a_invalid;
13149 }
13150 break;
13151 case 0x10:
13152 minor = (ctx->opcode >> 6) & 0xf;
13153 switch (minor) {
13154 /* Arithmetic */
13155 case ADD:
13156 mips32_op = OPC_ADD;
13157 goto do_arith;
13158 case ADDU32:
13159 mips32_op = OPC_ADDU;
13160 goto do_arith;
13161 case SUB:
13162 mips32_op = OPC_SUB;
13163 goto do_arith;
13164 case SUBU32:
13165 mips32_op = OPC_SUBU;
13166 goto do_arith;
13167 case MUL:
13168 mips32_op = OPC_MUL;
13169 do_arith:
d75c135e 13170 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13171 break;
13172 /* Shifts */
13173 case SLLV:
13174 mips32_op = OPC_SLLV;
13175 goto do_shift;
13176 case SRLV:
13177 mips32_op = OPC_SRLV;
13178 goto do_shift;
13179 case SRAV:
13180 mips32_op = OPC_SRAV;
13181 goto do_shift;
13182 case ROTRV:
13183 mips32_op = OPC_ROTRV;
13184 do_shift:
d75c135e 13185 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13186 break;
13187 /* Logical operations */
13188 case AND:
13189 mips32_op = OPC_AND;
13190 goto do_logic;
13191 case OR32:
13192 mips32_op = OPC_OR;
13193 goto do_logic;
13194 case NOR:
13195 mips32_op = OPC_NOR;
13196 goto do_logic;
13197 case XOR32:
13198 mips32_op = OPC_XOR;
13199 do_logic:
d75c135e 13200 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13201 break;
13202 /* Set less than */
13203 case SLT:
13204 mips32_op = OPC_SLT;
13205 goto do_slt;
13206 case SLTU:
13207 mips32_op = OPC_SLTU;
13208 do_slt:
d75c135e 13209 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13210 break;
13211 default:
13212 goto pool32a_invalid;
13213 }
13214 break;
13215 case 0x18:
13216 minor = (ctx->opcode >> 6) & 0xf;
13217 switch (minor) {
13218 /* Conditional moves */
13219 case MOVN:
13220 mips32_op = OPC_MOVN;
13221 goto do_cmov;
13222 case MOVZ:
13223 mips32_op = OPC_MOVZ;
13224 do_cmov:
d75c135e 13225 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
13226 break;
13227 case LWXS:
13228 gen_ldxs(ctx, rs, rt, rd);
13229 break;
13230 default:
13231 goto pool32a_invalid;
13232 }
13233 break;
13234 case INS:
13235 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13236 return;
13237 case EXT:
13238 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13239 return;
13240 case POOL32AXF:
240ce26a 13241 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
13242 break;
13243 case 0x07:
13244 generate_exception(ctx, EXCP_BREAK);
13245 break;
13246 default:
13247 pool32a_invalid:
13248 MIPS_INVAL("pool32a");
13249 generate_exception(ctx, EXCP_RI);
13250 break;
13251 }
13252 break;
13253 case POOL32B:
13254 minor = (ctx->opcode >> 12) & 0xf;
13255 switch (minor) {
13256 case CACHE:
2e15497c 13257 check_cp0_enabled(ctx);
3c824109
NF
13258 /* Treat as no-op. */
13259 break;
13260 case LWC2:
13261 case SWC2:
13262 /* COP2: Not implemented. */
13263 generate_exception_err(ctx, EXCP_CpU, 2);
13264 break;
3c824109
NF
13265#ifdef TARGET_MIPS64
13266 case LDP:
13267 case SDP:
d9224450
MR
13268 check_insn(ctx, ISA_MIPS3);
13269 check_mips_64(ctx);
13270 /* Fallthrough */
3c824109 13271#endif
d9224450
MR
13272 case LWP:
13273 case SWP:
3c824109
NF
13274 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13275 break;
3c824109
NF
13276#ifdef TARGET_MIPS64
13277 case LDM:
13278 case SDM:
d9224450
MR
13279 check_insn(ctx, ISA_MIPS3);
13280 check_mips_64(ctx);
13281 /* Fallthrough */
3c824109 13282#endif
d9224450
MR
13283 case LWM32:
13284 case SWM32:
3c824109
NF
13285 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13286 break;
13287 default:
13288 MIPS_INVAL("pool32b");
13289 generate_exception(ctx, EXCP_RI);
13290 break;
13291 }
13292 break;
13293 case POOL32F:
5ab5c041 13294 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
13295 minor = ctx->opcode & 0x3f;
13296 check_cp1_enabled(ctx);
13297 switch (minor) {
13298 case ALNV_PS:
13299 mips32_op = OPC_ALNV_PS;
13300 goto do_madd;
13301 case MADD_S:
13302 mips32_op = OPC_MADD_S;
13303 goto do_madd;
13304 case MADD_D:
13305 mips32_op = OPC_MADD_D;
13306 goto do_madd;
13307 case MADD_PS:
13308 mips32_op = OPC_MADD_PS;
13309 goto do_madd;
13310 case MSUB_S:
13311 mips32_op = OPC_MSUB_S;
13312 goto do_madd;
13313 case MSUB_D:
13314 mips32_op = OPC_MSUB_D;
13315 goto do_madd;
13316 case MSUB_PS:
13317 mips32_op = OPC_MSUB_PS;
13318 goto do_madd;
13319 case NMADD_S:
13320 mips32_op = OPC_NMADD_S;
13321 goto do_madd;
13322 case NMADD_D:
13323 mips32_op = OPC_NMADD_D;
13324 goto do_madd;
13325 case NMADD_PS:
13326 mips32_op = OPC_NMADD_PS;
13327 goto do_madd;
13328 case NMSUB_S:
13329 mips32_op = OPC_NMSUB_S;
13330 goto do_madd;
13331 case NMSUB_D:
13332 mips32_op = OPC_NMSUB_D;
13333 goto do_madd;
13334 case NMSUB_PS:
13335 mips32_op = OPC_NMSUB_PS;
13336 do_madd:
13337 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13338 break;
13339 case CABS_COND_FMT:
13340 cond = (ctx->opcode >> 6) & 0xf;
13341 cc = (ctx->opcode >> 13) & 0x7;
13342 fmt = (ctx->opcode >> 10) & 0x3;
13343 switch (fmt) {
13344 case 0x0:
13345 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13346 break;
13347 case 0x1:
13348 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13349 break;
13350 case 0x2:
13351 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13352 break;
13353 default:
13354 goto pool32f_invalid;
13355 }
13356 break;
13357 case C_COND_FMT:
13358 cond = (ctx->opcode >> 6) & 0xf;
13359 cc = (ctx->opcode >> 13) & 0x7;
13360 fmt = (ctx->opcode >> 10) & 0x3;
13361 switch (fmt) {
13362 case 0x0:
13363 gen_cmp_s(ctx, cond, rt, rs, cc);
13364 break;
13365 case 0x1:
13366 gen_cmp_d(ctx, cond, rt, rs, cc);
13367 break;
13368 case 0x2:
13369 gen_cmp_ps(ctx, cond, rt, rs, cc);
13370 break;
13371 default:
13372 goto pool32f_invalid;
13373 }
13374 break;
13375 case POOL32FXF:
d75c135e 13376 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
13377 break;
13378 case 0x00:
13379 /* PLL foo */
13380 switch ((ctx->opcode >> 6) & 0x7) {
13381 case PLL_PS:
13382 mips32_op = OPC_PLL_PS;
13383 goto do_ps;
13384 case PLU_PS:
13385 mips32_op = OPC_PLU_PS;
13386 goto do_ps;
13387 case PUL_PS:
13388 mips32_op = OPC_PUL_PS;
13389 goto do_ps;
13390 case PUU_PS:
13391 mips32_op = OPC_PUU_PS;
13392 goto do_ps;
13393 case CVT_PS_S:
13394 mips32_op = OPC_CVT_PS_S;
13395 do_ps:
13396 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13397 break;
13398 default:
13399 goto pool32f_invalid;
13400 }
13401 break;
13402 case 0x08:
13403 /* [LS][WDU]XC1 */
13404 switch ((ctx->opcode >> 6) & 0x7) {
13405 case LWXC1:
13406 mips32_op = OPC_LWXC1;
13407 goto do_ldst_cp1;
13408 case SWXC1:
13409 mips32_op = OPC_SWXC1;
13410 goto do_ldst_cp1;
13411 case LDXC1:
13412 mips32_op = OPC_LDXC1;
13413 goto do_ldst_cp1;
13414 case SDXC1:
13415 mips32_op = OPC_SDXC1;
13416 goto do_ldst_cp1;
13417 case LUXC1:
13418 mips32_op = OPC_LUXC1;
13419 goto do_ldst_cp1;
13420 case SUXC1:
13421 mips32_op = OPC_SUXC1;
13422 do_ldst_cp1:
13423 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13424 break;
13425 default:
13426 goto pool32f_invalid;
13427 }
13428 break;
13429 case 0x18:
13430 /* 3D insns */
13431 fmt = (ctx->opcode >> 9) & 0x3;
13432 switch ((ctx->opcode >> 6) & 0x7) {
13433 case RSQRT2_FMT:
13434 switch (fmt) {
13435 case FMT_SDPS_S:
13436 mips32_op = OPC_RSQRT2_S;
13437 goto do_3d;
13438 case FMT_SDPS_D:
13439 mips32_op = OPC_RSQRT2_D;
13440 goto do_3d;
13441 case FMT_SDPS_PS:
13442 mips32_op = OPC_RSQRT2_PS;
13443 goto do_3d;
13444 default:
13445 goto pool32f_invalid;
13446 }
13447 break;
13448 case RECIP2_FMT:
13449 switch (fmt) {
13450 case FMT_SDPS_S:
13451 mips32_op = OPC_RECIP2_S;
13452 goto do_3d;
13453 case FMT_SDPS_D:
13454 mips32_op = OPC_RECIP2_D;
13455 goto do_3d;
13456 case FMT_SDPS_PS:
13457 mips32_op = OPC_RECIP2_PS;
13458 goto do_3d;
13459 default:
13460 goto pool32f_invalid;
13461 }
13462 break;
13463 case ADDR_PS:
13464 mips32_op = OPC_ADDR_PS;
13465 goto do_3d;
13466 case MULR_PS:
13467 mips32_op = OPC_MULR_PS;
13468 do_3d:
13469 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13470 break;
13471 default:
13472 goto pool32f_invalid;
13473 }
13474 break;
13475 case 0x20:
13476 /* MOV[FT].fmt and PREFX */
13477 cc = (ctx->opcode >> 13) & 0x7;
13478 fmt = (ctx->opcode >> 9) & 0x3;
13479 switch ((ctx->opcode >> 6) & 0x7) {
13480 case MOVF_FMT:
13481 switch (fmt) {
13482 case FMT_SDPS_S:
13483 gen_movcf_s(rs, rt, cc, 0);
13484 break;
13485 case FMT_SDPS_D:
13486 gen_movcf_d(ctx, rs, rt, cc, 0);
13487 break;
13488 case FMT_SDPS_PS:
7f6613ce 13489 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13490 break;
13491 default:
13492 goto pool32f_invalid;
13493 }
13494 break;
13495 case MOVT_FMT:
13496 switch (fmt) {
13497 case FMT_SDPS_S:
13498 gen_movcf_s(rs, rt, cc, 1);
13499 break;
13500 case FMT_SDPS_D:
13501 gen_movcf_d(ctx, rs, rt, cc, 1);
13502 break;
13503 case FMT_SDPS_PS:
7f6613ce 13504 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13505 break;
13506 default:
13507 goto pool32f_invalid;
13508 }
13509 break;
13510 case PREFX:
13511 break;
13512 default:
13513 goto pool32f_invalid;
13514 }
13515 break;
13516#define FINSN_3ARG_SDPS(prfx) \
13517 switch ((ctx->opcode >> 8) & 0x3) { \
13518 case FMT_SDPS_S: \
13519 mips32_op = OPC_##prfx##_S; \
13520 goto do_fpop; \
13521 case FMT_SDPS_D: \
13522 mips32_op = OPC_##prfx##_D; \
13523 goto do_fpop; \
13524 case FMT_SDPS_PS: \
13525 mips32_op = OPC_##prfx##_PS; \
13526 goto do_fpop; \
13527 default: \
13528 goto pool32f_invalid; \
13529 }
13530 case 0x30:
13531 /* regular FP ops */
13532 switch ((ctx->opcode >> 6) & 0x3) {
13533 case ADD_FMT:
13534 FINSN_3ARG_SDPS(ADD);
13535 break;
13536 case SUB_FMT:
13537 FINSN_3ARG_SDPS(SUB);
13538 break;
13539 case MUL_FMT:
13540 FINSN_3ARG_SDPS(MUL);
13541 break;
13542 case DIV_FMT:
13543 fmt = (ctx->opcode >> 8) & 0x3;
13544 if (fmt == 1) {
13545 mips32_op = OPC_DIV_D;
13546 } else if (fmt == 0) {
13547 mips32_op = OPC_DIV_S;
13548 } else {
13549 goto pool32f_invalid;
13550 }
13551 goto do_fpop;
13552 default:
13553 goto pool32f_invalid;
13554 }
13555 break;
13556 case 0x38:
13557 /* cmovs */
13558 switch ((ctx->opcode >> 6) & 0x3) {
13559 case MOVN_FMT:
13560 FINSN_3ARG_SDPS(MOVN);
13561 break;
13562 case MOVZ_FMT:
13563 FINSN_3ARG_SDPS(MOVZ);
13564 break;
13565 default:
13566 goto pool32f_invalid;
13567 }
13568 break;
13569 do_fpop:
13570 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13571 break;
13572 default:
13573 pool32f_invalid:
13574 MIPS_INVAL("pool32f");
13575 generate_exception(ctx, EXCP_RI);
13576 break;
13577 }
13578 } else {
13579 generate_exception_err(ctx, EXCP_CpU, 1);
13580 }
13581 break;
13582 case POOL32I:
13583 minor = (ctx->opcode >> 21) & 0x1f;
13584 switch (minor) {
13585 case BLTZ:
b231c103
YK
13586 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13587 break;
3c824109 13588 case BLTZAL:
b231c103
YK
13589 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13590 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13591 break;
3c824109 13592 case BLTZALS:
b231c103
YK
13593 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13594 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13595 break;
3c824109 13596 case BGEZ:
b231c103
YK
13597 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13598 break;
3c824109 13599 case BGEZAL:
b231c103
YK
13600 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13601 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13602 break;
3c824109 13603 case BGEZALS:
b231c103
YK
13604 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13605 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13606 break;
3c824109 13607 case BLEZ:
b231c103
YK
13608 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13609 break;
3c824109 13610 case BGTZ:
b231c103 13611 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13612 break;
13613
13614 /* Traps */
13615 case TLTI:
13616 mips32_op = OPC_TLTI;
13617 goto do_trapi;
13618 case TGEI:
13619 mips32_op = OPC_TGEI;
13620 goto do_trapi;
13621 case TLTIU:
13622 mips32_op = OPC_TLTIU;
13623 goto do_trapi;
13624 case TGEIU:
13625 mips32_op = OPC_TGEIU;
13626 goto do_trapi;
13627 case TNEI:
13628 mips32_op = OPC_TNEI;
13629 goto do_trapi;
13630 case TEQI:
13631 mips32_op = OPC_TEQI;
13632 do_trapi:
13633 gen_trap(ctx, mips32_op, rs, -1, imm);
13634 break;
13635
13636 case BNEZC:
13637 case BEQZC:
13638 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13639 4, rs, 0, imm << 1, 0);
3c824109
NF
13640 /* Compact branches don't have a delay slot, so just let
13641 the normal delay slot handling take us to the branch
13642 target. */
13643 break;
13644 case LUI:
d75c135e 13645 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
13646 break;
13647 case SYNCI:
a83bddd6
DZ
13648 /* Break the TB to be able to sync copied instructions
13649 immediately */
13650 ctx->bstate = BS_STOP;
3c824109
NF
13651 break;
13652 case BC2F:
13653 case BC2T:
13654 /* COP2: Not implemented. */
13655 generate_exception_err(ctx, EXCP_CpU, 2);
13656 break;
13657 case BC1F:
13658 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13659 goto do_cp1branch;
13660 case BC1T:
13661 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13662 goto do_cp1branch;
13663 case BC1ANY4F:
13664 mips32_op = OPC_BC1FANY4;
13665 goto do_cp1mips3d;
13666 case BC1ANY4T:
13667 mips32_op = OPC_BC1TANY4;
13668 do_cp1mips3d:
13669 check_cop1x(ctx);
d75c135e 13670 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13671 /* Fall through */
13672 do_cp1branch:
272f458d
MR
13673 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13674 check_cp1_enabled(ctx);
13675 gen_compute_branch1(ctx, mips32_op,
13676 (ctx->opcode >> 18) & 0x7, imm << 1);
13677 } else {
13678 generate_exception_err(ctx, EXCP_CpU, 1);
13679 }
3c824109
NF
13680 break;
13681 case BPOSGE64:
13682 case BPOSGE32:
13683 /* MIPS DSP: not implemented */
13684 /* Fall through */
13685 default:
13686 MIPS_INVAL("pool32i");
13687 generate_exception(ctx, EXCP_RI);
13688 break;
13689 }
13690 break;
13691 case POOL32C:
13692 minor = (ctx->opcode >> 12) & 0xf;
13693 switch (minor) {
13694 case LWL:
13695 mips32_op = OPC_LWL;
5c13fdfd 13696 goto do_ld_lr;
3c824109
NF
13697 case SWL:
13698 mips32_op = OPC_SWL;
5c13fdfd 13699 goto do_st_lr;
3c824109
NF
13700 case LWR:
13701 mips32_op = OPC_LWR;
5c13fdfd 13702 goto do_ld_lr;
3c824109
NF
13703 case SWR:
13704 mips32_op = OPC_SWR;
5c13fdfd 13705 goto do_st_lr;
3c824109
NF
13706#if defined(TARGET_MIPS64)
13707 case LDL:
d9224450
MR
13708 check_insn(ctx, ISA_MIPS3);
13709 check_mips_64(ctx);
3c824109 13710 mips32_op = OPC_LDL;
5c13fdfd 13711 goto do_ld_lr;
3c824109 13712 case SDL:
d9224450
MR
13713 check_insn(ctx, ISA_MIPS3);
13714 check_mips_64(ctx);
3c824109 13715 mips32_op = OPC_SDL;
5c13fdfd 13716 goto do_st_lr;
3c824109 13717 case LDR:
d9224450
MR
13718 check_insn(ctx, ISA_MIPS3);
13719 check_mips_64(ctx);
3c824109 13720 mips32_op = OPC_LDR;
5c13fdfd 13721 goto do_ld_lr;
3c824109 13722 case SDR:
d9224450
MR
13723 check_insn(ctx, ISA_MIPS3);
13724 check_mips_64(ctx);
3c824109 13725 mips32_op = OPC_SDR;
5c13fdfd 13726 goto do_st_lr;
3c824109 13727 case LWU:
d9224450
MR
13728 check_insn(ctx, ISA_MIPS3);
13729 check_mips_64(ctx);
3c824109 13730 mips32_op = OPC_LWU;
5c13fdfd 13731 goto do_ld_lr;
3c824109 13732 case LLD:
d9224450
MR
13733 check_insn(ctx, ISA_MIPS3);
13734 check_mips_64(ctx);
3c824109 13735 mips32_op = OPC_LLD;
5c13fdfd 13736 goto do_ld_lr;
3c824109
NF
13737#endif
13738 case LL:
13739 mips32_op = OPC_LL;
5c13fdfd
AJ
13740 goto do_ld_lr;
13741 do_ld_lr:
d75c135e 13742 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13743 break;
13744 do_st_lr:
13745 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13746 break;
13747 case SC:
13748 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13749 break;
13750#if defined(TARGET_MIPS64)
13751 case SCD:
d9224450
MR
13752 check_insn(ctx, ISA_MIPS3);
13753 check_mips_64(ctx);
3c824109
NF
13754 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13755 break;
13756#endif
13757 case PREF:
13758 /* Treat as no-op */
13759 break;
13760 default:
13761 MIPS_INVAL("pool32c");
13762 generate_exception(ctx, EXCP_RI);
13763 break;
13764 }
13765 break;
13766 case ADDI32:
13767 mips32_op = OPC_ADDI;
13768 goto do_addi;
13769 case ADDIU32:
13770 mips32_op = OPC_ADDIU;
13771 do_addi:
d75c135e 13772 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13773 break;
13774
13775 /* Logical operations */
13776 case ORI32:
13777 mips32_op = OPC_ORI;
13778 goto do_logici;
13779 case XORI32:
13780 mips32_op = OPC_XORI;
13781 goto do_logici;
13782 case ANDI32:
13783 mips32_op = OPC_ANDI;
13784 do_logici:
d75c135e 13785 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13786 break;
13787
13788 /* Set less than immediate */
13789 case SLTI32:
13790 mips32_op = OPC_SLTI;
13791 goto do_slti;
13792 case SLTIU32:
13793 mips32_op = OPC_SLTIU;
13794 do_slti:
d75c135e 13795 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13796 break;
13797 case JALX32:
13798 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13799 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13800 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13801 break;
13802 case JALS32:
13803 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13804 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13805 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13806 break;
13807 case BEQ32:
b231c103 13808 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13809 break;
13810 case BNE32:
b231c103 13811 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13812 break;
13813 case J32:
13814 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13815 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13816 break;
13817 case JAL32:
13818 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13819 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13820 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13821 break;
13822 /* Floating point (COP1) */
13823 case LWC132:
13824 mips32_op = OPC_LWC1;
13825 goto do_cop1;
13826 case LDC132:
13827 mips32_op = OPC_LDC1;
13828 goto do_cop1;
13829 case SWC132:
13830 mips32_op = OPC_SWC1;
13831 goto do_cop1;
13832 case SDC132:
13833 mips32_op = OPC_SDC1;
13834 do_cop1:
5ab5c041 13835 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13836 break;
13837 case ADDIUPC:
13838 {
13839 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13840 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13841
13842 gen_addiupc(ctx, reg, offset, 0, 0);
13843 }
13844 break;
13845 /* Loads and stores */
13846 case LB32:
13847 mips32_op = OPC_LB;
5c13fdfd 13848 goto do_ld;
3c824109
NF
13849 case LBU32:
13850 mips32_op = OPC_LBU;
5c13fdfd 13851 goto do_ld;
3c824109
NF
13852 case LH32:
13853 mips32_op = OPC_LH;
5c13fdfd 13854 goto do_ld;
3c824109
NF
13855 case LHU32:
13856 mips32_op = OPC_LHU;
5c13fdfd 13857 goto do_ld;
3c824109
NF
13858 case LW32:
13859 mips32_op = OPC_LW;
5c13fdfd 13860 goto do_ld;
3c824109
NF
13861#ifdef TARGET_MIPS64
13862 case LD32:
d9224450
MR
13863 check_insn(ctx, ISA_MIPS3);
13864 check_mips_64(ctx);
3c824109 13865 mips32_op = OPC_LD;
5c13fdfd 13866 goto do_ld;
3c824109 13867 case SD32:
d9224450
MR
13868 check_insn(ctx, ISA_MIPS3);
13869 check_mips_64(ctx);
3c824109 13870 mips32_op = OPC_SD;
5c13fdfd 13871 goto do_st;
3c824109
NF
13872#endif
13873 case SB32:
13874 mips32_op = OPC_SB;
5c13fdfd 13875 goto do_st;
3c824109
NF
13876 case SH32:
13877 mips32_op = OPC_SH;
5c13fdfd 13878 goto do_st;
3c824109
NF
13879 case SW32:
13880 mips32_op = OPC_SW;
5c13fdfd
AJ
13881 goto do_st;
13882 do_ld:
d75c135e 13883 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13884 break;
13885 do_st:
13886 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13887 break;
13888 default:
13889 generate_exception(ctx, EXCP_RI);
13890 break;
13891 }
13892}
13893
240ce26a 13894static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13895{
13896 uint32_t op;
13897
13898 /* make sure instructions are on a halfword boundary */
13899 if (ctx->pc & 0x1) {
13900 env->CP0_BadVAddr = ctx->pc;
13901 generate_exception(ctx, EXCP_AdEL);
13902 ctx->bstate = BS_STOP;
13903 return 2;
13904 }
13905
13906 op = (ctx->opcode >> 10) & 0x3f;
13907 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13908 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13909 switch (op & 0x7) { /* MSB-3..MSB-5 */
13910 case 0:
13911 /* POOL32A, POOL32B, POOL32I, POOL32C */
13912 case 4:
13913 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13914 case 5:
13915 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13916 case 6:
13917 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13918 case 7:
13919 /* LB32, LH32, LWC132, LDC132, LW32 */
13920 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13921 generate_exception(ctx, EXCP_RI);
13922 /* Just stop translation; the user is confused. */
13923 ctx->bstate = BS_STOP;
13924 return 2;
13925 }
13926 break;
b231c103
YK
13927 case 1:
13928 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13929 case 2:
13930 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13931 case 3:
13932 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13933 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13934 generate_exception(ctx, EXCP_RI);
13935 /* Just stop translation; the user is confused. */
13936 ctx->bstate = BS_STOP;
13937 return 2;
13938 }
13939 break;
3c824109
NF
13940 }
13941 }
b231c103 13942
3c824109
NF
13943 switch (op) {
13944 case POOL16A:
13945 {
13946 int rd = mmreg(uMIPS_RD(ctx->opcode));
13947 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13948 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13949 uint32_t opc = 0;
13950
13951 switch (ctx->opcode & 0x1) {
13952 case ADDU16:
13953 opc = OPC_ADDU;
13954 break;
13955 case SUBU16:
13956 opc = OPC_SUBU;
13957 break;
13958 }
13959
d75c135e 13960 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
13961 }
13962 break;
13963 case POOL16B:
13964 {
13965 int rd = mmreg(uMIPS_RD(ctx->opcode));
13966 int rs = mmreg(uMIPS_RS(ctx->opcode));
13967 int amount = (ctx->opcode >> 1) & 0x7;
13968 uint32_t opc = 0;
13969 amount = amount == 0 ? 8 : amount;
13970
13971 switch (ctx->opcode & 0x1) {
13972 case SLL16:
13973 opc = OPC_SLL;
13974 break;
13975 case SRL16:
13976 opc = OPC_SRL;
13977 break;
13978 }
13979
d75c135e 13980 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
13981 }
13982 break;
13983 case POOL16C:
240ce26a 13984 gen_pool16c_insn(ctx);
3c824109
NF
13985 break;
13986 case LWGP16:
13987 {
13988 int rd = mmreg(uMIPS_RD(ctx->opcode));
13989 int rb = 28; /* GP */
13990 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
13991
d75c135e 13992 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13993 }
13994 break;
13995 case POOL16F:
13996 if (ctx->opcode & 1) {
13997 generate_exception(ctx, EXCP_RI);
13998 } else {
13999 /* MOVEP */
14000 int enc_dest = uMIPS_RD(ctx->opcode);
14001 int enc_rt = uMIPS_RS2(ctx->opcode);
14002 int enc_rs = uMIPS_RS1(ctx->opcode);
14003 int rd, rs, re, rt;
14004 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14005 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14006 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14007
14008 rd = rd_enc[enc_dest];
14009 re = re_enc[enc_dest];
14010 rs = rs_rt_enc[enc_rs];
14011 rt = rs_rt_enc[enc_rt];
14012
7215d7e7
MR
14013 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14014 gen_arith(ctx, OPC_ADDU, re, rt, 0);
3c824109
NF
14015 }
14016 break;
14017 case LBU16:
14018 {
14019 int rd = mmreg(uMIPS_RD(ctx->opcode));
14020 int rb = mmreg(uMIPS_RS(ctx->opcode));
14021 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14022 offset = (offset == 0xf ? -1 : offset);
14023
d75c135e 14024 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
14025 }
14026 break;
14027 case LHU16:
14028 {
14029 int rd = mmreg(uMIPS_RD(ctx->opcode));
14030 int rb = mmreg(uMIPS_RS(ctx->opcode));
14031 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14032
d75c135e 14033 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
14034 }
14035 break;
14036 case LWSP16:
14037 {
14038 int rd = (ctx->opcode >> 5) & 0x1f;
14039 int rb = 29; /* SP */
14040 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14041
d75c135e 14042 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14043 }
14044 break;
14045 case LW16:
14046 {
14047 int rd = mmreg(uMIPS_RD(ctx->opcode));
14048 int rb = mmreg(uMIPS_RS(ctx->opcode));
14049 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14050
d75c135e 14051 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
14052 }
14053 break;
14054 case SB16:
14055 {
14056 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14057 int rb = mmreg(uMIPS_RS(ctx->opcode));
14058 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14059
5c13fdfd 14060 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
14061 }
14062 break;
14063 case SH16:
14064 {
14065 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14066 int rb = mmreg(uMIPS_RS(ctx->opcode));
14067 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14068
5c13fdfd 14069 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
14070 }
14071 break;
14072 case SWSP16:
14073 {
14074 int rd = (ctx->opcode >> 5) & 0x1f;
14075 int rb = 29; /* SP */
14076 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14077
5c13fdfd 14078 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14079 }
14080 break;
14081 case SW16:
14082 {
14083 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14084 int rb = mmreg(uMIPS_RS(ctx->opcode));
14085 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14086
5c13fdfd 14087 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
14088 }
14089 break;
14090 case MOVE16:
14091 {
14092 int rd = uMIPS_RD5(ctx->opcode);
14093 int rs = uMIPS_RS5(ctx->opcode);
14094
7215d7e7 14095 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
14096 }
14097 break;
14098 case ANDI16:
d75c135e 14099 gen_andi16(ctx);
3c824109
NF
14100 break;
14101 case POOL16D:
14102 switch (ctx->opcode & 0x1) {
14103 case ADDIUS5:
d75c135e 14104 gen_addius5(ctx);
3c824109
NF
14105 break;
14106 case ADDIUSP:
d75c135e 14107 gen_addiusp(ctx);
3c824109
NF
14108 break;
14109 }
14110 break;
14111 case POOL16E:
14112 switch (ctx->opcode & 0x1) {
14113 case ADDIUR2:
d75c135e 14114 gen_addiur2(ctx);
3c824109
NF
14115 break;
14116 case ADDIUR1SP:
d75c135e 14117 gen_addiur1sp(ctx);
3c824109
NF
14118 break;
14119 }
14120 break;
14121 case B16:
14122 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 14123 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
14124 break;
14125 case BNEZ16:
14126 case BEQZ16:
14127 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14128 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 14129 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
14130 break;
14131 case LI16:
14132 {
14133 int reg = mmreg(uMIPS_RD(ctx->opcode));
14134 int imm = ZIMM(ctx->opcode, 0, 7);
14135
14136 imm = (imm == 0x7f ? -1 : imm);
14137 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14138 }
14139 break;
14140 case RES_20:
14141 case RES_28:
14142 case RES_29:
14143 case RES_30:
14144 case RES_31:
14145 case RES_38:
14146 case RES_39:
14147 generate_exception(ctx, EXCP_RI);
14148 break;
14149 default:
240ce26a 14150 decode_micromips32_opc (env, ctx, op);
3c824109
NF
14151 return 4;
14152 }
14153
14154 return 2;
14155}
14156
14157/* SmartMIPS extension to MIPS32 */
14158
14159#if defined(TARGET_MIPS64)
14160
14161/* MDMX extension to MIPS64 */
14162
14163#endif
14164
9b1a1d68 14165/* MIPSDSP functions. */
d75c135e 14166static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
14167 int rd, int base, int offset)
14168{
14169 const char *opn = "ldx";
14170 TCGv t0;
14171
9b1a1d68
JL
14172 check_dsp(ctx);
14173 t0 = tcg_temp_new();
14174
14175 if (base == 0) {
14176 gen_load_gpr(t0, offset);
14177 } else if (offset == 0) {
14178 gen_load_gpr(t0, base);
14179 } else {
14180 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14181 }
14182
9b1a1d68
JL
14183 switch (opc) {
14184 case OPC_LBUX:
5f68f5ae 14185 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
14186 gen_store_gpr(t0, rd);
14187 opn = "lbux";
14188 break;
14189 case OPC_LHX:
5f68f5ae 14190 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
14191 gen_store_gpr(t0, rd);
14192 opn = "lhx";
14193 break;
14194 case OPC_LWX:
5f68f5ae 14195 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
14196 gen_store_gpr(t0, rd);
14197 opn = "lwx";
14198 break;
14199#if defined(TARGET_MIPS64)
14200 case OPC_LDX:
5f68f5ae 14201 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
14202 gen_store_gpr(t0, rd);
14203 opn = "ldx";
14204 break;
14205#endif
14206 }
14207 (void)opn; /* avoid a compiler warning */
14208 MIPS_DEBUG("%s %s, %s(%s)", opn,
14209 regnames[rd], regnames[offset], regnames[base]);
14210 tcg_temp_free(t0);
14211}
14212
461c08df
JL
14213static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14214 int ret, int v1, int v2)
14215{
14216 const char *opn = "mipsdsp arith";
14217 TCGv v1_t;
14218 TCGv v2_t;
14219
14220 if (ret == 0) {
14221 /* Treat as NOP. */
14222 MIPS_DEBUG("NOP");
14223 return;
14224 }
14225
14226 v1_t = tcg_temp_new();
14227 v2_t = tcg_temp_new();
14228
14229 gen_load_gpr(v1_t, v1);
14230 gen_load_gpr(v2_t, v2);
14231
14232 switch (op1) {
14233 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14234 case OPC_MULT_G_2E:
14235 check_dspr2(ctx);
14236 switch (op2) {
14237 case OPC_ADDUH_QB:
14238 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
14239 break;
14240 case OPC_ADDUH_R_QB:
14241 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14242 break;
14243 case OPC_ADDQH_PH:
14244 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
14245 break;
14246 case OPC_ADDQH_R_PH:
14247 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14248 break;
14249 case OPC_ADDQH_W:
14250 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
14251 break;
14252 case OPC_ADDQH_R_W:
14253 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14254 break;
14255 case OPC_SUBUH_QB:
14256 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
14257 break;
14258 case OPC_SUBUH_R_QB:
14259 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
14260 break;
14261 case OPC_SUBQH_PH:
14262 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
14263 break;
14264 case OPC_SUBQH_R_PH:
14265 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
14266 break;
14267 case OPC_SUBQH_W:
14268 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
14269 break;
14270 case OPC_SUBQH_R_W:
14271 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
14272 break;
14273 }
14274 break;
14275 case OPC_ABSQ_S_PH_DSP:
14276 switch (op2) {
14277 case OPC_ABSQ_S_QB:
14278 check_dspr2(ctx);
14279 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
14280 break;
14281 case OPC_ABSQ_S_PH:
14282 check_dsp(ctx);
14283 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
14284 break;
14285 case OPC_ABSQ_S_W:
14286 check_dsp(ctx);
14287 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
14288 break;
14289 case OPC_PRECEQ_W_PHL:
14290 check_dsp(ctx);
14291 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
14292 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14293 break;
14294 case OPC_PRECEQ_W_PHR:
14295 check_dsp(ctx);
14296 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
14297 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
14298 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14299 break;
14300 case OPC_PRECEQU_PH_QBL:
14301 check_dsp(ctx);
14302 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
14303 break;
14304 case OPC_PRECEQU_PH_QBR:
14305 check_dsp(ctx);
14306 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
14307 break;
14308 case OPC_PRECEQU_PH_QBLA:
14309 check_dsp(ctx);
14310 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
14311 break;
14312 case OPC_PRECEQU_PH_QBRA:
14313 check_dsp(ctx);
14314 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
14315 break;
14316 case OPC_PRECEU_PH_QBL:
14317 check_dsp(ctx);
14318 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
14319 break;
14320 case OPC_PRECEU_PH_QBR:
14321 check_dsp(ctx);
14322 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
14323 break;
14324 case OPC_PRECEU_PH_QBLA:
14325 check_dsp(ctx);
14326 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
14327 break;
14328 case OPC_PRECEU_PH_QBRA:
14329 check_dsp(ctx);
14330 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
14331 break;
14332 }
14333 break;
14334 case OPC_ADDU_QB_DSP:
14335 switch (op2) {
14336 case OPC_ADDQ_PH:
14337 check_dsp(ctx);
14338 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14339 break;
14340 case OPC_ADDQ_S_PH:
14341 check_dsp(ctx);
14342 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14343 break;
14344 case OPC_ADDQ_S_W:
14345 check_dsp(ctx);
14346 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14347 break;
14348 case OPC_ADDU_QB:
14349 check_dsp(ctx);
14350 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14351 break;
14352 case OPC_ADDU_S_QB:
14353 check_dsp(ctx);
14354 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14355 break;
14356 case OPC_ADDU_PH:
14357 check_dspr2(ctx);
14358 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14359 break;
14360 case OPC_ADDU_S_PH:
14361 check_dspr2(ctx);
14362 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14363 break;
14364 case OPC_SUBQ_PH:
14365 check_dsp(ctx);
14366 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14367 break;
14368 case OPC_SUBQ_S_PH:
14369 check_dsp(ctx);
14370 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14371 break;
14372 case OPC_SUBQ_S_W:
14373 check_dsp(ctx);
14374 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14375 break;
14376 case OPC_SUBU_QB:
14377 check_dsp(ctx);
14378 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14379 break;
14380 case OPC_SUBU_S_QB:
14381 check_dsp(ctx);
14382 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14383 break;
14384 case OPC_SUBU_PH:
14385 check_dspr2(ctx);
14386 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14387 break;
14388 case OPC_SUBU_S_PH:
14389 check_dspr2(ctx);
14390 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14391 break;
14392 case OPC_ADDSC:
14393 check_dsp(ctx);
14394 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14395 break;
14396 case OPC_ADDWC:
14397 check_dsp(ctx);
14398 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14399 break;
14400 case OPC_MODSUB:
14401 check_dsp(ctx);
14402 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
14403 break;
14404 case OPC_RADDU_W_QB:
14405 check_dsp(ctx);
14406 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
14407 break;
14408 }
14409 break;
14410 case OPC_CMPU_EQ_QB_DSP:
14411 switch (op2) {
14412 case OPC_PRECR_QB_PH:
14413 check_dspr2(ctx);
14414 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14415 break;
14416 case OPC_PRECRQ_QB_PH:
14417 check_dsp(ctx);
14418 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
14419 break;
14420 case OPC_PRECR_SRA_PH_W:
14421 check_dspr2(ctx);
14422 {
14423 TCGv_i32 sa_t = tcg_const_i32(v2);
14424 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
14425 cpu_gpr[ret]);
14426 tcg_temp_free_i32(sa_t);
14427 break;
14428 }
14429 case OPC_PRECR_SRA_R_PH_W:
14430 check_dspr2(ctx);
14431 {
14432 TCGv_i32 sa_t = tcg_const_i32(v2);
14433 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
14434 cpu_gpr[ret]);
14435 tcg_temp_free_i32(sa_t);
14436 break;
14437 }
14438 case OPC_PRECRQ_PH_W:
14439 check_dsp(ctx);
14440 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14441 break;
14442 case OPC_PRECRQ_RS_PH_W:
14443 check_dsp(ctx);
14444 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14445 break;
14446 case OPC_PRECRQU_S_QB_PH:
14447 check_dsp(ctx);
14448 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14449 break;
14450 }
14451 break;
14452#ifdef TARGET_MIPS64
14453 case OPC_ABSQ_S_QH_DSP:
14454 switch (op2) {
14455 case OPC_PRECEQ_L_PWL:
14456 check_dsp(ctx);
14457 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14458 break;
14459 case OPC_PRECEQ_L_PWR:
14460 check_dsp(ctx);
14461 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14462 break;
14463 case OPC_PRECEQ_PW_QHL:
14464 check_dsp(ctx);
14465 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14466 break;
14467 case OPC_PRECEQ_PW_QHR:
14468 check_dsp(ctx);
14469 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14470 break;
14471 case OPC_PRECEQ_PW_QHLA:
14472 check_dsp(ctx);
14473 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14474 break;
14475 case OPC_PRECEQ_PW_QHRA:
14476 check_dsp(ctx);
14477 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14478 break;
14479 case OPC_PRECEQU_QH_OBL:
14480 check_dsp(ctx);
14481 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14482 break;
14483 case OPC_PRECEQU_QH_OBR:
14484 check_dsp(ctx);
14485 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14486 break;
14487 case OPC_PRECEQU_QH_OBLA:
14488 check_dsp(ctx);
14489 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14490 break;
14491 case OPC_PRECEQU_QH_OBRA:
14492 check_dsp(ctx);
14493 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14494 break;
14495 case OPC_PRECEU_QH_OBL:
14496 check_dsp(ctx);
14497 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14498 break;
14499 case OPC_PRECEU_QH_OBR:
14500 check_dsp(ctx);
14501 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14502 break;
14503 case OPC_PRECEU_QH_OBLA:
14504 check_dsp(ctx);
14505 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14506 break;
14507 case OPC_PRECEU_QH_OBRA:
14508 check_dsp(ctx);
14509 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14510 break;
14511 case OPC_ABSQ_S_OB:
14512 check_dspr2(ctx);
14513 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14514 break;
14515 case OPC_ABSQ_S_PW:
14516 check_dsp(ctx);
14517 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14518 break;
14519 case OPC_ABSQ_S_QH:
14520 check_dsp(ctx);
14521 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14522 break;
14523 }
14524 break;
14525 case OPC_ADDU_OB_DSP:
14526 switch (op2) {
14527 case OPC_RADDU_L_OB:
14528 check_dsp(ctx);
14529 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14530 break;
14531 case OPC_SUBQ_PW:
14532 check_dsp(ctx);
14533 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14534 break;
14535 case OPC_SUBQ_S_PW:
14536 check_dsp(ctx);
14537 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14538 break;
14539 case OPC_SUBQ_QH:
14540 check_dsp(ctx);
14541 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14542 break;
14543 case OPC_SUBQ_S_QH:
14544 check_dsp(ctx);
14545 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14546 break;
14547 case OPC_SUBU_OB:
14548 check_dsp(ctx);
14549 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14550 break;
14551 case OPC_SUBU_S_OB:
14552 check_dsp(ctx);
14553 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14554 break;
14555 case OPC_SUBU_QH:
14556 check_dspr2(ctx);
14557 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14558 break;
14559 case OPC_SUBU_S_QH:
14560 check_dspr2(ctx);
14561 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14562 break;
14563 case OPC_SUBUH_OB:
14564 check_dspr2(ctx);
14565 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14566 break;
14567 case OPC_SUBUH_R_OB:
14568 check_dspr2(ctx);
14569 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14570 break;
14571 case OPC_ADDQ_PW:
14572 check_dsp(ctx);
14573 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14574 break;
14575 case OPC_ADDQ_S_PW:
14576 check_dsp(ctx);
14577 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14578 break;
14579 case OPC_ADDQ_QH:
14580 check_dsp(ctx);
14581 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14582 break;
14583 case OPC_ADDQ_S_QH:
14584 check_dsp(ctx);
14585 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14586 break;
14587 case OPC_ADDU_OB:
14588 check_dsp(ctx);
14589 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14590 break;
14591 case OPC_ADDU_S_OB:
14592 check_dsp(ctx);
14593 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14594 break;
14595 case OPC_ADDU_QH:
14596 check_dspr2(ctx);
14597 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14598 break;
14599 case OPC_ADDU_S_QH:
14600 check_dspr2(ctx);
14601 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14602 break;
14603 case OPC_ADDUH_OB:
14604 check_dspr2(ctx);
14605 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14606 break;
14607 case OPC_ADDUH_R_OB:
14608 check_dspr2(ctx);
14609 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14610 break;
14611 }
14612 break;
14613 case OPC_CMPU_EQ_OB_DSP:
14614 switch (op2) {
14615 case OPC_PRECR_OB_QH:
14616 check_dspr2(ctx);
14617 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14618 break;
14619 case OPC_PRECR_SRA_QH_PW:
14620 check_dspr2(ctx);
14621 {
14622 TCGv_i32 ret_t = tcg_const_i32(ret);
14623 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14624 tcg_temp_free_i32(ret_t);
14625 break;
14626 }
14627 case OPC_PRECR_SRA_R_QH_PW:
14628 check_dspr2(ctx);
14629 {
14630 TCGv_i32 sa_v = tcg_const_i32(ret);
14631 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14632 tcg_temp_free_i32(sa_v);
14633 break;
14634 }
14635 case OPC_PRECRQ_OB_QH:
14636 check_dsp(ctx);
14637 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14638 break;
14639 case OPC_PRECRQ_PW_L:
14640 check_dsp(ctx);
14641 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14642 break;
14643 case OPC_PRECRQ_QH_PW:
14644 check_dsp(ctx);
14645 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14646 break;
14647 case OPC_PRECRQ_RS_QH_PW:
14648 check_dsp(ctx);
14649 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14650 break;
14651 case OPC_PRECRQU_S_OB_QH:
14652 check_dsp(ctx);
14653 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14654 break;
14655 }
14656 break;
14657#endif
14658 }
14659
14660 tcg_temp_free(v1_t);
14661 tcg_temp_free(v2_t);
14662
14663 (void)opn; /* avoid a compiler warning */
14664 MIPS_DEBUG("%s", opn);
14665}
9b1a1d68 14666
77c5fa8b
JL
14667static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14668 int ret, int v1, int v2)
14669{
14670 uint32_t op2;
14671 const char *opn = "mipsdsp shift";
14672 TCGv t0;
14673 TCGv v1_t;
14674 TCGv v2_t;
14675
14676 if (ret == 0) {
14677 /* Treat as NOP. */
14678 MIPS_DEBUG("NOP");
14679 return;
14680 }
14681
14682 t0 = tcg_temp_new();
14683 v1_t = tcg_temp_new();
14684 v2_t = tcg_temp_new();
14685
14686 tcg_gen_movi_tl(t0, v1);
14687 gen_load_gpr(v1_t, v1);
14688 gen_load_gpr(v2_t, v2);
14689
14690 switch (opc) {
14691 case OPC_SHLL_QB_DSP:
14692 {
14693 op2 = MASK_SHLL_QB(ctx->opcode);
14694 switch (op2) {
14695 case OPC_SHLL_QB:
14696 check_dsp(ctx);
14697 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14698 break;
14699 case OPC_SHLLV_QB:
14700 check_dsp(ctx);
14701 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14702 break;
14703 case OPC_SHLL_PH:
14704 check_dsp(ctx);
14705 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14706 break;
14707 case OPC_SHLLV_PH:
14708 check_dsp(ctx);
14709 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14710 break;
14711 case OPC_SHLL_S_PH:
14712 check_dsp(ctx);
14713 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14714 break;
14715 case OPC_SHLLV_S_PH:
14716 check_dsp(ctx);
14717 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14718 break;
14719 case OPC_SHLL_S_W:
14720 check_dsp(ctx);
14721 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14722 break;
14723 case OPC_SHLLV_S_W:
14724 check_dsp(ctx);
14725 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14726 break;
14727 case OPC_SHRL_QB:
14728 check_dsp(ctx);
14729 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14730 break;
14731 case OPC_SHRLV_QB:
14732 check_dsp(ctx);
14733 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14734 break;
14735 case OPC_SHRL_PH:
14736 check_dspr2(ctx);
14737 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14738 break;
14739 case OPC_SHRLV_PH:
14740 check_dspr2(ctx);
14741 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14742 break;
14743 case OPC_SHRA_QB:
14744 check_dspr2(ctx);
14745 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14746 break;
14747 case OPC_SHRA_R_QB:
14748 check_dspr2(ctx);
14749 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14750 break;
14751 case OPC_SHRAV_QB:
14752 check_dspr2(ctx);
14753 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14754 break;
14755 case OPC_SHRAV_R_QB:
14756 check_dspr2(ctx);
14757 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14758 break;
14759 case OPC_SHRA_PH:
14760 check_dsp(ctx);
14761 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14762 break;
14763 case OPC_SHRA_R_PH:
14764 check_dsp(ctx);
14765 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14766 break;
14767 case OPC_SHRAV_PH:
14768 check_dsp(ctx);
14769 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14770 break;
14771 case OPC_SHRAV_R_PH:
14772 check_dsp(ctx);
14773 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14774 break;
14775 case OPC_SHRA_R_W:
14776 check_dsp(ctx);
14777 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14778 break;
14779 case OPC_SHRAV_R_W:
14780 check_dsp(ctx);
14781 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14782 break;
14783 default: /* Invalid */
14784 MIPS_INVAL("MASK SHLL.QB");
14785 generate_exception(ctx, EXCP_RI);
14786 break;
14787 }
14788 break;
14789 }
14790#ifdef TARGET_MIPS64
14791 case OPC_SHLL_OB_DSP:
14792 op2 = MASK_SHLL_OB(ctx->opcode);
14793 switch (op2) {
14794 case OPC_SHLL_PW:
14795 check_dsp(ctx);
14796 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14797 break;
14798 case OPC_SHLLV_PW:
14799 check_dsp(ctx);
14800 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14801 break;
14802 case OPC_SHLL_S_PW:
14803 check_dsp(ctx);
14804 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14805 break;
14806 case OPC_SHLLV_S_PW:
14807 check_dsp(ctx);
14808 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14809 break;
14810 case OPC_SHLL_OB:
14811 check_dsp(ctx);
14812 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14813 break;
14814 case OPC_SHLLV_OB:
14815 check_dsp(ctx);
14816 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14817 break;
14818 case OPC_SHLL_QH:
14819 check_dsp(ctx);
14820 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14821 break;
14822 case OPC_SHLLV_QH:
14823 check_dsp(ctx);
14824 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14825 break;
14826 case OPC_SHLL_S_QH:
14827 check_dsp(ctx);
14828 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14829 break;
14830 case OPC_SHLLV_S_QH:
14831 check_dsp(ctx);
14832 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14833 break;
14834 case OPC_SHRA_OB:
14835 check_dspr2(ctx);
14836 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14837 break;
14838 case OPC_SHRAV_OB:
14839 check_dspr2(ctx);
14840 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14841 break;
14842 case OPC_SHRA_R_OB:
14843 check_dspr2(ctx);
14844 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14845 break;
14846 case OPC_SHRAV_R_OB:
14847 check_dspr2(ctx);
14848 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14849 break;
14850 case OPC_SHRA_PW:
14851 check_dsp(ctx);
14852 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14853 break;
14854 case OPC_SHRAV_PW:
14855 check_dsp(ctx);
14856 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14857 break;
14858 case OPC_SHRA_R_PW:
14859 check_dsp(ctx);
14860 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14861 break;
14862 case OPC_SHRAV_R_PW:
14863 check_dsp(ctx);
14864 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14865 break;
14866 case OPC_SHRA_QH:
14867 check_dsp(ctx);
14868 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14869 break;
14870 case OPC_SHRAV_QH:
14871 check_dsp(ctx);
14872 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14873 break;
14874 case OPC_SHRA_R_QH:
14875 check_dsp(ctx);
14876 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14877 break;
14878 case OPC_SHRAV_R_QH:
14879 check_dsp(ctx);
14880 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14881 break;
14882 case OPC_SHRL_OB:
14883 check_dsp(ctx);
14884 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14885 break;
14886 case OPC_SHRLV_OB:
14887 check_dsp(ctx);
14888 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14889 break;
14890 case OPC_SHRL_QH:
14891 check_dspr2(ctx);
14892 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14893 break;
14894 case OPC_SHRLV_QH:
14895 check_dspr2(ctx);
14896 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14897 break;
14898 default: /* Invalid */
14899 MIPS_INVAL("MASK SHLL.OB");
14900 generate_exception(ctx, EXCP_RI);
14901 break;
14902 }
14903 break;
14904#endif
14905 }
14906
14907 tcg_temp_free(t0);
14908 tcg_temp_free(v1_t);
14909 tcg_temp_free(v2_t);
14910 (void)opn; /* avoid a compiler warning */
14911 MIPS_DEBUG("%s", opn);
14912}
14913
a22260ae
JL
14914static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14915 int ret, int v1, int v2, int check_ret)
14916{
14917 const char *opn = "mipsdsp multiply";
14918 TCGv_i32 t0;
14919 TCGv v1_t;
14920 TCGv v2_t;
14921
14922 if ((ret == 0) && (check_ret == 1)) {
14923 /* Treat as NOP. */
14924 MIPS_DEBUG("NOP");
14925 return;
14926 }
14927
14928 t0 = tcg_temp_new_i32();
14929 v1_t = tcg_temp_new();
14930 v2_t = tcg_temp_new();
14931
14932 tcg_gen_movi_i32(t0, ret);
14933 gen_load_gpr(v1_t, v1);
14934 gen_load_gpr(v2_t, v2);
14935
14936 switch (op1) {
14937 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14938 * the same mask and op1. */
14939 case OPC_MULT_G_2E:
639eadb9 14940 check_dspr2(ctx);
a22260ae
JL
14941 switch (op2) {
14942 case OPC_MUL_PH:
14943 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14944 break;
14945 case OPC_MUL_S_PH:
14946 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14947 break;
14948 case OPC_MULQ_S_W:
14949 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14950 break;
14951 case OPC_MULQ_RS_W:
14952 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14953 break;
14954 }
14955 break;
14956 case OPC_DPA_W_PH_DSP:
14957 switch (op2) {
14958 case OPC_DPAU_H_QBL:
14959 check_dsp(ctx);
14960 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14961 break;
14962 case OPC_DPAU_H_QBR:
14963 check_dsp(ctx);
14964 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14965 break;
14966 case OPC_DPSU_H_QBL:
14967 check_dsp(ctx);
14968 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14969 break;
14970 case OPC_DPSU_H_QBR:
14971 check_dsp(ctx);
14972 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14973 break;
14974 case OPC_DPA_W_PH:
14975 check_dspr2(ctx);
14976 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14977 break;
14978 case OPC_DPAX_W_PH:
14979 check_dspr2(ctx);
14980 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
14981 break;
14982 case OPC_DPAQ_S_W_PH:
14983 check_dsp(ctx);
14984 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14985 break;
14986 case OPC_DPAQX_S_W_PH:
14987 check_dspr2(ctx);
14988 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14989 break;
14990 case OPC_DPAQX_SA_W_PH:
14991 check_dspr2(ctx);
14992 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14993 break;
14994 case OPC_DPS_W_PH:
14995 check_dspr2(ctx);
14996 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
14997 break;
14998 case OPC_DPSX_W_PH:
14999 check_dspr2(ctx);
15000 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15001 break;
15002 case OPC_DPSQ_S_W_PH:
15003 check_dsp(ctx);
15004 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15005 break;
15006 case OPC_DPSQX_S_W_PH:
15007 check_dspr2(ctx);
15008 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15009 break;
15010 case OPC_DPSQX_SA_W_PH:
15011 check_dspr2(ctx);
15012 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15013 break;
15014 case OPC_MULSAQ_S_W_PH:
15015 check_dsp(ctx);
15016 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15017 break;
15018 case OPC_DPAQ_SA_L_W:
15019 check_dsp(ctx);
15020 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15021 break;
15022 case OPC_DPSQ_SA_L_W:
15023 check_dsp(ctx);
15024 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15025 break;
15026 case OPC_MAQ_S_W_PHL:
15027 check_dsp(ctx);
15028 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15029 break;
15030 case OPC_MAQ_S_W_PHR:
15031 check_dsp(ctx);
15032 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15033 break;
15034 case OPC_MAQ_SA_W_PHL:
15035 check_dsp(ctx);
15036 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15037 break;
15038 case OPC_MAQ_SA_W_PHR:
15039 check_dsp(ctx);
15040 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15041 break;
15042 case OPC_MULSA_W_PH:
15043 check_dspr2(ctx);
15044 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15045 break;
15046 }
15047 break;
15048#ifdef TARGET_MIPS64
15049 case OPC_DPAQ_W_QH_DSP:
15050 {
15051 int ac = ret & 0x03;
15052 tcg_gen_movi_i32(t0, ac);
15053
15054 switch (op2) {
15055 case OPC_DMADD:
15056 check_dsp(ctx);
15057 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15058 break;
15059 case OPC_DMADDU:
15060 check_dsp(ctx);
15061 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15062 break;
15063 case OPC_DMSUB:
15064 check_dsp(ctx);
15065 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15066 break;
15067 case OPC_DMSUBU:
15068 check_dsp(ctx);
15069 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15070 break;
15071 case OPC_DPA_W_QH:
15072 check_dspr2(ctx);
15073 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15074 break;
15075 case OPC_DPAQ_S_W_QH:
15076 check_dsp(ctx);
15077 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15078 break;
15079 case OPC_DPAQ_SA_L_PW:
15080 check_dsp(ctx);
15081 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15082 break;
15083 case OPC_DPAU_H_OBL:
15084 check_dsp(ctx);
15085 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15086 break;
15087 case OPC_DPAU_H_OBR:
15088 check_dsp(ctx);
15089 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15090 break;
15091 case OPC_DPS_W_QH:
15092 check_dspr2(ctx);
15093 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15094 break;
15095 case OPC_DPSQ_S_W_QH:
15096 check_dsp(ctx);
15097 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15098 break;
15099 case OPC_DPSQ_SA_L_PW:
15100 check_dsp(ctx);
15101 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15102 break;
15103 case OPC_DPSU_H_OBL:
15104 check_dsp(ctx);
15105 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15106 break;
15107 case OPC_DPSU_H_OBR:
15108 check_dsp(ctx);
15109 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15110 break;
15111 case OPC_MAQ_S_L_PWL:
15112 check_dsp(ctx);
15113 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15114 break;
15115 case OPC_MAQ_S_L_PWR:
15116 check_dsp(ctx);
15117 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15118 break;
15119 case OPC_MAQ_S_W_QHLL:
15120 check_dsp(ctx);
15121 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15122 break;
15123 case OPC_MAQ_SA_W_QHLL:
15124 check_dsp(ctx);
15125 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15126 break;
15127 case OPC_MAQ_S_W_QHLR:
15128 check_dsp(ctx);
15129 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15130 break;
15131 case OPC_MAQ_SA_W_QHLR:
15132 check_dsp(ctx);
15133 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15134 break;
15135 case OPC_MAQ_S_W_QHRL:
15136 check_dsp(ctx);
15137 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15138 break;
15139 case OPC_MAQ_SA_W_QHRL:
15140 check_dsp(ctx);
15141 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15142 break;
15143 case OPC_MAQ_S_W_QHRR:
15144 check_dsp(ctx);
15145 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15146 break;
15147 case OPC_MAQ_SA_W_QHRR:
15148 check_dsp(ctx);
15149 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15150 break;
15151 case OPC_MULSAQ_S_L_PW:
15152 check_dsp(ctx);
15153 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15154 break;
15155 case OPC_MULSAQ_S_W_QH:
15156 check_dsp(ctx);
15157 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15158 break;
15159 }
15160 }
15161 break;
15162#endif
15163 case OPC_ADDU_QB_DSP:
15164 switch (op2) {
15165 case OPC_MULEU_S_PH_QBL:
15166 check_dsp(ctx);
15167 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15168 break;
15169 case OPC_MULEU_S_PH_QBR:
15170 check_dsp(ctx);
15171 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15172 break;
15173 case OPC_MULQ_RS_PH:
15174 check_dsp(ctx);
15175 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15176 break;
15177 case OPC_MULEQ_S_W_PHL:
15178 check_dsp(ctx);
15179 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15180 break;
15181 case OPC_MULEQ_S_W_PHR:
15182 check_dsp(ctx);
15183 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15184 break;
15185 case OPC_MULQ_S_PH:
15186 check_dspr2(ctx);
15187 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15188 break;
15189 }
15190 break;
15191#ifdef TARGET_MIPS64
15192 case OPC_ADDU_OB_DSP:
15193 switch (op2) {
15194 case OPC_MULEQ_S_PW_QHL:
15195 check_dsp(ctx);
15196 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15197 break;
15198 case OPC_MULEQ_S_PW_QHR:
15199 check_dsp(ctx);
15200 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15201 break;
15202 case OPC_MULEU_S_QH_OBL:
15203 check_dsp(ctx);
15204 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15205 break;
15206 case OPC_MULEU_S_QH_OBR:
15207 check_dsp(ctx);
15208 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15209 break;
15210 case OPC_MULQ_RS_QH:
15211 check_dsp(ctx);
15212 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15213 break;
15214 }
15215 break;
15216#endif
15217 }
15218
15219 tcg_temp_free_i32(t0);
15220 tcg_temp_free(v1_t);
15221 tcg_temp_free(v2_t);
15222
15223 (void)opn; /* avoid a compiler warning */
15224 MIPS_DEBUG("%s", opn);
15225
15226}
15227
d75c135e 15228static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
15229 int ret, int val)
15230{
15231 const char *opn = "mipsdsp Bit/ Manipulation";
15232 int16_t imm;
15233 TCGv t0;
15234 TCGv val_t;
15235
15236 if (ret == 0) {
15237 /* Treat as NOP. */
15238 MIPS_DEBUG("NOP");
15239 return;
15240 }
15241
15242 t0 = tcg_temp_new();
15243 val_t = tcg_temp_new();
15244 gen_load_gpr(val_t, val);
15245
15246 switch (op1) {
15247 case OPC_ABSQ_S_PH_DSP:
15248 switch (op2) {
15249 case OPC_BITREV:
15250 check_dsp(ctx);
15251 gen_helper_bitrev(cpu_gpr[ret], val_t);
15252 break;
15253 case OPC_REPL_QB:
15254 check_dsp(ctx);
15255 {
15256 target_long result;
15257 imm = (ctx->opcode >> 16) & 0xFF;
15258 result = (uint32_t)imm << 24 |
15259 (uint32_t)imm << 16 |
15260 (uint32_t)imm << 8 |
15261 (uint32_t)imm;
15262 result = (int32_t)result;
15263 tcg_gen_movi_tl(cpu_gpr[ret], result);
15264 }
15265 break;
15266 case OPC_REPLV_QB:
15267 check_dsp(ctx);
15268 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15269 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15270 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15271 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15272 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15273 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15274 break;
15275 case OPC_REPL_PH:
15276 check_dsp(ctx);
15277 {
15278 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 15279 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
15280 tcg_gen_movi_tl(cpu_gpr[ret], \
15281 (target_long)((int32_t)imm << 16 | \
c4aaba92 15282 (uint16_t)imm));
1cb6686c
JL
15283 }
15284 break;
15285 case OPC_REPLV_PH:
15286 check_dsp(ctx);
15287 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15288 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15289 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15290 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15291 break;
15292 }
15293 break;
15294#ifdef TARGET_MIPS64
15295 case OPC_ABSQ_S_QH_DSP:
15296 switch (op2) {
15297 case OPC_REPL_OB:
15298 check_dsp(ctx);
15299 {
15300 target_long temp;
15301
15302 imm = (ctx->opcode >> 16) & 0xFF;
15303 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
15304 temp = (temp << 16) | temp;
15305 temp = (temp << 32) | temp;
15306 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15307 break;
15308 }
15309 case OPC_REPL_PW:
15310 check_dsp(ctx);
15311 {
15312 target_long temp;
15313
15314 imm = (ctx->opcode >> 16) & 0x03FF;
15315 imm = (int16_t)(imm << 6) >> 6;
15316 temp = ((target_long)imm << 32) \
15317 | ((target_long)imm & 0xFFFFFFFF);
15318 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15319 break;
15320 }
15321 case OPC_REPL_QH:
15322 check_dsp(ctx);
15323 {
15324 target_long temp;
15325
15326 imm = (ctx->opcode >> 16) & 0x03FF;
15327 imm = (int16_t)(imm << 6) >> 6;
15328
15329 temp = ((uint64_t)(uint16_t)imm << 48) |
15330 ((uint64_t)(uint16_t)imm << 32) |
15331 ((uint64_t)(uint16_t)imm << 16) |
15332 (uint64_t)(uint16_t)imm;
15333 tcg_gen_movi_tl(cpu_gpr[ret], temp);
15334 break;
15335 }
15336 case OPC_REPLV_OB:
15337 check_dsp(ctx);
15338 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
15339 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
15340 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15341 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15342 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15343 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15344 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15345 break;
15346 case OPC_REPLV_PW:
15347 check_dsp(ctx);
15348 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
15349 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15350 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15351 break;
15352 case OPC_REPLV_QH:
15353 check_dsp(ctx);
15354 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
15355 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
15356 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15357 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
15358 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
15359 break;
15360 }
15361 break;
15362#endif
15363 }
15364 tcg_temp_free(t0);
15365 tcg_temp_free(val_t);
15366
15367 (void)opn; /* avoid a compiler warning */
15368 MIPS_DEBUG("%s", opn);
15369}
15370
26690560
JL
15371static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
15372 uint32_t op1, uint32_t op2,
15373 int ret, int v1, int v2, int check_ret)
15374{
15375 const char *opn = "mipsdsp add compare pick";
26690560
JL
15376 TCGv t1;
15377 TCGv v1_t;
15378 TCGv v2_t;
15379
15380 if ((ret == 0) && (check_ret == 1)) {
15381 /* Treat as NOP. */
15382 MIPS_DEBUG("NOP");
15383 return;
15384 }
15385
26690560
JL
15386 t1 = tcg_temp_new();
15387 v1_t = tcg_temp_new();
15388 v2_t = tcg_temp_new();
15389
15390 gen_load_gpr(v1_t, v1);
15391 gen_load_gpr(v2_t, v2);
15392
15393 switch (op1) {
26690560
JL
15394 case OPC_CMPU_EQ_QB_DSP:
15395 switch (op2) {
15396 case OPC_CMPU_EQ_QB:
15397 check_dsp(ctx);
15398 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
15399 break;
15400 case OPC_CMPU_LT_QB:
15401 check_dsp(ctx);
15402 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
15403 break;
15404 case OPC_CMPU_LE_QB:
15405 check_dsp(ctx);
15406 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
15407 break;
15408 case OPC_CMPGU_EQ_QB:
15409 check_dsp(ctx);
15410 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
15411 break;
15412 case OPC_CMPGU_LT_QB:
15413 check_dsp(ctx);
15414 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
15415 break;
15416 case OPC_CMPGU_LE_QB:
15417 check_dsp(ctx);
15418 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
15419 break;
15420 case OPC_CMPGDU_EQ_QB:
15421 check_dspr2(ctx);
15422 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
15423 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15424 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15425 tcg_gen_shli_tl(t1, t1, 24);
15426 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15427 break;
15428 case OPC_CMPGDU_LT_QB:
15429 check_dspr2(ctx);
15430 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
15431 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15432 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15433 tcg_gen_shli_tl(t1, t1, 24);
15434 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15435 break;
15436 case OPC_CMPGDU_LE_QB:
15437 check_dspr2(ctx);
15438 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
15439 tcg_gen_mov_tl(cpu_gpr[ret], t1);
15440 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15441 tcg_gen_shli_tl(t1, t1, 24);
15442 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15443 break;
15444 case OPC_CMP_EQ_PH:
15445 check_dsp(ctx);
15446 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15447 break;
15448 case OPC_CMP_LT_PH:
15449 check_dsp(ctx);
15450 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15451 break;
15452 case OPC_CMP_LE_PH:
15453 check_dsp(ctx);
15454 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15455 break;
15456 case OPC_PICK_QB:
15457 check_dsp(ctx);
15458 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15459 break;
15460 case OPC_PICK_PH:
15461 check_dsp(ctx);
15462 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15463 break;
15464 case OPC_PACKRL_PH:
15465 check_dsp(ctx);
15466 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15467 break;
15468 }
15469 break;
15470#ifdef TARGET_MIPS64
15471 case OPC_CMPU_EQ_OB_DSP:
15472 switch (op2) {
15473 case OPC_CMP_EQ_PW:
15474 check_dsp(ctx);
15475 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15476 break;
15477 case OPC_CMP_LT_PW:
15478 check_dsp(ctx);
15479 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15480 break;
15481 case OPC_CMP_LE_PW:
15482 check_dsp(ctx);
15483 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15484 break;
15485 case OPC_CMP_EQ_QH:
15486 check_dsp(ctx);
15487 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15488 break;
15489 case OPC_CMP_LT_QH:
15490 check_dsp(ctx);
15491 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15492 break;
15493 case OPC_CMP_LE_QH:
15494 check_dsp(ctx);
15495 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15496 break;
15497 case OPC_CMPGDU_EQ_OB:
15498 check_dspr2(ctx);
15499 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15500 break;
15501 case OPC_CMPGDU_LT_OB:
15502 check_dspr2(ctx);
15503 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15504 break;
15505 case OPC_CMPGDU_LE_OB:
15506 check_dspr2(ctx);
15507 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15508 break;
15509 case OPC_CMPGU_EQ_OB:
15510 check_dsp(ctx);
15511 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15512 break;
15513 case OPC_CMPGU_LT_OB:
15514 check_dsp(ctx);
15515 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15516 break;
15517 case OPC_CMPGU_LE_OB:
15518 check_dsp(ctx);
15519 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15520 break;
15521 case OPC_CMPU_EQ_OB:
15522 check_dsp(ctx);
15523 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15524 break;
15525 case OPC_CMPU_LT_OB:
15526 check_dsp(ctx);
15527 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15528 break;
15529 case OPC_CMPU_LE_OB:
15530 check_dsp(ctx);
15531 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15532 break;
15533 case OPC_PACKRL_PW:
15534 check_dsp(ctx);
15535 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15536 break;
15537 case OPC_PICK_OB:
15538 check_dsp(ctx);
15539 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15540 break;
15541 case OPC_PICK_PW:
15542 check_dsp(ctx);
15543 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15544 break;
15545 case OPC_PICK_QH:
15546 check_dsp(ctx);
15547 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15548 break;
15549 }
15550 break;
df6126a7
AJ
15551#endif
15552 }
15553
15554 tcg_temp_free(t1);
15555 tcg_temp_free(v1_t);
15556 tcg_temp_free(v2_t);
15557
15558 (void)opn; /* avoid a compiler warning */
15559 MIPS_DEBUG("%s", opn);
15560}
15561
15562static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15563 uint32_t op1, int rt, int rs, int sa)
15564{
15565 const char *opn = "mipsdsp append/dappend";
15566 TCGv t0;
15567
15568 check_dspr2(ctx);
15569
15570 if (rt == 0) {
15571 /* Treat as NOP. */
15572 MIPS_DEBUG("NOP");
15573 return;
15574 }
15575
15576 t0 = tcg_temp_new();
15577 gen_load_gpr(t0, rs);
15578
15579 switch (op1) {
15580 case OPC_APPEND_DSP:
15581 switch (MASK_APPEND(ctx->opcode)) {
15582 case OPC_APPEND:
15583 if (sa != 0) {
15584 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15585 }
15586 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15587 break;
15588 case OPC_PREPEND:
15589 if (sa != 0) {
15590 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15591 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15592 tcg_gen_shli_tl(t0, t0, 32 - sa);
15593 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15594 }
15595 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15596 break;
15597 case OPC_BALIGN:
15598 sa &= 3;
15599 if (sa != 0 && sa != 2) {
15600 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15601 tcg_gen_ext32u_tl(t0, t0);
15602 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15603 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15604 }
15605 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15606 break;
15607 default: /* Invalid */
15608 MIPS_INVAL("MASK APPEND");
15609 generate_exception(ctx, EXCP_RI);
15610 break;
15611 }
15612 break;
15613#ifdef TARGET_MIPS64
26690560 15614 case OPC_DAPPEND_DSP:
df6126a7 15615 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15616 case OPC_DAPPEND:
df6126a7
AJ
15617 if (sa != 0) {
15618 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15619 }
26690560
JL
15620 break;
15621 case OPC_PREPENDD:
df6126a7
AJ
15622 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15623 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15624 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15625 break;
15626 case OPC_PREPENDW:
df6126a7
AJ
15627 if (sa != 0) {
15628 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15629 tcg_gen_shli_tl(t0, t0, 64 - sa);
15630 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15631 }
26690560
JL
15632 break;
15633 case OPC_DBALIGN:
df6126a7
AJ
15634 sa &= 7;
15635 if (sa != 0 && sa != 2 && sa != 4) {
15636 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15637 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15638 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15639 }
26690560
JL
15640 break;
15641 default: /* Invalid */
15642 MIPS_INVAL("MASK DAPPEND");
15643 generate_exception(ctx, EXCP_RI);
15644 break;
15645 }
15646 break;
15647#endif
15648 }
df6126a7 15649 tcg_temp_free(t0);
26690560
JL
15650 (void)opn; /* avoid a compiler warning */
15651 MIPS_DEBUG("%s", opn);
15652}
15653
b53371ed
JL
15654static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15655 int ret, int v1, int v2, int check_ret)
15656
15657{
15658 const char *opn = "mipsdsp accumulator";
15659 TCGv t0;
15660 TCGv t1;
15661 TCGv v1_t;
15662 TCGv v2_t;
15663 int16_t imm;
15664
15665 if ((ret == 0) && (check_ret == 1)) {
15666 /* Treat as NOP. */
15667 MIPS_DEBUG("NOP");
15668 return;
15669 }
15670
15671 t0 = tcg_temp_new();
15672 t1 = tcg_temp_new();
15673 v1_t = tcg_temp_new();
15674 v2_t = tcg_temp_new();
15675
15676 gen_load_gpr(v1_t, v1);
15677 gen_load_gpr(v2_t, v2);
15678
15679 switch (op1) {
15680 case OPC_EXTR_W_DSP:
15681 check_dsp(ctx);
15682 switch (op2) {
15683 case OPC_EXTR_W:
15684 tcg_gen_movi_tl(t0, v2);
15685 tcg_gen_movi_tl(t1, v1);
15686 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15687 break;
15688 case OPC_EXTR_R_W:
15689 tcg_gen_movi_tl(t0, v2);
15690 tcg_gen_movi_tl(t1, v1);
15691 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15692 break;
15693 case OPC_EXTR_RS_W:
15694 tcg_gen_movi_tl(t0, v2);
15695 tcg_gen_movi_tl(t1, v1);
15696 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15697 break;
15698 case OPC_EXTR_S_H:
15699 tcg_gen_movi_tl(t0, v2);
15700 tcg_gen_movi_tl(t1, v1);
15701 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15702 break;
15703 case OPC_EXTRV_S_H:
15704 tcg_gen_movi_tl(t0, v2);
15705 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15706 break;
15707 case OPC_EXTRV_W:
15708 tcg_gen_movi_tl(t0, v2);
15709 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15710 break;
15711 case OPC_EXTRV_R_W:
15712 tcg_gen_movi_tl(t0, v2);
15713 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15714 break;
15715 case OPC_EXTRV_RS_W:
15716 tcg_gen_movi_tl(t0, v2);
15717 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15718 break;
15719 case OPC_EXTP:
15720 tcg_gen_movi_tl(t0, v2);
15721 tcg_gen_movi_tl(t1, v1);
15722 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15723 break;
15724 case OPC_EXTPV:
15725 tcg_gen_movi_tl(t0, v2);
15726 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15727 break;
15728 case OPC_EXTPDP:
15729 tcg_gen_movi_tl(t0, v2);
15730 tcg_gen_movi_tl(t1, v1);
15731 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15732 break;
15733 case OPC_EXTPDPV:
15734 tcg_gen_movi_tl(t0, v2);
15735 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15736 break;
15737 case OPC_SHILO:
15738 imm = (ctx->opcode >> 20) & 0x3F;
15739 tcg_gen_movi_tl(t0, ret);
15740 tcg_gen_movi_tl(t1, imm);
15741 gen_helper_shilo(t0, t1, cpu_env);
15742 break;
15743 case OPC_SHILOV:
15744 tcg_gen_movi_tl(t0, ret);
15745 gen_helper_shilo(t0, v1_t, cpu_env);
15746 break;
15747 case OPC_MTHLIP:
15748 tcg_gen_movi_tl(t0, ret);
15749 gen_helper_mthlip(t0, v1_t, cpu_env);
15750 break;
15751 case OPC_WRDSP:
15752 imm = (ctx->opcode >> 11) & 0x3FF;
15753 tcg_gen_movi_tl(t0, imm);
15754 gen_helper_wrdsp(v1_t, t0, cpu_env);
15755 break;
15756 case OPC_RDDSP:
15757 imm = (ctx->opcode >> 16) & 0x03FF;
15758 tcg_gen_movi_tl(t0, imm);
15759 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15760 break;
15761 }
15762 break;
15763#ifdef TARGET_MIPS64
15764 case OPC_DEXTR_W_DSP:
15765 check_dsp(ctx);
15766 switch (op2) {
15767 case OPC_DMTHLIP:
15768 tcg_gen_movi_tl(t0, ret);
15769 gen_helper_dmthlip(v1_t, t0, cpu_env);
15770 break;
15771 case OPC_DSHILO:
15772 {
15773 int shift = (ctx->opcode >> 19) & 0x7F;
15774 int ac = (ctx->opcode >> 11) & 0x03;
15775 tcg_gen_movi_tl(t0, shift);
15776 tcg_gen_movi_tl(t1, ac);
15777 gen_helper_dshilo(t0, t1, cpu_env);
15778 break;
15779 }
15780 case OPC_DSHILOV:
15781 {
15782 int ac = (ctx->opcode >> 11) & 0x03;
15783 tcg_gen_movi_tl(t0, ac);
15784 gen_helper_dshilo(v1_t, t0, cpu_env);
15785 break;
15786 }
15787 case OPC_DEXTP:
15788 tcg_gen_movi_tl(t0, v2);
15789 tcg_gen_movi_tl(t1, v1);
15790
15791 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15792 break;
15793 case OPC_DEXTPV:
15794 tcg_gen_movi_tl(t0, v2);
15795 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15796 break;
15797 case OPC_DEXTPDP:
15798 tcg_gen_movi_tl(t0, v2);
15799 tcg_gen_movi_tl(t1, v1);
15800 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15801 break;
15802 case OPC_DEXTPDPV:
15803 tcg_gen_movi_tl(t0, v2);
15804 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15805 break;
15806 case OPC_DEXTR_L:
15807 tcg_gen_movi_tl(t0, v2);
15808 tcg_gen_movi_tl(t1, v1);
15809 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15810 break;
15811 case OPC_DEXTR_R_L:
15812 tcg_gen_movi_tl(t0, v2);
15813 tcg_gen_movi_tl(t1, v1);
15814 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15815 break;
15816 case OPC_DEXTR_RS_L:
15817 tcg_gen_movi_tl(t0, v2);
15818 tcg_gen_movi_tl(t1, v1);
15819 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15820 break;
15821 case OPC_DEXTR_W:
15822 tcg_gen_movi_tl(t0, v2);
15823 tcg_gen_movi_tl(t1, v1);
15824 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15825 break;
15826 case OPC_DEXTR_R_W:
15827 tcg_gen_movi_tl(t0, v2);
15828 tcg_gen_movi_tl(t1, v1);
15829 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15830 break;
15831 case OPC_DEXTR_RS_W:
15832 tcg_gen_movi_tl(t0, v2);
15833 tcg_gen_movi_tl(t1, v1);
15834 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15835 break;
15836 case OPC_DEXTR_S_H:
15837 tcg_gen_movi_tl(t0, v2);
15838 tcg_gen_movi_tl(t1, v1);
15839 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15840 break;
15841 case OPC_DEXTRV_S_H:
15842 tcg_gen_movi_tl(t0, v2);
15843 tcg_gen_movi_tl(t1, v1);
15844 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15845 break;
15846 case OPC_DEXTRV_L:
15847 tcg_gen_movi_tl(t0, v2);
15848 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15849 break;
15850 case OPC_DEXTRV_R_L:
15851 tcg_gen_movi_tl(t0, v2);
15852 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15853 break;
15854 case OPC_DEXTRV_RS_L:
15855 tcg_gen_movi_tl(t0, v2);
15856 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15857 break;
15858 case OPC_DEXTRV_W:
15859 tcg_gen_movi_tl(t0, v2);
15860 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15861 break;
15862 case OPC_DEXTRV_R_W:
15863 tcg_gen_movi_tl(t0, v2);
15864 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15865 break;
15866 case OPC_DEXTRV_RS_W:
15867 tcg_gen_movi_tl(t0, v2);
15868 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15869 break;
15870 }
15871 break;
15872#endif
15873 }
15874
15875 tcg_temp_free(t0);
15876 tcg_temp_free(t1);
15877 tcg_temp_free(v1_t);
15878 tcg_temp_free(v2_t);
15879
15880 (void)opn; /* avoid a compiler warning */
15881 MIPS_DEBUG("%s", opn);
15882}
15883
9b1a1d68
JL
15884/* End MIPSDSP functions. */
15885
31837be3
YK
15886/* Compact Branches */
15887static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15888 int rs, int rt, int32_t offset)
15889{
15890 int bcond_compute = 0;
15891 TCGv t0 = tcg_temp_new();
15892 TCGv t1 = tcg_temp_new();
15893
15894 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15895#ifdef MIPS_DEBUG_DISAS
339cd2a8
LA
15896 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15897 "\n", ctx->pc);
31837be3
YK
15898#endif
15899 generate_exception(ctx, EXCP_RI);
15900 goto out;
15901 }
15902
15903 /* Load needed operands and calculate btarget */
15904 switch (opc) {
15905 /* compact branch */
15906 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15907 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15908 gen_load_gpr(t0, rs);
15909 gen_load_gpr(t1, rt);
15910 bcond_compute = 1;
15911 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15912 if (rs <= rt && rs == 0) {
15913 /* OPC_BEQZALC, OPC_BNEZALC */
15914 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15915 }
15916 break;
15917 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15918 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15919 gen_load_gpr(t0, rs);
15920 gen_load_gpr(t1, rt);
15921 bcond_compute = 1;
15922 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15923 break;
15924 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15925 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15926 if (rs == 0 || rs == rt) {
15927 /* OPC_BLEZALC, OPC_BGEZALC */
15928 /* OPC_BGTZALC, OPC_BLTZALC */
15929 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15930 }
15931 gen_load_gpr(t0, rs);
15932 gen_load_gpr(t1, rt);
15933 bcond_compute = 1;
15934 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15935 break;
15936 case OPC_BC:
15937 case OPC_BALC:
15938 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15939 break;
15940 case OPC_BEQZC:
15941 case OPC_BNEZC:
15942 if (rs != 0) {
15943 /* OPC_BEQZC, OPC_BNEZC */
15944 gen_load_gpr(t0, rs);
15945 bcond_compute = 1;
15946 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15947 } else {
15948 /* OPC_JIC, OPC_JIALC */
15949 TCGv tbase = tcg_temp_new();
15950 TCGv toffset = tcg_temp_new();
15951
15952 gen_load_gpr(tbase, rt);
15953 tcg_gen_movi_tl(toffset, offset);
15954 gen_op_addr_add(ctx, btarget, tbase, toffset);
15955 tcg_temp_free(tbase);
15956 tcg_temp_free(toffset);
15957 }
15958 break;
15959 default:
15960 MIPS_INVAL("Compact branch/jump");
15961 generate_exception(ctx, EXCP_RI);
15962 goto out;
15963 }
15964
15965 if (bcond_compute == 0) {
15966 /* Uncoditional compact branch */
15967 switch (opc) {
15968 case OPC_JIALC:
15969 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15970 /* Fallthrough */
15971 case OPC_JIC:
15972 ctx->hflags |= MIPS_HFLAG_BR;
15973 break;
15974 case OPC_BALC:
15975 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15976 /* Fallthrough */
15977 case OPC_BC:
15978 ctx->hflags |= MIPS_HFLAG_B;
15979 break;
15980 default:
15981 MIPS_INVAL("Compact branch/jump");
15982 generate_exception(ctx, EXCP_RI);
15983 goto out;
15984 }
15985
15986 /* Generating branch here as compact branches don't have delay slot */
15987 gen_branch(ctx, 4);
15988 } else {
15989 /* Conditional compact branch */
339cd2a8 15990 int fs = gen_new_label();
31837be3
YK
15991 save_cpu_state(ctx, 0);
15992
15993 switch (opc) {
15994 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15995 if (rs == 0 && rt != 0) {
15996 /* OPC_BLEZALC */
339cd2a8 15997 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
15998 } else if (rs != 0 && rt != 0 && rs == rt) {
15999 /* OPC_BGEZALC */
339cd2a8 16000 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16001 } else {
16002 /* OPC_BGEUC */
339cd2a8 16003 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
31837be3
YK
16004 }
16005 break;
16006 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
16007 if (rs == 0 && rt != 0) {
16008 /* OPC_BGTZALC */
339cd2a8 16009 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16010 } else if (rs != 0 && rt != 0 && rs == rt) {
16011 /* OPC_BLTZALC */
339cd2a8 16012 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16013 } else {
16014 /* OPC_BLTUC */
339cd2a8 16015 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
31837be3
YK
16016 }
16017 break;
16018 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
16019 if (rs == 0 && rt != 0) {
16020 /* OPC_BLEZC */
339cd2a8 16021 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
31837be3
YK
16022 } else if (rs != 0 && rt != 0 && rs == rt) {
16023 /* OPC_BGEZC */
339cd2a8 16024 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
31837be3
YK
16025 } else {
16026 /* OPC_BGEC */
339cd2a8 16027 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
31837be3
YK
16028 }
16029 break;
16030 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
16031 if (rs == 0 && rt != 0) {
16032 /* OPC_BGTZC */
339cd2a8 16033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
31837be3
YK
16034 } else if (rs != 0 && rt != 0 && rs == rt) {
16035 /* OPC_BLTZC */
339cd2a8 16036 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
31837be3
YK
16037 } else {
16038 /* OPC_BLTC */
339cd2a8 16039 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
31837be3
YK
16040 }
16041 break;
16042 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
16043 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
16044 if (rs >= rt) {
16045 /* OPC_BOVC, OPC_BNVC */
16046 TCGv t2 = tcg_temp_new();
16047 TCGv t3 = tcg_temp_new();
16048 TCGv t4 = tcg_temp_new();
16049 TCGv input_overflow = tcg_temp_new();
16050
16051 gen_load_gpr(t0, rs);
16052 gen_load_gpr(t1, rt);
16053 tcg_gen_ext32s_tl(t2, t0);
16054 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
16055 tcg_gen_ext32s_tl(t3, t1);
16056 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
16057 tcg_gen_or_tl(input_overflow, input_overflow, t4);
16058
16059 tcg_gen_add_tl(t4, t2, t3);
16060 tcg_gen_ext32s_tl(t4, t4);
16061 tcg_gen_xor_tl(t2, t2, t3);
16062 tcg_gen_xor_tl(t3, t4, t3);
16063 tcg_gen_andc_tl(t2, t3, t2);
16064 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
16065 tcg_gen_or_tl(t4, t4, input_overflow);
16066 if (opc == OPC_BOVC) {
16067 /* OPC_BOVC */
339cd2a8 16068 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
31837be3
YK
16069 } else {
16070 /* OPC_BNVC */
339cd2a8 16071 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
31837be3
YK
16072 }
16073 tcg_temp_free(input_overflow);
16074 tcg_temp_free(t4);
16075 tcg_temp_free(t3);
16076 tcg_temp_free(t2);
16077 } else if (rs < rt && rs == 0) {
16078 /* OPC_BEQZALC, OPC_BNEZALC */
16079 if (opc == OPC_BEQZALC) {
16080 /* OPC_BEQZALC */
339cd2a8 16081 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
31837be3
YK
16082 } else {
16083 /* OPC_BNEZALC */
339cd2a8 16084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
31837be3
YK
16085 }
16086 } else {
16087 /* OPC_BEQC, OPC_BNEC */
16088 if (opc == OPC_BEQC) {
16089 /* OPC_BEQC */
339cd2a8 16090 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
31837be3
YK
16091 } else {
16092 /* OPC_BNEC */
339cd2a8 16093 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
31837be3
YK
16094 }
16095 }
16096 break;
16097 case OPC_BEQZC:
339cd2a8 16098 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
31837be3
YK
16099 break;
16100 case OPC_BNEZC:
339cd2a8 16101 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
31837be3
YK
16102 break;
16103 default:
16104 MIPS_INVAL("Compact conditional branch/jump");
16105 generate_exception(ctx, EXCP_RI);
16106 goto out;
16107 }
16108
16109 /* Generating branch here as compact branches don't have delay slot */
339cd2a8
LA
16110 gen_goto_tb(ctx, 1, ctx->btarget);
16111 gen_set_label(fs);
16112
16113 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
31837be3 16114 MIPS_DEBUG("Compact conditional branch");
31837be3
YK
16115 }
16116
16117out:
16118 tcg_temp_free(t0);
16119 tcg_temp_free(t1);
16120}
16121
10dc65db
LA
16122static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16123{
4267d3e6 16124 int rs, rt, rd, sa;
b42ee5e1 16125 uint32_t op1, op2;
10dc65db
LA
16126
16127 rs = (ctx->opcode >> 21) & 0x1f;
16128 rt = (ctx->opcode >> 16) & 0x1f;
16129 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 16130 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16131
16132 op1 = MASK_SPECIAL(ctx->opcode);
16133 switch (op1) {
d4ea6acd
LA
16134 case OPC_LSA:
16135 if (rd != 0) {
16136 int imm2 = extract32(ctx->opcode, 6, 3);
16137 TCGv t0 = tcg_temp_new();
16138 TCGv t1 = tcg_temp_new();
16139 gen_load_gpr(t0, rs);
16140 gen_load_gpr(t1, rt);
16141 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16142 tcg_gen_add_tl(t0, t0, t1);
16143 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
16144 tcg_temp_free(t1);
16145 tcg_temp_free(t0);
16146 }
16147 break;
b42ee5e1
LA
16148 case OPC_MULT ... OPC_DIVU:
16149 op2 = MASK_R6_MULDIV(ctx->opcode);
16150 switch (op2) {
16151 case R6_OPC_MUL:
16152 case R6_OPC_MUH:
16153 case R6_OPC_MULU:
16154 case R6_OPC_MUHU:
16155 case R6_OPC_DIV:
16156 case R6_OPC_MOD:
16157 case R6_OPC_DIVU:
16158 case R6_OPC_MODU:
16159 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16160 break;
16161 default:
16162 MIPS_INVAL("special_r6 muldiv");
16163 generate_exception(ctx, EXCP_RI);
16164 break;
16165 }
16166 break;
10dc65db
LA
16167 case OPC_SELEQZ:
16168 case OPC_SELNEZ:
16169 gen_cond_move(ctx, op1, rd, rs, rt);
16170 break;
4267d3e6
LA
16171 case R6_OPC_CLO:
16172 case R6_OPC_CLZ:
16173 if (rt == 0 && sa == 1) {
16174 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16175 We need additionally to check other fields */
16176 gen_cl(ctx, op1, rd, rs);
16177 } else {
16178 generate_exception(ctx, EXCP_RI);
16179 }
16180 break;
16181 case R6_OPC_SDBBP:
faf1f68b
LA
16182 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16183 generate_exception(ctx, EXCP_RI);
16184 } else {
16185 generate_exception(ctx, EXCP_DBp);
16186 }
4267d3e6 16187 break;
b42ee5e1 16188#if defined(TARGET_MIPS64)
d4ea6acd
LA
16189 case OPC_DLSA:
16190 check_mips_64(ctx);
16191 if (rd != 0) {
16192 int imm2 = extract32(ctx->opcode, 6, 3);
16193 TCGv t0 = tcg_temp_new();
16194 TCGv t1 = tcg_temp_new();
16195 gen_load_gpr(t0, rs);
16196 gen_load_gpr(t1, rt);
16197 tcg_gen_shli_tl(t0, t0, imm2 + 1);
16198 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
16199 tcg_temp_free(t1);
16200 tcg_temp_free(t0);
16201 }
16202 break;
4267d3e6
LA
16203 case R6_OPC_DCLO:
16204 case R6_OPC_DCLZ:
16205 if (rt == 0 && sa == 1) {
16206 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16207 We need additionally to check other fields */
16208 check_mips_64(ctx);
16209 gen_cl(ctx, op1, rd, rs);
16210 } else {
16211 generate_exception(ctx, EXCP_RI);
16212 }
16213 break;
b42ee5e1
LA
16214 case OPC_DMULT ... OPC_DDIVU:
16215 op2 = MASK_R6_MULDIV(ctx->opcode);
16216 switch (op2) {
16217 case R6_OPC_DMUL:
16218 case R6_OPC_DMUH:
16219 case R6_OPC_DMULU:
16220 case R6_OPC_DMUHU:
16221 case R6_OPC_DDIV:
16222 case R6_OPC_DMOD:
16223 case R6_OPC_DDIVU:
16224 case R6_OPC_DMODU:
16225 check_mips_64(ctx);
16226 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16227 break;
16228 default:
16229 MIPS_INVAL("special_r6 muldiv");
16230 generate_exception(ctx, EXCP_RI);
16231 break;
16232 }
16233 break;
16234#endif
10dc65db
LA
16235 default: /* Invalid */
16236 MIPS_INVAL("special_r6");
16237 generate_exception(ctx, EXCP_RI);
16238 break;
16239 }
16240}
16241
16242static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16243{
b42ee5e1 16244 int rs, rt, rd, sa;
10dc65db
LA
16245 uint32_t op1;
16246
16247 rs = (ctx->opcode >> 21) & 0x1f;
16248 rt = (ctx->opcode >> 16) & 0x1f;
16249 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 16250 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16251
16252 op1 = MASK_SPECIAL(ctx->opcode);
16253 switch (op1) {
16254 case OPC_MOVN: /* Conditional move */
16255 case OPC_MOVZ:
16256 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16257 INSN_LOONGSON2E | INSN_LOONGSON2F);
16258 gen_cond_move(ctx, op1, rd, rs, rt);
16259 break;
16260 case OPC_MFHI: /* Move from HI/LO */
16261 case OPC_MFLO:
16262 gen_HILO(ctx, op1, rs & 3, rd);
16263 break;
16264 case OPC_MTHI:
16265 case OPC_MTLO: /* Move to HI/LO */
16266 gen_HILO(ctx, op1, rd & 3, rs);
16267 break;
16268 case OPC_MOVCI:
16269 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16270 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16271 check_cp1_enabled(ctx);
16272 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16273 (ctx->opcode >> 16) & 1);
16274 } else {
16275 generate_exception_err(ctx, EXCP_CpU, 1);
16276 }
16277 break;
b42ee5e1
LA
16278 case OPC_MULT:
16279 case OPC_MULTU:
16280 if (sa) {
16281 check_insn(ctx, INSN_VR54XX);
16282 op1 = MASK_MUL_VR54XX(ctx->opcode);
16283 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16284 } else {
16285 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16286 }
16287 break;
16288 case OPC_DIV:
16289 case OPC_DIVU:
16290 gen_muldiv(ctx, op1, 0, rs, rt);
16291 break;
16292#if defined(TARGET_MIPS64)
16293 case OPC_DMULT ... OPC_DDIVU:
16294 check_insn(ctx, ISA_MIPS3);
16295 check_mips_64(ctx);
16296 gen_muldiv(ctx, op1, 0, rs, rt);
16297 break;
16298#endif
0aefa333 16299 case OPC_JR:
b231c103 16300 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 16301 break;
4267d3e6
LA
16302 case OPC_SPIM:
16303#ifdef MIPS_STRICT_STANDARD
16304 MIPS_INVAL("SPIM");
16305 generate_exception(ctx, EXCP_RI);
16306#else
16307 /* Implemented as RI exception for now. */
16308 MIPS_INVAL("spim (unofficial)");
16309 generate_exception(ctx, EXCP_RI);
16310#endif
16311 break;
10dc65db
LA
16312 default: /* Invalid */
16313 MIPS_INVAL("special_legacy");
16314 generate_exception(ctx, EXCP_RI);
16315 break;
16316 }
16317}
16318
099e5b4d 16319static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 16320{
3c824109 16321 int rs, rt, rd, sa;
099e5b4d 16322 uint32_t op1;
3c824109 16323
3c824109
NF
16324 rs = (ctx->opcode >> 21) & 0x1f;
16325 rt = (ctx->opcode >> 16) & 0x1f;
16326 rd = (ctx->opcode >> 11) & 0x1f;
16327 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
16328
16329 op1 = MASK_SPECIAL(ctx->opcode);
16330 switch (op1) {
16331 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
16332 if (sa == 5 && rd == 0 &&
16333 rs == 0 && rt == 0) { /* PAUSE */
16334 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16335 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16336 MIPS_DEBUG("CTI in delay / forbidden slot");
16337 generate_exception(ctx, EXCP_RI);
16338 break;
16339 }
16340 }
16341 /* Fallthrough */
099e5b4d
LA
16342 case OPC_SRA:
16343 gen_shift_imm(ctx, op1, rd, rt, sa);
16344 break;
16345 case OPC_SRL:
16346 switch ((ctx->opcode >> 21) & 0x1f) {
16347 case 1:
16348 /* rotr is decoded as srl on non-R2 CPUs */
16349 if (ctx->insn_flags & ISA_MIPS32R2) {
16350 op1 = OPC_ROTR;
ea63e2c3 16351 }
099e5b4d
LA
16352 /* Fallthrough */
16353 case 0:
16354 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 16355 break;
099e5b4d
LA
16356 default:
16357 generate_exception(ctx, EXCP_RI);
ea63e2c3 16358 break;
099e5b4d
LA
16359 }
16360 break;
099e5b4d
LA
16361 case OPC_ADD ... OPC_SUBU:
16362 gen_arith(ctx, op1, rd, rs, rt);
16363 break;
16364 case OPC_SLLV: /* Shifts */
16365 case OPC_SRAV:
16366 gen_shift(ctx, op1, rd, rs, rt);
16367 break;
16368 case OPC_SRLV:
16369 switch ((ctx->opcode >> 6) & 0x1f) {
16370 case 1:
16371 /* rotrv is decoded as srlv on non-R2 CPUs */
16372 if (ctx->insn_flags & ISA_MIPS32R2) {
16373 op1 = OPC_ROTRV;
26135ead 16374 }
099e5b4d
LA
16375 /* Fallthrough */
16376 case 0:
16377 gen_shift(ctx, op1, rd, rs, rt);
26135ead 16378 break;
099e5b4d
LA
16379 default:
16380 generate_exception(ctx, EXCP_RI);
6af0bf9c 16381 break;
099e5b4d
LA
16382 }
16383 break;
16384 case OPC_SLT: /* Set on less than */
16385 case OPC_SLTU:
16386 gen_slt(ctx, op1, rd, rs, rt);
16387 break;
16388 case OPC_AND: /* Logic*/
16389 case OPC_OR:
16390 case OPC_NOR:
16391 case OPC_XOR:
16392 gen_logic(ctx, op1, rd, rs, rt);
16393 break;
0aefa333 16394 case OPC_JALR:
b231c103 16395 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
16396 break;
16397 case OPC_TGE ... OPC_TEQ: /* Traps */
16398 case OPC_TNE:
d9224450 16399 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16400 gen_trap(ctx, op1, rs, rt, -1);
16401 break;
d4ea6acd 16402 case OPC_LSA: /* OPC_PMON */
f7685877
YK
16403 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16404 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
16405 decode_opc_special_r6(env, ctx);
16406 } else {
16407 /* Pmon entry point, also R4010 selsl */
b48cfdff 16408#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
16409 MIPS_INVAL("PMON / selsl");
16410 generate_exception(ctx, EXCP_RI);
b48cfdff 16411#else
d4ea6acd 16412 gen_helper_0e0i(pmon, sa);
b48cfdff 16413#endif
d4ea6acd 16414 }
099e5b4d
LA
16415 break;
16416 case OPC_SYSCALL:
16417 generate_exception(ctx, EXCP_SYSCALL);
16418 ctx->bstate = BS_STOP;
16419 break;
16420 case OPC_BREAK:
16421 generate_exception(ctx, EXCP_BREAK);
16422 break;
099e5b4d 16423 case OPC_SYNC:
d9224450 16424 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
16425 /* Treat as NOP. */
16426 break;
4ad40f36 16427
d26bc211 16428#if defined(TARGET_MIPS64)
099e5b4d
LA
16429 /* MIPS64 specific opcodes */
16430 case OPC_DSLL:
16431 case OPC_DSRA:
16432 case OPC_DSLL32:
16433 case OPC_DSRA32:
16434 check_insn(ctx, ISA_MIPS3);
16435 check_mips_64(ctx);
16436 gen_shift_imm(ctx, op1, rd, rt, sa);
16437 break;
16438 case OPC_DSRL:
16439 switch ((ctx->opcode >> 21) & 0x1f) {
16440 case 1:
16441 /* drotr is decoded as dsrl on non-R2 CPUs */
16442 if (ctx->insn_flags & ISA_MIPS32R2) {
16443 op1 = OPC_DROTR;
ea63e2c3 16444 }
099e5b4d
LA
16445 /* Fallthrough */
16446 case 0:
d75c135e 16447 check_insn(ctx, ISA_MIPS3);
e189e748 16448 check_mips_64(ctx);
099e5b4d 16449 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16450 break;
099e5b4d
LA
16451 default:
16452 generate_exception(ctx, EXCP_RI);
460f00c4 16453 break;
099e5b4d
LA
16454 }
16455 break;
16456 case OPC_DSRL32:
16457 switch ((ctx->opcode >> 21) & 0x1f) {
16458 case 1:
16459 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16460 if (ctx->insn_flags & ISA_MIPS32R2) {
16461 op1 = OPC_DROTR32;
ea63e2c3 16462 }
099e5b4d
LA
16463 /* Fallthrough */
16464 case 0:
d75c135e 16465 check_insn(ctx, ISA_MIPS3);
e189e748 16466 check_mips_64(ctx);
099e5b4d 16467 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16468 break;
099e5b4d 16469 default:
6af0bf9c
FB
16470 generate_exception(ctx, EXCP_RI);
16471 break;
16472 }
16473 break;
099e5b4d
LA
16474 case OPC_DADD ... OPC_DSUBU:
16475 check_insn(ctx, ISA_MIPS3);
16476 check_mips_64(ctx);
16477 gen_arith(ctx, op1, rd, rs, rt);
16478 break;
16479 case OPC_DSLLV:
16480 case OPC_DSRAV:
16481 check_insn(ctx, ISA_MIPS3);
16482 check_mips_64(ctx);
16483 gen_shift(ctx, op1, rd, rs, rt);
16484 break;
16485 case OPC_DSRLV:
16486 switch ((ctx->opcode >> 6) & 0x1f) {
16487 case 1:
16488 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16489 if (ctx->insn_flags & ISA_MIPS32R2) {
16490 op1 = OPC_DROTRV;
6af0bf9c 16491 }
099e5b4d
LA
16492 /* Fallthrough */
16493 case 0:
16494 check_insn(ctx, ISA_MIPS3);
e189e748 16495 check_mips_64(ctx);
099e5b4d 16496 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16497 break;
099e5b4d 16498 default:
6af0bf9c
FB
16499 generate_exception(ctx, EXCP_RI);
16500 break;
16501 }
16502 break;
f7685877
YK
16503 case OPC_DLSA:
16504 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16505 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16506 decode_opc_special_r6(env, ctx);
16507 }
16508 break;
099e5b4d 16509#endif
10dc65db
LA
16510 default:
16511 if (ctx->insn_flags & ISA_MIPS32R6) {
16512 decode_opc_special_r6(env, ctx);
16513 } else {
16514 decode_opc_special_legacy(env, ctx);
16515 }
16516 }
16517}
16518
10dc65db 16519static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16520{
16521 int rs, rt, rd;
16522 uint32_t op1;
6c5c1e20 16523
4267d3e6
LA
16524 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16525
099e5b4d
LA
16526 rs = (ctx->opcode >> 21) & 0x1f;
16527 rt = (ctx->opcode >> 16) & 0x1f;
16528 rd = (ctx->opcode >> 11) & 0x1f;
16529
16530 op1 = MASK_SPECIAL2(ctx->opcode);
16531 switch (op1) {
16532 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16533 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16534 check_insn(ctx, ISA_MIPS32);
16535 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16536 break;
16537 case OPC_MUL:
099e5b4d
LA
16538 gen_arith(ctx, op1, rd, rs, rt);
16539 break;
fac5a073
LA
16540 case OPC_DIV_G_2F:
16541 case OPC_DIVU_G_2F:
16542 case OPC_MULT_G_2F:
16543 case OPC_MULTU_G_2F:
16544 case OPC_MOD_G_2F:
16545 case OPC_MODU_G_2F:
16546 check_insn(ctx, INSN_LOONGSON2F);
16547 gen_loongson_integer(ctx, op1, rd, rs, rt);
16548 break;
099e5b4d
LA
16549 case OPC_CLO:
16550 case OPC_CLZ:
16551 check_insn(ctx, ISA_MIPS32);
16552 gen_cl(ctx, op1, rd, rs);
16553 break;
16554 case OPC_SDBBP:
16555 /* XXX: not clear which exception should be raised
16556 * when in debug mode...
16557 */
16558 check_insn(ctx, ISA_MIPS32);
16559 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16560 generate_exception(ctx, EXCP_DBp);
16561 } else {
16562 generate_exception(ctx, EXCP_DBp);
16563 }
16564 /* Treat as NOP. */
16565 break;
9b1a1d68 16566#if defined(TARGET_MIPS64)
099e5b4d
LA
16567 case OPC_DCLO:
16568 case OPC_DCLZ:
16569 check_insn(ctx, ISA_MIPS64);
16570 check_mips_64(ctx);
16571 gen_cl(ctx, op1, rd, rs);
16572 break;
4267d3e6
LA
16573 case OPC_DMULT_G_2F:
16574 case OPC_DMULTU_G_2F:
16575 case OPC_DDIV_G_2F:
16576 case OPC_DDIVU_G_2F:
16577 case OPC_DMOD_G_2F:
16578 case OPC_DMODU_G_2F:
16579 check_insn(ctx, INSN_LOONGSON2F);
16580 gen_loongson_integer(ctx, op1, rd, rs, rt);
16581 break;
10dc65db 16582#endif
4267d3e6
LA
16583 default: /* Invalid */
16584 MIPS_INVAL("special2_legacy");
16585 generate_exception(ctx, EXCP_RI);
16586 break;
10dc65db
LA
16587 }
16588}
16589
16590static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16591{
15eacb9b
YK
16592 int rs, rt, rd, sa;
16593 uint32_t op1, op2;
10dc65db
LA
16594 int16_t imm;
16595
16596 rs = (ctx->opcode >> 21) & 0x1f;
16597 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16598 rd = (ctx->opcode >> 11) & 0x1f;
16599 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16600 imm = (int16_t)ctx->opcode >> 7;
16601
16602 op1 = MASK_SPECIAL3(ctx->opcode);
16603 switch (op1) {
bf7910c6
LA
16604 case R6_OPC_PREF:
16605 if (rt >= 24) {
16606 /* hint codes 24-31 are reserved and signal RI */
16607 generate_exception(ctx, EXCP_RI);
16608 }
16609 /* Treat as NOP. */
16610 break;
16611 case R6_OPC_CACHE:
16612 /* Treat as NOP. */
16613 break;
10dc65db
LA
16614 case R6_OPC_SC:
16615 gen_st_cond(ctx, op1, rt, rs, imm);
16616 break;
16617 case R6_OPC_LL:
16618 gen_ld(ctx, op1, rt, rs, imm);
16619 break;
15eacb9b
YK
16620 case OPC_BSHFL:
16621 {
16622 if (rd == 0) {
16623 /* Treat as NOP. */
16624 break;
16625 }
16626 TCGv t0 = tcg_temp_new();
16627 gen_load_gpr(t0, rt);
16628
16629 op2 = MASK_BSHFL(ctx->opcode);
16630 switch (op2) {
16631 case OPC_ALIGN ... OPC_ALIGN_END:
16632 sa &= 3;
16633 if (sa == 0) {
16634 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16635 } else {
16636 TCGv t1 = tcg_temp_new();
16637 TCGv_i64 t2 = tcg_temp_new_i64();
16638 gen_load_gpr(t1, rs);
16639 tcg_gen_concat_tl_i64(t2, t1, t0);
16640 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16641#if defined(TARGET_MIPS64)
16642 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16643#else
16644 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16645#endif
16646 tcg_temp_free_i64(t2);
16647 tcg_temp_free(t1);
16648 }
16649 break;
16650 case OPC_BITSWAP:
16651 gen_helper_bitswap(cpu_gpr[rd], t0);
16652 break;
16653 }
16654 tcg_temp_free(t0);
16655 }
16656 break;
bf7910c6
LA
16657#if defined(TARGET_MIPS64)
16658 case R6_OPC_SCD:
16659 gen_st_cond(ctx, op1, rt, rs, imm);
16660 break;
16661 case R6_OPC_LLD:
16662 gen_ld(ctx, op1, rt, rs, imm);
16663 break;
15eacb9b
YK
16664 case OPC_DBSHFL:
16665 check_mips_64(ctx);
16666 {
16667 if (rd == 0) {
16668 /* Treat as NOP. */
16669 break;
16670 }
16671 TCGv t0 = tcg_temp_new();
16672 gen_load_gpr(t0, rt);
16673
16674 op2 = MASK_DBSHFL(ctx->opcode);
16675 switch (op2) {
16676 case OPC_DALIGN ... OPC_DALIGN_END:
16677 sa &= 7;
16678 if (sa == 0) {
16679 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16680 } else {
16681 TCGv t1 = tcg_temp_new();
16682 gen_load_gpr(t1, rs);
16683 tcg_gen_shli_tl(t0, t0, 8 * sa);
16684 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16685 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16686 tcg_temp_free(t1);
16687 }
16688 break;
16689 case OPC_DBITSWAP:
16690 gen_helper_dbitswap(cpu_gpr[rd], t0);
16691 break;
16692 }
16693 tcg_temp_free(t0);
16694 }
16695 break;
bf7910c6 16696#endif
10dc65db
LA
16697 default: /* Invalid */
16698 MIPS_INVAL("special3_r6");
16699 generate_exception(ctx, EXCP_RI);
16700 break;
16701 }
16702}
16703
16704static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16705{
fac5a073 16706 int rs, rt, rd;
099e5b4d 16707 uint32_t op1, op2;
099e5b4d
LA
16708
16709 rs = (ctx->opcode >> 21) & 0x1f;
16710 rt = (ctx->opcode >> 16) & 0x1f;
16711 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16712
16713 op1 = MASK_SPECIAL3(ctx->opcode);
16714 switch (op1) {
099e5b4d
LA
16715 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16716 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16717 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16718 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16719 * the same mask and op1. */
16720 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16721 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16722 switch (op2) {
099e5b4d
LA
16723 case OPC_ADDUH_QB:
16724 case OPC_ADDUH_R_QB:
16725 case OPC_ADDQH_PH:
16726 case OPC_ADDQH_R_PH:
16727 case OPC_ADDQH_W:
16728 case OPC_ADDQH_R_W:
16729 case OPC_SUBUH_QB:
16730 case OPC_SUBUH_R_QB:
16731 case OPC_SUBQH_PH:
16732 case OPC_SUBQH_R_PH:
16733 case OPC_SUBQH_W:
16734 case OPC_SUBQH_R_W:
461c08df
JL
16735 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16736 break;
099e5b4d
LA
16737 case OPC_MUL_PH:
16738 case OPC_MUL_S_PH:
16739 case OPC_MULQ_S_W:
16740 case OPC_MULQ_RS_W:
16741 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16742 break;
461c08df 16743 default:
099e5b4d 16744 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16745 generate_exception(ctx, EXCP_RI);
16746 break;
16747 }
099e5b4d
LA
16748 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16749 gen_loongson_integer(ctx, op1, rd, rs, rt);
16750 } else {
16751 generate_exception(ctx, EXCP_RI);
16752 }
16753 break;
16754 case OPC_LX_DSP:
16755 op2 = MASK_LX(ctx->opcode);
16756 switch (op2) {
16757#if defined(TARGET_MIPS64)
16758 case OPC_LDX:
16759#endif
16760 case OPC_LBUX:
16761 case OPC_LHX:
16762 case OPC_LWX:
16763 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16764 break;
16765 default: /* Invalid */
16766 MIPS_INVAL("MASK LX");
16767 generate_exception(ctx, EXCP_RI);
16768 break;
16769 }
16770 break;
16771 case OPC_ABSQ_S_PH_DSP:
16772 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16773 switch (op2) {
16774 case OPC_ABSQ_S_QB:
16775 case OPC_ABSQ_S_PH:
16776 case OPC_ABSQ_S_W:
16777 case OPC_PRECEQ_W_PHL:
16778 case OPC_PRECEQ_W_PHR:
16779 case OPC_PRECEQU_PH_QBL:
16780 case OPC_PRECEQU_PH_QBR:
16781 case OPC_PRECEQU_PH_QBLA:
16782 case OPC_PRECEQU_PH_QBRA:
16783 case OPC_PRECEU_PH_QBL:
16784 case OPC_PRECEU_PH_QBR:
16785 case OPC_PRECEU_PH_QBLA:
16786 case OPC_PRECEU_PH_QBRA:
16787 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16788 break;
16789 case OPC_BITREV:
16790 case OPC_REPL_QB:
16791 case OPC_REPLV_QB:
16792 case OPC_REPL_PH:
16793 case OPC_REPLV_PH:
16794 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16795 break;
16796 default:
16797 MIPS_INVAL("MASK ABSQ_S.PH");
16798 generate_exception(ctx, EXCP_RI);
16799 break;
16800 }
16801 break;
16802 case OPC_ADDU_QB_DSP:
16803 op2 = MASK_ADDU_QB(ctx->opcode);
16804 switch (op2) {
16805 case OPC_ADDQ_PH:
16806 case OPC_ADDQ_S_PH:
16807 case OPC_ADDQ_S_W:
16808 case OPC_ADDU_QB:
16809 case OPC_ADDU_S_QB:
16810 case OPC_ADDU_PH:
16811 case OPC_ADDU_S_PH:
16812 case OPC_SUBQ_PH:
16813 case OPC_SUBQ_S_PH:
16814 case OPC_SUBQ_S_W:
16815 case OPC_SUBU_QB:
16816 case OPC_SUBU_S_QB:
16817 case OPC_SUBU_PH:
16818 case OPC_SUBU_S_PH:
16819 case OPC_ADDSC:
16820 case OPC_ADDWC:
16821 case OPC_MODSUB:
16822 case OPC_RADDU_W_QB:
16823 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16824 break;
16825 case OPC_MULEU_S_PH_QBL:
16826 case OPC_MULEU_S_PH_QBR:
16827 case OPC_MULQ_RS_PH:
16828 case OPC_MULEQ_S_W_PHL:
16829 case OPC_MULEQ_S_W_PHR:
16830 case OPC_MULQ_S_PH:
16831 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16832 break;
16833 default: /* Invalid */
16834 MIPS_INVAL("MASK ADDU.QB");
16835 generate_exception(ctx, EXCP_RI);
461c08df 16836 break;
461c08df 16837
099e5b4d
LA
16838 }
16839 break;
16840 case OPC_CMPU_EQ_QB_DSP:
16841 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16842 switch (op2) {
16843 case OPC_PRECR_SRA_PH_W:
16844 case OPC_PRECR_SRA_R_PH_W:
16845 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16846 break;
099e5b4d
LA
16847 case OPC_PRECR_QB_PH:
16848 case OPC_PRECRQ_QB_PH:
16849 case OPC_PRECRQ_PH_W:
16850 case OPC_PRECRQ_RS_PH_W:
16851 case OPC_PRECRQU_S_QB_PH:
16852 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16853 break;
099e5b4d
LA
16854 case OPC_CMPU_EQ_QB:
16855 case OPC_CMPU_LT_QB:
16856 case OPC_CMPU_LE_QB:
16857 case OPC_CMP_EQ_PH:
16858 case OPC_CMP_LT_PH:
16859 case OPC_CMP_LE_PH:
16860 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16861 break;
099e5b4d
LA
16862 case OPC_CMPGU_EQ_QB:
16863 case OPC_CMPGU_LT_QB:
16864 case OPC_CMPGU_LE_QB:
16865 case OPC_CMPGDU_EQ_QB:
16866 case OPC_CMPGDU_LT_QB:
16867 case OPC_CMPGDU_LE_QB:
16868 case OPC_PICK_QB:
16869 case OPC_PICK_PH:
16870 case OPC_PACKRL_PH:
16871 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16872 break;
16873 default: /* Invalid */
16874 MIPS_INVAL("MASK CMPU.EQ.QB");
16875 generate_exception(ctx, EXCP_RI);
16876 break;
16877 }
16878 break;
16879 case OPC_SHLL_QB_DSP:
16880 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16881 break;
16882 case OPC_DPA_W_PH_DSP:
16883 op2 = MASK_DPA_W_PH(ctx->opcode);
16884 switch (op2) {
16885 case OPC_DPAU_H_QBL:
16886 case OPC_DPAU_H_QBR:
16887 case OPC_DPSU_H_QBL:
16888 case OPC_DPSU_H_QBR:
16889 case OPC_DPA_W_PH:
16890 case OPC_DPAX_W_PH:
16891 case OPC_DPAQ_S_W_PH:
16892 case OPC_DPAQX_S_W_PH:
16893 case OPC_DPAQX_SA_W_PH:
16894 case OPC_DPS_W_PH:
16895 case OPC_DPSX_W_PH:
16896 case OPC_DPSQ_S_W_PH:
16897 case OPC_DPSQX_S_W_PH:
16898 case OPC_DPSQX_SA_W_PH:
16899 case OPC_MULSAQ_S_W_PH:
16900 case OPC_DPAQ_SA_L_W:
16901 case OPC_DPSQ_SA_L_W:
16902 case OPC_MAQ_S_W_PHL:
16903 case OPC_MAQ_S_W_PHR:
16904 case OPC_MAQ_SA_W_PHL:
16905 case OPC_MAQ_SA_W_PHR:
16906 case OPC_MULSA_W_PH:
16907 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16908 break;
16909 default: /* Invalid */
16910 MIPS_INVAL("MASK DPAW.PH");
16911 generate_exception(ctx, EXCP_RI);
16912 break;
16913 }
16914 break;
16915 case OPC_INSV_DSP:
16916 op2 = MASK_INSV(ctx->opcode);
16917 switch (op2) {
16918 case OPC_INSV:
16919 check_dsp(ctx);
16920 {
16921 TCGv t0, t1;
16922
16923 if (rt == 0) {
16924 MIPS_DEBUG("NOP");
16925 break;
16926 }
16927
16928 t0 = tcg_temp_new();
16929 t1 = tcg_temp_new();
16930
16931 gen_load_gpr(t0, rt);
16932 gen_load_gpr(t1, rs);
16933
16934 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16935
16936 tcg_temp_free(t0);
16937 tcg_temp_free(t1);
a22260ae
JL
16938 break;
16939 }
099e5b4d
LA
16940 default: /* Invalid */
16941 MIPS_INVAL("MASK INSV");
16942 generate_exception(ctx, EXCP_RI);
16943 break;
16944 }
16945 break;
16946 case OPC_APPEND_DSP:
16947 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16948 break;
16949 case OPC_EXTR_W_DSP:
16950 op2 = MASK_EXTR_W(ctx->opcode);
16951 switch (op2) {
16952 case OPC_EXTR_W:
16953 case OPC_EXTR_R_W:
16954 case OPC_EXTR_RS_W:
16955 case OPC_EXTR_S_H:
16956 case OPC_EXTRV_S_H:
16957 case OPC_EXTRV_W:
16958 case OPC_EXTRV_R_W:
16959 case OPC_EXTRV_RS_W:
16960 case OPC_EXTP:
16961 case OPC_EXTPV:
16962 case OPC_EXTPDP:
16963 case OPC_EXTPDPV:
16964 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16965 break;
16966 case OPC_RDDSP:
16967 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16968 break;
16969 case OPC_SHILO:
16970 case OPC_SHILOV:
16971 case OPC_MTHLIP:
16972 case OPC_WRDSP:
16973 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16974 break;
16975 default: /* Invalid */
16976 MIPS_INVAL("MASK EXTR.W");
16977 generate_exception(ctx, EXCP_RI);
16978 break;
16979 }
16980 break;
099e5b4d 16981#if defined(TARGET_MIPS64)
fac5a073
LA
16982 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
16983 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
16984 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
16985 check_insn(ctx, INSN_LOONGSON2E);
16986 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 16987 break;
099e5b4d
LA
16988 case OPC_ABSQ_S_QH_DSP:
16989 op2 = MASK_ABSQ_S_QH(ctx->opcode);
16990 switch (op2) {
16991 case OPC_PRECEQ_L_PWL:
16992 case OPC_PRECEQ_L_PWR:
16993 case OPC_PRECEQ_PW_QHL:
16994 case OPC_PRECEQ_PW_QHR:
16995 case OPC_PRECEQ_PW_QHLA:
16996 case OPC_PRECEQ_PW_QHRA:
16997 case OPC_PRECEQU_QH_OBL:
16998 case OPC_PRECEQU_QH_OBR:
16999 case OPC_PRECEQU_QH_OBLA:
17000 case OPC_PRECEQU_QH_OBRA:
17001 case OPC_PRECEU_QH_OBL:
17002 case OPC_PRECEU_QH_OBR:
17003 case OPC_PRECEU_QH_OBLA:
17004 case OPC_PRECEU_QH_OBRA:
17005 case OPC_ABSQ_S_OB:
17006 case OPC_ABSQ_S_PW:
17007 case OPC_ABSQ_S_QH:
17008 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17009 break;
17010 case OPC_REPL_OB:
17011 case OPC_REPL_PW:
17012 case OPC_REPL_QH:
17013 case OPC_REPLV_OB:
17014 case OPC_REPLV_PW:
17015 case OPC_REPLV_QH:
17016 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17017 break;
17018 default: /* Invalid */
17019 MIPS_INVAL("MASK ABSQ_S.QH");
17020 generate_exception(ctx, EXCP_RI);
17021 break;
17022 }
17023 break;
17024 case OPC_ADDU_OB_DSP:
17025 op2 = MASK_ADDU_OB(ctx->opcode);
17026 switch (op2) {
17027 case OPC_RADDU_L_OB:
17028 case OPC_SUBQ_PW:
17029 case OPC_SUBQ_S_PW:
17030 case OPC_SUBQ_QH:
17031 case OPC_SUBQ_S_QH:
17032 case OPC_SUBU_OB:
17033 case OPC_SUBU_S_OB:
17034 case OPC_SUBU_QH:
17035 case OPC_SUBU_S_QH:
17036 case OPC_SUBUH_OB:
17037 case OPC_SUBUH_R_OB:
17038 case OPC_ADDQ_PW:
17039 case OPC_ADDQ_S_PW:
17040 case OPC_ADDQ_QH:
17041 case OPC_ADDQ_S_QH:
17042 case OPC_ADDU_OB:
17043 case OPC_ADDU_S_OB:
17044 case OPC_ADDU_QH:
17045 case OPC_ADDU_S_QH:
17046 case OPC_ADDUH_OB:
17047 case OPC_ADDUH_R_OB:
17048 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 17049 break;
099e5b4d
LA
17050 case OPC_MULEQ_S_PW_QHL:
17051 case OPC_MULEQ_S_PW_QHR:
17052 case OPC_MULEU_S_QH_OBL:
17053 case OPC_MULEU_S_QH_OBR:
17054 case OPC_MULQ_RS_QH:
17055 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17056 break;
099e5b4d
LA
17057 default: /* Invalid */
17058 MIPS_INVAL("MASK ADDU.OB");
17059 generate_exception(ctx, EXCP_RI);
26690560 17060 break;
099e5b4d
LA
17061 }
17062 break;
17063 case OPC_CMPU_EQ_OB_DSP:
17064 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17065 switch (op2) {
17066 case OPC_PRECR_SRA_QH_PW:
17067 case OPC_PRECR_SRA_R_QH_PW:
17068 /* Return value is rt. */
17069 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 17070 break;
099e5b4d
LA
17071 case OPC_PRECR_OB_QH:
17072 case OPC_PRECRQ_OB_QH:
17073 case OPC_PRECRQ_PW_L:
17074 case OPC_PRECRQ_QH_PW:
17075 case OPC_PRECRQ_RS_QH_PW:
17076 case OPC_PRECRQU_S_OB_QH:
17077 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 17078 break;
099e5b4d
LA
17079 case OPC_CMPU_EQ_OB:
17080 case OPC_CMPU_LT_OB:
17081 case OPC_CMPU_LE_OB:
17082 case OPC_CMP_EQ_QH:
17083 case OPC_CMP_LT_QH:
17084 case OPC_CMP_LE_QH:
17085 case OPC_CMP_EQ_PW:
17086 case OPC_CMP_LT_PW:
17087 case OPC_CMP_LE_PW:
17088 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 17089 break;
099e5b4d
LA
17090 case OPC_CMPGDU_EQ_OB:
17091 case OPC_CMPGDU_LT_OB:
17092 case OPC_CMPGDU_LE_OB:
17093 case OPC_CMPGU_EQ_OB:
17094 case OPC_CMPGU_LT_OB:
17095 case OPC_CMPGU_LE_OB:
17096 case OPC_PACKRL_PW:
17097 case OPC_PICK_OB:
17098 case OPC_PICK_PW:
17099 case OPC_PICK_QH:
17100 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 17101 break;
099e5b4d
LA
17102 default: /* Invalid */
17103 MIPS_INVAL("MASK CMPU_EQ.OB");
17104 generate_exception(ctx, EXCP_RI);
161f85e6 17105 break;
099e5b4d
LA
17106 }
17107 break;
17108 case OPC_DAPPEND_DSP:
17109 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17110 break;
17111 case OPC_DEXTR_W_DSP:
17112 op2 = MASK_DEXTR_W(ctx->opcode);
17113 switch (op2) {
17114 case OPC_DEXTP:
17115 case OPC_DEXTPDP:
17116 case OPC_DEXTPDPV:
17117 case OPC_DEXTPV:
17118 case OPC_DEXTR_L:
17119 case OPC_DEXTR_R_L:
17120 case OPC_DEXTR_RS_L:
17121 case OPC_DEXTR_W:
17122 case OPC_DEXTR_R_W:
17123 case OPC_DEXTR_RS_W:
17124 case OPC_DEXTR_S_H:
17125 case OPC_DEXTRV_L:
17126 case OPC_DEXTRV_R_L:
17127 case OPC_DEXTRV_RS_L:
17128 case OPC_DEXTRV_S_H:
17129 case OPC_DEXTRV_W:
17130 case OPC_DEXTRV_R_W:
17131 case OPC_DEXTRV_RS_W:
17132 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 17133 break;
099e5b4d
LA
17134 case OPC_DMTHLIP:
17135 case OPC_DSHILO:
17136 case OPC_DSHILOV:
17137 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 17138 break;
099e5b4d
LA
17139 default: /* Invalid */
17140 MIPS_INVAL("MASK EXTR.W");
17141 generate_exception(ctx, EXCP_RI);
461c08df 17142 break;
099e5b4d
LA
17143 }
17144 break;
17145 case OPC_DPAQ_W_QH_DSP:
17146 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17147 switch (op2) {
17148 case OPC_DPAU_H_OBL:
17149 case OPC_DPAU_H_OBR:
17150 case OPC_DPSU_H_OBL:
17151 case OPC_DPSU_H_OBR:
17152 case OPC_DPA_W_QH:
17153 case OPC_DPAQ_S_W_QH:
17154 case OPC_DPS_W_QH:
17155 case OPC_DPSQ_S_W_QH:
17156 case OPC_MULSAQ_S_W_QH:
17157 case OPC_DPAQ_SA_L_PW:
17158 case OPC_DPSQ_SA_L_PW:
17159 case OPC_MULSAQ_S_L_PW:
17160 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17161 break;
17162 case OPC_MAQ_S_W_QHLL:
17163 case OPC_MAQ_S_W_QHLR:
17164 case OPC_MAQ_S_W_QHRL:
17165 case OPC_MAQ_S_W_QHRR:
17166 case OPC_MAQ_SA_W_QHLL:
17167 case OPC_MAQ_SA_W_QHLR:
17168 case OPC_MAQ_SA_W_QHRL:
17169 case OPC_MAQ_SA_W_QHRR:
17170 case OPC_MAQ_S_L_PWL:
17171 case OPC_MAQ_S_L_PWR:
17172 case OPC_DMADD:
17173 case OPC_DMADDU:
17174 case OPC_DMSUB:
17175 case OPC_DMSUBU:
17176 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 17177 break;
099e5b4d
LA
17178 default: /* Invalid */
17179 MIPS_INVAL("MASK DPAQ.W.QH");
17180 generate_exception(ctx, EXCP_RI);
b53371ed 17181 break;
099e5b4d
LA
17182 }
17183 break;
17184 case OPC_DINSV_DSP:
17185 op2 = MASK_INSV(ctx->opcode);
17186 switch (op2) {
17187 case OPC_DINSV:
17188 {
17189 TCGv t0, t1;
17190
17191 if (rt == 0) {
17192 MIPS_DEBUG("NOP");
a22260ae
JL
17193 break;
17194 }
099e5b4d 17195 check_dsp(ctx);
1cb6686c 17196
099e5b4d
LA
17197 t0 = tcg_temp_new();
17198 t1 = tcg_temp_new();
1cb6686c 17199
099e5b4d
LA
17200 gen_load_gpr(t0, rt);
17201 gen_load_gpr(t1, rs);
1cb6686c 17202
099e5b4d 17203 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 17204
099e5b4d
LA
17205 tcg_temp_free(t0);
17206 tcg_temp_free(t1);
77c5fa8b 17207 break;
099e5b4d 17208 }
7a387fff 17209 default: /* Invalid */
099e5b4d 17210 MIPS_INVAL("MASK DINSV");
7a387fff
TS
17211 generate_exception(ctx, EXCP_RI);
17212 break;
17213 }
17214 break;
099e5b4d
LA
17215 case OPC_SHLL_OB_DSP:
17216 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17217 break;
17218#endif
fac5a073
LA
17219 default: /* Invalid */
17220 MIPS_INVAL("special3_legacy");
17221 generate_exception(ctx, EXCP_RI);
17222 break;
17223 }
17224}
17225
17226static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17227{
17228 int rs, rt, rd, sa;
17229 uint32_t op1, op2;
17230
17231 rs = (ctx->opcode >> 21) & 0x1f;
17232 rt = (ctx->opcode >> 16) & 0x1f;
17233 rd = (ctx->opcode >> 11) & 0x1f;
17234 sa = (ctx->opcode >> 6) & 0x1f;
17235
17236 op1 = MASK_SPECIAL3(ctx->opcode);
17237 switch (op1) {
17238 case OPC_EXT:
17239 case OPC_INS:
17240 check_insn(ctx, ISA_MIPS32R2);
17241 gen_bitops(ctx, op1, rt, rs, sa, rd);
17242 break;
17243 case OPC_BSHFL:
fac5a073 17244 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
17245 switch (op2) {
17246 case OPC_ALIGN ... OPC_ALIGN_END:
17247 case OPC_BITSWAP:
17248 check_insn(ctx, ISA_MIPS32R6);
17249 decode_opc_special3_r6(env, ctx);
17250 break;
17251 default:
17252 check_insn(ctx, ISA_MIPS32R2);
17253 gen_bshfl(ctx, op2, rt, rd);
17254 break;
17255 }
fac5a073
LA
17256 break;
17257#if defined(TARGET_MIPS64)
17258 case OPC_DEXTM ... OPC_DEXT:
17259 case OPC_DINSM ... OPC_DINS:
17260 check_insn(ctx, ISA_MIPS64R2);
17261 check_mips_64(ctx);
17262 gen_bitops(ctx, op1, rt, rs, sa, rd);
17263 break;
17264 case OPC_DBSHFL:
fac5a073 17265 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
17266 switch (op2) {
17267 case OPC_DALIGN ... OPC_DALIGN_END:
17268 case OPC_DBITSWAP:
17269 check_insn(ctx, ISA_MIPS32R6);
17270 decode_opc_special3_r6(env, ctx);
17271 break;
17272 default:
17273 check_insn(ctx, ISA_MIPS64R2);
17274 check_mips_64(ctx);
17275 op2 = MASK_DBSHFL(ctx->opcode);
17276 gen_bshfl(ctx, op2, rt, rd);
17277 break;
17278 }
fac5a073
LA
17279 break;
17280#endif
17281 case OPC_RDHWR:
17282 gen_rdhwr(ctx, rt, rd);
17283 break;
17284 case OPC_FORK:
17285 check_insn(ctx, ASE_MT);
17286 {
17287 TCGv t0 = tcg_temp_new();
17288 TCGv t1 = tcg_temp_new();
17289
17290 gen_load_gpr(t0, rt);
17291 gen_load_gpr(t1, rs);
17292 gen_helper_fork(t0, t1);
17293 tcg_temp_free(t0);
17294 tcg_temp_free(t1);
17295 }
17296 break;
17297 case OPC_YIELD:
17298 check_insn(ctx, ASE_MT);
17299 {
17300 TCGv t0 = tcg_temp_new();
17301
17302 save_cpu_state(ctx, 1);
17303 gen_load_gpr(t0, rs);
17304 gen_helper_yield(t0, cpu_env, t0);
17305 gen_store_gpr(t0, rd);
17306 tcg_temp_free(t0);
17307 }
17308 break;
10dc65db
LA
17309 default:
17310 if (ctx->insn_flags & ISA_MIPS32R6) {
17311 decode_opc_special3_r6(env, ctx);
17312 } else {
17313 decode_opc_special3_legacy(env, ctx);
17314 }
099e5b4d
LA
17315 }
17316}
17317
863f264d
YK
17318/* MIPS SIMD Architecture (MSA) */
17319static inline int check_msa_access(DisasContext *ctx)
17320{
17321 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17322 !(ctx->hflags & MIPS_HFLAG_F64))) {
17323 generate_exception(ctx, EXCP_RI);
17324 return 0;
17325 }
17326
17327 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17328 if (ctx->insn_flags & ASE_MSA) {
17329 generate_exception(ctx, EXCP_MSADIS);
17330 return 0;
17331 } else {
17332 generate_exception(ctx, EXCP_RI);
17333 return 0;
17334 }
17335 }
17336 return 1;
17337}
17338
5692c6e1
YK
17339static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17340{
17341 /* generates tcg ops to check if any element is 0 */
17342 /* Note this function only works with MSA_WRLEN = 128 */
17343 uint64_t eval_zero_or_big = 0;
17344 uint64_t eval_big = 0;
17345 TCGv_i64 t0 = tcg_temp_new_i64();
17346 TCGv_i64 t1 = tcg_temp_new_i64();
17347 switch (df) {
17348 case DF_BYTE:
17349 eval_zero_or_big = 0x0101010101010101ULL;
17350 eval_big = 0x8080808080808080ULL;
17351 break;
17352 case DF_HALF:
17353 eval_zero_or_big = 0x0001000100010001ULL;
17354 eval_big = 0x8000800080008000ULL;
17355 break;
17356 case DF_WORD:
17357 eval_zero_or_big = 0x0000000100000001ULL;
17358 eval_big = 0x8000000080000000ULL;
17359 break;
17360 case DF_DOUBLE:
17361 eval_zero_or_big = 0x0000000000000001ULL;
17362 eval_big = 0x8000000000000000ULL;
17363 break;
17364 }
17365 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17366 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17367 tcg_gen_andi_i64(t0, t0, eval_big);
17368 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17369 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17370 tcg_gen_andi_i64(t1, t1, eval_big);
17371 tcg_gen_or_i64(t0, t0, t1);
17372 /* if all bits are zero then all elements are not zero */
17373 /* if some bit is non-zero then some element is zero */
17374 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17375 tcg_gen_trunc_i64_tl(tresult, t0);
17376 tcg_temp_free_i64(t0);
17377 tcg_temp_free_i64(t1);
17378}
17379
17380static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17381{
17382 uint8_t df = (ctx->opcode >> 21) & 0x3;
17383 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17384 int64_t s16 = (int16_t)ctx->opcode;
17385
17386 check_msa_access(ctx);
17387
17388 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17389 MIPS_DEBUG("CTI in delay / forbidden slot");
17390 generate_exception(ctx, EXCP_RI);
17391 return;
17392 }
17393 switch (op1) {
17394 case OPC_BZ_V:
17395 case OPC_BNZ_V:
17396 {
17397 TCGv_i64 t0 = tcg_temp_new_i64();
17398 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17399 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17400 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17401 tcg_gen_trunc_i64_tl(bcond, t0);
17402 tcg_temp_free_i64(t0);
17403 }
17404 break;
17405 case OPC_BZ_B:
17406 case OPC_BZ_H:
17407 case OPC_BZ_W:
17408 case OPC_BZ_D:
17409 gen_check_zero_element(bcond, df, wt);
17410 break;
17411 case OPC_BNZ_B:
17412 case OPC_BNZ_H:
17413 case OPC_BNZ_W:
17414 case OPC_BNZ_D:
17415 gen_check_zero_element(bcond, df, wt);
17416 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17417 break;
17418 }
17419
17420 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17421
17422 ctx->hflags |= MIPS_HFLAG_BC;
17423 ctx->hflags |= MIPS_HFLAG_BDS32;
17424}
17425
4c789546
YK
17426static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17427{
17428#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17429 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17430 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17431 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17432
17433 TCGv_i32 twd = tcg_const_i32(wd);
17434 TCGv_i32 tws = tcg_const_i32(ws);
17435 TCGv_i32 ti8 = tcg_const_i32(i8);
17436
17437 switch (MASK_MSA_I8(ctx->opcode)) {
17438 case OPC_ANDI_B:
17439 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17440 break;
17441 case OPC_ORI_B:
17442 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17443 break;
17444 case OPC_NORI_B:
17445 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17446 break;
17447 case OPC_XORI_B:
17448 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17449 break;
17450 case OPC_BMNZI_B:
17451 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17452 break;
17453 case OPC_BMZI_B:
17454 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17455 break;
17456 case OPC_BSELI_B:
17457 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17458 break;
17459 case OPC_SHF_B:
17460 case OPC_SHF_H:
17461 case OPC_SHF_W:
17462 {
17463 uint8_t df = (ctx->opcode >> 24) & 0x3;
17464 if (df == DF_DOUBLE) {
17465 generate_exception(ctx, EXCP_RI);
17466 } else {
17467 TCGv_i32 tdf = tcg_const_i32(df);
17468 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17469 tcg_temp_free_i32(tdf);
17470 }
17471 }
17472 break;
17473 default:
17474 MIPS_INVAL("MSA instruction");
17475 generate_exception(ctx, EXCP_RI);
17476 break;
17477 }
17478
17479 tcg_temp_free_i32(twd);
17480 tcg_temp_free_i32(tws);
17481 tcg_temp_free_i32(ti8);
17482}
17483
80e71591
YK
17484static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17485{
17486#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17487 uint8_t df = (ctx->opcode >> 21) & 0x3;
17488 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17489 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17490 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17491 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17492
17493 TCGv_i32 tdf = tcg_const_i32(df);
17494 TCGv_i32 twd = tcg_const_i32(wd);
17495 TCGv_i32 tws = tcg_const_i32(ws);
17496 TCGv_i32 timm = tcg_temp_new_i32();
17497 tcg_gen_movi_i32(timm, u5);
17498
17499 switch (MASK_MSA_I5(ctx->opcode)) {
17500 case OPC_ADDVI_df:
17501 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17502 break;
17503 case OPC_SUBVI_df:
17504 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17505 break;
17506 case OPC_MAXI_S_df:
17507 tcg_gen_movi_i32(timm, s5);
17508 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17509 break;
17510 case OPC_MAXI_U_df:
17511 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17512 break;
17513 case OPC_MINI_S_df:
17514 tcg_gen_movi_i32(timm, s5);
17515 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17516 break;
17517 case OPC_MINI_U_df:
17518 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17519 break;
17520 case OPC_CEQI_df:
17521 tcg_gen_movi_i32(timm, s5);
17522 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17523 break;
17524 case OPC_CLTI_S_df:
17525 tcg_gen_movi_i32(timm, s5);
17526 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17527 break;
17528 case OPC_CLTI_U_df:
17529 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17530 break;
17531 case OPC_CLEI_S_df:
17532 tcg_gen_movi_i32(timm, s5);
17533 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17534 break;
17535 case OPC_CLEI_U_df:
17536 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17537 break;
17538 case OPC_LDI_df:
17539 {
17540 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17541 tcg_gen_movi_i32(timm, s10);
17542 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
17543 }
17544 break;
17545 default:
17546 MIPS_INVAL("MSA instruction");
17547 generate_exception(ctx, EXCP_RI);
17548 break;
17549 }
17550
17551 tcg_temp_free_i32(tdf);
17552 tcg_temp_free_i32(twd);
17553 tcg_temp_free_i32(tws);
17554 tcg_temp_free_i32(timm);
17555}
17556
d4cf28de
YK
17557static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
17558{
17559#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17560 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
17561 uint32_t df = 0, m = 0;
17562 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17563 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17564
17565 TCGv_i32 tdf;
17566 TCGv_i32 tm;
17567 TCGv_i32 twd;
17568 TCGv_i32 tws;
17569
17570 if ((dfm & 0x40) == 0x00) {
17571 m = dfm & 0x3f;
17572 df = DF_DOUBLE;
17573 } else if ((dfm & 0x60) == 0x40) {
17574 m = dfm & 0x1f;
17575 df = DF_WORD;
17576 } else if ((dfm & 0x70) == 0x60) {
17577 m = dfm & 0x0f;
17578 df = DF_HALF;
17579 } else if ((dfm & 0x78) == 0x70) {
17580 m = dfm & 0x7;
17581 df = DF_BYTE;
17582 } else {
17583 generate_exception(ctx, EXCP_RI);
17584 return;
17585 }
17586
17587 tdf = tcg_const_i32(df);
17588 tm = tcg_const_i32(m);
17589 twd = tcg_const_i32(wd);
17590 tws = tcg_const_i32(ws);
17591
17592 switch (MASK_MSA_BIT(ctx->opcode)) {
17593 case OPC_SLLI_df:
17594 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
17595 break;
17596 case OPC_SRAI_df:
17597 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
17598 break;
17599 case OPC_SRLI_df:
17600 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
17601 break;
17602 case OPC_BCLRI_df:
17603 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
17604 break;
17605 case OPC_BSETI_df:
17606 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
17607 break;
17608 case OPC_BNEGI_df:
17609 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
17610 break;
17611 case OPC_BINSLI_df:
17612 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
17613 break;
17614 case OPC_BINSRI_df:
17615 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
17616 break;
17617 case OPC_SAT_S_df:
17618 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
17619 break;
17620 case OPC_SAT_U_df:
17621 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
17622 break;
17623 case OPC_SRARI_df:
17624 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
17625 break;
17626 case OPC_SRLRI_df:
17627 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
17628 break;
17629 default:
17630 MIPS_INVAL("MSA instruction");
17631 generate_exception(ctx, EXCP_RI);
17632 break;
17633 }
17634
17635 tcg_temp_free_i32(tdf);
17636 tcg_temp_free_i32(tm);
17637 tcg_temp_free_i32(twd);
17638 tcg_temp_free_i32(tws);
17639}
17640
28f99f08
YK
17641static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
17642{
17643#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17644 uint8_t df = (ctx->opcode >> 21) & 0x3;
17645 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17646 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17647 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17648
17649 TCGv_i32 tdf = tcg_const_i32(df);
17650 TCGv_i32 twd = tcg_const_i32(wd);
17651 TCGv_i32 tws = tcg_const_i32(ws);
17652 TCGv_i32 twt = tcg_const_i32(wt);
17653
17654 switch (MASK_MSA_3R(ctx->opcode)) {
17655 case OPC_SLL_df:
17656 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
17657 break;
17658 case OPC_ADDV_df:
17659 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
17660 break;
17661 case OPC_CEQ_df:
17662 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
17663 break;
17664 case OPC_ADD_A_df:
17665 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
17666 break;
17667 case OPC_SUBS_S_df:
17668 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
17669 break;
17670 case OPC_MULV_df:
17671 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
17672 break;
17673 case OPC_SLD_df:
17674 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
17675 break;
17676 case OPC_VSHF_df:
17677 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
17678 break;
17679 case OPC_SRA_df:
17680 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
17681 break;
17682 case OPC_SUBV_df:
17683 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
17684 break;
17685 case OPC_ADDS_A_df:
17686 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
17687 break;
17688 case OPC_SUBS_U_df:
17689 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
17690 break;
17691 case OPC_MADDV_df:
17692 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
17693 break;
17694 case OPC_SPLAT_df:
17695 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
17696 break;
17697 case OPC_SRAR_df:
17698 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
17699 break;
17700 case OPC_SRL_df:
17701 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
17702 break;
17703 case OPC_MAX_S_df:
17704 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
17705 break;
17706 case OPC_CLT_S_df:
17707 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
17708 break;
17709 case OPC_ADDS_S_df:
17710 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
17711 break;
17712 case OPC_SUBSUS_U_df:
17713 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
17714 break;
17715 case OPC_MSUBV_df:
17716 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
17717 break;
17718 case OPC_PCKEV_df:
17719 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
17720 break;
17721 case OPC_SRLR_df:
17722 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
17723 break;
17724 case OPC_BCLR_df:
17725 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
17726 break;
17727 case OPC_MAX_U_df:
17728 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
17729 break;
17730 case OPC_CLT_U_df:
17731 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
17732 break;
17733 case OPC_ADDS_U_df:
17734 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
17735 break;
17736 case OPC_SUBSUU_S_df:
17737 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
17738 break;
17739 case OPC_PCKOD_df:
17740 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
17741 break;
17742 case OPC_BSET_df:
17743 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
17744 break;
17745 case OPC_MIN_S_df:
17746 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
17747 break;
17748 case OPC_CLE_S_df:
17749 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
17750 break;
17751 case OPC_AVE_S_df:
17752 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
17753 break;
17754 case OPC_ASUB_S_df:
17755 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
17756 break;
17757 case OPC_DIV_S_df:
17758 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
17759 break;
17760 case OPC_ILVL_df:
17761 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
17762 break;
17763 case OPC_BNEG_df:
17764 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
17765 break;
17766 case OPC_MIN_U_df:
17767 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
17768 break;
17769 case OPC_CLE_U_df:
17770 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
17771 break;
17772 case OPC_AVE_U_df:
17773 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
17774 break;
17775 case OPC_ASUB_U_df:
17776 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
17777 break;
17778 case OPC_DIV_U_df:
17779 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
17780 break;
17781 case OPC_ILVR_df:
17782 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
17783 break;
17784 case OPC_BINSL_df:
17785 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
17786 break;
17787 case OPC_MAX_A_df:
17788 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
17789 break;
17790 case OPC_AVER_S_df:
17791 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
17792 break;
17793 case OPC_MOD_S_df:
17794 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
17795 break;
17796 case OPC_ILVEV_df:
17797 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
17798 break;
17799 case OPC_BINSR_df:
17800 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
17801 break;
17802 case OPC_MIN_A_df:
17803 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
17804 break;
17805 case OPC_AVER_U_df:
17806 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
17807 break;
17808 case OPC_MOD_U_df:
17809 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
17810 break;
17811 case OPC_ILVOD_df:
17812 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
17813 break;
17814
17815 case OPC_DOTP_S_df:
17816 case OPC_DOTP_U_df:
17817 case OPC_DPADD_S_df:
17818 case OPC_DPADD_U_df:
17819 case OPC_DPSUB_S_df:
17820 case OPC_HADD_S_df:
17821 case OPC_DPSUB_U_df:
17822 case OPC_HADD_U_df:
17823 case OPC_HSUB_S_df:
17824 case OPC_HSUB_U_df:
17825 if (df == DF_BYTE) {
17826 generate_exception(ctx, EXCP_RI);
17827 }
17828 switch (MASK_MSA_3R(ctx->opcode)) {
17829 case OPC_DOTP_S_df:
17830 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
17831 break;
17832 case OPC_DOTP_U_df:
17833 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
17834 break;
17835 case OPC_DPADD_S_df:
17836 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
17837 break;
17838 case OPC_DPADD_U_df:
17839 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
17840 break;
17841 case OPC_DPSUB_S_df:
17842 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
17843 break;
17844 case OPC_HADD_S_df:
17845 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
17846 break;
17847 case OPC_DPSUB_U_df:
17848 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
17849 break;
17850 case OPC_HADD_U_df:
17851 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
17852 break;
17853 case OPC_HSUB_S_df:
17854 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
17855 break;
17856 case OPC_HSUB_U_df:
17857 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
17858 break;
17859 }
17860 break;
17861 default:
17862 MIPS_INVAL("MSA instruction");
17863 generate_exception(ctx, EXCP_RI);
17864 break;
17865 }
17866 tcg_temp_free_i32(twd);
17867 tcg_temp_free_i32(tws);
17868 tcg_temp_free_i32(twt);
17869 tcg_temp_free_i32(tdf);
17870}
17871
1e608ec1
YK
17872static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
17873{
17874#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17875 uint8_t source = (ctx->opcode >> 11) & 0x1f;
17876 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
17877 TCGv telm = tcg_temp_new();
17878 TCGv_i32 tsr = tcg_const_i32(source);
17879 TCGv_i32 tdt = tcg_const_i32(dest);
17880
17881 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
17882 case OPC_CTCMSA:
17883 gen_load_gpr(telm, source);
17884 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
17885 break;
17886 case OPC_CFCMSA:
17887 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
17888 gen_store_gpr(telm, dest);
17889 break;
17890 case OPC_MOVE_V:
17891 gen_helper_msa_move_v(cpu_env, tdt, tsr);
17892 break;
17893 default:
17894 MIPS_INVAL("MSA instruction");
17895 generate_exception(ctx, EXCP_RI);
17896 break;
17897 }
17898
17899 tcg_temp_free(telm);
17900 tcg_temp_free_i32(tdt);
17901 tcg_temp_free_i32(tsr);
17902}
17903
17904static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
17905 uint32_t n)
17906{
17907#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17908 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17909 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17910
17911 TCGv_i32 tws = tcg_const_i32(ws);
17912 TCGv_i32 twd = tcg_const_i32(wd);
17913 TCGv_i32 tn = tcg_const_i32(n);
17914 TCGv_i32 tdf = tcg_const_i32(df);
17915
17916 switch (MASK_MSA_ELM(ctx->opcode)) {
17917 case OPC_SLDI_df:
17918 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
17919 break;
17920 case OPC_SPLATI_df:
17921 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
17922 break;
17923 case OPC_INSVE_df:
17924 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
17925 break;
17926 case OPC_COPY_S_df:
17927 case OPC_COPY_U_df:
17928 case OPC_INSERT_df:
17929#if !defined(TARGET_MIPS64)
17930 /* Double format valid only for MIPS64 */
17931 if (df == DF_DOUBLE) {
17932 generate_exception(ctx, EXCP_RI);
17933 break;
17934 }
17935#endif
17936 switch (MASK_MSA_ELM(ctx->opcode)) {
17937 case OPC_COPY_S_df:
17938 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
17939 break;
17940 case OPC_COPY_U_df:
17941 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
17942 break;
17943 case OPC_INSERT_df:
17944 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
17945 break;
17946 }
17947 break;
17948 default:
17949 MIPS_INVAL("MSA instruction");
17950 generate_exception(ctx, EXCP_RI);
17951 }
17952 tcg_temp_free_i32(twd);
17953 tcg_temp_free_i32(tws);
17954 tcg_temp_free_i32(tn);
17955 tcg_temp_free_i32(tdf);
17956}
17957
17958static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
17959{
17960 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
17961 uint32_t df = 0, n = 0;
17962
17963 if ((dfn & 0x30) == 0x00) {
17964 n = dfn & 0x0f;
17965 df = DF_BYTE;
17966 } else if ((dfn & 0x38) == 0x20) {
17967 n = dfn & 0x07;
17968 df = DF_HALF;
17969 } else if ((dfn & 0x3c) == 0x30) {
17970 n = dfn & 0x03;
17971 df = DF_WORD;
17972 } else if ((dfn & 0x3e) == 0x38) {
17973 n = dfn & 0x01;
17974 df = DF_DOUBLE;
17975 } else if (dfn == 0x3E) {
17976 /* CTCMSA, CFCMSA, MOVE.V */
17977 gen_msa_elm_3e(env, ctx);
17978 return;
17979 } else {
17980 generate_exception(ctx, EXCP_RI);
17981 return;
17982 }
17983
17984 gen_msa_elm_df(env, ctx, df, n);
17985}
17986
7d05b9c8
YK
17987static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
17988{
17989#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17990 uint8_t df = (ctx->opcode >> 21) & 0x1;
17991 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17992 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17993 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17994
17995 TCGv_i32 twd = tcg_const_i32(wd);
17996 TCGv_i32 tws = tcg_const_i32(ws);
17997 TCGv_i32 twt = tcg_const_i32(wt);
17998 TCGv_i32 tdf = tcg_temp_new_i32();
17999
18000 /* adjust df value for floating-point instruction */
18001 tcg_gen_movi_i32(tdf, df + 2);
18002
18003 switch (MASK_MSA_3RF(ctx->opcode)) {
18004 case OPC_FCAF_df:
18005 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18006 break;
18007 case OPC_FADD_df:
18008 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18009 break;
18010 case OPC_FCUN_df:
18011 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18012 break;
18013 case OPC_FSUB_df:
18014 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18015 break;
18016 case OPC_FCOR_df:
18017 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18018 break;
18019 case OPC_FCEQ_df:
18020 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18021 break;
18022 case OPC_FMUL_df:
18023 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18024 break;
18025 case OPC_FCUNE_df:
18026 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18027 break;
18028 case OPC_FCUEQ_df:
18029 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18030 break;
18031 case OPC_FDIV_df:
18032 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18033 break;
18034 case OPC_FCNE_df:
18035 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18036 break;
18037 case OPC_FCLT_df:
18038 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18039 break;
18040 case OPC_FMADD_df:
18041 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18042 break;
18043 case OPC_MUL_Q_df:
18044 tcg_gen_movi_i32(tdf, df + 1);
18045 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18046 break;
18047 case OPC_FCULT_df:
18048 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18049 break;
18050 case OPC_FMSUB_df:
18051 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18052 break;
18053 case OPC_MADD_Q_df:
18054 tcg_gen_movi_i32(tdf, df + 1);
18055 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18056 break;
18057 case OPC_FCLE_df:
18058 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18059 break;
18060 case OPC_MSUB_Q_df:
18061 tcg_gen_movi_i32(tdf, df + 1);
18062 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18063 break;
18064 case OPC_FCULE_df:
18065 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18066 break;
18067 case OPC_FEXP2_df:
18068 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18069 break;
18070 case OPC_FSAF_df:
18071 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18072 break;
18073 case OPC_FEXDO_df:
18074 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18075 break;
18076 case OPC_FSUN_df:
18077 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18078 break;
18079 case OPC_FSOR_df:
18080 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18081 break;
18082 case OPC_FSEQ_df:
18083 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18084 break;
18085 case OPC_FTQ_df:
18086 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18087 break;
18088 case OPC_FSUNE_df:
18089 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18090 break;
18091 case OPC_FSUEQ_df:
18092 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18093 break;
18094 case OPC_FSNE_df:
18095 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18096 break;
18097 case OPC_FSLT_df:
18098 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18099 break;
18100 case OPC_FMIN_df:
18101 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18102 break;
18103 case OPC_MULR_Q_df:
18104 tcg_gen_movi_i32(tdf, df + 1);
18105 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18106 break;
18107 case OPC_FSULT_df:
18108 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18109 break;
18110 case OPC_FMIN_A_df:
18111 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18112 break;
18113 case OPC_MADDR_Q_df:
18114 tcg_gen_movi_i32(tdf, df + 1);
18115 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18116 break;
18117 case OPC_FSLE_df:
18118 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18119 break;
18120 case OPC_FMAX_df:
18121 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18122 break;
18123 case OPC_MSUBR_Q_df:
18124 tcg_gen_movi_i32(tdf, df + 1);
18125 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18126 break;
18127 case OPC_FSULE_df:
18128 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18129 break;
18130 case OPC_FMAX_A_df:
18131 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18132 break;
18133 default:
18134 MIPS_INVAL("MSA instruction");
18135 generate_exception(ctx, EXCP_RI);
18136 break;
18137 }
18138
18139 tcg_temp_free_i32(twd);
18140 tcg_temp_free_i32(tws);
18141 tcg_temp_free_i32(twt);
18142 tcg_temp_free_i32(tdf);
18143}
18144
cbe50b9a
YK
18145static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18146{
18147#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18148 (op & (0x7 << 18)))
18149 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18150 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18151 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18152 uint8_t df = (ctx->opcode >> 16) & 0x3;
18153 TCGv_i32 twd = tcg_const_i32(wd);
18154 TCGv_i32 tws = tcg_const_i32(ws);
18155 TCGv_i32 twt = tcg_const_i32(wt);
18156 TCGv_i32 tdf = tcg_const_i32(df);
18157
18158 switch (MASK_MSA_2R(ctx->opcode)) {
18159 case OPC_FILL_df:
18160#if !defined(TARGET_MIPS64)
18161 /* Double format valid only for MIPS64 */
18162 if (df == DF_DOUBLE) {
18163 generate_exception(ctx, EXCP_RI);
18164 break;
18165 }
18166#endif
18167 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18168 break;
18169 case OPC_PCNT_df:
18170 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18171 break;
18172 case OPC_NLOC_df:
18173 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18174 break;
18175 case OPC_NLZC_df:
18176 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18177 break;
18178 default:
18179 MIPS_INVAL("MSA instruction");
18180 generate_exception(ctx, EXCP_RI);
18181 break;
18182 }
18183
18184 tcg_temp_free_i32(twd);
18185 tcg_temp_free_i32(tws);
18186 tcg_temp_free_i32(twt);
18187 tcg_temp_free_i32(tdf);
18188}
18189
3bdeb688
YK
18190static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18191{
18192#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18193 (op & (0xf << 17)))
18194 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18195 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18196 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18197 uint8_t df = (ctx->opcode >> 16) & 0x1;
18198 TCGv_i32 twd = tcg_const_i32(wd);
18199 TCGv_i32 tws = tcg_const_i32(ws);
18200 TCGv_i32 twt = tcg_const_i32(wt);
18201 /* adjust df value for floating-point instruction */
18202 TCGv_i32 tdf = tcg_const_i32(df + 2);
18203
18204 switch (MASK_MSA_2RF(ctx->opcode)) {
18205 case OPC_FCLASS_df:
18206 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18207 break;
18208 case OPC_FTRUNC_S_df:
18209 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18210 break;
18211 case OPC_FTRUNC_U_df:
18212 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18213 break;
18214 case OPC_FSQRT_df:
18215 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18216 break;
18217 case OPC_FRSQRT_df:
18218 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18219 break;
18220 case OPC_FRCP_df:
18221 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18222 break;
18223 case OPC_FRINT_df:
18224 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18225 break;
18226 case OPC_FLOG2_df:
18227 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18228 break;
18229 case OPC_FEXUPL_df:
18230 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18231 break;
18232 case OPC_FEXUPR_df:
18233 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18234 break;
18235 case OPC_FFQL_df:
18236 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18237 break;
18238 case OPC_FFQR_df:
18239 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18240 break;
18241 case OPC_FTINT_S_df:
18242 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18243 break;
18244 case OPC_FTINT_U_df:
18245 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18246 break;
18247 case OPC_FFINT_S_df:
18248 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18249 break;
18250 case OPC_FFINT_U_df:
18251 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18252 break;
18253 }
18254
18255 tcg_temp_free_i32(twd);
18256 tcg_temp_free_i32(tws);
18257 tcg_temp_free_i32(twt);
18258 tcg_temp_free_i32(tdf);
18259}
18260
cbe50b9a
YK
18261static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18262{
18263#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18264 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18265 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18266 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18267 TCGv_i32 twd = tcg_const_i32(wd);
18268 TCGv_i32 tws = tcg_const_i32(ws);
18269 TCGv_i32 twt = tcg_const_i32(wt);
18270
18271 switch (MASK_MSA_VEC(ctx->opcode)) {
18272 case OPC_AND_V:
18273 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18274 break;
18275 case OPC_OR_V:
18276 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18277 break;
18278 case OPC_NOR_V:
18279 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18280 break;
18281 case OPC_XOR_V:
18282 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18283 break;
18284 case OPC_BMNZ_V:
18285 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18286 break;
18287 case OPC_BMZ_V:
18288 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18289 break;
18290 case OPC_BSEL_V:
18291 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18292 break;
18293 default:
18294 MIPS_INVAL("MSA instruction");
18295 generate_exception(ctx, EXCP_RI);
18296 break;
18297 }
18298
18299 tcg_temp_free_i32(twd);
18300 tcg_temp_free_i32(tws);
18301 tcg_temp_free_i32(twt);
18302}
18303
18304static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18305{
18306 switch (MASK_MSA_VEC(ctx->opcode)) {
18307 case OPC_AND_V:
18308 case OPC_OR_V:
18309 case OPC_NOR_V:
18310 case OPC_XOR_V:
18311 case OPC_BMNZ_V:
18312 case OPC_BMZ_V:
18313 case OPC_BSEL_V:
18314 gen_msa_vec_v(env, ctx);
18315 break;
18316 case OPC_MSA_2R:
18317 gen_msa_2r(env, ctx);
18318 break;
3bdeb688
YK
18319 case OPC_MSA_2RF:
18320 gen_msa_2rf(env, ctx);
18321 break;
cbe50b9a
YK
18322 default:
18323 MIPS_INVAL("MSA instruction");
18324 generate_exception(ctx, EXCP_RI);
18325 break;
18326 }
18327}
18328
4c789546
YK
18329static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18330{
18331 uint32_t opcode = ctx->opcode;
18332 check_insn(ctx, ASE_MSA);
18333 check_msa_access(ctx);
18334
18335 switch (MASK_MSA_MINOR(opcode)) {
18336 case OPC_MSA_I8_00:
18337 case OPC_MSA_I8_01:
18338 case OPC_MSA_I8_02:
18339 gen_msa_i8(env, ctx);
18340 break;
80e71591
YK
18341 case OPC_MSA_I5_06:
18342 case OPC_MSA_I5_07:
18343 gen_msa_i5(env, ctx);
18344 break;
d4cf28de
YK
18345 case OPC_MSA_BIT_09:
18346 case OPC_MSA_BIT_0A:
18347 gen_msa_bit(env, ctx);
18348 break;
28f99f08
YK
18349 case OPC_MSA_3R_0D:
18350 case OPC_MSA_3R_0E:
18351 case OPC_MSA_3R_0F:
18352 case OPC_MSA_3R_10:
18353 case OPC_MSA_3R_11:
18354 case OPC_MSA_3R_12:
18355 case OPC_MSA_3R_13:
18356 case OPC_MSA_3R_14:
18357 case OPC_MSA_3R_15:
18358 gen_msa_3r(env, ctx);
18359 break;
1e608ec1
YK
18360 case OPC_MSA_ELM:
18361 gen_msa_elm(env, ctx);
18362 break;
7d05b9c8
YK
18363 case OPC_MSA_3RF_1A:
18364 case OPC_MSA_3RF_1B:
18365 case OPC_MSA_3RF_1C:
18366 gen_msa_3rf(env, ctx);
18367 break;
cbe50b9a
YK
18368 case OPC_MSA_VEC:
18369 gen_msa_vec(env, ctx);
18370 break;
f7685877
YK
18371 case OPC_LD_B:
18372 case OPC_LD_H:
18373 case OPC_LD_W:
18374 case OPC_LD_D:
18375 case OPC_ST_B:
18376 case OPC_ST_H:
18377 case OPC_ST_W:
18378 case OPC_ST_D:
18379 {
18380 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18381 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18382 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18383 uint8_t df = (ctx->opcode >> 0) & 0x3;
18384
18385 TCGv_i32 tdf = tcg_const_i32(df);
18386 TCGv_i32 twd = tcg_const_i32(wd);
18387 TCGv_i32 trs = tcg_const_i32(rs);
18388 TCGv_i32 ts10 = tcg_const_i32(s10);
18389
18390 switch (MASK_MSA_MINOR(opcode)) {
18391 case OPC_LD_B:
18392 case OPC_LD_H:
18393 case OPC_LD_W:
18394 case OPC_LD_D:
18395 gen_helper_msa_ld_df(cpu_env, tdf, twd, trs, ts10);
18396 break;
18397 case OPC_ST_B:
18398 case OPC_ST_H:
18399 case OPC_ST_W:
18400 case OPC_ST_D:
18401 gen_helper_msa_st_df(cpu_env, tdf, twd, trs, ts10);
18402 break;
18403 }
18404
18405 tcg_temp_free_i32(twd);
18406 tcg_temp_free_i32(tdf);
18407 tcg_temp_free_i32(trs);
18408 tcg_temp_free_i32(ts10);
18409 }
18410 break;
4c789546
YK
18411 default:
18412 MIPS_INVAL("MSA instruction");
18413 generate_exception(ctx, EXCP_RI);
18414 break;
18415 }
18416
18417}
18418
d2bfa6e6 18419static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18420{
18421 int32_t offset;
18422 int rs, rt, rd, sa;
18423 uint32_t op, op1;
18424 int16_t imm;
18425
18426 /* make sure instructions are on a word boundary */
18427 if (ctx->pc & 0x3) {
18428 env->CP0_BadVAddr = ctx->pc;
aea14095 18429 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
18430 return;
18431 }
18432
18433 /* Handle blikely not taken case */
18434 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18435 int l1 = gen_new_label();
18436
18437 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
18438 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18439 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18440 gen_goto_tb(ctx, 1, ctx->pc + 4);
18441 gen_set_label(l1);
18442 }
18443
18444 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
18445 tcg_gen_debug_insn_start(ctx->pc);
18446 }
18447
18448 op = MASK_OP_MAJOR(ctx->opcode);
18449 rs = (ctx->opcode >> 21) & 0x1f;
18450 rt = (ctx->opcode >> 16) & 0x1f;
18451 rd = (ctx->opcode >> 11) & 0x1f;
18452 sa = (ctx->opcode >> 6) & 0x1f;
18453 imm = (int16_t)ctx->opcode;
18454 switch (op) {
18455 case OPC_SPECIAL:
18456 decode_opc_special(env, ctx);
18457 break;
18458 case OPC_SPECIAL2:
4267d3e6 18459 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
18460 break;
18461 case OPC_SPECIAL3:
18462 decode_opc_special3(env, ctx);
18463 break;
7a387fff
TS
18464 case OPC_REGIMM:
18465 op1 = MASK_REGIMM(ctx->opcode);
18466 switch (op1) {
fecd2646
LA
18467 case OPC_BLTZL: /* REGIMM branches */
18468 case OPC_BGEZL:
18469 case OPC_BLTZALL:
18470 case OPC_BGEZALL:
d9224450 18471 check_insn(ctx, ISA_MIPS2);
fecd2646 18472 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18473 /* Fallthrough */
fecd2646
LA
18474 case OPC_BLTZ:
18475 case OPC_BGEZ:
b231c103 18476 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18477 break;
fecd2646
LA
18478 case OPC_BLTZAL:
18479 case OPC_BGEZAL:
0aefa333
YK
18480 if (ctx->insn_flags & ISA_MIPS32R6) {
18481 if (rs == 0) {
18482 /* OPC_NAL, OPC_BAL */
b231c103 18483 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
18484 } else {
18485 generate_exception(ctx, EXCP_RI);
18486 }
18487 } else {
b231c103 18488 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 18489 }
c9602061 18490 break;
7a387fff
TS
18491 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18492 case OPC_TNEI:
d9224450 18493 check_insn(ctx, ISA_MIPS2);
fecd2646 18494 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
18495 gen_trap(ctx, op1, rs, -1, imm);
18496 break;
18497 case OPC_SYNCI:
d75c135e 18498 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
18499 /* Break the TB to be able to sync copied instructions
18500 immediately */
18501 ctx->bstate = BS_STOP;
6af0bf9c 18502 break;
e45a93e2
JL
18503 case OPC_BPOSGE32: /* MIPS DSP branch */
18504#if defined(TARGET_MIPS64)
18505 case OPC_BPOSGE64:
18506#endif
18507 check_dsp(ctx);
b231c103 18508 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 18509 break;
d4ea6acd
LA
18510#if defined(TARGET_MIPS64)
18511 case OPC_DAHI:
18512 check_insn(ctx, ISA_MIPS32R6);
18513 check_mips_64(ctx);
18514 if (rs != 0) {
18515 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18516 }
18517 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
18518 break;
18519 case OPC_DATI:
18520 check_insn(ctx, ISA_MIPS32R6);
18521 check_mips_64(ctx);
18522 if (rs != 0) {
18523 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18524 }
18525 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
18526 break;
18527#endif
6af0bf9c 18528 default: /* Invalid */
923617a3 18529 MIPS_INVAL("regimm");
6af0bf9c
FB
18530 generate_exception(ctx, EXCP_RI);
18531 break;
18532 }
18533 break;
7a387fff 18534 case OPC_CP0:
387a8fe5 18535 check_cp0_enabled(ctx);
7a387fff 18536 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 18537 switch (op1) {
7a387fff
TS
18538 case OPC_MFC0:
18539 case OPC_MTC0:
ead9360e
TS
18540 case OPC_MFTR:
18541 case OPC_MTTR:
d26bc211 18542#if defined(TARGET_MIPS64)
7a387fff
TS
18543 case OPC_DMFC0:
18544 case OPC_DMTC0:
18545#endif
f1aa6320 18546#ifndef CONFIG_USER_ONLY
932e71cd 18547 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 18548#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18549 break;
18550 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 18551#ifndef CONFIG_USER_ONLY
932e71cd 18552 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 18553#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
18554 break;
18555 case OPC_MFMC0:
8706c382 18556#ifndef CONFIG_USER_ONLY
932e71cd 18557 {
099e5b4d 18558 uint32_t op2;
35fbce2c 18559 TCGv t0 = tcg_temp_new();
6c5c1e20 18560
0eaef5aa 18561 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
18562 switch (op2) {
18563 case OPC_DMT:
d75c135e 18564 check_insn(ctx, ASE_MT);
9ed5726c 18565 gen_helper_dmt(t0);
35fbce2c 18566 gen_store_gpr(t0, rt);
6c5c1e20
TS
18567 break;
18568 case OPC_EMT:
d75c135e 18569 check_insn(ctx, ASE_MT);
9ed5726c 18570 gen_helper_emt(t0);
35fbce2c 18571 gen_store_gpr(t0, rt);
da80682b 18572 break;
6c5c1e20 18573 case OPC_DVPE:
d75c135e 18574 check_insn(ctx, ASE_MT);
895c2d04 18575 gen_helper_dvpe(t0, cpu_env);
35fbce2c 18576 gen_store_gpr(t0, rt);
6c5c1e20
TS
18577 break;
18578 case OPC_EVPE:
d75c135e 18579 check_insn(ctx, ASE_MT);
895c2d04 18580 gen_helper_evpe(t0, cpu_env);
35fbce2c 18581 gen_store_gpr(t0, rt);
6c5c1e20
TS
18582 break;
18583 case OPC_DI:
d75c135e 18584 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18585 save_cpu_state(ctx, 1);
895c2d04 18586 gen_helper_di(t0, cpu_env);
35fbce2c 18587 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18588 /* Stop translation as we may have switched
18589 the execution mode. */
6c5c1e20
TS
18590 ctx->bstate = BS_STOP;
18591 break;
18592 case OPC_EI:
d75c135e 18593 check_insn(ctx, ISA_MIPS32R2);
867abc7e 18594 save_cpu_state(ctx, 1);
895c2d04 18595 gen_helper_ei(t0, cpu_env);
35fbce2c 18596 gen_store_gpr(t0, rt);
d2bfa6e6
MR
18597 /* Stop translation as we may have switched
18598 the execution mode. */
6c5c1e20
TS
18599 ctx->bstate = BS_STOP;
18600 break;
18601 default: /* Invalid */
18602 MIPS_INVAL("mfmc0");
18603 generate_exception(ctx, EXCP_RI);
18604 break;
18605 }
6c5c1e20 18606 tcg_temp_free(t0);
7a387fff 18607 }
0eaef5aa 18608#endif /* !CONFIG_USER_ONLY */
6af0bf9c 18609 break;
7a387fff 18610 case OPC_RDPGPR:
d75c135e 18611 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18612 gen_load_srsgpr(rt, rd);
ead9360e 18613 break;
7a387fff 18614 case OPC_WRPGPR:
d75c135e 18615 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 18616 gen_store_srsgpr(rt, rd);
38121543 18617 break;
6af0bf9c 18618 default:
923617a3 18619 MIPS_INVAL("cp0");
7a387fff 18620 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
18621 break;
18622 }
18623 break;
31837be3
YK
18624 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18625 if (ctx->insn_flags & ISA_MIPS32R6) {
18626 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18627 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18628 } else {
18629 /* OPC_ADDI */
18630 /* Arithmetic with immediate opcode */
18631 gen_arith_imm(ctx, op, rt, rs, imm);
18632 }
18633 break;
324d9e32 18634 case OPC_ADDIU:
d75c135e 18635 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 18636 break;
324d9e32
AJ
18637 case OPC_SLTI: /* Set on less than with immediate opcode */
18638 case OPC_SLTIU:
d75c135e 18639 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
18640 break;
18641 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 18642 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
18643 case OPC_ORI:
18644 case OPC_XORI:
d75c135e 18645 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 18646 break;
7a387fff
TS
18647 case OPC_J ... OPC_JAL: /* Jump */
18648 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 18649 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 18650 break;
31837be3
YK
18651 /* Branch */
18652 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18653 if (ctx->insn_flags & ISA_MIPS32R6) {
18654 if (rt == 0) {
18655 generate_exception(ctx, EXCP_RI);
18656 break;
18657 }
18658 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18659 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18660 } else {
18661 /* OPC_BLEZL */
b231c103 18662 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18663 }
18664 break;
18665 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18666 if (ctx->insn_flags & ISA_MIPS32R6) {
18667 if (rt == 0) {
18668 generate_exception(ctx, EXCP_RI);
18669 break;
18670 }
18671 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18672 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18673 } else {
18674 /* OPC_BGTZL */
b231c103 18675 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18676 }
18677 break;
18678 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18679 if (rt == 0) {
18680 /* OPC_BLEZ */
b231c103 18681 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18682 } else {
18683 check_insn(ctx, ISA_MIPS32R6);
18684 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18685 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18686 }
18687 break;
18688 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18689 if (rt == 0) {
18690 /* OPC_BGTZ */
b231c103 18691 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
18692 } else {
18693 check_insn(ctx, ISA_MIPS32R6);
18694 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18695 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
18696 }
18697 break;
18698 case OPC_BEQL:
18699 case OPC_BNEL:
d9224450 18700 check_insn(ctx, ISA_MIPS2);
fecd2646 18701 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18702 /* Fallthrough */
31837be3
YK
18703 case OPC_BEQ:
18704 case OPC_BNE:
b231c103 18705 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 18706 break;
d9224450
MR
18707 case OPC_LL: /* Load and stores */
18708 check_insn(ctx, ISA_MIPS2);
18709 /* Fallthrough */
18710 case OPC_LWL:
fecd2646
LA
18711 case OPC_LWR:
18712 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 18713 /* Fallthrough */
fecd2646
LA
18714 case OPC_LB ... OPC_LH:
18715 case OPC_LW ... OPC_LHU:
d75c135e 18716 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 18717 break;
fecd2646 18718 case OPC_SWL:
7a387fff 18719 case OPC_SWR:
fecd2646
LA
18720 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18721 case OPC_SB ... OPC_SH:
18722 case OPC_SW:
5c13fdfd 18723 gen_st(ctx, op, rt, rs, imm);
7a387fff 18724 break;
d66c7132 18725 case OPC_SC:
d9224450 18726 check_insn(ctx, ISA_MIPS2);
4368b29a 18727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
18728 gen_st_cond(ctx, op, rt, rs, imm);
18729 break;
7a387fff 18730 case OPC_CACHE:
bf7910c6 18731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 18732 check_cp0_enabled(ctx);
d75c135e 18733 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 18734 /* Treat as NOP. */
34ae7b51 18735 break;
7a387fff 18736 case OPC_PREF:
bf7910c6 18737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 18738 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 18739 /* Treat as NOP. */
6af0bf9c 18740 break;
4ad40f36 18741
923617a3 18742 /* Floating point (COP1). */
7a387fff
TS
18743 case OPC_LWC1:
18744 case OPC_LDC1:
18745 case OPC_SWC1:
18746 case OPC_SDC1:
5ab5c041 18747 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
18748 break;
18749
7a387fff 18750 case OPC_CP1:
5692c6e1
YK
18751 op1 = MASK_CP1(ctx->opcode);
18752
18753 switch (op1) {
18754 case OPC_MFHC1:
18755 case OPC_MTHC1:
5e755519 18756 check_cp1_enabled(ctx);
5692c6e1
YK
18757 check_insn(ctx, ISA_MIPS32R2);
18758 case OPC_MFC1:
18759 case OPC_CFC1:
18760 case OPC_MTC1:
18761 case OPC_CTC1:
18762 check_cp1_enabled(ctx);
18763 gen_cp1(ctx, op1, rt, rd);
18764 break;
d26bc211 18765#if defined(TARGET_MIPS64)
5692c6e1
YK
18766 case OPC_DMFC1:
18767 case OPC_DMTC1:
18768 check_cp1_enabled(ctx);
18769 check_insn(ctx, ISA_MIPS3);
d9224450 18770 check_mips_64(ctx);
5692c6e1
YK
18771 gen_cp1(ctx, op1, rt, rd);
18772 break;
e189e748 18773#endif
5692c6e1
YK
18774 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
18775 check_cp1_enabled(ctx);
18776 if (ctx->insn_flags & ISA_MIPS32R6) {
18777 /* OPC_BC1EQZ */
31837be3
YK
18778 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18779 rt, imm << 2);
5692c6e1
YK
18780 } else {
18781 /* OPC_BC1ANY2 */
b8aa4598 18782 check_cop1x(ctx);
d75c135e 18783 check_insn(ctx, ASE_MIPS3D);
d75c135e 18784 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 18785 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
18786 }
18787 break;
18788 case OPC_BC1NEZ:
18789 check_cp1_enabled(ctx);
18790 check_insn(ctx, ISA_MIPS32R6);
18791 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
18792 rt, imm << 2);
18793 break;
18794 case OPC_BC1ANY4:
18795 check_cp1_enabled(ctx);
18796 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18797 check_cop1x(ctx);
18798 check_insn(ctx, ASE_MIPS3D);
18799 /* fall through */
18800 case OPC_BC1:
18801 check_cp1_enabled(ctx);
18802 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18803 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
18804 (rt >> 2) & 0x7, imm << 2);
18805 break;
18806 case OPC_PS_FMT:
18807 check_cp1_enabled(ctx);
18808 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18809 case OPC_S_FMT:
18810 case OPC_D_FMT:
18811 check_cp1_enabled(ctx);
18812 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18813 (imm >> 8) & 0x7);
18814 break;
18815 case OPC_W_FMT:
18816 case OPC_L_FMT:
18817 {
18818 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
18819 check_cp1_enabled(ctx);
18820 if (ctx->insn_flags & ISA_MIPS32R6) {
18821 switch (r6_op) {
18822 case R6_OPC_CMP_AF_S:
18823 case R6_OPC_CMP_UN_S:
18824 case R6_OPC_CMP_EQ_S:
18825 case R6_OPC_CMP_UEQ_S:
18826 case R6_OPC_CMP_LT_S:
18827 case R6_OPC_CMP_ULT_S:
18828 case R6_OPC_CMP_LE_S:
18829 case R6_OPC_CMP_ULE_S:
18830 case R6_OPC_CMP_SAF_S:
18831 case R6_OPC_CMP_SUN_S:
18832 case R6_OPC_CMP_SEQ_S:
18833 case R6_OPC_CMP_SEUQ_S:
18834 case R6_OPC_CMP_SLT_S:
18835 case R6_OPC_CMP_SULT_S:
18836 case R6_OPC_CMP_SLE_S:
18837 case R6_OPC_CMP_SULE_S:
18838 case R6_OPC_CMP_OR_S:
18839 case R6_OPC_CMP_UNE_S:
18840 case R6_OPC_CMP_NE_S:
18841 case R6_OPC_CMP_SOR_S:
18842 case R6_OPC_CMP_SUNE_S:
18843 case R6_OPC_CMP_SNE_S:
18844 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18845 break;
18846 case R6_OPC_CMP_AF_D:
18847 case R6_OPC_CMP_UN_D:
18848 case R6_OPC_CMP_EQ_D:
18849 case R6_OPC_CMP_UEQ_D:
18850 case R6_OPC_CMP_LT_D:
18851 case R6_OPC_CMP_ULT_D:
18852 case R6_OPC_CMP_LE_D:
18853 case R6_OPC_CMP_ULE_D:
18854 case R6_OPC_CMP_SAF_D:
18855 case R6_OPC_CMP_SUN_D:
18856 case R6_OPC_CMP_SEQ_D:
18857 case R6_OPC_CMP_SEUQ_D:
18858 case R6_OPC_CMP_SLT_D:
18859 case R6_OPC_CMP_SULT_D:
18860 case R6_OPC_CMP_SLE_D:
18861 case R6_OPC_CMP_SULE_D:
18862 case R6_OPC_CMP_OR_D:
18863 case R6_OPC_CMP_UNE_D:
18864 case R6_OPC_CMP_NE_D:
18865 case R6_OPC_CMP_SOR_D:
18866 case R6_OPC_CMP_SUNE_D:
18867 case R6_OPC_CMP_SNE_D:
18868 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
18869 break;
18870 default:
d2bfa6e6
MR
18871 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
18872 rt, rd, sa, (imm >> 8) & 0x7);
18873
5692c6e1 18874 break;
3f493883 18875 }
5692c6e1
YK
18876 } else {
18877 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
18878 (imm >> 8) & 0x7);
36d23958 18879 }
5692c6e1
YK
18880 break;
18881 }
18882 case OPC_BZ_V:
18883 case OPC_BNZ_V:
18884 case OPC_BZ_B:
18885 case OPC_BZ_H:
18886 case OPC_BZ_W:
18887 case OPC_BZ_D:
18888 case OPC_BNZ_B:
18889 case OPC_BNZ_H:
18890 case OPC_BNZ_W:
18891 case OPC_BNZ_D:
18892 check_insn(ctx, ASE_MSA);
18893 gen_msa_branch(env, ctx, op1);
18894 break;
18895 default:
18896 MIPS_INVAL("cp1");
18897 generate_exception(ctx, EXCP_RI);
18898 break;
6ea83fed 18899 }
4ad40f36
FB
18900 break;
18901
31837be3
YK
18902 /* Compact branches [R6] and COP2 [non-R6] */
18903 case OPC_BC: /* OPC_LWC2 */
18904 case OPC_BALC: /* OPC_SWC2 */
18905 if (ctx->insn_flags & ISA_MIPS32R6) {
18906 /* OPC_BC, OPC_BALC */
18907 gen_compute_compact_branch(ctx, op, 0, 0,
18908 sextract32(ctx->opcode << 2, 0, 28));
18909 } else {
18910 /* OPC_LWC2, OPC_SWC2 */
18911 /* COP2: Not implemented. */
18912 generate_exception_err(ctx, EXCP_CpU, 2);
18913 }
18914 break;
18915 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
18916 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
18917 if (ctx->insn_flags & ISA_MIPS32R6) {
18918 if (rs != 0) {
18919 /* OPC_BEQZC, OPC_BNEZC */
18920 gen_compute_compact_branch(ctx, op, rs, 0,
18921 sextract32(ctx->opcode << 2, 0, 23));
18922 } else {
18923 /* OPC_JIC, OPC_JIALC */
18924 gen_compute_compact_branch(ctx, op, 0, rt, imm);
18925 }
18926 } else {
18927 /* OPC_LWC2, OPC_SWC2 */
18928 /* COP2: Not implemented. */
18929 generate_exception_err(ctx, EXCP_CpU, 2);
18930 }
4ad40f36 18931 break;
bd277fa1 18932 case OPC_CP2:
d75c135e 18933 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
18934 /* Note that these instructions use different fields. */
18935 gen_loongson_multimedia(ctx, sa, rd, rt);
18936 break;
4ad40f36 18937
7a387fff 18938 case OPC_CP3:
fecd2646 18939 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 18940 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 18941 check_cp1_enabled(ctx);
36d23958
TS
18942 op1 = MASK_CP3(ctx->opcode);
18943 switch (op1) {
d9224450
MR
18944 case OPC_LUXC1:
18945 case OPC_SUXC1:
18946 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
18947 /* Fallthrough */
5a5012ec
TS
18948 case OPC_LWXC1:
18949 case OPC_LDXC1:
5a5012ec
TS
18950 case OPC_SWXC1:
18951 case OPC_SDXC1:
d9224450 18952 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 18953 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 18954 break;
e0c84da7 18955 case OPC_PREFX:
d9224450 18956 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 18957 /* Treat as NOP. */
e0c84da7 18958 break;
5a5012ec 18959 case OPC_ALNV_PS:
d9224450
MR
18960 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
18961 /* Fallthrough */
5a5012ec
TS
18962 case OPC_MADD_S:
18963 case OPC_MADD_D:
18964 case OPC_MADD_PS:
18965 case OPC_MSUB_S:
18966 case OPC_MSUB_D:
18967 case OPC_MSUB_PS:
18968 case OPC_NMADD_S:
18969 case OPC_NMADD_D:
18970 case OPC_NMADD_PS:
18971 case OPC_NMSUB_S:
18972 case OPC_NMSUB_D:
18973 case OPC_NMSUB_PS:
d9224450 18974 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
18975 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
18976 break;
36d23958 18977 default:
923617a3 18978 MIPS_INVAL("cp3");
e397ee33 18979 generate_exception (ctx, EXCP_RI);
36d23958
TS
18980 break;
18981 }
18982 } else {
e397ee33 18983 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 18984 }
4ad40f36
FB
18985 break;
18986
d26bc211 18987#if defined(TARGET_MIPS64)
7a387fff 18988 /* MIPS64 opcodes */
7a387fff 18989 case OPC_LDL ... OPC_LDR:
bf7910c6 18990 case OPC_LLD:
fecd2646
LA
18991 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18992 case OPC_LWU:
7a387fff 18993 case OPC_LD:
d75c135e 18994 check_insn(ctx, ISA_MIPS3);
5c13fdfd 18995 check_mips_64(ctx);
d75c135e 18996 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
18997 break;
18998 case OPC_SDL ... OPC_SDR:
fecd2646 18999 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 19000 case OPC_SD:
d75c135e 19001 check_insn(ctx, ISA_MIPS3);
e189e748 19002 check_mips_64(ctx);
5c13fdfd 19003 gen_st(ctx, op, rt, rs, imm);
7a387fff 19004 break;
d66c7132 19005 case OPC_SCD:
bf7910c6 19006 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19007 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
19008 check_mips_64(ctx);
19009 gen_st_cond(ctx, op, rt, rs, imm);
19010 break;
31837be3
YK
19011 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19012 if (ctx->insn_flags & ISA_MIPS32R6) {
19013 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19014 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19015 } else {
19016 /* OPC_DADDI */
19017 check_insn(ctx, ISA_MIPS3);
19018 check_mips_64(ctx);
19019 gen_arith_imm(ctx, op, rt, rs, imm);
19020 }
19021 break;
324d9e32 19022 case OPC_DADDIU:
d75c135e 19023 check_insn(ctx, ISA_MIPS3);
e189e748 19024 check_mips_64(ctx);
d75c135e 19025 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19026 break;
31837be3
YK
19027#else
19028 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19029 if (ctx->insn_flags & ISA_MIPS32R6) {
19030 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19031 } else {
19032 MIPS_INVAL("major opcode");
19033 generate_exception(ctx, EXCP_RI);
19034 }
19035 break;
6af0bf9c 19036#endif
d4ea6acd
LA
19037 case OPC_DAUI: /* OPC_JALX */
19038 if (ctx->insn_flags & ISA_MIPS32R6) {
19039#if defined(TARGET_MIPS64)
19040 /* OPC_DAUI */
19041 check_mips_64(ctx);
19042 if (rt != 0) {
19043 TCGv t0 = tcg_temp_new();
19044 gen_load_gpr(t0, rs);
19045 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19046 tcg_temp_free(t0);
19047 }
19048 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
19049#else
19050 generate_exception(ctx, EXCP_RI);
19051 MIPS_INVAL("major opcode");
19052#endif
19053 } else {
19054 /* OPC_JALX */
19055 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19056 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19057 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 19058 }
364d4831 19059 break;
4c789546 19060 case OPC_MSA: /* OPC_MDMX */
7a387fff 19061 /* MDMX: Not implemented. */
4c789546 19062 gen_msa(env, ctx);
d4ea6acd
LA
19063 break;
19064 case OPC_PCREL:
19065 check_insn(ctx, ISA_MIPS32R6);
19066 gen_pcrel(ctx, rs, imm);
19067 break;
6af0bf9c 19068 default: /* Invalid */
923617a3 19069 MIPS_INVAL("major opcode");
6af0bf9c
FB
19070 generate_exception(ctx, EXCP_RI);
19071 break;
19072 }
6af0bf9c
FB
19073}
19074
2cfc5f17 19075static inline void
6429db34
AF
19076gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19077 bool search_pc)
6af0bf9c 19078{
ed2803da 19079 CPUState *cs = CPU(cpu);
6429db34 19080 CPUMIPSState *env = &cpu->env;
278d0702 19081 DisasContext ctx;
6af0bf9c
FB
19082 target_ulong pc_start;
19083 uint16_t *gen_opc_end;
a1d1bb31 19084 CPUBreakpoint *bp;
6af0bf9c 19085 int j, lj = -1;
2e70f6ef
PB
19086 int num_insns;
19087 int max_insns;
c9602061 19088 int insn_bytes;
339cd2a8 19089 int is_slot;
6af0bf9c 19090
93fcfe39
AL
19091 if (search_pc)
19092 qemu_log("search pc %d\n", search_pc);
4ad40f36 19093
6af0bf9c 19094 pc_start = tb->pc;
92414b31 19095 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 19096 ctx.pc = pc_start;
4ad40f36 19097 ctx.saved_pc = -1;
ed2803da 19098 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 19099 ctx.insn_flags = env->insn_flags;
5ab5c041 19100 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
19101 ctx.tb = tb;
19102 ctx.bstate = BS_NONE;
e98c0d17 19103 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 19104 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 19105 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
19106 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19107 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
4ad40f36 19108 /* Restore delay slot state from the tb context. */
c068688b 19109 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 19110 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 19111 restore_cpu_state(env, &ctx);
932e71cd 19112#ifdef CONFIG_USER_ONLY
0eaef5aa 19113 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 19114#else
0eaef5aa 19115 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 19116#endif
2e70f6ef
PB
19117 num_insns = 0;
19118 max_insns = tb->cflags & CF_COUNT_MASK;
19119 if (max_insns == 0)
19120 max_insns = CF_COUNT_MASK;
d12d51d5 19121 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 19122 gen_tb_start();
faf7aaa9 19123 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
19124 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
19125 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 19126 if (bp->pc == ctx.pc) {
278d0702 19127 save_cpu_state(&ctx, 1);
4ad40f36 19128 ctx.bstate = BS_BRANCH;
895c2d04 19129 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
19130 /* Include the breakpoint location or the tb won't
19131 * be flushed when it must be. */
19132 ctx.pc += 4;
4ad40f36
FB
19133 goto done_generating;
19134 }
19135 }
19136 }
19137
6af0bf9c 19138 if (search_pc) {
92414b31 19139 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
19140 if (lj < j) {
19141 lj++;
19142 while (lj < j)
ab1103de 19143 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 19144 }
25983cad 19145 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 19146 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 19147 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 19148 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 19149 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 19150 }
2e70f6ef
PB
19151 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
19152 gen_io_start();
c9602061 19153
339cd2a8 19154 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 19155 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 19156 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 19157 insn_bytes = 4;
240ce26a 19158 decode_opc(env, &ctx);
d75c135e 19159 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 19160 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19161 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 19162 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 19163 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 19164 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
19165 } else {
19166 generate_exception(&ctx, EXCP_RI);
3c824109 19167 ctx.bstate = BS_STOP;
c9602061
NF
19168 break;
19169 }
31837be3 19170
b231c103 19171 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
19172 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19173 MIPS_HFLAG_FBNSLOT))) {
19174 /* force to generate branch as there is neither delay nor
19175 forbidden slot */
19176 is_slot = 1;
b231c103
YK
19177 }
19178 }
339cd2a8 19179 if (is_slot) {
31837be3 19180 gen_branch(&ctx, insn_bytes);
c9602061
NF
19181 }
19182 ctx.pc += insn_bytes;
19183
2e70f6ef 19184 num_insns++;
4ad40f36 19185
7b270ef2
NF
19186 /* Execute a branch and its delay slot as a single instruction.
19187 This is what GDB expects and is consistent with what the
19188 hardware does (e.g. if a delay slot instruction faults, the
19189 reported PC is the PC of the branch). */
ed2803da 19190 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 19191 break;
ed2803da 19192 }
4ad40f36 19193
6af0bf9c
FB
19194 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
19195 break;
4ad40f36 19196
efd7f486 19197 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 19198 break;
efd7f486 19199 }
faf7aaa9 19200
2e70f6ef
PB
19201 if (num_insns >= max_insns)
19202 break;
1b530a6d
AJ
19203
19204 if (singlestep)
19205 break;
6af0bf9c 19206 }
ed2803da 19207 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 19208 gen_io_end();
ed2803da
AF
19209 }
19210 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
342368af 19211 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
895c2d04 19212 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 19213 } else {
6958549d 19214 switch (ctx.bstate) {
16c00cb2 19215 case BS_STOP:
df1561e2
TS
19216 gen_goto_tb(&ctx, 0, ctx.pc);
19217 break;
16c00cb2 19218 case BS_NONE:
278d0702 19219 save_cpu_state(&ctx, 0);
16c00cb2
TS
19220 gen_goto_tb(&ctx, 0, ctx.pc);
19221 break;
5a5012ec 19222 case BS_EXCP:
57fec1fe 19223 tcg_gen_exit_tb(0);
16c00cb2 19224 break;
5a5012ec
TS
19225 case BS_BRANCH:
19226 default:
19227 break;
6958549d 19228 }
6af0bf9c 19229 }
4ad40f36 19230done_generating:
806f352d 19231 gen_tb_end(tb, num_insns);
efd7f486 19232 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 19233 if (search_pc) {
92414b31 19234 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
19235 lj++;
19236 while (lj <= j)
ab1103de 19237 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
19238 } else {
19239 tb->size = ctx.pc - pc_start;
2e70f6ef 19240 tb->icount = num_insns;
6af0bf9c
FB
19241 }
19242#ifdef DEBUG_DISAS
d12d51d5 19243 LOG_DISAS("\n");
8fec2b8c 19244 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 19245 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 19246 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 19247 qemu_log("\n");
6af0bf9c
FB
19248 }
19249#endif
6af0bf9c
FB
19250}
19251
7db13fae 19252void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19253{
6429db34 19254 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
19255}
19256
7db13fae 19257void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 19258{
6429db34 19259 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
19260}
19261
7db13fae 19262static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 19263 int flags)
6ea83fed
FB
19264{
19265 int i;
5e755519 19266 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 19267
2a5612e6
SW
19268#define printfpr(fp) \
19269 do { \
19270 if (is_fpu64) \
19271 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19272 " fd:%13g fs:%13g psu: %13g\n", \
19273 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19274 (double)(fp)->fd, \
19275 (double)(fp)->fs[FP_ENDIAN_IDX], \
19276 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19277 else { \
19278 fpr_t tmp; \
19279 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19280 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19281 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19282 " fd:%13g fs:%13g psu:%13g\n", \
19283 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19284 (double)tmp.fd, \
19285 (double)tmp.fs[FP_ENDIAN_IDX], \
19286 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19287 } \
6ea83fed
FB
19288 } while(0)
19289
5a5012ec 19290
9a78eead
SW
19291 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19292 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 19293 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
19294 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19295 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 19296 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
19297 }
19298
19299#undef printfpr
19300}
19301
d26bc211 19302#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 19303/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 19304 sign-extended values on 64bit machines. */
c570fd16
TS
19305
19306#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19307
8706c382 19308static void
7db13fae 19309cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 19310 fprintf_function cpu_fprintf,
8706c382 19311 int flags)
c570fd16
TS
19312{
19313 int i;
19314
b5dc7732
TS
19315 if (!SIGN_EXT_P(env->active_tc.PC))
19316 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
19317 if (!SIGN_EXT_P(env->active_tc.HI[0]))
19318 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
19319 if (!SIGN_EXT_P(env->active_tc.LO[0]))
19320 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 19321 if (!SIGN_EXT_P(env->btarget))
3594c774 19322 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
19323
19324 for (i = 0; i < 32; i++) {
b5dc7732
TS
19325 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
19326 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
19327 }
19328
19329 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 19330 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
19331 if (!SIGN_EXT_P(env->lladdr))
19332 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
19333}
19334#endif
19335
878096ee
AF
19336void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19337 int flags)
6af0bf9c 19338{
878096ee
AF
19339 MIPSCPU *cpu = MIPS_CPU(cs);
19340 CPUMIPSState *env = &cpu->env;
6af0bf9c 19341 int i;
3b46e624 19342
a7200c9f
SW
19343 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19344 " LO=0x" TARGET_FMT_lx " ds %04x "
19345 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
19346 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19347 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
19348 for (i = 0; i < 32; i++) {
19349 if ((i & 3) == 0)
19350 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 19351 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
19352 if ((i & 3) == 3)
19353 cpu_fprintf(f, "\n");
19354 }
568b600d 19355
3594c774 19356 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 19357 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 19358 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 19359 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
19360 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19361 env->CP0_Config2, env->CP0_Config3);
19362 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19363 env->CP0_Config4, env->CP0_Config5);
5e755519 19364 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 19365 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 19366#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
19367 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
19368#endif
6af0bf9c
FB
19369}
19370
78ce64f4 19371void mips_tcg_init(void)
39454628 19372{
f01be154 19373 int i;
39454628
TS
19374 static int inited;
19375
19376 /* Initialize various static tables. */
19377 if (inited)
6958549d 19378 return;
39454628 19379
a7812ae4 19380 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 19381 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 19382 for (i = 1; i < 32; i++)
a7812ae4 19383 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19384 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 19385 regnames[i]);
d73ee8a2 19386
863f264d
YK
19387 for (i = 0; i < 32; i++) {
19388 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19389 msa_wr_d[i * 2] =
19390 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
cb269f27
YK
19391 /* The scalar floating-point unit (FPU) registers are mapped on
19392 * the MSA vector registers. */
19393 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
19394 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19395 msa_wr_d[i * 2 + 1] =
19396 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19397 }
19398
a7812ae4 19399 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 19400 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 19401 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 19402 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19403 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 19404 regnames_HI[i]);
a7812ae4 19405 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 19406 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 19407 regnames_LO[i]);
4b2eb8d2 19408 }
a7812ae4 19409 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 19410 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 19411 "DSPControl");
1ba74fb8 19412 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 19413 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 19414 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 19415 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 19416 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19417 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 19418
a7812ae4 19419 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19420 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
19421 "fcr0");
19422 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 19423 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 19424 "fcr31");
39454628
TS
19425
19426 inited = 1;
19427}
19428
aaed909a
FB
19429#include "translate_init.c"
19430
30bf942d 19431MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 19432{
0f71a709 19433 MIPSCPU *cpu;
6af0bf9c 19434 CPUMIPSState *env;
c227f099 19435 const mips_def_t *def;
6af0bf9c 19436
aaed909a
FB
19437 def = cpu_mips_find_by_name(cpu_model);
19438 if (!def)
19439 return NULL;
0f71a709
AF
19440 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19441 env = &cpu->env;
aaed909a
FB
19442 env->cpu_model = def;
19443
51cc2e78
BS
19444#ifndef CONFIG_USER_ONLY
19445 mmu_init(env, def);
19446#endif
19447 fpu_init(env, def);
19448 mvp_init(env, def);
c1caf1d9
AF
19449
19450 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19451
30bf942d 19452 return cpu;
6ae81775
TS
19453}
19454
1bba0dc9 19455void cpu_state_reset(CPUMIPSState *env)
6ae81775 19456{
55e5c285
AF
19457 MIPSCPU *cpu = mips_env_get_cpu(env);
19458 CPUState *cs = CPU(cpu);
6ae81775 19459
51cc2e78
BS
19460 /* Reset registers to their default values */
19461 env->CP0_PRid = env->cpu_model->CP0_PRid;
19462 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19463#ifdef TARGET_WORDS_BIGENDIAN
19464 env->CP0_Config0 |= (1 << CP0C0_BE);
19465#endif
19466 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19467 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19468 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
19469 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19470 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
19471 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19472 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
19473 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19474 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
19475 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19476 << env->cpu_model->CP0_LLAddr_shift;
19477 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
19478 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19479 env->CCRes = env->cpu_model->CCRes;
19480 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19481 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19482 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19483 env->current_tc = 0;
19484 env->SEGBITS = env->cpu_model->SEGBITS;
19485 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19486#if defined(TARGET_MIPS64)
19487 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19488 env->SEGMask |= 3ULL << 62;
19489 }
19490#endif
19491 env->PABITS = env->cpu_model->PABITS;
19492 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
19493 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19494 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19495 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19496 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19497 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19498 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19499 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19500 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19501 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19502 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
19503 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19504 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
f1cb0951 19505 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
863f264d 19506 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
19507 env->insn_flags = env->cpu_model->insn_flags;
19508
0eaef5aa 19509#if defined(CONFIG_USER_ONLY)
03e6e501 19510 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
19511# ifdef TARGET_MIPS64
19512 /* Enable 64-bit register mode. */
19513 env->CP0_Status |= (1 << CP0St_PX);
19514# endif
19515# ifdef TARGET_ABI_MIPSN64
19516 /* Enable 64-bit address mode. */
19517 env->CP0_Status |= (1 << CP0St_UX);
19518# endif
94159135
MI
19519 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19520 hardware registers. */
19521 env->CP0_HWREna |= 0x0000000F;
91a75935 19522 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 19523 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 19524 }
6f0af304
PJ
19525 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19526 env->CP0_Status |= (1 << CP0St_MX);
853c3240 19527 }
4d66261f
PJ
19528# if defined(TARGET_MIPS64)
19529 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19530 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19531 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
19532 env->CP0_Status |= (1 << CP0St_FR);
19533 }
4d66261f 19534# endif
932e71cd
AJ
19535#else
19536 if (env->hflags & MIPS_HFLAG_BMASK) {
19537 /* If the exception was raised from a delay slot,
19538 come back to the jump. */
c3577479
MR
19539 env->CP0_ErrorEPC = (env->active_tc.PC
19540 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 19541 } else {
932e71cd
AJ
19542 env->CP0_ErrorEPC = env->active_tc.PC;
19543 }
19544 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
19545 env->CP0_Random = env->tlb->nb_tlb - 1;
19546 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 19547 env->CP0_Wired = 0;
0a2672b7
JH
19548 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19549 if (kvm_enabled()) {
19550 env->CP0_EBase |= 0x40000000;
19551 } else {
19552 env->CP0_EBase |= 0x80000000;
19553 }
932e71cd
AJ
19554 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19555 /* vectored interrupts not implemented, timer on int 7,
19556 no performance counters. */
19557 env->CP0_IntCtl = 0xe0000000;
19558 {
19559 int i;
19560
19561 for (i = 0; i < 7; i++) {
19562 env->CP0_WatchLo[i] = 0;
19563 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 19564 }
932e71cd
AJ
19565 env->CP0_WatchLo[7] = 0;
19566 env->CP0_WatchHi[7] = 0;
fd88b6ab 19567 }
932e71cd
AJ
19568 /* Count register increments in debug mode, EJTAG version 1 */
19569 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 19570
4b69c7e2
JH
19571 cpu_mips_store_count(env, 1);
19572
9e56e756
EI
19573 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
19574 int i;
19575
19576 /* Only TC0 on VPE 0 starts as active. */
19577 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 19578 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
19579 env->tcs[i].CP0_TCHalt = 1;
19580 }
19581 env->active_tc.CP0_TCHalt = 1;
259186a7 19582 cs->halted = 1;
9e56e756 19583
55e5c285 19584 if (cs->cpu_index == 0) {
9e56e756
EI
19585 /* VPE0 starts up enabled. */
19586 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
19587 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
19588
19589 /* TC0 starts up unhalted. */
259186a7 19590 cs->halted = 0;
9e56e756
EI
19591 env->active_tc.CP0_TCHalt = 0;
19592 env->tcs[0].CP0_TCHalt = 0;
19593 /* With thread 0 active. */
19594 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
19595 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
19596 }
19597 }
51cc2e78 19598#endif
ddc584bd
LA
19599 if ((env->insn_flags & ISA_MIPS32R6) &&
19600 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
19601 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19602 env->CP0_Status |= (1 << CP0St_FR);
19603 }
19604
863f264d
YK
19605 /* MSA */
19606 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
19607 msa_reset(env);
19608 }
19609
03e6e501 19610 compute_hflags(env);
27103424 19611 cs->exception_index = EXCP_NONE;
6af0bf9c 19612}
d2856f1a 19613
7db13fae 19614void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 19615{
25983cad 19616 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
19617 env->hflags &= ~MIPS_HFLAG_BMASK;
19618 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
19619 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
19620 case MIPS_HFLAG_BR:
19621 break;
19622 case MIPS_HFLAG_BC:
19623 case MIPS_HFLAG_BL:
19624 case MIPS_HFLAG_B:
19625 env->btarget = gen_opc_btarget[pc_pos];
19626 break;
19627 }
d2856f1a 19628}