]> Git Repo - qemu.git/blame - target-mips/translate.c
tcg/mips: fix store softmmu slow path
[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),
e37e863f 140 /* Cache and prefetch */
7a387fff
TS
141 OPC_CACHE = (0x2F << 26),
142 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
143 /* PC-relative address computation / loads */
144 OPC_PCREL = (0x3B << 26),
145};
146
147/* PC-relative address computation / loads */
148#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
149#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
150enum {
151 /* Instructions determined by bits 19 and 20 */
152 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
153 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
154 OPC_LWUPC = OPC_PCREL | (2 << 19),
155
156 /* Instructions determined by bits 16 ... 20 */
157 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
158 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
159
160 /* Other */
161 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
162};
163
164/* MIPS special opcodes */
7a387fff
TS
165#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
166
e37e863f
FB
167enum {
168 /* Shifts */
7a387fff 169 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
170 /* NOP is SLL r0, r0, 0 */
171 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
172 /* EHB is SLL r0, r0, 3 */
173 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 174 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
175 OPC_SRA = 0x03 | OPC_SPECIAL,
176 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 177 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 178 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
179 OPC_SRAV = 0x07 | OPC_SPECIAL,
180 OPC_DSLLV = 0x14 | OPC_SPECIAL,
181 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 182 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
183 OPC_DSRAV = 0x17 | OPC_SPECIAL,
184 OPC_DSLL = 0x38 | OPC_SPECIAL,
185 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 186 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
187 OPC_DSRA = 0x3B | OPC_SPECIAL,
188 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
189 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 190 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 191 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 192 /* Multiplication / division */
7a387fff
TS
193 OPC_MULT = 0x18 | OPC_SPECIAL,
194 OPC_MULTU = 0x19 | OPC_SPECIAL,
195 OPC_DIV = 0x1A | OPC_SPECIAL,
196 OPC_DIVU = 0x1B | OPC_SPECIAL,
197 OPC_DMULT = 0x1C | OPC_SPECIAL,
198 OPC_DMULTU = 0x1D | OPC_SPECIAL,
199 OPC_DDIV = 0x1E | OPC_SPECIAL,
200 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 201
e37e863f 202 /* 2 registers arithmetic / logic */
7a387fff
TS
203 OPC_ADD = 0x20 | OPC_SPECIAL,
204 OPC_ADDU = 0x21 | OPC_SPECIAL,
205 OPC_SUB = 0x22 | OPC_SPECIAL,
206 OPC_SUBU = 0x23 | OPC_SPECIAL,
207 OPC_AND = 0x24 | OPC_SPECIAL,
208 OPC_OR = 0x25 | OPC_SPECIAL,
209 OPC_XOR = 0x26 | OPC_SPECIAL,
210 OPC_NOR = 0x27 | OPC_SPECIAL,
211 OPC_SLT = 0x2A | OPC_SPECIAL,
212 OPC_SLTU = 0x2B | OPC_SPECIAL,
213 OPC_DADD = 0x2C | OPC_SPECIAL,
214 OPC_DADDU = 0x2D | OPC_SPECIAL,
215 OPC_DSUB = 0x2E | OPC_SPECIAL,
216 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 217 /* Jumps */
7a387fff
TS
218 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
219 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 220 /* Traps */
7a387fff
TS
221 OPC_TGE = 0x30 | OPC_SPECIAL,
222 OPC_TGEU = 0x31 | OPC_SPECIAL,
223 OPC_TLT = 0x32 | OPC_SPECIAL,
224 OPC_TLTU = 0x33 | OPC_SPECIAL,
225 OPC_TEQ = 0x34 | OPC_SPECIAL,
226 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 227 /* HI / LO registers load & stores */
7a387fff
TS
228 OPC_MFHI = 0x10 | OPC_SPECIAL,
229 OPC_MTHI = 0x11 | OPC_SPECIAL,
230 OPC_MFLO = 0x12 | OPC_SPECIAL,
231 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 232 /* Conditional moves */
7a387fff
TS
233 OPC_MOVZ = 0x0A | OPC_SPECIAL,
234 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 235
b691d9d2
LA
236 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
237 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
238
7a387fff 239 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
240
241 /* Special */
a0d700e4 242 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
243 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
244 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 245 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
246 OPC_SYNC = 0x0F | OPC_SPECIAL,
247
7a387fff
TS
248 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
249 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
250 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
251 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
252};
253
b42ee5e1
LA
254/* R6 Multiply and Divide instructions have the same Opcode
255 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
256#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
257
258enum {
259 R6_OPC_MUL = OPC_MULT | (2 << 6),
260 R6_OPC_MUH = OPC_MULT | (3 << 6),
261 R6_OPC_MULU = OPC_MULTU | (2 << 6),
262 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
263 R6_OPC_DIV = OPC_DIV | (2 << 6),
264 R6_OPC_MOD = OPC_DIV | (3 << 6),
265 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
266 R6_OPC_MODU = OPC_DIVU | (3 << 6),
267
268 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
269 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
270 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
271 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
272 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
273 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
274 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
275 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
276
277 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
278 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
279 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
280 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
281 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
282
283 OPC_LSA = 0x05 | OPC_SPECIAL,
284 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
285};
286
e9c71dd1
TS
287/* Multiplication variants of the vr54xx. */
288#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
289
290enum {
291 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
292 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
293 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
294 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
295 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
296 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
297 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
298 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
299 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
300 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
301 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
302 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
303 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
304 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
305};
306
7a387fff
TS
307/* REGIMM (rt field) opcodes */
308#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
309
310enum {
311 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
312 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
313 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
314 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
315 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
316 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
317 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
318 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
319 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
320 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
321 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
322 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
323 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
324 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
325 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
326
327 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
328 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
329};
330
7a387fff
TS
331/* Special2 opcodes */
332#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
333
e37e863f 334enum {
7a387fff
TS
335 /* Multiply & xxx operations */
336 OPC_MADD = 0x00 | OPC_SPECIAL2,
337 OPC_MADDU = 0x01 | OPC_SPECIAL2,
338 OPC_MUL = 0x02 | OPC_SPECIAL2,
339 OPC_MSUB = 0x04 | OPC_SPECIAL2,
340 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
341 /* Loongson 2F */
342 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
343 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
344 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
345 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
346 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
347 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
348 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
349 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
350 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
351 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
352 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
353 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 354 /* Misc */
7a387fff
TS
355 OPC_CLZ = 0x20 | OPC_SPECIAL2,
356 OPC_CLO = 0x21 | OPC_SPECIAL2,
357 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
358 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 359 /* Special */
7a387fff
TS
360 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
361};
362
363/* Special3 opcodes */
364#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
365
366enum {
367 OPC_EXT = 0x00 | OPC_SPECIAL3,
368 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
369 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
370 OPC_DEXT = 0x03 | OPC_SPECIAL3,
371 OPC_INS = 0x04 | OPC_SPECIAL3,
372 OPC_DINSM = 0x05 | OPC_SPECIAL3,
373 OPC_DINSU = 0x06 | OPC_SPECIAL3,
374 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
375 OPC_FORK = 0x08 | OPC_SPECIAL3,
376 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
377 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
378 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
379 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
380
381 /* Loongson 2E */
382 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
383 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
384 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
385 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
386 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
387 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
388 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
389 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
390 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
391 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
392 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
393 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
394
395 /* MIPS DSP Load */
396 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
397 /* MIPS DSP Arithmetic */
398 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 399 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 400 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 401 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
402 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
403 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 405 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
406 /* MIPS DSP GPR-Based Shift Sub-class */
407 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 408 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
409 /* MIPS DSP Multiply Sub-class insns */
410 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
411 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 413 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
414 /* DSP Bit/Manipulation Sub-class */
415 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 416 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 417 /* MIPS DSP Append Sub-class */
26690560 418 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 419 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
420 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
421 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 422 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
423
424 /* R6 */
bf7910c6
LA
425 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
426 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
427 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
428 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
429 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
430 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
431};
432
7a387fff
TS
433/* BSHFL opcodes */
434#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
435
e37e863f 436enum {
15eacb9b
YK
437 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
438 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
439 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
440 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
441 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
442 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
443};
444
7a387fff
TS
445/* DBSHFL opcodes */
446#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
447
e37e863f 448enum {
15eacb9b
YK
449 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
450 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
451 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
452 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
453 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
454};
455
e45a93e2
JL
456/* MIPS DSP REGIMM opcodes */
457enum {
458 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 459 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
460};
461
9b1a1d68
JL
462#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
463/* MIPS DSP Load */
464enum {
465 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
466 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
467 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 468 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
469};
470
461c08df
JL
471#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
472enum {
473 /* MIPS DSP Arithmetic Sub-class */
474 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
475 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
476 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
481 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
482 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
488 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
489 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
490 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
491 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
492 /* MIPS DSP Multiply Sub-class insns */
493 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
494 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
495 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
499};
500
501#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
502#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
503enum {
504 /* MIPS DSP Arithmetic Sub-class */
505 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
506 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
507 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
517 /* MIPS DSP Multiply Sub-class insns */
518 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
519 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
520 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
522};
523
524#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
525enum {
526 /* MIPS DSP Arithmetic Sub-class */
527 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
528 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
529 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
546};
547
548#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
549enum {
550 /* MIPS DSP Arithmetic Sub-class */
551 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
552 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
553 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
558 /* DSP Compare-Pick Sub-class */
559 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 574};
a22260ae 575
77c5fa8b
JL
576#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
577enum {
578 /* MIPS DSP GPR-Based Shift Sub-class */
579 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
580 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
581 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
601};
461c08df 602
a22260ae
JL
603#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604enum {
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
607 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
608 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
620 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
623 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
628};
629
1cb6686c
JL
630#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
631enum {
632 /* DSP Bit/Manipulation Sub-class */
633 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
634};
635
26690560
JL
636#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637enum {
df6126a7 638 /* MIPS DSP Append Sub-class */
26690560
JL
639 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
640 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
641 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
642};
643
b53371ed
JL
644#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
645enum {
646 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
647 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
648 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
649 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
659 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
660 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
661 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
662 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
663 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
664};
665
461c08df
JL
666#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
667enum {
668 /* MIPS DSP Arithmetic Sub-class */
669 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
670 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
671 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
686 /* DSP Bit/Manipulation Sub-class */
687 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 693};
461c08df 694
461c08df
JL
695#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
696enum {
a22260ae
JL
697 /* MIPS DSP Multiply Sub-class insns */
698 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
699 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
700 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
703 /* MIPS DSP Arithmetic Sub-class */
704 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
705 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
706 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
715 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
716 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
725};
461c08df 726
461c08df
JL
727#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
728enum {
26690560
JL
729 /* DSP Compare-Pick Sub-class */
730 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
731 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
732 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
749 /* MIPS DSP Arithmetic Sub-class */
750 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
758};
461c08df 759
26690560
JL
760#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
761enum {
df6126a7 762 /* DSP Append Sub-class */
26690560
JL
763 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
764 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
765 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
766 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
767};
26690560 768
b53371ed
JL
769#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
770enum {
771 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
772 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
773 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
774 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
775 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
793};
794
1cb6686c
JL
795#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796enum {
797 /* DSP Bit/Manipulation Sub-class */
798 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
799};
1cb6686c 800
a22260ae
JL
801#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802enum {
803 /* MIPS DSP Multiply Sub-class insns */
804 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
805 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
806 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
830};
a22260ae 831
77c5fa8b
JL
832#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
833enum {
834 /* MIPS DSP GPR-Based Shift Sub-class */
835 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
836 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
837 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
861};
77c5fa8b 862
7a387fff
TS
863/* Coprocessor 0 (rs field) */
864#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
865
6ea83fed 866enum {
7a387fff
TS
867 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
868 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
869 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
870 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 871 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
872 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
873 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 874 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
875 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
876 OPC_C0 = (0x10 << 21) | OPC_CP0,
877 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
878 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 879};
7a387fff
TS
880
881/* MFMC0 opcodes */
b48cfdff 882#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
883
884enum {
ead9360e
TS
885 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
886 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
887 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
888 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
889 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
890 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
891};
892
893/* Coprocessor 0 (with rs == C0) */
894#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
895
896enum {
897 OPC_TLBR = 0x01 | OPC_C0,
898 OPC_TLBWI = 0x02 | OPC_C0,
899 OPC_TLBWR = 0x06 | OPC_C0,
900 OPC_TLBP = 0x08 | OPC_C0,
901 OPC_RFE = 0x10 | OPC_C0,
902 OPC_ERET = 0x18 | OPC_C0,
903 OPC_DERET = 0x1F | OPC_C0,
904 OPC_WAIT = 0x20 | OPC_C0,
905};
906
907/* Coprocessor 1 (rs field) */
908#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
909
bf4120ad
NF
910/* Values for the fmt field in FP instructions */
911enum {
912 /* 0 - 15 are reserved */
e459440a
AJ
913 FMT_S = 16, /* single fp */
914 FMT_D = 17, /* double fp */
915 FMT_E = 18, /* extended fp */
916 FMT_Q = 19, /* quad fp */
917 FMT_W = 20, /* 32-bit fixed */
918 FMT_L = 21, /* 64-bit fixed */
919 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
920 /* 23 - 31 are reserved */
921};
922
7a387fff
TS
923enum {
924 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
925 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
926 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 927 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
928 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
929 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
930 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 931 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 932 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
933 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
934 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
935 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
936 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
937 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
938 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
939 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
940 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
941 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
942 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
943 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
7a387fff
TS
944};
945
5a5012ec
TS
946#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
947#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
948
7a387fff
TS
949enum {
950 OPC_BC1F = (0x00 << 16) | OPC_BC1,
951 OPC_BC1T = (0x01 << 16) | OPC_BC1,
952 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
953 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
954};
955
5a5012ec
TS
956enum {
957 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
958 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
959};
960
961enum {
962 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
963 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
964};
7a387fff
TS
965
966#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
967
968enum {
969 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
970 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
971 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
972 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
973 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
974 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
975 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
976 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
977 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
978 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
979 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
980};
981
bd277fa1
RH
982#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
983
984enum {
985 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
986 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
987 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
988 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
989 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
990 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
991 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
992 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
993
994 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
995 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
996 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
997 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
998 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
999 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1000 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1001 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1002
1003 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1004 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1005 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1006 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1007 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1008 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1009 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1010 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1011
1012 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1013 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1014 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1015 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1016 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1017 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1018 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1019 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1020
1021 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1022 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1023 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1024 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1025 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1026 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1027
1028 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1029 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1030 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1031 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1032 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1033 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1034
1035 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1036 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1037 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1038 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1039 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1040 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1041
1042 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1043 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1044 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1045 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1046 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1047 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1048
1049 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1050 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1051 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1052 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1053 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1054 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1055
1056 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1057 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1058 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1059 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1060 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1061 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1062
1063 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1064 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1065 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1066 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1067 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1068 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1069
1070 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1071 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1072 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1073 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1074 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1075 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1076};
1077
1078
e0c84da7
TS
1079#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1080
1081enum {
1082 OPC_LWXC1 = 0x00 | OPC_CP3,
1083 OPC_LDXC1 = 0x01 | OPC_CP3,
1084 OPC_LUXC1 = 0x05 | OPC_CP3,
1085 OPC_SWXC1 = 0x08 | OPC_CP3,
1086 OPC_SDXC1 = 0x09 | OPC_CP3,
1087 OPC_SUXC1 = 0x0D | OPC_CP3,
1088 OPC_PREFX = 0x0F | OPC_CP3,
1089 OPC_ALNV_PS = 0x1E | OPC_CP3,
1090 OPC_MADD_S = 0x20 | OPC_CP3,
1091 OPC_MADD_D = 0x21 | OPC_CP3,
1092 OPC_MADD_PS = 0x26 | OPC_CP3,
1093 OPC_MSUB_S = 0x28 | OPC_CP3,
1094 OPC_MSUB_D = 0x29 | OPC_CP3,
1095 OPC_MSUB_PS = 0x2E | OPC_CP3,
1096 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1097 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1098 OPC_NMADD_PS= 0x36 | OPC_CP3,
1099 OPC_NMSUB_S = 0x38 | OPC_CP3,
1100 OPC_NMSUB_D = 0x39 | OPC_CP3,
1101 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1102};
1103
39454628 1104/* global register indices */
a7812ae4
PB
1105static TCGv_ptr cpu_env;
1106static TCGv cpu_gpr[32], cpu_PC;
340fff72 1107static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1108static TCGv cpu_dspctrl, btarget, bcond;
1109static TCGv_i32 hflags;
a7812ae4 1110static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1111static TCGv_i64 fpu_f64[32];
aa0bf00b 1112
1a7ff922 1113static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1114static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1115
022c62cb 1116#include "exec/gen-icount.h"
2e70f6ef 1117
895c2d04 1118#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1119 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1120 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1121 tcg_temp_free_i32(helper_tmp); \
1122 } while(0)
be24bb4f 1123
895c2d04 1124#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1125 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1126 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1127 tcg_temp_free_i32(helper_tmp); \
1128 } while(0)
be24bb4f 1129
895c2d04
BS
1130#define gen_helper_1e0i(name, ret, arg1) do { \
1131 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1132 gen_helper_##name(ret, cpu_env, helper_tmp); \
1133 tcg_temp_free_i32(helper_tmp); \
1134 } while(0)
1135
1136#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1137 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1138 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1139 tcg_temp_free_i32(helper_tmp); \
1140 } while(0)
1141
1142#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1143 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1144 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1145 tcg_temp_free_i32(helper_tmp); \
1146 } while(0)
1147
1148#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1149 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1150 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1151 tcg_temp_free_i32(helper_tmp); \
1152 } while(0)
be24bb4f 1153
895c2d04 1154#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1155 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1156 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1157 tcg_temp_free_i32(helper_tmp); \
1158 } while(0)
c239529e 1159
8e9ade68
TS
1160typedef struct DisasContext {
1161 struct TranslationBlock *tb;
1162 target_ulong pc, saved_pc;
1163 uint32_t opcode;
7b270ef2 1164 int singlestep_enabled;
d75c135e 1165 int insn_flags;
5ab5c041 1166 int32_t CP0_Config1;
8e9ade68
TS
1167 /* Routine used to access memory */
1168 int mem_idx;
1169 uint32_t hflags, saved_hflags;
1170 int bstate;
1171 target_ulong btarget;
d279279e 1172 bool ulri;
8e9ade68
TS
1173} DisasContext;
1174
1175enum {
1176 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1177 * exception condition */
8e9ade68
TS
1178 BS_STOP = 1, /* We want to stop translation for any reason */
1179 BS_BRANCH = 2, /* We reached a branch condition */
1180 BS_EXCP = 3, /* We reached an exception condition */
1181};
1182
d73ee8a2
RH
1183static const char * const regnames[] = {
1184 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1185 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1186 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1187 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1188};
6af0bf9c 1189
d73ee8a2
RH
1190static const char * const regnames_HI[] = {
1191 "HI0", "HI1", "HI2", "HI3",
1192};
4b2eb8d2 1193
d73ee8a2
RH
1194static const char * const regnames_LO[] = {
1195 "LO0", "LO1", "LO2", "LO3",
1196};
4b2eb8d2 1197
d73ee8a2
RH
1198static const char * const fregnames[] = {
1199 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1200 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1201 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1202 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1203};
958fb4a9 1204
fb7729e2
RH
1205#define MIPS_DEBUG(fmt, ...) \
1206 do { \
1207 if (MIPS_DEBUG_DISAS) { \
1208 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1209 TARGET_FMT_lx ": %08x " fmt "\n", \
1210 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1211 } \
1212 } while (0)
1213
1214#define LOG_DISAS(...) \
1215 do { \
1216 if (MIPS_DEBUG_DISAS) { \
1217 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1218 } \
1219 } while (0)
958fb4a9 1220
8e9ade68 1221#define MIPS_INVAL(op) \
8e9ade68 1222 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1223 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1224
8e9ade68
TS
1225/* General purpose registers moves. */
1226static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1227{
8e9ade68
TS
1228 if (reg == 0)
1229 tcg_gen_movi_tl(t, 0);
1230 else
4b2eb8d2 1231 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1232}
1233
8e9ade68 1234static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1235{
8e9ade68 1236 if (reg != 0)
4b2eb8d2 1237 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1238}
1239
8e9ade68 1240/* Moves to/from shadow registers. */
be24bb4f 1241static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1242{
d9bea114 1243 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1244
1245 if (from == 0)
d9bea114 1246 tcg_gen_movi_tl(t0, 0);
8e9ade68 1247 else {
d9bea114 1248 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1249 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1250
7db13fae 1251 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1252 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1253 tcg_gen_andi_i32(t2, t2, 0xf);
1254 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1255 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1256 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1257
d9bea114 1258 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1259 tcg_temp_free_ptr(addr);
d9bea114 1260 tcg_temp_free_i32(t2);
8e9ade68 1261 }
d9bea114
AJ
1262 gen_store_gpr(t0, to);
1263 tcg_temp_free(t0);
aaa9128a
TS
1264}
1265
be24bb4f 1266static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1267{
be24bb4f 1268 if (to != 0) {
d9bea114
AJ
1269 TCGv t0 = tcg_temp_new();
1270 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1271 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1272
d9bea114 1273 gen_load_gpr(t0, from);
7db13fae 1274 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1275 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1276 tcg_gen_andi_i32(t2, t2, 0xf);
1277 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1278 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1279 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1280
d9bea114 1281 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1282 tcg_temp_free_ptr(addr);
d9bea114
AJ
1283 tcg_temp_free_i32(t2);
1284 tcg_temp_free(t0);
8e9ade68 1285 }
aaa9128a
TS
1286}
1287
aaa9128a 1288/* Floating point register moves. */
d73ee8a2 1289static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1290{
d73ee8a2 1291 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1292}
1293
d73ee8a2 1294static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1295{
d73ee8a2
RH
1296 TCGv_i64 t64 = tcg_temp_new_i64();
1297 tcg_gen_extu_i32_i64(t64, t);
1298 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1299 tcg_temp_free_i64(t64);
6d066274
AJ
1300}
1301
7f6613ce 1302static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1303{
7f6613ce
PJ
1304 if (ctx->hflags & MIPS_HFLAG_F64) {
1305 TCGv_i64 t64 = tcg_temp_new_i64();
1306 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1307 tcg_gen_trunc_i64_i32(t, t64);
1308 tcg_temp_free_i64(t64);
1309 } else {
1310 gen_load_fpr32(t, reg | 1);
1311 }
6d066274
AJ
1312}
1313
7f6613ce 1314static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1315{
7f6613ce
PJ
1316 if (ctx->hflags & MIPS_HFLAG_F64) {
1317 TCGv_i64 t64 = tcg_temp_new_i64();
1318 tcg_gen_extu_i32_i64(t64, t);
1319 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1320 tcg_temp_free_i64(t64);
1321 } else {
1322 gen_store_fpr32(t, reg | 1);
1323 }
aa0bf00b 1324}
6ea83fed 1325
d73ee8a2 1326static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1327{
f364515c 1328 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1329 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1330 } else {
d73ee8a2 1331 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1332 }
1333}
6ea83fed 1334
d73ee8a2 1335static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1336{
f364515c 1337 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1338 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1339 } else {
d73ee8a2
RH
1340 TCGv_i64 t0;
1341 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1342 t0 = tcg_temp_new_i64();
6d066274 1343 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1344 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1345 tcg_temp_free_i64(t0);
aa0bf00b
TS
1346 }
1347}
6ea83fed 1348
d94536f4 1349static inline int get_fp_bit (int cc)
a16336e4 1350{
d94536f4
AJ
1351 if (cc)
1352 return 24 + cc;
1353 else
1354 return 23;
a16336e4
TS
1355}
1356
30898801 1357/* Tests */
8e9ade68
TS
1358static inline void gen_save_pc(target_ulong pc)
1359{
1eb75d4a 1360 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1361}
30898801 1362
356265ae 1363static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1364{
d12d51d5 1365 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1366 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1367 gen_save_pc(ctx->pc);
6af0bf9c
FB
1368 ctx->saved_pc = ctx->pc;
1369 }
1370 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1371 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1372 ctx->saved_hflags = ctx->hflags;
364d4831 1373 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1374 case MIPS_HFLAG_BR:
5a5012ec
TS
1375 break;
1376 case MIPS_HFLAG_BC:
5a5012ec 1377 case MIPS_HFLAG_BL:
5a5012ec 1378 case MIPS_HFLAG_B:
d077b6f7 1379 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1380 break;
6af0bf9c
FB
1381 }
1382 }
1383}
1384
7db13fae 1385static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1386{
fd4a04eb 1387 ctx->saved_hflags = ctx->hflags;
364d4831 1388 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1389 case MIPS_HFLAG_BR:
fd4a04eb
TS
1390 break;
1391 case MIPS_HFLAG_BC:
1392 case MIPS_HFLAG_BL:
39454628 1393 case MIPS_HFLAG_B:
fd4a04eb 1394 ctx->btarget = env->btarget;
fd4a04eb 1395 break;
5a5012ec
TS
1396 }
1397}
1398
356265ae 1399static inline void
48d38ca5 1400generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1401{
a7812ae4
PB
1402 TCGv_i32 texcp = tcg_const_i32(excp);
1403 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1404 save_cpu_state(ctx, 1);
895c2d04 1405 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1406 tcg_temp_free_i32(terr);
1407 tcg_temp_free_i32(texcp);
aaa9128a
TS
1408}
1409
356265ae 1410static inline void
48d38ca5 1411generate_exception (DisasContext *ctx, int excp)
aaa9128a 1412{
6af0bf9c 1413 save_cpu_state(ctx, 1);
895c2d04 1414 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1415}
1416
48d38ca5 1417/* Addresses computation */
941694d0 1418static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1419{
941694d0 1420 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1421
1422#if defined(TARGET_MIPS64)
01f72885 1423 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1424 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1425 }
1426#endif
4ad40f36
FB
1427}
1428
31837be3
YK
1429/* Addresses computation (translation time) */
1430static target_long addr_add(DisasContext *ctx, target_long base,
1431 target_long offset)
1432{
1433 target_long sum = base + offset;
1434
1435#if defined(TARGET_MIPS64)
1436 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1437 sum = (int32_t)sum;
1438 }
1439#endif
1440 return sum;
1441}
1442
356265ae 1443static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1444{
fe253235 1445 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1446 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1447}
1448
356265ae 1449static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1450{
fe253235 1451 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1452 generate_exception_err(ctx, EXCP_CpU, 1);
1453}
1454
b8aa4598
TS
1455/* Verify that the processor is running with COP1X instructions enabled.
1456 This is associated with the nabla symbol in the MIPS32 and MIPS64
1457 opcode tables. */
1458
356265ae 1459static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1460{
1461 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1462 generate_exception(ctx, EXCP_RI);
1463}
1464
1465/* Verify that the processor is running with 64-bit floating-point
1466 operations enabled. */
1467
356265ae 1468static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1469{
b8aa4598 1470 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1471 generate_exception(ctx, EXCP_RI);
1472}
1473
1474/*
1475 * Verify if floating point register is valid; an operation is not defined
1476 * if bit 0 of any register specification is set and the FR bit in the
1477 * Status register equals zero, since the register numbers specify an
1478 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1479 * in the Status register equals one, both even and odd register numbers
1480 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1481 *
1482 * Multiple 64 bit wide registers can be checked by calling
1483 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1484 */
356265ae 1485static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1486{
fe253235 1487 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1488 generate_exception(ctx, EXCP_RI);
1489}
1490
853c3240
JL
1491/* Verify that the processor is running with DSP instructions enabled.
1492 This is enabled by CP0 Status register MX(24) bit.
1493 */
1494
1495static inline void check_dsp(DisasContext *ctx)
1496{
1497 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1498 if (ctx->insn_flags & ASE_DSP) {
1499 generate_exception(ctx, EXCP_DSPDIS);
1500 } else {
1501 generate_exception(ctx, EXCP_RI);
1502 }
853c3240
JL
1503 }
1504}
1505
1506static inline void check_dspr2(DisasContext *ctx)
1507{
1508 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1509 if (ctx->insn_flags & ASE_DSP) {
1510 generate_exception(ctx, EXCP_DSPDIS);
1511 } else {
1512 generate_exception(ctx, EXCP_RI);
1513 }
853c3240
JL
1514 }
1515}
1516
3a95e3a7 1517/* This code generates a "reserved instruction" exception if the
e189e748 1518 CPU does not support the instruction set corresponding to flags. */
d75c135e 1519static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1520{
d75c135e 1521 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1522 generate_exception(ctx, EXCP_RI);
d75c135e 1523 }
3a95e3a7
TS
1524}
1525
fecd2646
LA
1526/* This code generates a "reserved instruction" exception if the
1527 CPU has corresponding flag set which indicates that the instruction
1528 has been removed. */
1529static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1530{
1531 if (unlikely(ctx->insn_flags & flags)) {
1532 generate_exception(ctx, EXCP_RI);
1533 }
1534}
1535
c7986fd6 1536#ifdef TARGET_MIPS64
e189e748
TS
1537/* This code generates a "reserved instruction" exception if 64-bit
1538 instructions are not enabled. */
356265ae 1539static inline void check_mips_64(DisasContext *ctx)
e189e748 1540{
fe253235 1541 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1542 generate_exception(ctx, EXCP_RI);
1543}
c7986fd6 1544#endif
e189e748 1545
8153667c
NF
1546/* Define small wrappers for gen_load_fpr* so that we have a uniform
1547 calling interface for 32 and 64-bit FPRs. No sense in changing
1548 all callers for gen_load_fpr32 when we need the CTX parameter for
1549 this one use. */
1550#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1551#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1552#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1553static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1554 int ft, int fs, int cc) \
1555{ \
1556 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1557 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1558 switch (ifmt) { \
1559 case FMT_PS: \
1560 check_cp1_64bitmode(ctx); \
1561 break; \
1562 case FMT_D: \
1563 if (abs) { \
1564 check_cop1x(ctx); \
1565 } \
1566 check_cp1_registers(ctx, fs | ft); \
1567 break; \
1568 case FMT_S: \
1569 if (abs) { \
1570 check_cop1x(ctx); \
1571 } \
1572 break; \
1573 } \
1574 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1575 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1576 switch (n) { \
895c2d04
BS
1577 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1578 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1579 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1580 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1581 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1582 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1583 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1584 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1585 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1586 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1587 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1588 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1589 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1590 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1591 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1592 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1593 default: abort(); \
1594 } \
1595 tcg_temp_free_i##bits (fp0); \
1596 tcg_temp_free_i##bits (fp1); \
1597}
1598
1599FOP_CONDS(, 0, d, FMT_D, 64)
1600FOP_CONDS(abs, 1, d, FMT_D, 64)
1601FOP_CONDS(, 0, s, FMT_S, 32)
1602FOP_CONDS(abs, 1, s, FMT_S, 32)
1603FOP_CONDS(, 0, ps, FMT_PS, 64)
1604FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1605#undef FOP_CONDS
3f493883
YK
1606
1607#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1608static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1609 int ft, int fs, int fd) \
1610{ \
1611 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1612 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1613 switch (ifmt) { \
1614 case FMT_D: \
1615 check_cp1_registers(ctx, fs | ft | fd); \
1616 break; \
1617 } \
1618 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1619 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1620 switch (n) { \
1621 case 0: \
1622 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1623 break; \
1624 case 1: \
1625 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1626 break; \
1627 case 2: \
1628 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1629 break; \
1630 case 3: \
1631 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1632 break; \
1633 case 4: \
1634 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1635 break; \
1636 case 5: \
1637 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1638 break; \
1639 case 6: \
1640 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1641 break; \
1642 case 7: \
1643 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1644 break; \
1645 case 8: \
1646 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1647 break; \
1648 case 9: \
1649 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1650 break; \
1651 case 10: \
1652 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1653 break; \
1654 case 11: \
1655 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1656 break; \
1657 case 12: \
1658 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1659 break; \
1660 case 13: \
1661 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1662 break; \
1663 case 14: \
1664 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1665 break; \
1666 case 15: \
1667 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1668 break; \
1669 case 17: \
1670 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1671 break; \
1672 case 18: \
1673 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1674 break; \
1675 case 19: \
1676 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1677 break; \
1678 case 25: \
1679 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1680 break; \
1681 case 26: \
1682 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1683 break; \
1684 case 27: \
1685 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1686 break; \
1687 default: \
1688 abort(); \
1689 } \
1690 STORE; \
1691 tcg_temp_free_i ## bits (fp0); \
1692 tcg_temp_free_i ## bits (fp1); \
1693}
1694
1695FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1696FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1697#undef FOP_CONDNS
8153667c
NF
1698#undef gen_ldcmp_fpr32
1699#undef gen_ldcmp_fpr64
1700
958fb4a9 1701/* load/store instructions. */
e7139c44 1702#ifdef CONFIG_USER_ONLY
d9bea114 1703#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1704static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1705{ \
1706 TCGv t0 = tcg_temp_new(); \
1707 tcg_gen_mov_tl(t0, arg1); \
1708 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1709 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1710 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1711 tcg_temp_free(t0); \
aaa9128a 1712}
e7139c44
AJ
1713#else
1714#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1715static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1716{ \
895c2d04 1717 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1718}
1719#endif
aaa9128a
TS
1720OP_LD_ATOMIC(ll,ld32s);
1721#if defined(TARGET_MIPS64)
1722OP_LD_ATOMIC(lld,ld64);
1723#endif
1724#undef OP_LD_ATOMIC
1725
590bc601
PB
1726#ifdef CONFIG_USER_ONLY
1727#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1728static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1729{ \
1730 TCGv t0 = tcg_temp_new(); \
1731 int l1 = gen_new_label(); \
1732 int l2 = gen_new_label(); \
1733 \
1734 tcg_gen_andi_tl(t0, arg2, almask); \
1735 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1736 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1737 generate_exception(ctx, EXCP_AdES); \
1738 gen_set_label(l1); \
7db13fae 1739 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1740 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1741 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1742 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1743 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1744 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1745 gen_set_label(l2); \
1746 tcg_gen_movi_tl(t0, 0); \
1747 gen_store_gpr(t0, rt); \
1748 tcg_temp_free(t0); \
1749}
1750#else
1751#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1752static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1753{ \
1754 TCGv t0 = tcg_temp_new(); \
895c2d04 1755 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1756 gen_store_gpr(t0, rt); \
590bc601
PB
1757 tcg_temp_free(t0); \
1758}
1759#endif
590bc601 1760OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1761#if defined(TARGET_MIPS64)
590bc601 1762OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1763#endif
1764#undef OP_ST_ATOMIC
1765
662d7485
NF
1766static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1767 int base, int16_t offset)
1768{
1769 if (base == 0) {
1770 tcg_gen_movi_tl(addr, offset);
1771 } else if (offset == 0) {
1772 gen_load_gpr(addr, base);
1773 } else {
1774 tcg_gen_movi_tl(addr, offset);
1775 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1776 }
1777}
1778
364d4831
NF
1779static target_ulong pc_relative_pc (DisasContext *ctx)
1780{
1781 target_ulong pc = ctx->pc;
1782
1783 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1784 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1785
1786 pc -= branch_bytes;
1787 }
1788
1789 pc &= ~(target_ulong)3;
1790 return pc;
1791}
1792
5c13fdfd 1793/* Load */
d75c135e
AJ
1794static void gen_ld(DisasContext *ctx, uint32_t opc,
1795 int rt, int base, int16_t offset)
6af0bf9c 1796{
5c13fdfd 1797 const char *opn = "ld";
fc40787a 1798 TCGv t0, t1, t2;
afa88c3a 1799
d75c135e 1800 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1801 /* Loongson CPU uses a load to zero register for prefetch.
1802 We emulate it as a NOP. On other CPU we must perform the
1803 actual memory access. */
1804 MIPS_DEBUG("NOP");
1805 return;
1806 }
6af0bf9c 1807
afa88c3a 1808 t0 = tcg_temp_new();
662d7485 1809 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1810
6af0bf9c 1811 switch (opc) {
d26bc211 1812#if defined(TARGET_MIPS64)
6e473128 1813 case OPC_LWU:
5f68f5ae 1814 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1815 gen_store_gpr(t0, rt);
6e473128
TS
1816 opn = "lwu";
1817 break;
6af0bf9c 1818 case OPC_LD:
5f68f5ae 1819 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1820 gen_store_gpr(t0, rt);
6af0bf9c
FB
1821 opn = "ld";
1822 break;
7a387fff 1823 case OPC_LLD:
bf7910c6 1824 case R6_OPC_LLD:
b835e919 1825 save_cpu_state(ctx, 1);
5c13fdfd 1826 op_ld_lld(t0, t0, ctx);
78723684 1827 gen_store_gpr(t0, rt);
7a387fff
TS
1828 opn = "lld";
1829 break;
6af0bf9c 1830 case OPC_LDL:
3cee3050 1831 t1 = tcg_temp_new();
fc40787a
AJ
1832 tcg_gen_andi_tl(t1, t0, 7);
1833#ifndef TARGET_WORDS_BIGENDIAN
1834 tcg_gen_xori_tl(t1, t1, 7);
1835#endif
1836 tcg_gen_shli_tl(t1, t1, 3);
1837 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1838 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1839 tcg_gen_shl_tl(t0, t0, t1);
1840 tcg_gen_xori_tl(t1, t1, 63);
1841 t2 = tcg_const_tl(0x7fffffffffffffffull);
1842 tcg_gen_shr_tl(t2, t2, t1);
78723684 1843 gen_load_gpr(t1, rt);
fc40787a
AJ
1844 tcg_gen_and_tl(t1, t1, t2);
1845 tcg_temp_free(t2);
1846 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1847 tcg_temp_free(t1);
fc40787a 1848 gen_store_gpr(t0, rt);
6af0bf9c
FB
1849 opn = "ldl";
1850 break;
6af0bf9c 1851 case OPC_LDR:
3cee3050 1852 t1 = tcg_temp_new();
fc40787a
AJ
1853 tcg_gen_andi_tl(t1, t0, 7);
1854#ifdef TARGET_WORDS_BIGENDIAN
1855 tcg_gen_xori_tl(t1, t1, 7);
1856#endif
1857 tcg_gen_shli_tl(t1, t1, 3);
1858 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1859 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1860 tcg_gen_shr_tl(t0, t0, t1);
1861 tcg_gen_xori_tl(t1, t1, 63);
1862 t2 = tcg_const_tl(0xfffffffffffffffeull);
1863 tcg_gen_shl_tl(t2, t2, t1);
78723684 1864 gen_load_gpr(t1, rt);
fc40787a
AJ
1865 tcg_gen_and_tl(t1, t1, t2);
1866 tcg_temp_free(t2);
1867 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1868 tcg_temp_free(t1);
fc40787a 1869 gen_store_gpr(t0, rt);
6af0bf9c
FB
1870 opn = "ldr";
1871 break;
364d4831 1872 case OPC_LDPC:
3cee3050 1873 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1874 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1875 tcg_temp_free(t1);
5f68f5ae 1876 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1877 gen_store_gpr(t0, rt);
5c13fdfd 1878 opn = "ldpc";
364d4831 1879 break;
6af0bf9c 1880#endif
364d4831 1881 case OPC_LWPC:
3cee3050 1882 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1883 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1884 tcg_temp_free(t1);
5f68f5ae 1885 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1886 gen_store_gpr(t0, rt);
5c13fdfd 1887 opn = "lwpc";
364d4831 1888 break;
6af0bf9c 1889 case OPC_LW:
5f68f5ae 1890 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1891 gen_store_gpr(t0, rt);
6af0bf9c
FB
1892 opn = "lw";
1893 break;
6af0bf9c 1894 case OPC_LH:
5f68f5ae 1895 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1896 gen_store_gpr(t0, rt);
6af0bf9c
FB
1897 opn = "lh";
1898 break;
6af0bf9c 1899 case OPC_LHU:
5f68f5ae 1900 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1901 gen_store_gpr(t0, rt);
6af0bf9c
FB
1902 opn = "lhu";
1903 break;
1904 case OPC_LB:
5f68f5ae 1905 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1906 gen_store_gpr(t0, rt);
6af0bf9c
FB
1907 opn = "lb";
1908 break;
6af0bf9c 1909 case OPC_LBU:
5f68f5ae 1910 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1911 gen_store_gpr(t0, rt);
6af0bf9c
FB
1912 opn = "lbu";
1913 break;
1914 case OPC_LWL:
3cee3050 1915 t1 = tcg_temp_new();
fc40787a
AJ
1916 tcg_gen_andi_tl(t1, t0, 3);
1917#ifndef TARGET_WORDS_BIGENDIAN
1918 tcg_gen_xori_tl(t1, t1, 3);
1919#endif
1920 tcg_gen_shli_tl(t1, t1, 3);
1921 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1922 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1923 tcg_gen_shl_tl(t0, t0, t1);
1924 tcg_gen_xori_tl(t1, t1, 31);
1925 t2 = tcg_const_tl(0x7fffffffull);
1926 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1927 gen_load_gpr(t1, rt);
fc40787a
AJ
1928 tcg_gen_and_tl(t1, t1, t2);
1929 tcg_temp_free(t2);
1930 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1931 tcg_temp_free(t1);
fc40787a
AJ
1932 tcg_gen_ext32s_tl(t0, t0);
1933 gen_store_gpr(t0, rt);
6af0bf9c
FB
1934 opn = "lwl";
1935 break;
6af0bf9c 1936 case OPC_LWR:
3cee3050 1937 t1 = tcg_temp_new();
fc40787a
AJ
1938 tcg_gen_andi_tl(t1, t0, 3);
1939#ifdef TARGET_WORDS_BIGENDIAN
1940 tcg_gen_xori_tl(t1, t1, 3);
1941#endif
1942 tcg_gen_shli_tl(t1, t1, 3);
1943 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1944 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1945 tcg_gen_shr_tl(t0, t0, t1);
1946 tcg_gen_xori_tl(t1, t1, 31);
1947 t2 = tcg_const_tl(0xfffffffeull);
1948 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1949 gen_load_gpr(t1, rt);
fc40787a
AJ
1950 tcg_gen_and_tl(t1, t1, t2);
1951 tcg_temp_free(t2);
1952 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1953 tcg_temp_free(t1);
c728154b 1954 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1955 gen_store_gpr(t0, rt);
6af0bf9c
FB
1956 opn = "lwr";
1957 break;
6af0bf9c 1958 case OPC_LL:
4368b29a 1959 case R6_OPC_LL:
e7139c44 1960 save_cpu_state(ctx, 1);
5c13fdfd 1961 op_ld_ll(t0, t0, ctx);
78723684 1962 gen_store_gpr(t0, rt);
6af0bf9c
FB
1963 opn = "ll";
1964 break;
d66c7132 1965 }
2abf314d 1966 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1967 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1968 tcg_temp_free(t0);
d66c7132
AJ
1969}
1970
5c13fdfd
AJ
1971/* Store */
1972static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1973 int base, int16_t offset)
1974{
1975 const char *opn = "st";
1976 TCGv t0 = tcg_temp_new();
1977 TCGv t1 = tcg_temp_new();
1978
1979 gen_base_offset_addr(ctx, t0, base, offset);
1980 gen_load_gpr(t1, rt);
1981 switch (opc) {
1982#if defined(TARGET_MIPS64)
1983 case OPC_SD:
5f68f5ae 1984 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
1985 opn = "sd";
1986 break;
1987 case OPC_SDL:
1988 save_cpu_state(ctx, 1);
895c2d04 1989 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1990 opn = "sdl";
1991 break;
1992 case OPC_SDR:
1993 save_cpu_state(ctx, 1);
895c2d04 1994 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1995 opn = "sdr";
1996 break;
1997#endif
1998 case OPC_SW:
5f68f5ae 1999 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
2000 opn = "sw";
2001 break;
2002 case OPC_SH:
5f68f5ae 2003 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
2004 opn = "sh";
2005 break;
2006 case OPC_SB:
5f68f5ae 2007 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2008 opn = "sb";
2009 break;
2010 case OPC_SWL:
2011 save_cpu_state(ctx, 1);
895c2d04 2012 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2013 opn = "swl";
2014 break;
2015 case OPC_SWR:
2016 save_cpu_state(ctx, 1);
895c2d04 2017 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2018 opn = "swr";
2019 break;
2020 }
2abf314d 2021 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2022 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2023 tcg_temp_free(t0);
2024 tcg_temp_free(t1);
2025}
2026
2027
d66c7132
AJ
2028/* Store conditional */
2029static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2030 int base, int16_t offset)
2031{
2032 const char *opn = "st_cond";
2033 TCGv t0, t1;
2034
2d2826b9 2035#ifdef CONFIG_USER_ONLY
d66c7132 2036 t0 = tcg_temp_local_new();
d66c7132 2037 t1 = tcg_temp_local_new();
2d2826b9
AJ
2038#else
2039 t0 = tcg_temp_new();
2040 t1 = tcg_temp_new();
2041#endif
2042 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2043 gen_load_gpr(t1, rt);
2044 switch (opc) {
2045#if defined(TARGET_MIPS64)
2046 case OPC_SCD:
bf7910c6 2047 case R6_OPC_SCD:
b835e919 2048 save_cpu_state(ctx, 1);
5c13fdfd 2049 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2050 opn = "scd";
2051 break;
2052#endif
6af0bf9c 2053 case OPC_SC:
4368b29a 2054 case R6_OPC_SC:
e7139c44 2055 save_cpu_state(ctx, 1);
5c13fdfd 2056 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2057 opn = "sc";
2058 break;
6af0bf9c 2059 }
2abf314d 2060 (void)opn; /* avoid a compiler warning */
6af0bf9c 2061 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2062 tcg_temp_free(t1);
d66c7132 2063 tcg_temp_free(t0);
6af0bf9c
FB
2064}
2065
6ea83fed 2066/* Load and store */
7a387fff 2067static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2068 int base, int16_t offset)
6ea83fed 2069{
923617a3 2070 const char *opn = "flt_ldst";
4e2474d6 2071 TCGv t0 = tcg_temp_new();
6ea83fed 2072
662d7485 2073 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2074 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2075 memory access. */
6ea83fed
FB
2076 switch (opc) {
2077 case OPC_LWC1:
b6d96bed 2078 {
a7812ae4 2079 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 2080 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 2081 gen_store_fpr32(fp0, ft);
a7812ae4 2082 tcg_temp_free_i32(fp0);
b6d96bed 2083 }
6ea83fed
FB
2084 opn = "lwc1";
2085 break;
2086 case OPC_SWC1:
b6d96bed 2087 {
a7812ae4 2088 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 2089 gen_load_fpr32(fp0, ft);
5f68f5ae 2090 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 2091 tcg_temp_free_i32(fp0);
b6d96bed 2092 }
6ea83fed
FB
2093 opn = "swc1";
2094 break;
2095 case OPC_LDC1:
b6d96bed 2096 {
a7812ae4 2097 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 2098 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 2099 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2100 tcg_temp_free_i64(fp0);
b6d96bed 2101 }
6ea83fed
FB
2102 opn = "ldc1";
2103 break;
2104 case OPC_SDC1:
b6d96bed 2105 {
a7812ae4 2106 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2107 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 2108 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 2109 tcg_temp_free_i64(fp0);
b6d96bed 2110 }
6ea83fed
FB
2111 opn = "sdc1";
2112 break;
2113 default:
923617a3 2114 MIPS_INVAL(opn);
e397ee33 2115 generate_exception(ctx, EXCP_RI);
78723684 2116 goto out;
6ea83fed 2117 }
2abf314d 2118 (void)opn; /* avoid a compiler warning */
6ea83fed 2119 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2120 out:
2121 tcg_temp_free(t0);
6ea83fed 2122}
6ea83fed 2123
5ab5c041
AJ
2124static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2125 int rs, int16_t imm)
26ebe468 2126{
5ab5c041 2127 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
2128 check_cp1_enabled(ctx);
2129 gen_flt_ldst(ctx, op, rt, rs, imm);
2130 } else {
2131 generate_exception_err(ctx, EXCP_CpU, 1);
2132 }
2133}
2134
6af0bf9c 2135/* Arithmetic with immediate operand */
d75c135e
AJ
2136static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2137 int rt, int rs, int16_t imm)
6af0bf9c 2138{
324d9e32 2139 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2140 const char *opn = "imm arith";
6af0bf9c 2141
7a387fff 2142 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2143 /* If no destination, treat it as a NOP.
2144 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2145 MIPS_DEBUG("NOP");
324d9e32 2146 return;
6af0bf9c
FB
2147 }
2148 switch (opc) {
2149 case OPC_ADDI:
48d38ca5 2150 {
324d9e32
AJ
2151 TCGv t0 = tcg_temp_local_new();
2152 TCGv t1 = tcg_temp_new();
2153 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2154 int l1 = gen_new_label();
2155
324d9e32
AJ
2156 gen_load_gpr(t1, rs);
2157 tcg_gen_addi_tl(t0, t1, uimm);
2158 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2159
324d9e32
AJ
2160 tcg_gen_xori_tl(t1, t1, ~uimm);
2161 tcg_gen_xori_tl(t2, t0, uimm);
2162 tcg_gen_and_tl(t1, t1, t2);
2163 tcg_temp_free(t2);
2164 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2165 tcg_temp_free(t1);
48d38ca5
TS
2166 /* operands of same sign, result different sign */
2167 generate_exception(ctx, EXCP_OVERFLOW);
2168 gen_set_label(l1);
78723684 2169 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2170 gen_store_gpr(t0, rt);
2171 tcg_temp_free(t0);
48d38ca5 2172 }
6af0bf9c
FB
2173 opn = "addi";
2174 break;
2175 case OPC_ADDIU:
324d9e32
AJ
2176 if (rs != 0) {
2177 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2178 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2179 } else {
2180 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2181 }
6af0bf9c
FB
2182 opn = "addiu";
2183 break;
d26bc211 2184#if defined(TARGET_MIPS64)
7a387fff 2185 case OPC_DADDI:
48d38ca5 2186 {
324d9e32
AJ
2187 TCGv t0 = tcg_temp_local_new();
2188 TCGv t1 = tcg_temp_new();
2189 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2190 int l1 = gen_new_label();
2191
324d9e32
AJ
2192 gen_load_gpr(t1, rs);
2193 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2194
324d9e32
AJ
2195 tcg_gen_xori_tl(t1, t1, ~uimm);
2196 tcg_gen_xori_tl(t2, t0, uimm);
2197 tcg_gen_and_tl(t1, t1, t2);
2198 tcg_temp_free(t2);
2199 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2200 tcg_temp_free(t1);
48d38ca5
TS
2201 /* operands of same sign, result different sign */
2202 generate_exception(ctx, EXCP_OVERFLOW);
2203 gen_set_label(l1);
324d9e32
AJ
2204 gen_store_gpr(t0, rt);
2205 tcg_temp_free(t0);
48d38ca5 2206 }
7a387fff
TS
2207 opn = "daddi";
2208 break;
2209 case OPC_DADDIU:
324d9e32
AJ
2210 if (rs != 0) {
2211 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2212 } else {
2213 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2214 }
7a387fff
TS
2215 opn = "daddiu";
2216 break;
2217#endif
324d9e32 2218 }
2abf314d 2219 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2220 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2221}
2222
2223/* Logic with immediate operand */
d75c135e 2224static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2225 int rt, int rs, int16_t imm)
324d9e32
AJ
2226{
2227 target_ulong uimm;
324d9e32
AJ
2228
2229 if (rt == 0) {
2230 /* If no destination, treat it as a NOP. */
2231 MIPS_DEBUG("NOP");
2232 return;
2233 }
2234 uimm = (uint16_t)imm;
2235 switch (opc) {
6af0bf9c 2236 case OPC_ANDI:
324d9e32
AJ
2237 if (likely(rs != 0))
2238 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2239 else
2240 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2241 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2242 regnames[rs], uimm);
6af0bf9c
FB
2243 break;
2244 case OPC_ORI:
324d9e32
AJ
2245 if (rs != 0)
2246 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2247 else
2248 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2249 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2250 regnames[rs], uimm);
6af0bf9c
FB
2251 break;
2252 case OPC_XORI:
324d9e32
AJ
2253 if (likely(rs != 0))
2254 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2255 else
2256 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2257 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2258 regnames[rs], uimm);
6af0bf9c
FB
2259 break;
2260 case OPC_LUI:
d4ea6acd
LA
2261 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2262 /* OPC_AUI */
2263 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2264 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2265 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2266 } else {
2267 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2268 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2269 }
7c2c3ea3
EJ
2270 break;
2271
2272 default:
2273 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2274 break;
324d9e32 2275 }
324d9e32
AJ
2276}
2277
2278/* Set on less than with immediate operand */
d75c135e 2279static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2280 int rt, int rs, int16_t imm)
324d9e32
AJ
2281{
2282 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2283 const char *opn = "imm arith";
2284 TCGv t0;
2285
2286 if (rt == 0) {
2287 /* If no destination, treat it as a NOP. */
2288 MIPS_DEBUG("NOP");
2289 return;
2290 }
2291 t0 = tcg_temp_new();
2292 gen_load_gpr(t0, rs);
2293 switch (opc) {
2294 case OPC_SLTI:
e68dd28f 2295 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2296 opn = "slti";
2297 break;
2298 case OPC_SLTIU:
e68dd28f 2299 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2300 opn = "sltiu";
2301 break;
2302 }
2abf314d 2303 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2304 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2305 tcg_temp_free(t0);
2306}
2307
2308/* Shifts with immediate operand */
d75c135e 2309static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2310 int rt, int rs, int16_t imm)
2311{
2312 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2313 const char *opn = "imm shift";
2314 TCGv t0;
2315
2316 if (rt == 0) {
2317 /* If no destination, treat it as a NOP. */
2318 MIPS_DEBUG("NOP");
2319 return;
2320 }
2321
2322 t0 = tcg_temp_new();
2323 gen_load_gpr(t0, rs);
2324 switch (opc) {
6af0bf9c 2325 case OPC_SLL:
78723684 2326 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2327 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2328 opn = "sll";
2329 break;
2330 case OPC_SRA:
324d9e32 2331 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2332 opn = "sra";
2333 break;
2334 case OPC_SRL:
ea63e2c3
NF
2335 if (uimm != 0) {
2336 tcg_gen_ext32u_tl(t0, t0);
2337 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2338 } else {
2339 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2340 }
ea63e2c3
NF
2341 opn = "srl";
2342 break;
2343 case OPC_ROTR:
2344 if (uimm != 0) {
2345 TCGv_i32 t1 = tcg_temp_new_i32();
2346
2347 tcg_gen_trunc_tl_i32(t1, t0);
2348 tcg_gen_rotri_i32(t1, t1, uimm);
2349 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2350 tcg_temp_free_i32(t1);
3399e30f
NF
2351 } else {
2352 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2353 }
2354 opn = "rotr";
7a387fff 2355 break;
d26bc211 2356#if defined(TARGET_MIPS64)
7a387fff 2357 case OPC_DSLL:
324d9e32 2358 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2359 opn = "dsll";
2360 break;
2361 case OPC_DSRA:
324d9e32 2362 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2363 opn = "dsra";
2364 break;
2365 case OPC_DSRL:
ea63e2c3
NF
2366 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2367 opn = "dsrl";
2368 break;
2369 case OPC_DROTR:
2370 if (uimm != 0) {
2371 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2372 } else {
2373 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2374 }
ea63e2c3 2375 opn = "drotr";
7a387fff
TS
2376 break;
2377 case OPC_DSLL32:
324d9e32 2378 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2379 opn = "dsll32";
2380 break;
2381 case OPC_DSRA32:
324d9e32 2382 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2383 opn = "dsra32";
2384 break;
2385 case OPC_DSRL32:
ea63e2c3
NF
2386 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2387 opn = "dsrl32";
2388 break;
2389 case OPC_DROTR32:
2390 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2391 opn = "drotr32";
6af0bf9c 2392 break;
7a387fff 2393#endif
6af0bf9c 2394 }
2abf314d 2395 (void)opn; /* avoid a compiler warning */
93b12ccc 2396 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2397 tcg_temp_free(t0);
6af0bf9c
FB
2398}
2399
2400/* Arithmetic */
d75c135e
AJ
2401static void gen_arith(DisasContext *ctx, uint32_t opc,
2402 int rd, int rs, int rt)
6af0bf9c 2403{
923617a3 2404 const char *opn = "arith";
6af0bf9c 2405
7a387fff
TS
2406 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2407 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2408 /* If no destination, treat it as a NOP.
2409 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2410 MIPS_DEBUG("NOP");
460f00c4 2411 return;
185f0762 2412 }
460f00c4 2413
6af0bf9c
FB
2414 switch (opc) {
2415 case OPC_ADD:
48d38ca5 2416 {
460f00c4
AJ
2417 TCGv t0 = tcg_temp_local_new();
2418 TCGv t1 = tcg_temp_new();
2419 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2420 int l1 = gen_new_label();
2421
460f00c4
AJ
2422 gen_load_gpr(t1, rs);
2423 gen_load_gpr(t2, rt);
2424 tcg_gen_add_tl(t0, t1, t2);
2425 tcg_gen_ext32s_tl(t0, t0);
2426 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2427 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2428 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2429 tcg_temp_free(t2);
2430 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2431 tcg_temp_free(t1);
48d38ca5
TS
2432 /* operands of same sign, result different sign */
2433 generate_exception(ctx, EXCP_OVERFLOW);
2434 gen_set_label(l1);
460f00c4
AJ
2435 gen_store_gpr(t0, rd);
2436 tcg_temp_free(t0);
48d38ca5 2437 }
6af0bf9c
FB
2438 opn = "add";
2439 break;
2440 case OPC_ADDU:
460f00c4
AJ
2441 if (rs != 0 && rt != 0) {
2442 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2443 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 } else {
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2450 }
6af0bf9c
FB
2451 opn = "addu";
2452 break;
2453 case OPC_SUB:
48d38ca5 2454 {
460f00c4
AJ
2455 TCGv t0 = tcg_temp_local_new();
2456 TCGv t1 = tcg_temp_new();
2457 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2458 int l1 = gen_new_label();
2459
460f00c4
AJ
2460 gen_load_gpr(t1, rs);
2461 gen_load_gpr(t2, rt);
2462 tcg_gen_sub_tl(t0, t1, t2);
2463 tcg_gen_ext32s_tl(t0, t0);
2464 tcg_gen_xor_tl(t2, t1, t2);
2465 tcg_gen_xor_tl(t1, t0, t1);
2466 tcg_gen_and_tl(t1, t1, t2);
2467 tcg_temp_free(t2);
2468 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2469 tcg_temp_free(t1);
31e3104f 2470 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2471 generate_exception(ctx, EXCP_OVERFLOW);
2472 gen_set_label(l1);
460f00c4
AJ
2473 gen_store_gpr(t0, rd);
2474 tcg_temp_free(t0);
48d38ca5 2475 }
6af0bf9c
FB
2476 opn = "sub";
2477 break;
2478 case OPC_SUBU:
460f00c4
AJ
2479 if (rs != 0 && rt != 0) {
2480 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2481 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2482 } else if (rs == 0 && rt != 0) {
2483 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2484 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2485 } else if (rs != 0 && rt == 0) {
2486 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2487 } else {
2488 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2489 }
6af0bf9c
FB
2490 opn = "subu";
2491 break;
d26bc211 2492#if defined(TARGET_MIPS64)
7a387fff 2493 case OPC_DADD:
48d38ca5 2494 {
460f00c4
AJ
2495 TCGv t0 = tcg_temp_local_new();
2496 TCGv t1 = tcg_temp_new();
2497 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2498 int l1 = gen_new_label();
2499
460f00c4
AJ
2500 gen_load_gpr(t1, rs);
2501 gen_load_gpr(t2, rt);
2502 tcg_gen_add_tl(t0, t1, t2);
2503 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2504 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2505 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2506 tcg_temp_free(t2);
2507 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2508 tcg_temp_free(t1);
48d38ca5
TS
2509 /* operands of same sign, result different sign */
2510 generate_exception(ctx, EXCP_OVERFLOW);
2511 gen_set_label(l1);
460f00c4
AJ
2512 gen_store_gpr(t0, rd);
2513 tcg_temp_free(t0);
48d38ca5 2514 }
7a387fff
TS
2515 opn = "dadd";
2516 break;
2517 case OPC_DADDU:
460f00c4
AJ
2518 if (rs != 0 && rt != 0) {
2519 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2520 } else if (rs == 0 && rt != 0) {
2521 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2522 } else if (rs != 0 && rt == 0) {
2523 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2524 } else {
2525 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2526 }
7a387fff
TS
2527 opn = "daddu";
2528 break;
2529 case OPC_DSUB:
48d38ca5 2530 {
460f00c4
AJ
2531 TCGv t0 = tcg_temp_local_new();
2532 TCGv t1 = tcg_temp_new();
2533 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2534 int l1 = gen_new_label();
2535
460f00c4
AJ
2536 gen_load_gpr(t1, rs);
2537 gen_load_gpr(t2, rt);
2538 tcg_gen_sub_tl(t0, t1, t2);
2539 tcg_gen_xor_tl(t2, t1, t2);
2540 tcg_gen_xor_tl(t1, t0, t1);
2541 tcg_gen_and_tl(t1, t1, t2);
2542 tcg_temp_free(t2);
2543 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2544 tcg_temp_free(t1);
31e3104f 2545 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2546 generate_exception(ctx, EXCP_OVERFLOW);
2547 gen_set_label(l1);
460f00c4
AJ
2548 gen_store_gpr(t0, rd);
2549 tcg_temp_free(t0);
48d38ca5 2550 }
7a387fff
TS
2551 opn = "dsub";
2552 break;
2553 case OPC_DSUBU:
460f00c4
AJ
2554 if (rs != 0 && rt != 0) {
2555 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2556 } else if (rs == 0 && rt != 0) {
2557 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2558 } else if (rs != 0 && rt == 0) {
2559 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2560 } else {
2561 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2562 }
7a387fff
TS
2563 opn = "dsubu";
2564 break;
2565#endif
460f00c4
AJ
2566 case OPC_MUL:
2567 if (likely(rs != 0 && rt != 0)) {
2568 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2569 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2570 } else {
2571 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2572 }
2573 opn = "mul";
6af0bf9c 2574 break;
460f00c4 2575 }
2abf314d 2576 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2577 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2578}
2579
2580/* Conditional move */
d75c135e 2581static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2582 int rd, int rs, int rt)
460f00c4
AJ
2583{
2584 const char *opn = "cond move";
acf12465 2585 TCGv t0, t1, t2;
460f00c4
AJ
2586
2587 if (rd == 0) {
acf12465 2588 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2589 MIPS_DEBUG("NOP");
2590 return;
2591 }
2592
acf12465
AJ
2593 t0 = tcg_temp_new();
2594 gen_load_gpr(t0, rt);
2595 t1 = tcg_const_tl(0);
2596 t2 = tcg_temp_new();
2597 gen_load_gpr(t2, rs);
460f00c4
AJ
2598 switch (opc) {
2599 case OPC_MOVN:
acf12465 2600 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2601 opn = "movn";
6af0bf9c 2602 break;
460f00c4 2603 case OPC_MOVZ:
acf12465 2604 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2605 opn = "movz";
2606 break;
b691d9d2
LA
2607 case OPC_SELNEZ:
2608 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2609 opn = "selnez";
2610 break;
2611 case OPC_SELEQZ:
2612 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2613 opn = "seleqz";
2614 break;
460f00c4 2615 }
acf12465
AJ
2616 tcg_temp_free(t2);
2617 tcg_temp_free(t1);
2618 tcg_temp_free(t0);
460f00c4 2619
2abf314d 2620 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2621 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2622}
2623
2624/* Logic */
d75c135e 2625static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2626 int rd, int rs, int rt)
460f00c4
AJ
2627{
2628 const char *opn = "logic";
2629
2630 if (rd == 0) {
2631 /* If no destination, treat it as a NOP. */
2632 MIPS_DEBUG("NOP");
2633 return;
2634 }
2635
2636 switch (opc) {
6af0bf9c 2637 case OPC_AND:
460f00c4
AJ
2638 if (likely(rs != 0 && rt != 0)) {
2639 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2640 } else {
2641 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2642 }
6af0bf9c
FB
2643 opn = "and";
2644 break;
2645 case OPC_NOR:
460f00c4
AJ
2646 if (rs != 0 && rt != 0) {
2647 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2648 } else if (rs == 0 && rt != 0) {
2649 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2650 } else if (rs != 0 && rt == 0) {
2651 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2652 } else {
2653 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2654 }
6af0bf9c
FB
2655 opn = "nor";
2656 break;
2657 case OPC_OR:
460f00c4
AJ
2658 if (likely(rs != 0 && rt != 0)) {
2659 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2660 } else if (rs == 0 && rt != 0) {
2661 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2662 } else if (rs != 0 && rt == 0) {
2663 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2664 } else {
2665 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2666 }
6af0bf9c
FB
2667 opn = "or";
2668 break;
2669 case OPC_XOR:
460f00c4
AJ
2670 if (likely(rs != 0 && rt != 0)) {
2671 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2672 } else if (rs == 0 && rt != 0) {
2673 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2674 } else if (rs != 0 && rt == 0) {
2675 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2676 } else {
2677 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2678 }
6af0bf9c
FB
2679 opn = "xor";
2680 break;
460f00c4 2681 }
2abf314d 2682 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2683 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2684}
2685
2686/* Set on lower than */
d75c135e 2687static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2688 int rd, int rs, int rt)
460f00c4
AJ
2689{
2690 const char *opn = "slt";
2691 TCGv t0, t1;
2692
2693 if (rd == 0) {
2694 /* If no destination, treat it as a NOP. */
2695 MIPS_DEBUG("NOP");
2696 return;
2697 }
2698
2699 t0 = tcg_temp_new();
2700 t1 = tcg_temp_new();
2701 gen_load_gpr(t0, rs);
2702 gen_load_gpr(t1, rt);
2703 switch (opc) {
2704 case OPC_SLT:
e68dd28f 2705 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2706 opn = "slt";
6af0bf9c 2707 break;
460f00c4 2708 case OPC_SLTU:
e68dd28f 2709 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2710 opn = "sltu";
2711 break;
2712 }
2abf314d 2713 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2714 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2715 tcg_temp_free(t0);
2716 tcg_temp_free(t1);
2717}
20c4c97c 2718
460f00c4 2719/* Shifts */
d75c135e
AJ
2720static void gen_shift(DisasContext *ctx, uint32_t opc,
2721 int rd, int rs, int rt)
460f00c4
AJ
2722{
2723 const char *opn = "shifts";
2724 TCGv t0, t1;
20c4c97c 2725
460f00c4
AJ
2726 if (rd == 0) {
2727 /* If no destination, treat it as a NOP.
2728 For add & sub, we must generate the overflow exception when needed. */
2729 MIPS_DEBUG("NOP");
2730 return;
2731 }
2732
2733 t0 = tcg_temp_new();
2734 t1 = tcg_temp_new();
2735 gen_load_gpr(t0, rs);
2736 gen_load_gpr(t1, rt);
2737 switch (opc) {
6af0bf9c 2738 case OPC_SLLV:
78723684
TS
2739 tcg_gen_andi_tl(t0, t0, 0x1f);
2740 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2741 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2742 opn = "sllv";
2743 break;
2744 case OPC_SRAV:
78723684 2745 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2746 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2747 opn = "srav";
2748 break;
2749 case OPC_SRLV:
ea63e2c3
NF
2750 tcg_gen_ext32u_tl(t1, t1);
2751 tcg_gen_andi_tl(t0, t0, 0x1f);
2752 tcg_gen_shr_tl(t0, t1, t0);
2753 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2754 opn = "srlv";
2755 break;
2756 case OPC_ROTRV:
2757 {
2758 TCGv_i32 t2 = tcg_temp_new_i32();
2759 TCGv_i32 t3 = tcg_temp_new_i32();
2760
2761 tcg_gen_trunc_tl_i32(t2, t0);
2762 tcg_gen_trunc_tl_i32(t3, t1);
2763 tcg_gen_andi_i32(t2, t2, 0x1f);
2764 tcg_gen_rotr_i32(t2, t3, t2);
2765 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2766 tcg_temp_free_i32(t2);
2767 tcg_temp_free_i32(t3);
2768 opn = "rotrv";
5a63bcb2 2769 }
7a387fff 2770 break;
d26bc211 2771#if defined(TARGET_MIPS64)
7a387fff 2772 case OPC_DSLLV:
78723684 2773 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2774 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2775 opn = "dsllv";
2776 break;
2777 case OPC_DSRAV:
78723684 2778 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2779 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2780 opn = "dsrav";
2781 break;
2782 case OPC_DSRLV:
ea63e2c3
NF
2783 tcg_gen_andi_tl(t0, t0, 0x3f);
2784 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2785 opn = "dsrlv";
2786 break;
2787 case OPC_DROTRV:
2788 tcg_gen_andi_tl(t0, t0, 0x3f);
2789 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2790 opn = "drotrv";
6af0bf9c 2791 break;
7a387fff 2792#endif
6af0bf9c 2793 }
2abf314d 2794 (void)opn; /* avoid a compiler warning */
6af0bf9c 2795 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2796 tcg_temp_free(t0);
2797 tcg_temp_free(t1);
6af0bf9c
FB
2798}
2799
2800/* Arithmetic on HI/LO registers */
26135ead 2801static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2802{
923617a3 2803 const char *opn = "hilo";
6af0bf9c
FB
2804
2805 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2806 /* Treat as NOP. */
6af0bf9c 2807 MIPS_DEBUG("NOP");
a1f6684d 2808 return;
6af0bf9c 2809 }
4133498f 2810
4133498f
JL
2811 if (acc != 0) {
2812 check_dsp(ctx);
2813 }
2814
6af0bf9c
FB
2815 switch (opc) {
2816 case OPC_MFHI:
4133498f
JL
2817#if defined(TARGET_MIPS64)
2818 if (acc != 0) {
2819 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2820 } else
2821#endif
2822 {
2823 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2824 }
6af0bf9c
FB
2825 opn = "mfhi";
2826 break;
2827 case OPC_MFLO:
4133498f
JL
2828#if defined(TARGET_MIPS64)
2829 if (acc != 0) {
2830 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2831 } else
2832#endif
2833 {
2834 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2835 }
6af0bf9c
FB
2836 opn = "mflo";
2837 break;
2838 case OPC_MTHI:
4133498f
JL
2839 if (reg != 0) {
2840#if defined(TARGET_MIPS64)
2841 if (acc != 0) {
2842 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2843 } else
2844#endif
2845 {
2846 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2847 }
2848 } else {
2849 tcg_gen_movi_tl(cpu_HI[acc], 0);
2850 }
6af0bf9c
FB
2851 opn = "mthi";
2852 break;
2853 case OPC_MTLO:
4133498f
JL
2854 if (reg != 0) {
2855#if defined(TARGET_MIPS64)
2856 if (acc != 0) {
2857 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2858 } else
2859#endif
2860 {
2861 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2862 }
2863 } else {
2864 tcg_gen_movi_tl(cpu_LO[acc], 0);
2865 }
6af0bf9c
FB
2866 opn = "mtlo";
2867 break;
6af0bf9c 2868 }
2abf314d 2869 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2870 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2871}
2872
d4ea6acd
LA
2873static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2874 TCGMemOp memop)
2875{
2876 TCGv t0 = tcg_const_tl(addr);
2877 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
2878 gen_store_gpr(t0, reg);
2879 tcg_temp_free(t0);
2880}
2881
2882static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
2883{
2884 target_long offset;
2885 target_long addr;
2886
2887 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
2888 case OPC_ADDIUPC:
2889 if (rs != 0) {
2890 offset = sextract32(ctx->opcode << 2, 0, 21);
2891 addr = addr_add(ctx, ctx->pc, offset);
2892 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2893 }
2894 break;
2895 case R6_OPC_LWPC:
2896 offset = sextract32(ctx->opcode << 2, 0, 21);
2897 addr = addr_add(ctx, ctx->pc, offset);
2898 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
2899 break;
2900#if defined(TARGET_MIPS64)
2901 case OPC_LWUPC:
2902 check_mips_64(ctx);
2903 offset = sextract32(ctx->opcode << 2, 0, 21);
2904 addr = addr_add(ctx, ctx->pc, offset);
2905 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
2906 break;
2907#endif
2908 default:
2909 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
2910 case OPC_AUIPC:
2911 if (rs != 0) {
2912 offset = imm << 16;
2913 addr = addr_add(ctx, ctx->pc, offset);
2914 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2915 }
2916 break;
2917 case OPC_ALUIPC:
2918 if (rs != 0) {
2919 offset = imm << 16;
2920 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
2921 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2922 }
2923 break;
2924#if defined(TARGET_MIPS64)
2925 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
2926 case R6_OPC_LDPC + (1 << 16):
2927 case R6_OPC_LDPC + (2 << 16):
2928 case R6_OPC_LDPC + (3 << 16):
2929 check_mips_64(ctx);
2930 offset = sextract32(ctx->opcode << 3, 0, 21);
2931 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
2932 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
2933 break;
2934#endif
2935 default:
2936 MIPS_INVAL("OPC_PCREL");
2937 generate_exception(ctx, EXCP_RI);
2938 break;
2939 }
2940 break;
2941 }
2942}
2943
b42ee5e1
LA
2944static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
2945{
2946 const char *opn = "r6 mul/div";
2947 TCGv t0, t1;
2948
2949 if (rd == 0) {
2950 /* Treat as NOP. */
2951 MIPS_DEBUG("NOP");
2952 return;
2953 }
2954
2955 t0 = tcg_temp_new();
2956 t1 = tcg_temp_new();
2957
2958 gen_load_gpr(t0, rs);
2959 gen_load_gpr(t1, rt);
2960
2961 switch (opc) {
2962 case R6_OPC_DIV:
2963 {
2964 TCGv t2 = tcg_temp_new();
2965 TCGv t3 = tcg_temp_new();
2966 tcg_gen_ext32s_tl(t0, t0);
2967 tcg_gen_ext32s_tl(t1, t1);
2968 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2969 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2970 tcg_gen_and_tl(t2, t2, t3);
2971 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2972 tcg_gen_or_tl(t2, t2, t3);
2973 tcg_gen_movi_tl(t3, 0);
2974 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2975 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2976 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2977 tcg_temp_free(t3);
2978 tcg_temp_free(t2);
2979 }
2980 opn = "div";
2981 break;
2982 case R6_OPC_MOD:
2983 {
2984 TCGv t2 = tcg_temp_new();
2985 TCGv t3 = tcg_temp_new();
2986 tcg_gen_ext32s_tl(t0, t0);
2987 tcg_gen_ext32s_tl(t1, t1);
2988 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2989 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2990 tcg_gen_and_tl(t2, t2, t3);
2991 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2992 tcg_gen_or_tl(t2, t2, t3);
2993 tcg_gen_movi_tl(t3, 0);
2994 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2995 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2996 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2997 tcg_temp_free(t3);
2998 tcg_temp_free(t2);
2999 }
3000 opn = "mod";
3001 break;
3002 case R6_OPC_DIVU:
3003 {
3004 TCGv t2 = tcg_const_tl(0);
3005 TCGv t3 = tcg_const_tl(1);
3006 tcg_gen_ext32u_tl(t0, t0);
3007 tcg_gen_ext32u_tl(t1, t1);
3008 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3009 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3010 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3011 tcg_temp_free(t3);
3012 tcg_temp_free(t2);
3013 }
3014 opn = "divu";
3015 break;
3016 case R6_OPC_MODU:
3017 {
3018 TCGv t2 = tcg_const_tl(0);
3019 TCGv t3 = tcg_const_tl(1);
3020 tcg_gen_ext32u_tl(t0, t0);
3021 tcg_gen_ext32u_tl(t1, t1);
3022 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3023 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3024 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3025 tcg_temp_free(t3);
3026 tcg_temp_free(t2);
3027 }
3028 opn = "modu";
3029 break;
3030 case R6_OPC_MUL:
3031 {
3032 TCGv_i32 t2 = tcg_temp_new_i32();
3033 TCGv_i32 t3 = tcg_temp_new_i32();
3034 tcg_gen_trunc_tl_i32(t2, t0);
3035 tcg_gen_trunc_tl_i32(t3, t1);
3036 tcg_gen_mul_i32(t2, t2, t3);
3037 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3038 tcg_temp_free_i32(t2);
3039 tcg_temp_free_i32(t3);
3040 }
3041 opn = "mul";
3042 break;
3043 case R6_OPC_MUH:
3044 {
3045 TCGv_i32 t2 = tcg_temp_new_i32();
3046 TCGv_i32 t3 = tcg_temp_new_i32();
3047 tcg_gen_trunc_tl_i32(t2, t0);
3048 tcg_gen_trunc_tl_i32(t3, t1);
3049 tcg_gen_muls2_i32(t2, t3, t2, t3);
3050 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3051 tcg_temp_free_i32(t2);
3052 tcg_temp_free_i32(t3);
3053 }
3054 opn = "muh";
3055 break;
3056 case R6_OPC_MULU:
3057 {
3058 TCGv_i32 t2 = tcg_temp_new_i32();
3059 TCGv_i32 t3 = tcg_temp_new_i32();
3060 tcg_gen_trunc_tl_i32(t2, t0);
3061 tcg_gen_trunc_tl_i32(t3, t1);
3062 tcg_gen_mul_i32(t2, t2, t3);
3063 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3064 tcg_temp_free_i32(t2);
3065 tcg_temp_free_i32(t3);
3066 }
3067 opn = "mulu";
3068 break;
3069 case R6_OPC_MUHU:
3070 {
3071 TCGv_i32 t2 = tcg_temp_new_i32();
3072 TCGv_i32 t3 = tcg_temp_new_i32();
3073 tcg_gen_trunc_tl_i32(t2, t0);
3074 tcg_gen_trunc_tl_i32(t3, t1);
3075 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3076 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3077 tcg_temp_free_i32(t2);
3078 tcg_temp_free_i32(t3);
3079 }
3080 opn = "muhu";
3081 break;
3082#if defined(TARGET_MIPS64)
3083 case R6_OPC_DDIV:
3084 {
3085 TCGv t2 = tcg_temp_new();
3086 TCGv t3 = tcg_temp_new();
3087 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3088 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3089 tcg_gen_and_tl(t2, t2, t3);
3090 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3091 tcg_gen_or_tl(t2, t2, t3);
3092 tcg_gen_movi_tl(t3, 0);
3093 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3094 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3095 tcg_temp_free(t3);
3096 tcg_temp_free(t2);
3097 }
3098 opn = "ddiv";
3099 break;
3100 case R6_OPC_DMOD:
3101 {
3102 TCGv t2 = tcg_temp_new();
3103 TCGv t3 = tcg_temp_new();
3104 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3105 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3106 tcg_gen_and_tl(t2, t2, t3);
3107 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3108 tcg_gen_or_tl(t2, t2, t3);
3109 tcg_gen_movi_tl(t3, 0);
3110 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3111 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3112 tcg_temp_free(t3);
3113 tcg_temp_free(t2);
3114 }
3115 opn = "dmod";
3116 break;
3117 case R6_OPC_DDIVU:
3118 {
3119 TCGv t2 = tcg_const_tl(0);
3120 TCGv t3 = tcg_const_tl(1);
3121 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3122 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3123 tcg_temp_free(t3);
3124 tcg_temp_free(t2);
3125 }
3126 opn = "ddivu";
3127 break;
3128 case R6_OPC_DMODU:
3129 {
3130 TCGv t2 = tcg_const_tl(0);
3131 TCGv t3 = tcg_const_tl(1);
3132 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3133 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3134 tcg_temp_free(t3);
3135 tcg_temp_free(t2);
3136 }
3137 opn = "dmodu";
3138 break;
3139 case R6_OPC_DMUL:
3140 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3141 opn = "dmul";
3142 break;
3143 case R6_OPC_DMUH:
3144 {
3145 TCGv t2 = tcg_temp_new();
3146 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3147 tcg_temp_free(t2);
3148 }
3149 opn = "dmuh";
3150 break;
3151 case R6_OPC_DMULU:
3152 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3153 opn = "dmulu";
3154 break;
3155 case R6_OPC_DMUHU:
3156 {
3157 TCGv t2 = tcg_temp_new();
3158 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3159 tcg_temp_free(t2);
3160 }
3161 opn = "dmuhu";
3162 break;
3163#endif
3164 default:
3165 MIPS_INVAL(opn);
3166 generate_exception(ctx, EXCP_RI);
3167 goto out;
3168 }
3169 (void)opn; /* avoid a compiler warning */
3170 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3171 out:
3172 tcg_temp_free(t0);
3173 tcg_temp_free(t1);
3174}
3175
26135ead
RS
3176static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3177 int acc, int rs, int rt)
6af0bf9c 3178{
923617a3 3179 const char *opn = "mul/div";
d45f89f4
AJ
3180 TCGv t0, t1;
3181
51127181
AJ
3182 t0 = tcg_temp_new();
3183 t1 = tcg_temp_new();
6af0bf9c 3184
78723684
TS
3185 gen_load_gpr(t0, rs);
3186 gen_load_gpr(t1, rt);
51127181 3187
26135ead
RS
3188 if (acc != 0) {
3189 check_dsp(ctx);
3190 }
3191
6af0bf9c
FB
3192 switch (opc) {
3193 case OPC_DIV:
48d38ca5 3194 {
51127181
AJ
3195 TCGv t2 = tcg_temp_new();
3196 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3197 tcg_gen_ext32s_tl(t0, t0);
3198 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3199 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3200 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3201 tcg_gen_and_tl(t2, t2, t3);
3202 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3203 tcg_gen_or_tl(t2, t2, t3);
3204 tcg_gen_movi_tl(t3, 0);
3205 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3206 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3207 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3208 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3209 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3210 tcg_temp_free(t3);
3211 tcg_temp_free(t2);
48d38ca5 3212 }
6af0bf9c
FB
3213 opn = "div";
3214 break;
3215 case OPC_DIVU:
48d38ca5 3216 {
51127181
AJ
3217 TCGv t2 = tcg_const_tl(0);
3218 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3219 tcg_gen_ext32u_tl(t0, t0);
3220 tcg_gen_ext32u_tl(t1, t1);
51127181 3221 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3222 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3223 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3224 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3225 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3226 tcg_temp_free(t3);
3227 tcg_temp_free(t2);
48d38ca5 3228 }
6af0bf9c
FB
3229 opn = "divu";
3230 break;
3231 case OPC_MULT:
214c465f 3232 {
ce1dd5d1
RH
3233 TCGv_i32 t2 = tcg_temp_new_i32();
3234 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3235 tcg_gen_trunc_tl_i32(t2, t0);
3236 tcg_gen_trunc_tl_i32(t3, t1);
3237 tcg_gen_muls2_i32(t2, t3, t2, t3);
3238 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3239 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3240 tcg_temp_free_i32(t2);
3241 tcg_temp_free_i32(t3);
214c465f 3242 }
6af0bf9c
FB
3243 opn = "mult";
3244 break;
3245 case OPC_MULTU:
214c465f 3246 {
ce1dd5d1
RH
3247 TCGv_i32 t2 = tcg_temp_new_i32();
3248 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3249 tcg_gen_trunc_tl_i32(t2, t0);
3250 tcg_gen_trunc_tl_i32(t3, t1);
3251 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3252 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3253 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3254 tcg_temp_free_i32(t2);
3255 tcg_temp_free_i32(t3);
214c465f 3256 }
6af0bf9c
FB
3257 opn = "multu";
3258 break;
d26bc211 3259#if defined(TARGET_MIPS64)
7a387fff 3260 case OPC_DDIV:
48d38ca5 3261 {
51127181
AJ
3262 TCGv t2 = tcg_temp_new();
3263 TCGv t3 = tcg_temp_new();
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3265 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3266 tcg_gen_and_tl(t2, t2, t3);
3267 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3268 tcg_gen_or_tl(t2, t2, t3);
3269 tcg_gen_movi_tl(t3, 0);
3270 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3271 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3272 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3273 tcg_temp_free(t3);
3274 tcg_temp_free(t2);
48d38ca5 3275 }
7a387fff
TS
3276 opn = "ddiv";
3277 break;
3278 case OPC_DDIVU:
48d38ca5 3279 {
51127181
AJ
3280 TCGv t2 = tcg_const_tl(0);
3281 TCGv t3 = tcg_const_tl(1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3283 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3284 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3285 tcg_temp_free(t3);
3286 tcg_temp_free(t2);
48d38ca5 3287 }
7a387fff
TS
3288 opn = "ddivu";
3289 break;
3290 case OPC_DMULT:
26135ead 3291 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3292 opn = "dmult";
3293 break;
3294 case OPC_DMULTU:
26135ead 3295 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3296 opn = "dmultu";
3297 break;
3298#endif
6af0bf9c 3299 case OPC_MADD:
214c465f 3300 {
d45f89f4
AJ
3301 TCGv_i64 t2 = tcg_temp_new_i64();
3302 TCGv_i64 t3 = tcg_temp_new_i64();
3303
3304 tcg_gen_ext_tl_i64(t2, t0);
3305 tcg_gen_ext_tl_i64(t3, t1);
3306 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3307 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3308 tcg_gen_add_i64(t2, t2, t3);
3309 tcg_temp_free_i64(t3);
3310 tcg_gen_trunc_i64_tl(t0, t2);
3311 tcg_gen_shri_i64(t2, t2, 32);
3312 tcg_gen_trunc_i64_tl(t1, t2);
3313 tcg_temp_free_i64(t2);
4133498f
JL
3314 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3315 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3316 }
6af0bf9c
FB
3317 opn = "madd";
3318 break;
3319 case OPC_MADDU:
4133498f 3320 {
d45f89f4
AJ
3321 TCGv_i64 t2 = tcg_temp_new_i64();
3322 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3323
78723684
TS
3324 tcg_gen_ext32u_tl(t0, t0);
3325 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3326 tcg_gen_extu_tl_i64(t2, t0);
3327 tcg_gen_extu_tl_i64(t3, t1);
3328 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3329 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3330 tcg_gen_add_i64(t2, t2, t3);
3331 tcg_temp_free_i64(t3);
3332 tcg_gen_trunc_i64_tl(t0, t2);
3333 tcg_gen_shri_i64(t2, t2, 32);
3334 tcg_gen_trunc_i64_tl(t1, t2);
3335 tcg_temp_free_i64(t2);
4133498f
JL
3336 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3337 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3338 }
6af0bf9c
FB
3339 opn = "maddu";
3340 break;
3341 case OPC_MSUB:
214c465f 3342 {
d45f89f4
AJ
3343 TCGv_i64 t2 = tcg_temp_new_i64();
3344 TCGv_i64 t3 = tcg_temp_new_i64();
3345
3346 tcg_gen_ext_tl_i64(t2, t0);
3347 tcg_gen_ext_tl_i64(t3, t1);
3348 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3349 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3350 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3351 tcg_temp_free_i64(t3);
3352 tcg_gen_trunc_i64_tl(t0, t2);
3353 tcg_gen_shri_i64(t2, t2, 32);
3354 tcg_gen_trunc_i64_tl(t1, t2);
3355 tcg_temp_free_i64(t2);
4133498f
JL
3356 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3357 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3358 }
6af0bf9c
FB
3359 opn = "msub";
3360 break;
3361 case OPC_MSUBU:
214c465f 3362 {
d45f89f4
AJ
3363 TCGv_i64 t2 = tcg_temp_new_i64();
3364 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3365
78723684
TS
3366 tcg_gen_ext32u_tl(t0, t0);
3367 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3368 tcg_gen_extu_tl_i64(t2, t0);
3369 tcg_gen_extu_tl_i64(t3, t1);
3370 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3371 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3372 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3373 tcg_temp_free_i64(t3);
3374 tcg_gen_trunc_i64_tl(t0, t2);
3375 tcg_gen_shri_i64(t2, t2, 32);
3376 tcg_gen_trunc_i64_tl(t1, t2);
3377 tcg_temp_free_i64(t2);
4133498f
JL
3378 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3379 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3380 }
6af0bf9c
FB
3381 opn = "msubu";
3382 break;
3383 default:
923617a3 3384 MIPS_INVAL(opn);
6af0bf9c 3385 generate_exception(ctx, EXCP_RI);
78723684 3386 goto out;
6af0bf9c 3387 }
2abf314d 3388 (void)opn; /* avoid a compiler warning */
6af0bf9c 3389 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3390 out:
3391 tcg_temp_free(t0);
3392 tcg_temp_free(t1);
6af0bf9c
FB
3393}
3394
e9c71dd1
TS
3395static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3396 int rd, int rs, int rt)
3397{
3398 const char *opn = "mul vr54xx";
f157bfe1
AJ
3399 TCGv t0 = tcg_temp_new();
3400 TCGv t1 = tcg_temp_new();
e9c71dd1 3401
6c5c1e20
TS
3402 gen_load_gpr(t0, rs);
3403 gen_load_gpr(t1, rt);
e9c71dd1
TS
3404
3405 switch (opc) {
3406 case OPC_VR54XX_MULS:
895c2d04 3407 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3408 opn = "muls";
6958549d 3409 break;
e9c71dd1 3410 case OPC_VR54XX_MULSU:
895c2d04 3411 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3412 opn = "mulsu";
6958549d 3413 break;
e9c71dd1 3414 case OPC_VR54XX_MACC:
895c2d04 3415 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3416 opn = "macc";
6958549d 3417 break;
e9c71dd1 3418 case OPC_VR54XX_MACCU:
895c2d04 3419 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3420 opn = "maccu";
6958549d 3421 break;
e9c71dd1 3422 case OPC_VR54XX_MSAC:
895c2d04 3423 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3424 opn = "msac";
6958549d 3425 break;
e9c71dd1 3426 case OPC_VR54XX_MSACU:
895c2d04 3427 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3428 opn = "msacu";
6958549d 3429 break;
e9c71dd1 3430 case OPC_VR54XX_MULHI:
895c2d04 3431 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3432 opn = "mulhi";
6958549d 3433 break;
e9c71dd1 3434 case OPC_VR54XX_MULHIU:
895c2d04 3435 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3436 opn = "mulhiu";
6958549d 3437 break;
e9c71dd1 3438 case OPC_VR54XX_MULSHI:
895c2d04 3439 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3440 opn = "mulshi";
6958549d 3441 break;
e9c71dd1 3442 case OPC_VR54XX_MULSHIU:
895c2d04 3443 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3444 opn = "mulshiu";
6958549d 3445 break;
e9c71dd1 3446 case OPC_VR54XX_MACCHI:
895c2d04 3447 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3448 opn = "macchi";
6958549d 3449 break;
e9c71dd1 3450 case OPC_VR54XX_MACCHIU:
895c2d04 3451 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3452 opn = "macchiu";
6958549d 3453 break;
e9c71dd1 3454 case OPC_VR54XX_MSACHI:
895c2d04 3455 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3456 opn = "msachi";
6958549d 3457 break;
e9c71dd1 3458 case OPC_VR54XX_MSACHIU:
895c2d04 3459 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3460 opn = "msachiu";
6958549d 3461 break;
e9c71dd1
TS
3462 default:
3463 MIPS_INVAL("mul vr54xx");
3464 generate_exception(ctx, EXCP_RI);
6c5c1e20 3465 goto out;
e9c71dd1 3466 }
6c5c1e20 3467 gen_store_gpr(t0, rd);
2abf314d 3468 (void)opn; /* avoid a compiler warning */
e9c71dd1 3469 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3470
3471 out:
3472 tcg_temp_free(t0);
3473 tcg_temp_free(t1);
e9c71dd1
TS
3474}
3475
7a387fff 3476static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3477 int rd, int rs)
3478{
923617a3 3479 const char *opn = "CLx";
20e1fb52 3480 TCGv t0;
6c5c1e20 3481
6af0bf9c 3482 if (rd == 0) {
ead9360e 3483 /* Treat as NOP. */
6af0bf9c 3484 MIPS_DEBUG("NOP");
20e1fb52 3485 return;
6af0bf9c 3486 }
20e1fb52 3487 t0 = tcg_temp_new();
6c5c1e20 3488 gen_load_gpr(t0, rs);
6af0bf9c
FB
3489 switch (opc) {
3490 case OPC_CLO:
4267d3e6 3491 case R6_OPC_CLO:
20e1fb52 3492 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3493 opn = "clo";
3494 break;
3495 case OPC_CLZ:
4267d3e6 3496 case R6_OPC_CLZ:
20e1fb52 3497 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3498 opn = "clz";
3499 break;
d26bc211 3500#if defined(TARGET_MIPS64)
7a387fff 3501 case OPC_DCLO:
4267d3e6 3502 case R6_OPC_DCLO:
20e1fb52 3503 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3504 opn = "dclo";
3505 break;
3506 case OPC_DCLZ:
4267d3e6 3507 case R6_OPC_DCLZ:
20e1fb52 3508 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3509 opn = "dclz";
3510 break;
3511#endif
6af0bf9c 3512 }
2abf314d 3513 (void)opn; /* avoid a compiler warning */
6af0bf9c 3514 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3515 tcg_temp_free(t0);
6af0bf9c
FB
3516}
3517
161f85e6 3518/* Godson integer instructions */
bd277fa1
RH
3519static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3520 int rd, int rs, int rt)
161f85e6
AJ
3521{
3522 const char *opn = "loongson";
3523 TCGv t0, t1;
3524
3525 if (rd == 0) {
3526 /* Treat as NOP. */
3527 MIPS_DEBUG("NOP");
3528 return;
3529 }
3530
3531 switch (opc) {
3532 case OPC_MULT_G_2E:
3533 case OPC_MULT_G_2F:
3534 case OPC_MULTU_G_2E:
3535 case OPC_MULTU_G_2F:
3536#if defined(TARGET_MIPS64)
3537 case OPC_DMULT_G_2E:
3538 case OPC_DMULT_G_2F:
3539 case OPC_DMULTU_G_2E:
3540 case OPC_DMULTU_G_2F:
3541#endif
3542 t0 = tcg_temp_new();
3543 t1 = tcg_temp_new();
3544 break;
3545 default:
3546 t0 = tcg_temp_local_new();
3547 t1 = tcg_temp_local_new();
3548 break;
3549 }
3550
3551 gen_load_gpr(t0, rs);
3552 gen_load_gpr(t1, rt);
3553
3554 switch (opc) {
3555 case OPC_MULT_G_2E:
3556 case OPC_MULT_G_2F:
3557 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3558 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3559 opn = "mult.g";
3560 break;
3561 case OPC_MULTU_G_2E:
3562 case OPC_MULTU_G_2F:
3563 tcg_gen_ext32u_tl(t0, t0);
3564 tcg_gen_ext32u_tl(t1, t1);
3565 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3566 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3567 opn = "multu.g";
3568 break;
3569 case OPC_DIV_G_2E:
3570 case OPC_DIV_G_2F:
3571 {
3572 int l1 = gen_new_label();
3573 int l2 = gen_new_label();
3574 int l3 = gen_new_label();
3575 tcg_gen_ext32s_tl(t0, t0);
3576 tcg_gen_ext32s_tl(t1, t1);
3577 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3578 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3579 tcg_gen_br(l3);
3580 gen_set_label(l1);
3581 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3582 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3583 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3584 tcg_gen_br(l3);
3585 gen_set_label(l2);
3586 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3587 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3588 gen_set_label(l3);
3589 }
3590 opn = "div.g";
3591 break;
3592 case OPC_DIVU_G_2E:
3593 case OPC_DIVU_G_2F:
3594 {
3595 int l1 = gen_new_label();
3596 int l2 = gen_new_label();
3597 tcg_gen_ext32u_tl(t0, t0);
3598 tcg_gen_ext32u_tl(t1, t1);
3599 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3600 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3601 tcg_gen_br(l2);
3602 gen_set_label(l1);
3603 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3604 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3605 gen_set_label(l2);
3606 }
3607 opn = "divu.g";
3608 break;
3609 case OPC_MOD_G_2E:
3610 case OPC_MOD_G_2F:
3611 {
3612 int l1 = gen_new_label();
3613 int l2 = gen_new_label();
3614 int l3 = gen_new_label();
3615 tcg_gen_ext32u_tl(t0, t0);
3616 tcg_gen_ext32u_tl(t1, t1);
3617 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3618 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3619 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3620 gen_set_label(l1);
3621 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3622 tcg_gen_br(l3);
3623 gen_set_label(l2);
3624 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3625 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3626 gen_set_label(l3);
3627 }
3628 opn = "mod.g";
3629 break;
3630 case OPC_MODU_G_2E:
3631 case OPC_MODU_G_2F:
3632 {
3633 int l1 = gen_new_label();
3634 int l2 = gen_new_label();
3635 tcg_gen_ext32u_tl(t0, t0);
3636 tcg_gen_ext32u_tl(t1, t1);
3637 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3638 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3639 tcg_gen_br(l2);
3640 gen_set_label(l1);
3641 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3642 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3643 gen_set_label(l2);
3644 }
3645 opn = "modu.g";
3646 break;
3647#if defined(TARGET_MIPS64)
3648 case OPC_DMULT_G_2E:
3649 case OPC_DMULT_G_2F:
3650 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3651 opn = "dmult.g";
3652 break;
3653 case OPC_DMULTU_G_2E:
3654 case OPC_DMULTU_G_2F:
3655 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3656 opn = "dmultu.g";
3657 break;
3658 case OPC_DDIV_G_2E:
3659 case OPC_DDIV_G_2F:
3660 {
3661 int l1 = gen_new_label();
3662 int l2 = gen_new_label();
3663 int l3 = gen_new_label();
3664 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3665 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3666 tcg_gen_br(l3);
3667 gen_set_label(l1);
3668 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3669 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3670 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3671 tcg_gen_br(l3);
3672 gen_set_label(l2);
3673 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3674 gen_set_label(l3);
3675 }
3676 opn = "ddiv.g";
3677 break;
3678 case OPC_DDIVU_G_2E:
3679 case OPC_DDIVU_G_2F:
3680 {
3681 int l1 = gen_new_label();
3682 int l2 = gen_new_label();
3683 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3684 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3685 tcg_gen_br(l2);
3686 gen_set_label(l1);
3687 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3688 gen_set_label(l2);
3689 }
3690 opn = "ddivu.g";
3691 break;
3692 case OPC_DMOD_G_2E:
3693 case OPC_DMOD_G_2F:
3694 {
3695 int l1 = gen_new_label();
3696 int l2 = gen_new_label();
3697 int l3 = gen_new_label();
3698 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3699 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3700 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3701 gen_set_label(l1);
3702 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3703 tcg_gen_br(l3);
3704 gen_set_label(l2);
3705 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3706 gen_set_label(l3);
3707 }
3708 opn = "dmod.g";
3709 break;
3710 case OPC_DMODU_G_2E:
3711 case OPC_DMODU_G_2F:
3712 {
3713 int l1 = gen_new_label();
3714 int l2 = gen_new_label();
3715 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3716 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3717 tcg_gen_br(l2);
3718 gen_set_label(l1);
3719 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3720 gen_set_label(l2);
3721 }
3722 opn = "dmodu.g";
3723 break;
3724#endif
3725 }
3726
2abf314d 3727 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3728 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3729 tcg_temp_free(t0);
3730 tcg_temp_free(t1);
3731}
3732
bd277fa1
RH
3733/* Loongson multimedia instructions */
3734static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3735{
3736 const char *opn = "loongson_cp2";
3737 uint32_t opc, shift_max;
3738 TCGv_i64 t0, t1;
3739
3740 opc = MASK_LMI(ctx->opcode);
3741 switch (opc) {
3742 case OPC_ADD_CP2:
3743 case OPC_SUB_CP2:
3744 case OPC_DADD_CP2:
3745 case OPC_DSUB_CP2:
3746 t0 = tcg_temp_local_new_i64();
3747 t1 = tcg_temp_local_new_i64();
3748 break;
3749 default:
3750 t0 = tcg_temp_new_i64();
3751 t1 = tcg_temp_new_i64();
3752 break;
3753 }
3754
3755 gen_load_fpr64(ctx, t0, rs);
3756 gen_load_fpr64(ctx, t1, rt);
3757
3758#define LMI_HELPER(UP, LO) \
3759 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3760#define LMI_HELPER_1(UP, LO) \
3761 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3762#define LMI_DIRECT(UP, LO, OP) \
3763 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3764
3765 switch (opc) {
3766 LMI_HELPER(PADDSH, paddsh);
3767 LMI_HELPER(PADDUSH, paddush);
3768 LMI_HELPER(PADDH, paddh);
3769 LMI_HELPER(PADDW, paddw);
3770 LMI_HELPER(PADDSB, paddsb);
3771 LMI_HELPER(PADDUSB, paddusb);
3772 LMI_HELPER(PADDB, paddb);
3773
3774 LMI_HELPER(PSUBSH, psubsh);
3775 LMI_HELPER(PSUBUSH, psubush);
3776 LMI_HELPER(PSUBH, psubh);
3777 LMI_HELPER(PSUBW, psubw);
3778 LMI_HELPER(PSUBSB, psubsb);
3779 LMI_HELPER(PSUBUSB, psubusb);
3780 LMI_HELPER(PSUBB, psubb);
3781
3782 LMI_HELPER(PSHUFH, pshufh);
3783 LMI_HELPER(PACKSSWH, packsswh);
3784 LMI_HELPER(PACKSSHB, packsshb);
3785 LMI_HELPER(PACKUSHB, packushb);
3786
3787 LMI_HELPER(PUNPCKLHW, punpcklhw);
3788 LMI_HELPER(PUNPCKHHW, punpckhhw);
3789 LMI_HELPER(PUNPCKLBH, punpcklbh);
3790 LMI_HELPER(PUNPCKHBH, punpckhbh);
3791 LMI_HELPER(PUNPCKLWD, punpcklwd);
3792 LMI_HELPER(PUNPCKHWD, punpckhwd);
3793
3794 LMI_HELPER(PAVGH, pavgh);
3795 LMI_HELPER(PAVGB, pavgb);
3796 LMI_HELPER(PMAXSH, pmaxsh);
3797 LMI_HELPER(PMINSH, pminsh);
3798 LMI_HELPER(PMAXUB, pmaxub);
3799 LMI_HELPER(PMINUB, pminub);
3800
3801 LMI_HELPER(PCMPEQW, pcmpeqw);
3802 LMI_HELPER(PCMPGTW, pcmpgtw);
3803 LMI_HELPER(PCMPEQH, pcmpeqh);
3804 LMI_HELPER(PCMPGTH, pcmpgth);
3805 LMI_HELPER(PCMPEQB, pcmpeqb);
3806 LMI_HELPER(PCMPGTB, pcmpgtb);
3807
3808 LMI_HELPER(PSLLW, psllw);
3809 LMI_HELPER(PSLLH, psllh);
3810 LMI_HELPER(PSRLW, psrlw);
3811 LMI_HELPER(PSRLH, psrlh);
3812 LMI_HELPER(PSRAW, psraw);
3813 LMI_HELPER(PSRAH, psrah);
3814
3815 LMI_HELPER(PMULLH, pmullh);
3816 LMI_HELPER(PMULHH, pmulhh);
3817 LMI_HELPER(PMULHUH, pmulhuh);
3818 LMI_HELPER(PMADDHW, pmaddhw);
3819
3820 LMI_HELPER(PASUBUB, pasubub);
3821 LMI_HELPER_1(BIADD, biadd);
3822 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3823
3824 LMI_DIRECT(PADDD, paddd, add);
3825 LMI_DIRECT(PSUBD, psubd, sub);
3826 LMI_DIRECT(XOR_CP2, xor, xor);
3827 LMI_DIRECT(NOR_CP2, nor, nor);
3828 LMI_DIRECT(AND_CP2, and, and);
3829 LMI_DIRECT(PANDN, pandn, andc);
3830 LMI_DIRECT(OR, or, or);
3831
3832 case OPC_PINSRH_0:
3833 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3834 opn = "pinsrh_0";
3835 break;
3836 case OPC_PINSRH_1:
3837 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3838 opn = "pinsrh_1";
3839 break;
3840 case OPC_PINSRH_2:
3841 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3842 opn = "pinsrh_2";
3843 break;
3844 case OPC_PINSRH_3:
3845 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3846 opn = "pinsrh_3";
3847 break;
3848
3849 case OPC_PEXTRH:
3850 tcg_gen_andi_i64(t1, t1, 3);
3851 tcg_gen_shli_i64(t1, t1, 4);
3852 tcg_gen_shr_i64(t0, t0, t1);
3853 tcg_gen_ext16u_i64(t0, t0);
3854 opn = "pextrh";
3855 break;
3856
3857 case OPC_ADDU_CP2:
3858 tcg_gen_add_i64(t0, t0, t1);
3859 tcg_gen_ext32s_i64(t0, t0);
3860 opn = "addu";
3861 break;
3862 case OPC_SUBU_CP2:
3863 tcg_gen_sub_i64(t0, t0, t1);
3864 tcg_gen_ext32s_i64(t0, t0);
3865 opn = "addu";
3866 break;
3867
3868 case OPC_SLL_CP2:
3869 opn = "sll";
3870 shift_max = 32;
3871 goto do_shift;
3872 case OPC_SRL_CP2:
3873 opn = "srl";
3874 shift_max = 32;
3875 goto do_shift;
3876 case OPC_SRA_CP2:
3877 opn = "sra";
3878 shift_max = 32;
3879 goto do_shift;
3880 case OPC_DSLL_CP2:
3881 opn = "dsll";
3882 shift_max = 64;
3883 goto do_shift;
3884 case OPC_DSRL_CP2:
3885 opn = "dsrl";
3886 shift_max = 64;
3887 goto do_shift;
3888 case OPC_DSRA_CP2:
3889 opn = "dsra";
3890 shift_max = 64;
3891 goto do_shift;
3892 do_shift:
3893 /* Make sure shift count isn't TCG undefined behaviour. */
3894 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3895
3896 switch (opc) {
3897 case OPC_SLL_CP2:
3898 case OPC_DSLL_CP2:
3899 tcg_gen_shl_i64(t0, t0, t1);
3900 break;
3901 case OPC_SRA_CP2:
3902 case OPC_DSRA_CP2:
3903 /* Since SRA is UndefinedResult without sign-extended inputs,
3904 we can treat SRA and DSRA the same. */
3905 tcg_gen_sar_i64(t0, t0, t1);
3906 break;
3907 case OPC_SRL_CP2:
3908 /* We want to shift in zeros for SRL; zero-extend first. */
3909 tcg_gen_ext32u_i64(t0, t0);
3910 /* FALLTHRU */
3911 case OPC_DSRL_CP2:
3912 tcg_gen_shr_i64(t0, t0, t1);
3913 break;
3914 }
3915
3916 if (shift_max == 32) {
3917 tcg_gen_ext32s_i64(t0, t0);
3918 }
3919
3920 /* Shifts larger than MAX produce zero. */
3921 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3922 tcg_gen_neg_i64(t1, t1);
3923 tcg_gen_and_i64(t0, t0, t1);
3924 break;
3925
3926 case OPC_ADD_CP2:
3927 case OPC_DADD_CP2:
3928 {
3929 TCGv_i64 t2 = tcg_temp_new_i64();
3930 int lab = gen_new_label();
3931
3932 tcg_gen_mov_i64(t2, t0);
3933 tcg_gen_add_i64(t0, t1, t2);
3934 if (opc == OPC_ADD_CP2) {
3935 tcg_gen_ext32s_i64(t0, t0);
3936 }
3937 tcg_gen_xor_i64(t1, t1, t2);
3938 tcg_gen_xor_i64(t2, t2, t0);
3939 tcg_gen_andc_i64(t1, t2, t1);
3940 tcg_temp_free_i64(t2);
3941 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3942 generate_exception(ctx, EXCP_OVERFLOW);
3943 gen_set_label(lab);
3944
3945 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3946 break;
3947 }
3948
3949 case OPC_SUB_CP2:
3950 case OPC_DSUB_CP2:
3951 {
3952 TCGv_i64 t2 = tcg_temp_new_i64();
3953 int lab = gen_new_label();
3954
3955 tcg_gen_mov_i64(t2, t0);
3956 tcg_gen_sub_i64(t0, t1, t2);
3957 if (opc == OPC_SUB_CP2) {
3958 tcg_gen_ext32s_i64(t0, t0);
3959 }
3960 tcg_gen_xor_i64(t1, t1, t2);
3961 tcg_gen_xor_i64(t2, t2, t0);
3962 tcg_gen_and_i64(t1, t1, t2);
3963 tcg_temp_free_i64(t2);
3964 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3965 generate_exception(ctx, EXCP_OVERFLOW);
3966 gen_set_label(lab);
3967
3968 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3969 break;
3970 }
3971
3972 case OPC_PMULUW:
3973 tcg_gen_ext32u_i64(t0, t0);
3974 tcg_gen_ext32u_i64(t1, t1);
3975 tcg_gen_mul_i64(t0, t0, t1);
3976 opn = "pmuluw";
3977 break;
3978
3979 case OPC_SEQU_CP2:
3980 case OPC_SEQ_CP2:
3981 case OPC_SLTU_CP2:
3982 case OPC_SLT_CP2:
3983 case OPC_SLEU_CP2:
3984 case OPC_SLE_CP2:
3985 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3986 FD field is the CC field? */
3987 default:
3988 MIPS_INVAL(opn);
3989 generate_exception(ctx, EXCP_RI);
3990 return;
3991 }
3992
3993#undef LMI_HELPER
3994#undef LMI_DIRECT
3995
3996 gen_store_fpr64(ctx, t0, rd);
3997
3998 (void)opn; /* avoid a compiler warning */
3999 MIPS_DEBUG("%s %s, %s, %s", opn,
4000 fregnames[rd], fregnames[rs], fregnames[rt]);
4001 tcg_temp_free_i64(t0);
4002 tcg_temp_free_i64(t1);
4003}
4004
6af0bf9c 4005/* Traps */
7a387fff 4006static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4007 int rs, int rt, int16_t imm)
4008{
4009 int cond;
cdc0faa6 4010 TCGv t0 = tcg_temp_new();
1ba74fb8 4011 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4012
4013 cond = 0;
4014 /* Load needed operands */
4015 switch (opc) {
4016 case OPC_TEQ:
4017 case OPC_TGE:
4018 case OPC_TGEU:
4019 case OPC_TLT:
4020 case OPC_TLTU:
4021 case OPC_TNE:
4022 /* Compare two registers */
4023 if (rs != rt) {
be24bb4f
TS
4024 gen_load_gpr(t0, rs);
4025 gen_load_gpr(t1, rt);
6af0bf9c
FB
4026 cond = 1;
4027 }
179e32bb 4028 break;
6af0bf9c
FB
4029 case OPC_TEQI:
4030 case OPC_TGEI:
4031 case OPC_TGEIU:
4032 case OPC_TLTI:
4033 case OPC_TLTIU:
4034 case OPC_TNEI:
4035 /* Compare register to immediate */
4036 if (rs != 0 || imm != 0) {
be24bb4f
TS
4037 gen_load_gpr(t0, rs);
4038 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4039 cond = 1;
4040 }
4041 break;
4042 }
4043 if (cond == 0) {
4044 switch (opc) {
4045 case OPC_TEQ: /* rs == rs */
4046 case OPC_TEQI: /* r0 == 0 */
4047 case OPC_TGE: /* rs >= rs */
4048 case OPC_TGEI: /* r0 >= 0 */
4049 case OPC_TGEU: /* rs >= rs unsigned */
4050 case OPC_TGEIU: /* r0 >= 0 unsigned */
4051 /* Always trap */
cdc0faa6 4052 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4053 break;
4054 case OPC_TLT: /* rs < rs */
4055 case OPC_TLTI: /* r0 < 0 */
4056 case OPC_TLTU: /* rs < rs unsigned */
4057 case OPC_TLTIU: /* r0 < 0 unsigned */
4058 case OPC_TNE: /* rs != rs */
4059 case OPC_TNEI: /* r0 != 0 */
ead9360e 4060 /* Never trap: treat as NOP. */
cdc0faa6 4061 break;
6af0bf9c
FB
4062 }
4063 } else {
cdc0faa6
AJ
4064 int l1 = gen_new_label();
4065
6af0bf9c
FB
4066 switch (opc) {
4067 case OPC_TEQ:
4068 case OPC_TEQI:
cdc0faa6 4069 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4070 break;
4071 case OPC_TGE:
4072 case OPC_TGEI:
cdc0faa6 4073 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4074 break;
4075 case OPC_TGEU:
4076 case OPC_TGEIU:
cdc0faa6 4077 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4078 break;
4079 case OPC_TLT:
4080 case OPC_TLTI:
cdc0faa6 4081 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4082 break;
4083 case OPC_TLTU:
4084 case OPC_TLTIU:
cdc0faa6 4085 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4086 break;
4087 case OPC_TNE:
4088 case OPC_TNEI:
cdc0faa6 4089 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4090 break;
6af0bf9c 4091 }
cdc0faa6 4092 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4093 gen_set_label(l1);
4094 }
be24bb4f
TS
4095 tcg_temp_free(t0);
4096 tcg_temp_free(t1);
6af0bf9c
FB
4097}
4098
356265ae 4099static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4100{
6e256c93
FB
4101 TranslationBlock *tb;
4102 tb = ctx->tb;
7b270ef2
NF
4103 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4104 likely(!ctx->singlestep_enabled)) {
57fec1fe 4105 tcg_gen_goto_tb(n);
9b9e4393 4106 gen_save_pc(dest);
8cfd0495 4107 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4108 } else {
9b9e4393 4109 gen_save_pc(dest);
7b270ef2
NF
4110 if (ctx->singlestep_enabled) {
4111 save_cpu_state(ctx, 0);
895c2d04 4112 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4113 }
57fec1fe 4114 tcg_gen_exit_tb(0);
6e256c93 4115 }
c53be334
FB
4116}
4117
6af0bf9c 4118/* Branches (before delay slot) */
7a387fff 4119static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4120 int insn_bytes,
b231c103
YK
4121 int rs, int rt, int32_t offset,
4122 int delayslot_size)
6af0bf9c 4123{
d077b6f7 4124 target_ulong btgt = -1;
3ad4bb2d 4125 int blink = 0;
2fdbad25 4126 int bcond_compute = 0;
1ba74fb8
AJ
4127 TCGv t0 = tcg_temp_new();
4128 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4129
4130 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4131#ifdef MIPS_DEBUG_DISAS
d12d51d5 4132 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 4133#endif
3ad4bb2d 4134 generate_exception(ctx, EXCP_RI);
6c5c1e20 4135 goto out;
3ad4bb2d 4136 }
6af0bf9c 4137
6af0bf9c
FB
4138 /* Load needed operands */
4139 switch (opc) {
4140 case OPC_BEQ:
4141 case OPC_BEQL:
4142 case OPC_BNE:
4143 case OPC_BNEL:
4144 /* Compare two registers */
4145 if (rs != rt) {
6c5c1e20
TS
4146 gen_load_gpr(t0, rs);
4147 gen_load_gpr(t1, rt);
2fdbad25 4148 bcond_compute = 1;
6af0bf9c 4149 }
7dca4ad0 4150 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4151 break;
4152 case OPC_BGEZ:
4153 case OPC_BGEZAL:
4154 case OPC_BGEZALL:
4155 case OPC_BGEZL:
4156 case OPC_BGTZ:
4157 case OPC_BGTZL:
4158 case OPC_BLEZ:
4159 case OPC_BLEZL:
4160 case OPC_BLTZ:
4161 case OPC_BLTZAL:
4162 case OPC_BLTZALL:
4163 case OPC_BLTZL:
4164 /* Compare to zero */
4165 if (rs != 0) {
6c5c1e20 4166 gen_load_gpr(t0, rs);
2fdbad25 4167 bcond_compute = 1;
6af0bf9c 4168 }
7dca4ad0 4169 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4170 break;
e45a93e2
JL
4171 case OPC_BPOSGE32:
4172#if defined(TARGET_MIPS64)
4173 case OPC_BPOSGE64:
4174 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4175#else
4176 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4177#endif
4178 bcond_compute = 1;
4179 btgt = ctx->pc + insn_bytes + offset;
4180 break;
6af0bf9c
FB
4181 case OPC_J:
4182 case OPC_JAL:
364d4831 4183 case OPC_JALX:
6af0bf9c 4184 /* Jump to immediate */
7dca4ad0 4185 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4186 break;
4187 case OPC_JR:
4188 case OPC_JALR:
4189 /* Jump to register */
7a387fff
TS
4190 if (offset != 0 && offset != 16) {
4191 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4192 others are reserved. */
923617a3 4193 MIPS_INVAL("jump hint");
6af0bf9c 4194 generate_exception(ctx, EXCP_RI);
6c5c1e20 4195 goto out;
6af0bf9c 4196 }
d077b6f7 4197 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4198 break;
4199 default:
4200 MIPS_INVAL("branch/jump");
4201 generate_exception(ctx, EXCP_RI);
6c5c1e20 4202 goto out;
6af0bf9c 4203 }
2fdbad25 4204 if (bcond_compute == 0) {
6af0bf9c
FB
4205 /* No condition to be computed */
4206 switch (opc) {
4207 case OPC_BEQ: /* rx == rx */
4208 case OPC_BEQL: /* rx == rx likely */
4209 case OPC_BGEZ: /* 0 >= 0 */
4210 case OPC_BGEZL: /* 0 >= 0 likely */
4211 case OPC_BLEZ: /* 0 <= 0 */
4212 case OPC_BLEZL: /* 0 <= 0 likely */
4213 /* Always take */
4ad40f36 4214 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4215 MIPS_DEBUG("balways");
4216 break;
4217 case OPC_BGEZAL: /* 0 >= 0 */
4218 case OPC_BGEZALL: /* 0 >= 0 likely */
4219 /* Always take and link */
4220 blink = 31;
4ad40f36 4221 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4222 MIPS_DEBUG("balways and link");
4223 break;
4224 case OPC_BNE: /* rx != rx */
4225 case OPC_BGTZ: /* 0 > 0 */
4226 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4227 /* Treat as NOP. */
6af0bf9c 4228 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4229 goto out;
eeef26cd 4230 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4231 /* Handle as an unconditional branch to get correct delay
4232 slot checking. */
4233 blink = 31;
b231c103 4234 btgt = ctx->pc + insn_bytes + delayslot_size;
3c824109 4235 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4236 MIPS_DEBUG("bnever and link");
3c824109 4237 break;
eeef26cd 4238 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4239 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4240 /* Skip the instruction in the delay slot */
4241 MIPS_DEBUG("bnever, link and skip");
4242 ctx->pc += 4;
6c5c1e20 4243 goto out;
6af0bf9c
FB
4244 case OPC_BNEL: /* rx != rx likely */
4245 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4246 case OPC_BLTZL: /* 0 < 0 likely */
4247 /* Skip the instruction in the delay slot */
4248 MIPS_DEBUG("bnever and skip");
9898128f 4249 ctx->pc += 4;
6c5c1e20 4250 goto out;
6af0bf9c 4251 case OPC_J:
4ad40f36 4252 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4253 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4254 break;
364d4831
NF
4255 case OPC_JALX:
4256 ctx->hflags |= MIPS_HFLAG_BX;
4257 /* Fallthrough */
6af0bf9c
FB
4258 case OPC_JAL:
4259 blink = 31;
4ad40f36 4260 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4261 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4262 break;
4263 case OPC_JR:
4ad40f36 4264 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4265 MIPS_DEBUG("jr %s", regnames[rs]);
4266 break;
4267 case OPC_JALR:
4268 blink = rt;
4ad40f36 4269 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4270 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4271 break;
4272 default:
4273 MIPS_INVAL("branch/jump");
4274 generate_exception(ctx, EXCP_RI);
6c5c1e20 4275 goto out;
6af0bf9c
FB
4276 }
4277 } else {
4278 switch (opc) {
4279 case OPC_BEQ:
e68dd28f 4280 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4281 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4282 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4283 goto not_likely;
4284 case OPC_BEQL:
e68dd28f 4285 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4286 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4287 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4288 goto likely;
4289 case OPC_BNE:
e68dd28f 4290 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4291 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4292 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4293 goto not_likely;
4294 case OPC_BNEL:
e68dd28f 4295 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4296 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4297 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4298 goto likely;
4299 case OPC_BGEZ:
e68dd28f 4300 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4301 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4302 goto not_likely;
4303 case OPC_BGEZL:
e68dd28f 4304 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4305 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4306 goto likely;
4307 case OPC_BGEZAL:
e68dd28f 4308 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4309 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4310 blink = 31;
4311 goto not_likely;
4312 case OPC_BGEZALL:
e68dd28f 4313 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4314 blink = 31;
d077b6f7 4315 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4316 goto likely;
4317 case OPC_BGTZ:
e68dd28f 4318 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4319 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4320 goto not_likely;
4321 case OPC_BGTZL:
e68dd28f 4322 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4323 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4324 goto likely;
4325 case OPC_BLEZ:
e68dd28f 4326 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4327 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4328 goto not_likely;
4329 case OPC_BLEZL:
e68dd28f 4330 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4331 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4332 goto likely;
4333 case OPC_BLTZ:
e68dd28f 4334 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4335 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4336 goto not_likely;
4337 case OPC_BLTZL:
e68dd28f 4338 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4339 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4340 goto likely;
e45a93e2
JL
4341 case OPC_BPOSGE32:
4342 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4343 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4344 goto not_likely;
4345#if defined(TARGET_MIPS64)
4346 case OPC_BPOSGE64:
4347 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4348 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4349 goto not_likely;
4350#endif
6af0bf9c 4351 case OPC_BLTZAL:
e68dd28f 4352 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4353 blink = 31;
d077b6f7 4354 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4355 not_likely:
4ad40f36 4356 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4357 break;
4358 case OPC_BLTZALL:
e68dd28f 4359 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4360 blink = 31;
d077b6f7 4361 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4362 likely:
4ad40f36 4363 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4364 break;
c53f4a62
TS
4365 default:
4366 MIPS_INVAL("conditional branch/jump");
4367 generate_exception(ctx, EXCP_RI);
6c5c1e20 4368 goto out;
6af0bf9c 4369 }
6af0bf9c 4370 }
923617a3 4371 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4372 blink, ctx->hflags, btgt);
9b9e4393 4373
d077b6f7 4374 ctx->btarget = btgt;
b231c103
YK
4375
4376 switch (delayslot_size) {
4377 case 2:
4378 ctx->hflags |= MIPS_HFLAG_BDS16;
4379 break;
4380 case 4:
4381 ctx->hflags |= MIPS_HFLAG_BDS32;
4382 break;
4383 }
4384
6af0bf9c 4385 if (blink > 0) {
b231c103 4386 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4387 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4388
364d4831 4389 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4390 }
6c5c1e20
TS
4391
4392 out:
364d4831
NF
4393 if (insn_bytes == 2)
4394 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4395 tcg_temp_free(t0);
4396 tcg_temp_free(t1);
6af0bf9c
FB
4397}
4398
7a387fff
TS
4399/* special3 bitfield operations */
4400static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4401 int rs, int lsb, int msb)
7a387fff 4402{
a7812ae4
PB
4403 TCGv t0 = tcg_temp_new();
4404 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4405
4406 gen_load_gpr(t1, rs);
7a387fff
TS
4407 switch (opc) {
4408 case OPC_EXT:
4409 if (lsb + msb > 31)
4410 goto fail;
505ad7c2
AJ
4411 tcg_gen_shri_tl(t0, t1, lsb);
4412 if (msb != 31) {
4413 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4414 } else {
4415 tcg_gen_ext32s_tl(t0, t0);
4416 }
7a387fff 4417 break;
c6d6dd7c 4418#if defined(TARGET_MIPS64)
7a387fff 4419 case OPC_DEXTM:
505ad7c2
AJ
4420 tcg_gen_shri_tl(t0, t1, lsb);
4421 if (msb != 31) {
4422 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4423 }
7a387fff
TS
4424 break;
4425 case OPC_DEXTU:
505ad7c2
AJ
4426 tcg_gen_shri_tl(t0, t1, lsb + 32);
4427 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4428 break;
4429 case OPC_DEXT:
505ad7c2
AJ
4430 tcg_gen_shri_tl(t0, t1, lsb);
4431 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4432 break;
c6d6dd7c 4433#endif
7a387fff
TS
4434 case OPC_INS:
4435 if (lsb > msb)
4436 goto fail;
6c5c1e20 4437 gen_load_gpr(t0, rt);
e0d002f1 4438 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4439 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4440 break;
c6d6dd7c 4441#if defined(TARGET_MIPS64)
7a387fff 4442 case OPC_DINSM:
6c5c1e20 4443 gen_load_gpr(t0, rt);
e0d002f1 4444 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4445 break;
4446 case OPC_DINSU:
6c5c1e20 4447 gen_load_gpr(t0, rt);
e0d002f1 4448 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4449 break;
4450 case OPC_DINS:
6c5c1e20 4451 gen_load_gpr(t0, rt);
e0d002f1 4452 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4453 break;
c6d6dd7c 4454#endif
7a387fff
TS
4455 default:
4456fail:
4457 MIPS_INVAL("bitops");
4458 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4459 tcg_temp_free(t0);
4460 tcg_temp_free(t1);
7a387fff
TS
4461 return;
4462 }
6c5c1e20
TS
4463 gen_store_gpr(t0, rt);
4464 tcg_temp_free(t0);
4465 tcg_temp_free(t1);
7a387fff
TS
4466}
4467
49bcf33c
AJ
4468static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4469{
3a55fa47 4470 TCGv t0;
49bcf33c 4471
3a55fa47
AJ
4472 if (rd == 0) {
4473 /* If no destination, treat it as a NOP. */
4474 MIPS_DEBUG("NOP");
4475 return;
4476 }
4477
4478 t0 = tcg_temp_new();
4479 gen_load_gpr(t0, rt);
49bcf33c
AJ
4480 switch (op2) {
4481 case OPC_WSBH:
3a55fa47
AJ
4482 {
4483 TCGv t1 = tcg_temp_new();
4484
4485 tcg_gen_shri_tl(t1, t0, 8);
4486 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4487 tcg_gen_shli_tl(t0, t0, 8);
4488 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4489 tcg_gen_or_tl(t0, t0, t1);
4490 tcg_temp_free(t1);
4491 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4492 }
49bcf33c
AJ
4493 break;
4494 case OPC_SEB:
3a55fa47 4495 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4496 break;
4497 case OPC_SEH:
3a55fa47 4498 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4499 break;
4500#if defined(TARGET_MIPS64)
4501 case OPC_DSBH:
3a55fa47
AJ
4502 {
4503 TCGv t1 = tcg_temp_new();
4504
4505 tcg_gen_shri_tl(t1, t0, 8);
4506 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4507 tcg_gen_shli_tl(t0, t0, 8);
4508 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4509 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4510 tcg_temp_free(t1);
4511 }
49bcf33c
AJ
4512 break;
4513 case OPC_DSHD:
3a55fa47
AJ
4514 {
4515 TCGv t1 = tcg_temp_new();
4516
4517 tcg_gen_shri_tl(t1, t0, 16);
4518 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4519 tcg_gen_shli_tl(t0, t0, 16);
4520 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4521 tcg_gen_or_tl(t0, t0, t1);
4522 tcg_gen_shri_tl(t1, t0, 32);
4523 tcg_gen_shli_tl(t0, t0, 32);
4524 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4525 tcg_temp_free(t1);
4526 }
49bcf33c
AJ
4527 break;
4528#endif
4529 default:
4530 MIPS_INVAL("bsfhl");
4531 generate_exception(ctx, EXCP_RI);
4532 tcg_temp_free(t0);
49bcf33c
AJ
4533 return;
4534 }
49bcf33c 4535 tcg_temp_free(t0);
49bcf33c
AJ
4536}
4537
f1aa6320 4538#ifndef CONFIG_USER_ONLY
0eaef5aa 4539/* CP0 (MMU and control) */
d9bea114 4540static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4541{
d9bea114 4542 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4543
d9bea114
AJ
4544 tcg_gen_ld_i32(t0, cpu_env, off);
4545 tcg_gen_ext_i32_tl(arg, t0);
4546 tcg_temp_free_i32(t0);
4f57689a
TS
4547}
4548
d9bea114 4549static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4550{
d9bea114
AJ
4551 tcg_gen_ld_tl(arg, cpu_env, off);
4552 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4553}
4554
d9bea114 4555static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4556{
d9bea114 4557 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4558
d9bea114
AJ
4559 tcg_gen_trunc_tl_i32(t0, arg);
4560 tcg_gen_st_i32(t0, cpu_env, off);
4561 tcg_temp_free_i32(t0);
f1aa6320
TS
4562}
4563
d9bea114 4564static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4565{
d9bea114
AJ
4566 tcg_gen_ext32s_tl(arg, arg);
4567 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4568}
4569
d75c135e 4570static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4571{
7a387fff 4572 const char *rn = "invalid";
873eb012 4573
e189e748 4574 if (sel != 0)
d75c135e 4575 check_insn(ctx, ISA_MIPS32);
e189e748 4576
873eb012
TS
4577 switch (reg) {
4578 case 0:
7a387fff
TS
4579 switch (sel) {
4580 case 0:
7db13fae 4581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4582 rn = "Index";
4583 break;
4584 case 1:
d75c135e 4585 check_insn(ctx, ASE_MT);
895c2d04 4586 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4587 rn = "MVPControl";
ead9360e 4588 break;
7a387fff 4589 case 2:
d75c135e 4590 check_insn(ctx, ASE_MT);
895c2d04 4591 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4592 rn = "MVPConf0";
ead9360e 4593 break;
7a387fff 4594 case 3:
d75c135e 4595 check_insn(ctx, ASE_MT);
895c2d04 4596 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4597 rn = "MVPConf1";
ead9360e 4598 break;
7a387fff
TS
4599 default:
4600 goto die;
4601 }
873eb012
TS
4602 break;
4603 case 1:
7a387fff
TS
4604 switch (sel) {
4605 case 0:
895c2d04 4606 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4607 rn = "Random";
2423f660 4608 break;
7a387fff 4609 case 1:
d75c135e 4610 check_insn(ctx, ASE_MT);
7db13fae 4611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4612 rn = "VPEControl";
ead9360e 4613 break;
7a387fff 4614 case 2:
d75c135e 4615 check_insn(ctx, ASE_MT);
7db13fae 4616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4617 rn = "VPEConf0";
ead9360e 4618 break;
7a387fff 4619 case 3:
d75c135e 4620 check_insn(ctx, ASE_MT);
7db13fae 4621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4622 rn = "VPEConf1";
ead9360e 4623 break;
7a387fff 4624 case 4:
d75c135e 4625 check_insn(ctx, ASE_MT);
7db13fae 4626 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4627 rn = "YQMask";
ead9360e 4628 break;
7a387fff 4629 case 5:
d75c135e 4630 check_insn(ctx, ASE_MT);
7db13fae 4631 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4632 rn = "VPESchedule";
ead9360e 4633 break;
7a387fff 4634 case 6:
d75c135e 4635 check_insn(ctx, ASE_MT);
7db13fae 4636 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4637 rn = "VPEScheFBack";
ead9360e 4638 break;
7a387fff 4639 case 7:
d75c135e 4640 check_insn(ctx, ASE_MT);
7db13fae 4641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4642 rn = "VPEOpt";
ead9360e 4643 break;
7a387fff
TS
4644 default:
4645 goto die;
4646 }
873eb012
TS
4647 break;
4648 case 2:
7a387fff
TS
4649 switch (sel) {
4650 case 0:
7db13fae 4651 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4652 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4653 rn = "EntryLo0";
4654 break;
7a387fff 4655 case 1:
d75c135e 4656 check_insn(ctx, ASE_MT);
895c2d04 4657 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4658 rn = "TCStatus";
ead9360e 4659 break;
7a387fff 4660 case 2:
d75c135e 4661 check_insn(ctx, ASE_MT);
895c2d04 4662 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4663 rn = "TCBind";
ead9360e 4664 break;
7a387fff 4665 case 3:
d75c135e 4666 check_insn(ctx, ASE_MT);
895c2d04 4667 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4668 rn = "TCRestart";
ead9360e 4669 break;
7a387fff 4670 case 4:
d75c135e 4671 check_insn(ctx, ASE_MT);
895c2d04 4672 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4673 rn = "TCHalt";
ead9360e 4674 break;
7a387fff 4675 case 5:
d75c135e 4676 check_insn(ctx, ASE_MT);
895c2d04 4677 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4678 rn = "TCContext";
ead9360e 4679 break;
7a387fff 4680 case 6:
d75c135e 4681 check_insn(ctx, ASE_MT);
895c2d04 4682 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4683 rn = "TCSchedule";
ead9360e 4684 break;
7a387fff 4685 case 7:
d75c135e 4686 check_insn(ctx, ASE_MT);
895c2d04 4687 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4688 rn = "TCScheFBack";
ead9360e 4689 break;
7a387fff
TS
4690 default:
4691 goto die;
4692 }
873eb012
TS
4693 break;
4694 case 3:
7a387fff
TS
4695 switch (sel) {
4696 case 0:
7db13fae 4697 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4698 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4699 rn = "EntryLo1";
4700 break;
7a387fff
TS
4701 default:
4702 goto die;
1579a72e 4703 }
873eb012
TS
4704 break;
4705 case 4:
7a387fff
TS
4706 switch (sel) {
4707 case 0:
7db13fae 4708 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4709 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4710 rn = "Context";
4711 break;
7a387fff 4712 case 1:
d9bea114 4713// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 4714 rn = "ContextConfig";
d279279e 4715 goto die;
2423f660 4716// break;
d279279e
PJ
4717 case 2:
4718 if (ctx->ulri) {
4719 tcg_gen_ld32s_tl(arg, cpu_env,
4720 offsetof(CPUMIPSState,
4721 active_tc.CP0_UserLocal));
4722 rn = "UserLocal";
4723 } else {
4724 tcg_gen_movi_tl(arg, 0);
4725 }
4726 break;
7a387fff
TS
4727 default:
4728 goto die;
1579a72e 4729 }
873eb012
TS
4730 break;
4731 case 5:
7a387fff
TS
4732 switch (sel) {
4733 case 0:
7db13fae 4734 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4735 rn = "PageMask";
4736 break;
7a387fff 4737 case 1:
d75c135e 4738 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4739 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4740 rn = "PageGrain";
4741 break;
7a387fff
TS
4742 default:
4743 goto die;
1579a72e 4744 }
873eb012
TS
4745 break;
4746 case 6:
7a387fff
TS
4747 switch (sel) {
4748 case 0:
7db13fae 4749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4750 rn = "Wired";
4751 break;
7a387fff 4752 case 1:
d75c135e 4753 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4754 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4755 rn = "SRSConf0";
ead9360e 4756 break;
7a387fff 4757 case 2:
d75c135e 4758 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4760 rn = "SRSConf1";
ead9360e 4761 break;
7a387fff 4762 case 3:
d75c135e 4763 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4764 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4765 rn = "SRSConf2";
ead9360e 4766 break;
7a387fff 4767 case 4:
d75c135e 4768 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4769 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4770 rn = "SRSConf3";
ead9360e 4771 break;
7a387fff 4772 case 5:
d75c135e 4773 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4774 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4775 rn = "SRSConf4";
ead9360e 4776 break;
7a387fff
TS
4777 default:
4778 goto die;
1579a72e 4779 }
873eb012 4780 break;
8c0fdd85 4781 case 7:
7a387fff
TS
4782 switch (sel) {
4783 case 0:
d75c135e 4784 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4785 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4786 rn = "HWREna";
4787 break;
7a387fff
TS
4788 default:
4789 goto die;
1579a72e 4790 }
8c0fdd85 4791 break;
873eb012 4792 case 8:
7a387fff
TS
4793 switch (sel) {
4794 case 0:
7db13fae 4795 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4796 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4797 rn = "BadVAddr";
2423f660 4798 break;
7a387fff
TS
4799 default:
4800 goto die;
4801 }
873eb012
TS
4802 break;
4803 case 9:
7a387fff
TS
4804 switch (sel) {
4805 case 0:
2e70f6ef
PB
4806 /* Mark as an IO operation because we read the time. */
4807 if (use_icount)
4808 gen_io_start();
895c2d04 4809 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4810 if (use_icount) {
4811 gen_io_end();
2e70f6ef 4812 }
55807224
EI
4813 /* Break the TB to be able to take timer interrupts immediately
4814 after reading count. */
4815 ctx->bstate = BS_STOP;
2423f660
TS
4816 rn = "Count";
4817 break;
4818 /* 6,7 are implementation dependent */
7a387fff
TS
4819 default:
4820 goto die;
2423f660 4821 }
873eb012
TS
4822 break;
4823 case 10:
7a387fff
TS
4824 switch (sel) {
4825 case 0:
7db13fae 4826 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4827 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4828 rn = "EntryHi";
4829 break;
7a387fff
TS
4830 default:
4831 goto die;
1579a72e 4832 }
873eb012
TS
4833 break;
4834 case 11:
7a387fff
TS
4835 switch (sel) {
4836 case 0:
7db13fae 4837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4838 rn = "Compare";
4839 break;
4840 /* 6,7 are implementation dependent */
7a387fff
TS
4841 default:
4842 goto die;
2423f660 4843 }
873eb012
TS
4844 break;
4845 case 12:
7a387fff
TS
4846 switch (sel) {
4847 case 0:
7db13fae 4848 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4849 rn = "Status";
4850 break;
7a387fff 4851 case 1:
d75c135e 4852 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4853 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4854 rn = "IntCtl";
4855 break;
7a387fff 4856 case 2:
d75c135e 4857 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4858 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4859 rn = "SRSCtl";
4860 break;
7a387fff 4861 case 3:
d75c135e 4862 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4863 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4864 rn = "SRSMap";
fd88b6ab 4865 break;
7a387fff
TS
4866 default:
4867 goto die;
4868 }
873eb012
TS
4869 break;
4870 case 13:
7a387fff
TS
4871 switch (sel) {
4872 case 0:
7db13fae 4873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4874 rn = "Cause";
4875 break;
7a387fff
TS
4876 default:
4877 goto die;
4878 }
873eb012
TS
4879 break;
4880 case 14:
7a387fff
TS
4881 switch (sel) {
4882 case 0:
7db13fae 4883 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4884 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4885 rn = "EPC";
4886 break;
7a387fff
TS
4887 default:
4888 goto die;
1579a72e 4889 }
873eb012
TS
4890 break;
4891 case 15:
7a387fff
TS
4892 switch (sel) {
4893 case 0:
7db13fae 4894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4895 rn = "PRid";
4896 break;
7a387fff 4897 case 1:
d75c135e 4898 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4899 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4900 rn = "EBase";
4901 break;
7a387fff
TS
4902 default:
4903 goto die;
4904 }
873eb012
TS
4905 break;
4906 case 16:
4907 switch (sel) {
4908 case 0:
7db13fae 4909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4910 rn = "Config";
4911 break;
4912 case 1:
7db13fae 4913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4914 rn = "Config1";
4915 break;
7a387fff 4916 case 2:
7db13fae 4917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4918 rn = "Config2";
4919 break;
4920 case 3:
7db13fae 4921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4922 rn = "Config3";
4923 break;
b4160af1
PJ
4924 case 4:
4925 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4926 rn = "Config4";
4927 break;
b4dd99a3
PJ
4928 case 5:
4929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4930 rn = "Config5";
4931 break;
e397ee33
TS
4932 /* 6,7 are implementation dependent */
4933 case 6:
7db13fae 4934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4935 rn = "Config6";
4936 break;
4937 case 7:
7db13fae 4938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4939 rn = "Config7";
4940 break;
873eb012 4941 default:
873eb012
TS
4942 goto die;
4943 }
4944 break;
4945 case 17:
7a387fff
TS
4946 switch (sel) {
4947 case 0:
895c2d04 4948 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4949 rn = "LLAddr";
4950 break;
7a387fff
TS
4951 default:
4952 goto die;
4953 }
873eb012
TS
4954 break;
4955 case 18:
7a387fff 4956 switch (sel) {
fd88b6ab 4957 case 0 ... 7:
895c2d04 4958 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4959 rn = "WatchLo";
4960 break;
7a387fff
TS
4961 default:
4962 goto die;
4963 }
873eb012
TS
4964 break;
4965 case 19:
7a387fff 4966 switch (sel) {
fd88b6ab 4967 case 0 ...7:
895c2d04 4968 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4969 rn = "WatchHi";
4970 break;
7a387fff
TS
4971 default:
4972 goto die;
4973 }
873eb012 4974 break;
8c0fdd85 4975 case 20:
7a387fff
TS
4976 switch (sel) {
4977 case 0:
d26bc211 4978#if defined(TARGET_MIPS64)
d75c135e 4979 check_insn(ctx, ISA_MIPS3);
7db13fae 4980 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4981 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4982 rn = "XContext";
4983 break;
703eaf37 4984#endif
7a387fff
TS
4985 default:
4986 goto die;
4987 }
8c0fdd85
TS
4988 break;
4989 case 21:
7a387fff
TS
4990 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4991 switch (sel) {
4992 case 0:
7db13fae 4993 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4994 rn = "Framemask";
4995 break;
7a387fff
TS
4996 default:
4997 goto die;
4998 }
8c0fdd85
TS
4999 break;
5000 case 22:
d9bea114 5001 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5002 rn = "'Diagnostic"; /* implementation dependent */
5003 break;
873eb012 5004 case 23:
7a387fff
TS
5005 switch (sel) {
5006 case 0:
895c2d04 5007 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5008 rn = "Debug";
5009 break;
7a387fff 5010 case 1:
d9bea114 5011// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5012 rn = "TraceControl";
5013// break;
7a387fff 5014 case 2:
d9bea114 5015// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5016 rn = "TraceControl2";
5017// break;
7a387fff 5018 case 3:
d9bea114 5019// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5020 rn = "UserTraceData";
5021// break;
7a387fff 5022 case 4:
d9bea114 5023// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5024 rn = "TraceBPC";
5025// break;
7a387fff
TS
5026 default:
5027 goto die;
5028 }
873eb012
TS
5029 break;
5030 case 24:
7a387fff
TS
5031 switch (sel) {
5032 case 0:
f0b3f3ae 5033 /* EJTAG support */
7db13fae 5034 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5035 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5036 rn = "DEPC";
5037 break;
7a387fff
TS
5038 default:
5039 goto die;
5040 }
873eb012 5041 break;
8c0fdd85 5042 case 25:
7a387fff
TS
5043 switch (sel) {
5044 case 0:
7db13fae 5045 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5046 rn = "Performance0";
7a387fff
TS
5047 break;
5048 case 1:
d9bea114 5049// gen_helper_mfc0_performance1(arg);
2423f660
TS
5050 rn = "Performance1";
5051// break;
7a387fff 5052 case 2:
d9bea114 5053// gen_helper_mfc0_performance2(arg);
2423f660
TS
5054 rn = "Performance2";
5055// break;
7a387fff 5056 case 3:
d9bea114 5057// gen_helper_mfc0_performance3(arg);
2423f660
TS
5058 rn = "Performance3";
5059// break;
7a387fff 5060 case 4:
d9bea114 5061// gen_helper_mfc0_performance4(arg);
2423f660
TS
5062 rn = "Performance4";
5063// break;
7a387fff 5064 case 5:
d9bea114 5065// gen_helper_mfc0_performance5(arg);
2423f660
TS
5066 rn = "Performance5";
5067// break;
7a387fff 5068 case 6:
d9bea114 5069// gen_helper_mfc0_performance6(arg);
2423f660
TS
5070 rn = "Performance6";
5071// break;
7a387fff 5072 case 7:
d9bea114 5073// gen_helper_mfc0_performance7(arg);
2423f660
TS
5074 rn = "Performance7";
5075// break;
7a387fff
TS
5076 default:
5077 goto die;
5078 }
8c0fdd85
TS
5079 break;
5080 case 26:
d9bea114 5081 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5082 rn = "ECC";
5083 break;
8c0fdd85 5084 case 27:
7a387fff 5085 switch (sel) {
7a387fff 5086 case 0 ... 3:
d9bea114 5087 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5088 rn = "CacheErr";
5089 break;
7a387fff
TS
5090 default:
5091 goto die;
5092 }
8c0fdd85 5093 break;
873eb012
TS
5094 case 28:
5095 switch (sel) {
5096 case 0:
7a387fff
TS
5097 case 2:
5098 case 4:
5099 case 6:
7db13fae 5100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5101 rn = "TagLo";
5102 break;
5103 case 1:
7a387fff
TS
5104 case 3:
5105 case 5:
5106 case 7:
7db13fae 5107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5108 rn = "DataLo";
5109 break;
5110 default:
873eb012
TS
5111 goto die;
5112 }
5113 break;
8c0fdd85 5114 case 29:
7a387fff
TS
5115 switch (sel) {
5116 case 0:
5117 case 2:
5118 case 4:
5119 case 6:
7db13fae 5120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5121 rn = "TagHi";
5122 break;
5123 case 1:
5124 case 3:
5125 case 5:
5126 case 7:
7db13fae 5127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5128 rn = "DataHi";
5129 break;
5130 default:
5131 goto die;
5132 }
8c0fdd85 5133 break;
873eb012 5134 case 30:
7a387fff
TS
5135 switch (sel) {
5136 case 0:
7db13fae 5137 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5138 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5139 rn = "ErrorEPC";
5140 break;
7a387fff
TS
5141 default:
5142 goto die;
5143 }
873eb012
TS
5144 break;
5145 case 31:
7a387fff
TS
5146 switch (sel) {
5147 case 0:
f0b3f3ae 5148 /* EJTAG support */
7db13fae 5149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5150 rn = "DESAVE";
5151 break;
7a387fff
TS
5152 default:
5153 goto die;
5154 }
873eb012
TS
5155 break;
5156 default:
873eb012
TS
5157 goto die;
5158 }
2abf314d 5159 (void)rn; /* avoid a compiler warning */
d12d51d5 5160 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5161 return;
5162
5163die:
d12d51d5 5164 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5165 generate_exception(ctx, EXCP_RI);
5166}
5167
d75c135e 5168static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5169{
7a387fff
TS
5170 const char *rn = "invalid";
5171
e189e748 5172 if (sel != 0)
d75c135e 5173 check_insn(ctx, ISA_MIPS32);
e189e748 5174
2e70f6ef
PB
5175 if (use_icount)
5176 gen_io_start();
5177
8c0fdd85
TS
5178 switch (reg) {
5179 case 0:
7a387fff
TS
5180 switch (sel) {
5181 case 0:
895c2d04 5182 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5183 rn = "Index";
5184 break;
5185 case 1:
d75c135e 5186 check_insn(ctx, ASE_MT);
895c2d04 5187 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5188 rn = "MVPControl";
ead9360e 5189 break;
7a387fff 5190 case 2:
d75c135e 5191 check_insn(ctx, ASE_MT);
ead9360e 5192 /* ignored */
7a387fff 5193 rn = "MVPConf0";
ead9360e 5194 break;
7a387fff 5195 case 3:
d75c135e 5196 check_insn(ctx, ASE_MT);
ead9360e 5197 /* ignored */
7a387fff 5198 rn = "MVPConf1";
ead9360e 5199 break;
7a387fff
TS
5200 default:
5201 goto die;
5202 }
8c0fdd85
TS
5203 break;
5204 case 1:
7a387fff
TS
5205 switch (sel) {
5206 case 0:
2423f660 5207 /* ignored */
7a387fff 5208 rn = "Random";
2423f660 5209 break;
7a387fff 5210 case 1:
d75c135e 5211 check_insn(ctx, ASE_MT);
895c2d04 5212 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5213 rn = "VPEControl";
ead9360e 5214 break;
7a387fff 5215 case 2:
d75c135e 5216 check_insn(ctx, ASE_MT);
895c2d04 5217 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5218 rn = "VPEConf0";
ead9360e 5219 break;
7a387fff 5220 case 3:
d75c135e 5221 check_insn(ctx, ASE_MT);
895c2d04 5222 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5223 rn = "VPEConf1";
ead9360e 5224 break;
7a387fff 5225 case 4:
d75c135e 5226 check_insn(ctx, ASE_MT);
895c2d04 5227 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5228 rn = "YQMask";
ead9360e 5229 break;
7a387fff 5230 case 5:
d75c135e 5231 check_insn(ctx, ASE_MT);
7db13fae 5232 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5233 rn = "VPESchedule";
ead9360e 5234 break;
7a387fff 5235 case 6:
d75c135e 5236 check_insn(ctx, ASE_MT);
7db13fae 5237 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5238 rn = "VPEScheFBack";
ead9360e 5239 break;
7a387fff 5240 case 7:
d75c135e 5241 check_insn(ctx, ASE_MT);
895c2d04 5242 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5243 rn = "VPEOpt";
ead9360e 5244 break;
7a387fff
TS
5245 default:
5246 goto die;
5247 }
8c0fdd85
TS
5248 break;
5249 case 2:
7a387fff
TS
5250 switch (sel) {
5251 case 0:
895c2d04 5252 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5253 rn = "EntryLo0";
5254 break;
7a387fff 5255 case 1:
d75c135e 5256 check_insn(ctx, ASE_MT);
895c2d04 5257 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5258 rn = "TCStatus";
ead9360e 5259 break;
7a387fff 5260 case 2:
d75c135e 5261 check_insn(ctx, ASE_MT);
895c2d04 5262 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5263 rn = "TCBind";
ead9360e 5264 break;
7a387fff 5265 case 3:
d75c135e 5266 check_insn(ctx, ASE_MT);
895c2d04 5267 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5268 rn = "TCRestart";
ead9360e 5269 break;
7a387fff 5270 case 4:
d75c135e 5271 check_insn(ctx, ASE_MT);
895c2d04 5272 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5273 rn = "TCHalt";
ead9360e 5274 break;
7a387fff 5275 case 5:
d75c135e 5276 check_insn(ctx, ASE_MT);
895c2d04 5277 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5278 rn = "TCContext";
ead9360e 5279 break;
7a387fff 5280 case 6:
d75c135e 5281 check_insn(ctx, ASE_MT);
895c2d04 5282 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5283 rn = "TCSchedule";
ead9360e 5284 break;
7a387fff 5285 case 7:
d75c135e 5286 check_insn(ctx, ASE_MT);
895c2d04 5287 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5288 rn = "TCScheFBack";
ead9360e 5289 break;
7a387fff
TS
5290 default:
5291 goto die;
5292 }
8c0fdd85
TS
5293 break;
5294 case 3:
7a387fff
TS
5295 switch (sel) {
5296 case 0:
895c2d04 5297 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5298 rn = "EntryLo1";
5299 break;
7a387fff
TS
5300 default:
5301 goto die;
876d4b07 5302 }
8c0fdd85
TS
5303 break;
5304 case 4:
7a387fff
TS
5305 switch (sel) {
5306 case 0:
895c2d04 5307 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5308 rn = "Context";
5309 break;
7a387fff 5310 case 1:
895c2d04 5311// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5312 rn = "ContextConfig";
d279279e 5313 goto die;
2423f660 5314// break;
d279279e
PJ
5315 case 2:
5316 if (ctx->ulri) {
5317 tcg_gen_st_tl(arg, cpu_env,
5318 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5319 rn = "UserLocal";
5320 }
5321 break;
7a387fff
TS
5322 default:
5323 goto die;
876d4b07 5324 }
8c0fdd85
TS
5325 break;
5326 case 5:
7a387fff
TS
5327 switch (sel) {
5328 case 0:
895c2d04 5329 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5330 rn = "PageMask";
5331 break;
7a387fff 5332 case 1:
d75c135e 5333 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5334 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5335 rn = "PageGrain";
5336 break;
7a387fff
TS
5337 default:
5338 goto die;
876d4b07 5339 }
8c0fdd85
TS
5340 break;
5341 case 6:
7a387fff
TS
5342 switch (sel) {
5343 case 0:
895c2d04 5344 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5345 rn = "Wired";
5346 break;
7a387fff 5347 case 1:
d75c135e 5348 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5349 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5350 rn = "SRSConf0";
ead9360e 5351 break;
7a387fff 5352 case 2:
d75c135e 5353 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5354 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5355 rn = "SRSConf1";
ead9360e 5356 break;
7a387fff 5357 case 3:
d75c135e 5358 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5359 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5360 rn = "SRSConf2";
ead9360e 5361 break;
7a387fff 5362 case 4:
d75c135e 5363 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5364 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5365 rn = "SRSConf3";
ead9360e 5366 break;
7a387fff 5367 case 5:
d75c135e 5368 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5369 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5370 rn = "SRSConf4";
ead9360e 5371 break;
7a387fff
TS
5372 default:
5373 goto die;
876d4b07 5374 }
8c0fdd85
TS
5375 break;
5376 case 7:
7a387fff
TS
5377 switch (sel) {
5378 case 0:
d75c135e 5379 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5380 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5381 ctx->bstate = BS_STOP;
2423f660
TS
5382 rn = "HWREna";
5383 break;
7a387fff
TS
5384 default:
5385 goto die;
876d4b07 5386 }
8c0fdd85
TS
5387 break;
5388 case 8:
7a387fff 5389 /* ignored */
f0b3f3ae 5390 rn = "BadVAddr";
8c0fdd85
TS
5391 break;
5392 case 9:
7a387fff
TS
5393 switch (sel) {
5394 case 0:
895c2d04 5395 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5396 rn = "Count";
5397 break;
876d4b07 5398 /* 6,7 are implementation dependent */
7a387fff
TS
5399 default:
5400 goto die;
876d4b07 5401 }
8c0fdd85
TS
5402 break;
5403 case 10:
7a387fff
TS
5404 switch (sel) {
5405 case 0:
895c2d04 5406 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5407 rn = "EntryHi";
5408 break;
7a387fff
TS
5409 default:
5410 goto die;
876d4b07 5411 }
8c0fdd85
TS
5412 break;
5413 case 11:
7a387fff
TS
5414 switch (sel) {
5415 case 0:
895c2d04 5416 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5417 rn = "Compare";
5418 break;
5419 /* 6,7 are implementation dependent */
7a387fff
TS
5420 default:
5421 goto die;
876d4b07 5422 }
8c0fdd85
TS
5423 break;
5424 case 12:
7a387fff
TS
5425 switch (sel) {
5426 case 0:
867abc7e 5427 save_cpu_state(ctx, 1);
895c2d04 5428 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5429 /* BS_STOP isn't good enough here, hflags may have changed. */
5430 gen_save_pc(ctx->pc + 4);
5431 ctx->bstate = BS_EXCP;
2423f660
TS
5432 rn = "Status";
5433 break;
7a387fff 5434 case 1:
d75c135e 5435 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5436 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5437 /* Stop translation as we may have switched the execution mode */
5438 ctx->bstate = BS_STOP;
2423f660
TS
5439 rn = "IntCtl";
5440 break;
7a387fff 5441 case 2:
d75c135e 5442 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5443 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5444 /* Stop translation as we may have switched the execution mode */
5445 ctx->bstate = BS_STOP;
2423f660
TS
5446 rn = "SRSCtl";
5447 break;
7a387fff 5448 case 3:
d75c135e 5449 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5450 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5451 /* Stop translation as we may have switched the execution mode */
5452 ctx->bstate = BS_STOP;
2423f660 5453 rn = "SRSMap";
fd88b6ab 5454 break;
7a387fff
TS
5455 default:
5456 goto die;
876d4b07 5457 }
8c0fdd85
TS
5458 break;
5459 case 13:
7a387fff
TS
5460 switch (sel) {
5461 case 0:
867abc7e 5462 save_cpu_state(ctx, 1);
895c2d04 5463 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5464 rn = "Cause";
5465 break;
7a387fff
TS
5466 default:
5467 goto die;
876d4b07 5468 }
8c0fdd85
TS
5469 break;
5470 case 14:
7a387fff
TS
5471 switch (sel) {
5472 case 0:
7db13fae 5473 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5474 rn = "EPC";
5475 break;
7a387fff
TS
5476 default:
5477 goto die;
876d4b07 5478 }
8c0fdd85
TS
5479 break;
5480 case 15:
7a387fff
TS
5481 switch (sel) {
5482 case 0:
2423f660
TS
5483 /* ignored */
5484 rn = "PRid";
5485 break;
7a387fff 5486 case 1:
d75c135e 5487 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5488 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5489 rn = "EBase";
5490 break;
7a387fff
TS
5491 default:
5492 goto die;
1579a72e 5493 }
8c0fdd85
TS
5494 break;
5495 case 16:
5496 switch (sel) {
5497 case 0:
895c2d04 5498 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5499 rn = "Config";
2423f660
TS
5500 /* Stop translation as we may have switched the execution mode */
5501 ctx->bstate = BS_STOP;
7a387fff
TS
5502 break;
5503 case 1:
e397ee33 5504 /* ignored, read only */
7a387fff
TS
5505 rn = "Config1";
5506 break;
5507 case 2:
895c2d04 5508 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5509 rn = "Config2";
2423f660
TS
5510 /* Stop translation as we may have switched the execution mode */
5511 ctx->bstate = BS_STOP;
8c0fdd85 5512 break;
7a387fff 5513 case 3:
e397ee33 5514 /* ignored, read only */
7a387fff
TS
5515 rn = "Config3";
5516 break;
b4160af1
PJ
5517 case 4:
5518 gen_helper_mtc0_config4(cpu_env, arg);
5519 rn = "Config4";
5520 ctx->bstate = BS_STOP;
5521 break;
b4dd99a3
PJ
5522 case 5:
5523 gen_helper_mtc0_config5(cpu_env, arg);
5524 rn = "Config5";
5525 /* Stop translation as we may have switched the execution mode */
5526 ctx->bstate = BS_STOP;
5527 break;
e397ee33
TS
5528 /* 6,7 are implementation dependent */
5529 case 6:
5530 /* ignored */
5531 rn = "Config6";
5532 break;
5533 case 7:
5534 /* ignored */
5535 rn = "Config7";
5536 break;
8c0fdd85
TS
5537 default:
5538 rn = "Invalid config selector";
5539 goto die;
5540 }
5541 break;
5542 case 17:
7a387fff
TS
5543 switch (sel) {
5544 case 0:
895c2d04 5545 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5546 rn = "LLAddr";
5547 break;
7a387fff
TS
5548 default:
5549 goto die;
5550 }
8c0fdd85
TS
5551 break;
5552 case 18:
7a387fff 5553 switch (sel) {
fd88b6ab 5554 case 0 ... 7:
895c2d04 5555 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5556 rn = "WatchLo";
5557 break;
7a387fff
TS
5558 default:
5559 goto die;
5560 }
8c0fdd85
TS
5561 break;
5562 case 19:
7a387fff 5563 switch (sel) {
fd88b6ab 5564 case 0 ... 7:
895c2d04 5565 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5566 rn = "WatchHi";
5567 break;
7a387fff
TS
5568 default:
5569 goto die;
5570 }
8c0fdd85
TS
5571 break;
5572 case 20:
7a387fff
TS
5573 switch (sel) {
5574 case 0:
d26bc211 5575#if defined(TARGET_MIPS64)
d75c135e 5576 check_insn(ctx, ISA_MIPS3);
895c2d04 5577 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5578 rn = "XContext";
5579 break;
703eaf37 5580#endif
7a387fff
TS
5581 default:
5582 goto die;
5583 }
8c0fdd85
TS
5584 break;
5585 case 21:
7a387fff
TS
5586 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5587 switch (sel) {
5588 case 0:
895c2d04 5589 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5590 rn = "Framemask";
5591 break;
7a387fff
TS
5592 default:
5593 goto die;
5594 }
5595 break;
8c0fdd85 5596 case 22:
7a387fff
TS
5597 /* ignored */
5598 rn = "Diagnostic"; /* implementation dependent */
2423f660 5599 break;
8c0fdd85 5600 case 23:
7a387fff
TS
5601 switch (sel) {
5602 case 0:
895c2d04 5603 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5604 /* BS_STOP isn't good enough here, hflags may have changed. */
5605 gen_save_pc(ctx->pc + 4);
5606 ctx->bstate = BS_EXCP;
2423f660
TS
5607 rn = "Debug";
5608 break;
7a387fff 5609 case 1:
895c2d04 5610// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5611 rn = "TraceControl";
8487327a
TS
5612 /* Stop translation as we may have switched the execution mode */
5613 ctx->bstate = BS_STOP;
2423f660 5614// break;
7a387fff 5615 case 2:
895c2d04 5616// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5617 rn = "TraceControl2";
8487327a
TS
5618 /* Stop translation as we may have switched the execution mode */
5619 ctx->bstate = BS_STOP;
2423f660 5620// break;
7a387fff 5621 case 3:
8487327a
TS
5622 /* Stop translation as we may have switched the execution mode */
5623 ctx->bstate = BS_STOP;
895c2d04 5624// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5625 rn = "UserTraceData";
8487327a
TS
5626 /* Stop translation as we may have switched the execution mode */
5627 ctx->bstate = BS_STOP;
2423f660 5628// break;
7a387fff 5629 case 4:
895c2d04 5630// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5631 /* Stop translation as we may have switched the execution mode */
5632 ctx->bstate = BS_STOP;
2423f660
TS
5633 rn = "TraceBPC";
5634// break;
7a387fff
TS
5635 default:
5636 goto die;
5637 }
8c0fdd85
TS
5638 break;
5639 case 24:
7a387fff
TS
5640 switch (sel) {
5641 case 0:
f1aa6320 5642 /* EJTAG support */
7db13fae 5643 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5644 rn = "DEPC";
5645 break;
7a387fff
TS
5646 default:
5647 goto die;
5648 }
8c0fdd85
TS
5649 break;
5650 case 25:
7a387fff
TS
5651 switch (sel) {
5652 case 0:
895c2d04 5653 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5654 rn = "Performance0";
5655 break;
7a387fff 5656 case 1:
d9bea114 5657// gen_helper_mtc0_performance1(arg);
2423f660
TS
5658 rn = "Performance1";
5659// break;
7a387fff 5660 case 2:
d9bea114 5661// gen_helper_mtc0_performance2(arg);
2423f660
TS
5662 rn = "Performance2";
5663// break;
7a387fff 5664 case 3:
d9bea114 5665// gen_helper_mtc0_performance3(arg);
2423f660
TS
5666 rn = "Performance3";
5667// break;
7a387fff 5668 case 4:
d9bea114 5669// gen_helper_mtc0_performance4(arg);
2423f660
TS
5670 rn = "Performance4";
5671// break;
7a387fff 5672 case 5:
d9bea114 5673// gen_helper_mtc0_performance5(arg);
2423f660
TS
5674 rn = "Performance5";
5675// break;
7a387fff 5676 case 6:
d9bea114 5677// gen_helper_mtc0_performance6(arg);
2423f660
TS
5678 rn = "Performance6";
5679// break;
7a387fff 5680 case 7:
d9bea114 5681// gen_helper_mtc0_performance7(arg);
2423f660
TS
5682 rn = "Performance7";
5683// break;
7a387fff
TS
5684 default:
5685 goto die;
5686 }
8c0fdd85
TS
5687 break;
5688 case 26:
2423f660 5689 /* ignored */
8c0fdd85 5690 rn = "ECC";
2423f660 5691 break;
8c0fdd85 5692 case 27:
7a387fff
TS
5693 switch (sel) {
5694 case 0 ... 3:
2423f660
TS
5695 /* ignored */
5696 rn = "CacheErr";
5697 break;
7a387fff
TS
5698 default:
5699 goto die;
5700 }
8c0fdd85
TS
5701 break;
5702 case 28:
5703 switch (sel) {
5704 case 0:
7a387fff
TS
5705 case 2:
5706 case 4:
5707 case 6:
895c2d04 5708 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5709 rn = "TagLo";
5710 break;
7a387fff
TS
5711 case 1:
5712 case 3:
5713 case 5:
5714 case 7:
895c2d04 5715 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5716 rn = "DataLo";
5717 break;
8c0fdd85 5718 default:
8c0fdd85
TS
5719 goto die;
5720 }
5721 break;
5722 case 29:
7a387fff
TS
5723 switch (sel) {
5724 case 0:
5725 case 2:
5726 case 4:
5727 case 6:
895c2d04 5728 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5729 rn = "TagHi";
5730 break;
5731 case 1:
5732 case 3:
5733 case 5:
5734 case 7:
895c2d04 5735 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5736 rn = "DataHi";
5737 break;
5738 default:
5739 rn = "invalid sel";
5740 goto die;
5741 }
8c0fdd85
TS
5742 break;
5743 case 30:
7a387fff
TS
5744 switch (sel) {
5745 case 0:
7db13fae 5746 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5747 rn = "ErrorEPC";
5748 break;
7a387fff
TS
5749 default:
5750 goto die;
5751 }
8c0fdd85
TS
5752 break;
5753 case 31:
7a387fff
TS
5754 switch (sel) {
5755 case 0:
f1aa6320 5756 /* EJTAG support */
7db13fae 5757 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5758 rn = "DESAVE";
5759 break;
7a387fff
TS
5760 default:
5761 goto die;
5762 }
2423f660
TS
5763 /* Stop translation as we may have switched the execution mode */
5764 ctx->bstate = BS_STOP;
8c0fdd85
TS
5765 break;
5766 default:
8c0fdd85
TS
5767 goto die;
5768 }
2abf314d 5769 (void)rn; /* avoid a compiler warning */
d12d51d5 5770 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5771 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5772 if (use_icount) {
5773 gen_io_end();
5774 ctx->bstate = BS_STOP;
5775 }
8c0fdd85
TS
5776 return;
5777
5778die:
d12d51d5 5779 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5780 generate_exception(ctx, EXCP_RI);
5781}
5782
d26bc211 5783#if defined(TARGET_MIPS64)
d75c135e 5784static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5785{
5786 const char *rn = "invalid";
5787
e189e748 5788 if (sel != 0)
d75c135e 5789 check_insn(ctx, ISA_MIPS64);
e189e748 5790
9c2149c8
TS
5791 switch (reg) {
5792 case 0:
5793 switch (sel) {
5794 case 0:
7db13fae 5795 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5796 rn = "Index";
5797 break;
5798 case 1:
d75c135e 5799 check_insn(ctx, ASE_MT);
895c2d04 5800 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5801 rn = "MVPControl";
ead9360e 5802 break;
9c2149c8 5803 case 2:
d75c135e 5804 check_insn(ctx, ASE_MT);
895c2d04 5805 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5806 rn = "MVPConf0";
ead9360e 5807 break;
9c2149c8 5808 case 3:
d75c135e 5809 check_insn(ctx, ASE_MT);
895c2d04 5810 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5811 rn = "MVPConf1";
ead9360e 5812 break;
9c2149c8
TS
5813 default:
5814 goto die;
5815 }
5816 break;
5817 case 1:
5818 switch (sel) {
5819 case 0:
895c2d04 5820 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5821 rn = "Random";
2423f660 5822 break;
9c2149c8 5823 case 1:
d75c135e 5824 check_insn(ctx, ASE_MT);
7db13fae 5825 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5826 rn = "VPEControl";
ead9360e 5827 break;
9c2149c8 5828 case 2:
d75c135e 5829 check_insn(ctx, ASE_MT);
7db13fae 5830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5831 rn = "VPEConf0";
ead9360e 5832 break;
9c2149c8 5833 case 3:
d75c135e 5834 check_insn(ctx, ASE_MT);
7db13fae 5835 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5836 rn = "VPEConf1";
ead9360e 5837 break;
9c2149c8 5838 case 4:
d75c135e 5839 check_insn(ctx, ASE_MT);
7db13fae 5840 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5841 rn = "YQMask";
ead9360e 5842 break;
9c2149c8 5843 case 5:
d75c135e 5844 check_insn(ctx, ASE_MT);
7db13fae 5845 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5846 rn = "VPESchedule";
ead9360e 5847 break;
9c2149c8 5848 case 6:
d75c135e 5849 check_insn(ctx, ASE_MT);
7db13fae 5850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5851 rn = "VPEScheFBack";
ead9360e 5852 break;
9c2149c8 5853 case 7:
d75c135e 5854 check_insn(ctx, ASE_MT);
7db13fae 5855 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5856 rn = "VPEOpt";
ead9360e 5857 break;
9c2149c8
TS
5858 default:
5859 goto die;
5860 }
5861 break;
5862 case 2:
5863 switch (sel) {
5864 case 0:
7db13fae 5865 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5866 rn = "EntryLo0";
5867 break;
9c2149c8 5868 case 1:
d75c135e 5869 check_insn(ctx, ASE_MT);
895c2d04 5870 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5871 rn = "TCStatus";
ead9360e 5872 break;
9c2149c8 5873 case 2:
d75c135e 5874 check_insn(ctx, ASE_MT);
895c2d04 5875 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5876 rn = "TCBind";
ead9360e 5877 break;
9c2149c8 5878 case 3:
d75c135e 5879 check_insn(ctx, ASE_MT);
895c2d04 5880 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5881 rn = "TCRestart";
ead9360e 5882 break;
9c2149c8 5883 case 4:
d75c135e 5884 check_insn(ctx, ASE_MT);
895c2d04 5885 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5886 rn = "TCHalt";
ead9360e 5887 break;
9c2149c8 5888 case 5:
d75c135e 5889 check_insn(ctx, ASE_MT);
895c2d04 5890 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5891 rn = "TCContext";
ead9360e 5892 break;
9c2149c8 5893 case 6:
d75c135e 5894 check_insn(ctx, ASE_MT);
895c2d04 5895 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5896 rn = "TCSchedule";
ead9360e 5897 break;
9c2149c8 5898 case 7:
d75c135e 5899 check_insn(ctx, ASE_MT);
895c2d04 5900 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5901 rn = "TCScheFBack";
ead9360e 5902 break;
9c2149c8
TS
5903 default:
5904 goto die;
5905 }
5906 break;
5907 case 3:
5908 switch (sel) {
5909 case 0:
7db13fae 5910 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5911 rn = "EntryLo1";
5912 break;
9c2149c8
TS
5913 default:
5914 goto die;
1579a72e 5915 }
9c2149c8
TS
5916 break;
5917 case 4:
5918 switch (sel) {
5919 case 0:
7db13fae 5920 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5921 rn = "Context";
5922 break;
9c2149c8 5923 case 1:
d9bea114 5924// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5925 rn = "ContextConfig";
d279279e 5926 goto die;
2423f660 5927// break;
d279279e
PJ
5928 case 2:
5929 if (ctx->ulri) {
5930 tcg_gen_ld_tl(arg, cpu_env,
5931 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5932 rn = "UserLocal";
5933 } else {
5934 tcg_gen_movi_tl(arg, 0);
5935 }
5936 break;
9c2149c8
TS
5937 default:
5938 goto die;
876d4b07 5939 }
9c2149c8
TS
5940 break;
5941 case 5:
5942 switch (sel) {
5943 case 0:
7db13fae 5944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5945 rn = "PageMask";
5946 break;
9c2149c8 5947 case 1:
d75c135e 5948 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5949 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5950 rn = "PageGrain";
5951 break;
9c2149c8
TS
5952 default:
5953 goto die;
876d4b07 5954 }
9c2149c8
TS
5955 break;
5956 case 6:
5957 switch (sel) {
5958 case 0:
7db13fae 5959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5960 rn = "Wired";
5961 break;
9c2149c8 5962 case 1:
d75c135e 5963 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5965 rn = "SRSConf0";
ead9360e 5966 break;
9c2149c8 5967 case 2:
d75c135e 5968 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5969 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5970 rn = "SRSConf1";
ead9360e 5971 break;
9c2149c8 5972 case 3:
d75c135e 5973 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5975 rn = "SRSConf2";
ead9360e 5976 break;
9c2149c8 5977 case 4:
d75c135e 5978 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5980 rn = "SRSConf3";
ead9360e 5981 break;
9c2149c8 5982 case 5:
d75c135e 5983 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5984 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5985 rn = "SRSConf4";
ead9360e 5986 break;
9c2149c8
TS
5987 default:
5988 goto die;
876d4b07 5989 }
9c2149c8
TS
5990 break;
5991 case 7:
5992 switch (sel) {
5993 case 0:
d75c135e 5994 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5996 rn = "HWREna";
5997 break;
9c2149c8
TS
5998 default:
5999 goto die;
876d4b07 6000 }
9c2149c8
TS
6001 break;
6002 case 8:
6003 switch (sel) {
6004 case 0:
7db13fae 6005 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6006 rn = "BadVAddr";
2423f660 6007 break;
9c2149c8
TS
6008 default:
6009 goto die;
876d4b07 6010 }
9c2149c8
TS
6011 break;
6012 case 9:
6013 switch (sel) {
6014 case 0:
2e70f6ef
PB
6015 /* Mark as an IO operation because we read the time. */
6016 if (use_icount)
6017 gen_io_start();
895c2d04 6018 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
6019 if (use_icount) {
6020 gen_io_end();
2e70f6ef 6021 }
55807224
EI
6022 /* Break the TB to be able to take timer interrupts immediately
6023 after reading count. */
6024 ctx->bstate = BS_STOP;
2423f660
TS
6025 rn = "Count";
6026 break;
6027 /* 6,7 are implementation dependent */
9c2149c8
TS
6028 default:
6029 goto die;
876d4b07 6030 }
9c2149c8
TS
6031 break;
6032 case 10:
6033 switch (sel) {
6034 case 0:
7db13fae 6035 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6036 rn = "EntryHi";
6037 break;
9c2149c8
TS
6038 default:
6039 goto die;
876d4b07 6040 }
9c2149c8
TS
6041 break;
6042 case 11:
6043 switch (sel) {
6044 case 0:
7db13fae 6045 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6046 rn = "Compare";
6047 break;
876d4b07 6048 /* 6,7 are implementation dependent */
9c2149c8
TS
6049 default:
6050 goto die;
876d4b07 6051 }
9c2149c8
TS
6052 break;
6053 case 12:
6054 switch (sel) {
6055 case 0:
7db13fae 6056 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6057 rn = "Status";
6058 break;
9c2149c8 6059 case 1:
d75c135e 6060 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6062 rn = "IntCtl";
6063 break;
9c2149c8 6064 case 2:
d75c135e 6065 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6066 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6067 rn = "SRSCtl";
6068 break;
9c2149c8 6069 case 3:
d75c135e 6070 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6071 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6072 rn = "SRSMap";
6073 break;
9c2149c8
TS
6074 default:
6075 goto die;
876d4b07 6076 }
9c2149c8
TS
6077 break;
6078 case 13:
6079 switch (sel) {
6080 case 0:
7db13fae 6081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6082 rn = "Cause";
6083 break;
9c2149c8
TS
6084 default:
6085 goto die;
876d4b07 6086 }
9c2149c8
TS
6087 break;
6088 case 14:
6089 switch (sel) {
6090 case 0:
7db13fae 6091 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6092 rn = "EPC";
6093 break;
9c2149c8
TS
6094 default:
6095 goto die;
876d4b07 6096 }
9c2149c8
TS
6097 break;
6098 case 15:
6099 switch (sel) {
6100 case 0:
7db13fae 6101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6102 rn = "PRid";
6103 break;
9c2149c8 6104 case 1:
d75c135e 6105 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6107 rn = "EBase";
6108 break;
9c2149c8
TS
6109 default:
6110 goto die;
876d4b07 6111 }
9c2149c8
TS
6112 break;
6113 case 16:
6114 switch (sel) {
6115 case 0:
7db13fae 6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6117 rn = "Config";
6118 break;
6119 case 1:
7db13fae 6120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6121 rn = "Config1";
6122 break;
6123 case 2:
7db13fae 6124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6125 rn = "Config2";
6126 break;
6127 case 3:
7db13fae 6128 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6129 rn = "Config3";
6130 break;
6131 /* 6,7 are implementation dependent */
f0b3f3ae 6132 case 6:
7db13fae 6133 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6134 rn = "Config6";
6135 break;
6136 case 7:
7db13fae 6137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6138 rn = "Config7";
6139 break;
9c2149c8
TS
6140 default:
6141 goto die;
6142 }
6143 break;
6144 case 17:
6145 switch (sel) {
6146 case 0:
895c2d04 6147 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6148 rn = "LLAddr";
6149 break;
9c2149c8
TS
6150 default:
6151 goto die;
6152 }
6153 break;
6154 case 18:
6155 switch (sel) {
fd88b6ab 6156 case 0 ... 7:
895c2d04 6157 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6158 rn = "WatchLo";
6159 break;
9c2149c8
TS
6160 default:
6161 goto die;
6162 }
6163 break;
6164 case 19:
6165 switch (sel) {
fd88b6ab 6166 case 0 ... 7:
895c2d04 6167 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6168 rn = "WatchHi";
6169 break;
9c2149c8
TS
6170 default:
6171 goto die;
6172 }
6173 break;
6174 case 20:
6175 switch (sel) {
6176 case 0:
d75c135e 6177 check_insn(ctx, ISA_MIPS3);
7db13fae 6178 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6179 rn = "XContext";
6180 break;
9c2149c8
TS
6181 default:
6182 goto die;
6183 }
6184 break;
6185 case 21:
6186 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6187 switch (sel) {
6188 case 0:
7db13fae 6189 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6190 rn = "Framemask";
6191 break;
9c2149c8
TS
6192 default:
6193 goto die;
6194 }
6195 break;
6196 case 22:
d9bea114 6197 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6198 rn = "'Diagnostic"; /* implementation dependent */
6199 break;
9c2149c8
TS
6200 case 23:
6201 switch (sel) {
6202 case 0:
895c2d04 6203 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6204 rn = "Debug";
6205 break;
9c2149c8 6206 case 1:
895c2d04 6207// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6208 rn = "TraceControl";
6209// break;
9c2149c8 6210 case 2:
895c2d04 6211// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6212 rn = "TraceControl2";
6213// break;
9c2149c8 6214 case 3:
895c2d04 6215// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6216 rn = "UserTraceData";
6217// break;
9c2149c8 6218 case 4:
895c2d04 6219// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6220 rn = "TraceBPC";
6221// break;
9c2149c8
TS
6222 default:
6223 goto die;
6224 }
6225 break;
6226 case 24:
6227 switch (sel) {
6228 case 0:
f0b3f3ae 6229 /* EJTAG support */
7db13fae 6230 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6231 rn = "DEPC";
6232 break;
9c2149c8
TS
6233 default:
6234 goto die;
6235 }
6236 break;
6237 case 25:
6238 switch (sel) {
6239 case 0:
7db13fae 6240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6241 rn = "Performance0";
9c2149c8
TS
6242 break;
6243 case 1:
d9bea114 6244// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6245 rn = "Performance1";
6246// break;
9c2149c8 6247 case 2:
d9bea114 6248// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6249 rn = "Performance2";
6250// break;
9c2149c8 6251 case 3:
d9bea114 6252// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6253 rn = "Performance3";
6254// break;
9c2149c8 6255 case 4:
d9bea114 6256// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6257 rn = "Performance4";
6258// break;
9c2149c8 6259 case 5:
d9bea114 6260// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6261 rn = "Performance5";
6262// break;
9c2149c8 6263 case 6:
d9bea114 6264// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6265 rn = "Performance6";
6266// break;
9c2149c8 6267 case 7:
d9bea114 6268// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6269 rn = "Performance7";
6270// break;
9c2149c8
TS
6271 default:
6272 goto die;
6273 }
6274 break;
6275 case 26:
d9bea114 6276 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6277 rn = "ECC";
6278 break;
9c2149c8
TS
6279 case 27:
6280 switch (sel) {
6281 /* ignored */
6282 case 0 ... 3:
d9bea114 6283 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6284 rn = "CacheErr";
6285 break;
9c2149c8
TS
6286 default:
6287 goto die;
6288 }
6289 break;
6290 case 28:
6291 switch (sel) {
6292 case 0:
6293 case 2:
6294 case 4:
6295 case 6:
7db13fae 6296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6297 rn = "TagLo";
6298 break;
6299 case 1:
6300 case 3:
6301 case 5:
6302 case 7:
7db13fae 6303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6304 rn = "DataLo";
6305 break;
6306 default:
6307 goto die;
6308 }
6309 break;
6310 case 29:
6311 switch (sel) {
6312 case 0:
6313 case 2:
6314 case 4:
6315 case 6:
7db13fae 6316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6317 rn = "TagHi";
6318 break;
6319 case 1:
6320 case 3:
6321 case 5:
6322 case 7:
7db13fae 6323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6324 rn = "DataHi";
6325 break;
6326 default:
6327 goto die;
6328 }
6329 break;
6330 case 30:
6331 switch (sel) {
6332 case 0:
7db13fae 6333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6334 rn = "ErrorEPC";
6335 break;
9c2149c8
TS
6336 default:
6337 goto die;
6338 }
6339 break;
6340 case 31:
6341 switch (sel) {
6342 case 0:
f0b3f3ae 6343 /* EJTAG support */
7db13fae 6344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6345 rn = "DESAVE";
6346 break;
9c2149c8
TS
6347 default:
6348 goto die;
6349 }
6350 break;
6351 default:
876d4b07 6352 goto die;
9c2149c8 6353 }
2abf314d 6354 (void)rn; /* avoid a compiler warning */
d12d51d5 6355 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6356 return;
6357
6358die:
d12d51d5 6359 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6360 generate_exception(ctx, EXCP_RI);
6361}
6362
d75c135e 6363static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6364{
6365 const char *rn = "invalid";
6366
e189e748 6367 if (sel != 0)
d75c135e 6368 check_insn(ctx, ISA_MIPS64);
e189e748 6369
2e70f6ef
PB
6370 if (use_icount)
6371 gen_io_start();
6372
9c2149c8
TS
6373 switch (reg) {
6374 case 0:
6375 switch (sel) {
6376 case 0:
895c2d04 6377 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6378 rn = "Index";
6379 break;
6380 case 1:
d75c135e 6381 check_insn(ctx, ASE_MT);
895c2d04 6382 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6383 rn = "MVPControl";
ead9360e 6384 break;
9c2149c8 6385 case 2:
d75c135e 6386 check_insn(ctx, ASE_MT);
ead9360e 6387 /* ignored */
9c2149c8 6388 rn = "MVPConf0";
ead9360e 6389 break;
9c2149c8 6390 case 3:
d75c135e 6391 check_insn(ctx, ASE_MT);
ead9360e 6392 /* ignored */
9c2149c8 6393 rn = "MVPConf1";
ead9360e 6394 break;
9c2149c8
TS
6395 default:
6396 goto die;
6397 }
6398 break;
6399 case 1:
6400 switch (sel) {
6401 case 0:
2423f660 6402 /* ignored */
9c2149c8 6403 rn = "Random";
2423f660 6404 break;
9c2149c8 6405 case 1:
d75c135e 6406 check_insn(ctx, ASE_MT);
895c2d04 6407 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6408 rn = "VPEControl";
ead9360e 6409 break;
9c2149c8 6410 case 2:
d75c135e 6411 check_insn(ctx, ASE_MT);
895c2d04 6412 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6413 rn = "VPEConf0";
ead9360e 6414 break;
9c2149c8 6415 case 3:
d75c135e 6416 check_insn(ctx, ASE_MT);
895c2d04 6417 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6418 rn = "VPEConf1";
ead9360e 6419 break;
9c2149c8 6420 case 4:
d75c135e 6421 check_insn(ctx, ASE_MT);
895c2d04 6422 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6423 rn = "YQMask";
ead9360e 6424 break;
9c2149c8 6425 case 5:
d75c135e 6426 check_insn(ctx, ASE_MT);
7db13fae 6427 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6428 rn = "VPESchedule";
ead9360e 6429 break;
9c2149c8 6430 case 6:
d75c135e 6431 check_insn(ctx, ASE_MT);
7db13fae 6432 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6433 rn = "VPEScheFBack";
ead9360e 6434 break;
9c2149c8 6435 case 7:
d75c135e 6436 check_insn(ctx, ASE_MT);
895c2d04 6437 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6438 rn = "VPEOpt";
ead9360e 6439 break;
9c2149c8
TS
6440 default:
6441 goto die;
6442 }
6443 break;
6444 case 2:
6445 switch (sel) {
6446 case 0:
895c2d04 6447 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
6448 rn = "EntryLo0";
6449 break;
9c2149c8 6450 case 1:
d75c135e 6451 check_insn(ctx, ASE_MT);
895c2d04 6452 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6453 rn = "TCStatus";
ead9360e 6454 break;
9c2149c8 6455 case 2:
d75c135e 6456 check_insn(ctx, ASE_MT);
895c2d04 6457 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6458 rn = "TCBind";
ead9360e 6459 break;
9c2149c8 6460 case 3:
d75c135e 6461 check_insn(ctx, ASE_MT);
895c2d04 6462 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6463 rn = "TCRestart";
ead9360e 6464 break;
9c2149c8 6465 case 4:
d75c135e 6466 check_insn(ctx, ASE_MT);
895c2d04 6467 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6468 rn = "TCHalt";
ead9360e 6469 break;
9c2149c8 6470 case 5:
d75c135e 6471 check_insn(ctx, ASE_MT);
895c2d04 6472 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6473 rn = "TCContext";
ead9360e 6474 break;
9c2149c8 6475 case 6:
d75c135e 6476 check_insn(ctx, ASE_MT);
895c2d04 6477 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6478 rn = "TCSchedule";
ead9360e 6479 break;
9c2149c8 6480 case 7:
d75c135e 6481 check_insn(ctx, ASE_MT);
895c2d04 6482 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6483 rn = "TCScheFBack";
ead9360e 6484 break;
9c2149c8
TS
6485 default:
6486 goto die;
6487 }
6488 break;
6489 case 3:
6490 switch (sel) {
6491 case 0:
895c2d04 6492 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6493 rn = "EntryLo1";
6494 break;
9c2149c8
TS
6495 default:
6496 goto die;
876d4b07 6497 }
9c2149c8
TS
6498 break;
6499 case 4:
6500 switch (sel) {
6501 case 0:
895c2d04 6502 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6503 rn = "Context";
6504 break;
9c2149c8 6505 case 1:
895c2d04 6506// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6507 rn = "ContextConfig";
d279279e 6508 goto die;
2423f660 6509// break;
d279279e
PJ
6510 case 2:
6511 if (ctx->ulri) {
6512 tcg_gen_st_tl(arg, cpu_env,
6513 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6514 rn = "UserLocal";
6515 }
6516 break;
9c2149c8
TS
6517 default:
6518 goto die;
876d4b07 6519 }
9c2149c8
TS
6520 break;
6521 case 5:
6522 switch (sel) {
6523 case 0:
895c2d04 6524 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6525 rn = "PageMask";
6526 break;
9c2149c8 6527 case 1:
d75c135e 6528 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6529 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6530 rn = "PageGrain";
6531 break;
9c2149c8
TS
6532 default:
6533 goto die;
876d4b07 6534 }
9c2149c8
TS
6535 break;
6536 case 6:
6537 switch (sel) {
6538 case 0:
895c2d04 6539 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6540 rn = "Wired";
6541 break;
9c2149c8 6542 case 1:
d75c135e 6543 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6544 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6545 rn = "SRSConf0";
ead9360e 6546 break;
9c2149c8 6547 case 2:
d75c135e 6548 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6549 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6550 rn = "SRSConf1";
ead9360e 6551 break;
9c2149c8 6552 case 3:
d75c135e 6553 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6554 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6555 rn = "SRSConf2";
ead9360e 6556 break;
9c2149c8 6557 case 4:
d75c135e 6558 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6559 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6560 rn = "SRSConf3";
ead9360e 6561 break;
9c2149c8 6562 case 5:
d75c135e 6563 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6564 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6565 rn = "SRSConf4";
ead9360e 6566 break;
9c2149c8
TS
6567 default:
6568 goto die;
876d4b07 6569 }
9c2149c8
TS
6570 break;
6571 case 7:
6572 switch (sel) {
6573 case 0:
d75c135e 6574 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6575 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6576 ctx->bstate = BS_STOP;
2423f660
TS
6577 rn = "HWREna";
6578 break;
9c2149c8
TS
6579 default:
6580 goto die;
876d4b07 6581 }
9c2149c8
TS
6582 break;
6583 case 8:
6584 /* ignored */
f0b3f3ae 6585 rn = "BadVAddr";
9c2149c8
TS
6586 break;
6587 case 9:
6588 switch (sel) {
6589 case 0:
895c2d04 6590 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6591 rn = "Count";
6592 break;
876d4b07 6593 /* 6,7 are implementation dependent */
9c2149c8
TS
6594 default:
6595 goto die;
876d4b07
TS
6596 }
6597 /* Stop translation as we may have switched the execution mode */
6598 ctx->bstate = BS_STOP;
9c2149c8
TS
6599 break;
6600 case 10:
6601 switch (sel) {
6602 case 0:
895c2d04 6603 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6604 rn = "EntryHi";
6605 break;
9c2149c8
TS
6606 default:
6607 goto die;
876d4b07 6608 }
9c2149c8
TS
6609 break;
6610 case 11:
6611 switch (sel) {
6612 case 0:
895c2d04 6613 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6614 rn = "Compare";
6615 break;
876d4b07 6616 /* 6,7 are implementation dependent */
9c2149c8
TS
6617 default:
6618 goto die;
876d4b07 6619 }
de9a95f0
AJ
6620 /* Stop translation as we may have switched the execution mode */
6621 ctx->bstate = BS_STOP;
9c2149c8
TS
6622 break;
6623 case 12:
6624 switch (sel) {
6625 case 0:
867abc7e 6626 save_cpu_state(ctx, 1);
895c2d04 6627 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6628 /* BS_STOP isn't good enough here, hflags may have changed. */
6629 gen_save_pc(ctx->pc + 4);
6630 ctx->bstate = BS_EXCP;
2423f660
TS
6631 rn = "Status";
6632 break;
9c2149c8 6633 case 1:
d75c135e 6634 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6635 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6636 /* Stop translation as we may have switched the execution mode */
6637 ctx->bstate = BS_STOP;
2423f660
TS
6638 rn = "IntCtl";
6639 break;
9c2149c8 6640 case 2:
d75c135e 6641 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6642 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6643 /* Stop translation as we may have switched the execution mode */
6644 ctx->bstate = BS_STOP;
2423f660
TS
6645 rn = "SRSCtl";
6646 break;
9c2149c8 6647 case 3:
d75c135e 6648 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6649 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6650 /* Stop translation as we may have switched the execution mode */
6651 ctx->bstate = BS_STOP;
2423f660
TS
6652 rn = "SRSMap";
6653 break;
6654 default:
9c2149c8 6655 goto die;
876d4b07 6656 }
9c2149c8
TS
6657 break;
6658 case 13:
6659 switch (sel) {
6660 case 0:
867abc7e 6661 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6662 /* Mark as an IO operation because we may trigger a software
6663 interrupt. */
6664 if (use_icount) {
6665 gen_io_start();
6666 }
895c2d04 6667 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6668 if (use_icount) {
6669 gen_io_end();
6670 }
6671 /* Stop translation as we may have triggered an intetrupt */
6672 ctx->bstate = BS_STOP;
2423f660
TS
6673 rn = "Cause";
6674 break;
9c2149c8
TS
6675 default:
6676 goto die;
876d4b07 6677 }
9c2149c8
TS
6678 break;
6679 case 14:
6680 switch (sel) {
6681 case 0:
7db13fae 6682 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6683 rn = "EPC";
6684 break;
9c2149c8
TS
6685 default:
6686 goto die;
876d4b07 6687 }
9c2149c8
TS
6688 break;
6689 case 15:
6690 switch (sel) {
6691 case 0:
2423f660
TS
6692 /* ignored */
6693 rn = "PRid";
6694 break;
9c2149c8 6695 case 1:
d75c135e 6696 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6697 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6698 rn = "EBase";
6699 break;
9c2149c8
TS
6700 default:
6701 goto die;
876d4b07 6702 }
9c2149c8
TS
6703 break;
6704 case 16:
6705 switch (sel) {
6706 case 0:
895c2d04 6707 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6708 rn = "Config";
2423f660
TS
6709 /* Stop translation as we may have switched the execution mode */
6710 ctx->bstate = BS_STOP;
9c2149c8
TS
6711 break;
6712 case 1:
1fc7bf6e 6713 /* ignored, read only */
9c2149c8
TS
6714 rn = "Config1";
6715 break;
6716 case 2:
895c2d04 6717 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6718 rn = "Config2";
2423f660
TS
6719 /* Stop translation as we may have switched the execution mode */
6720 ctx->bstate = BS_STOP;
9c2149c8
TS
6721 break;
6722 case 3:
2423f660 6723 /* ignored */
9c2149c8
TS
6724 rn = "Config3";
6725 break;
6726 /* 6,7 are implementation dependent */
6727 default:
6728 rn = "Invalid config selector";
6729 goto die;
6730 }
9c2149c8
TS
6731 break;
6732 case 17:
6733 switch (sel) {
6734 case 0:
895c2d04 6735 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6736 rn = "LLAddr";
6737 break;
9c2149c8
TS
6738 default:
6739 goto die;
6740 }
6741 break;
6742 case 18:
6743 switch (sel) {
fd88b6ab 6744 case 0 ... 7:
895c2d04 6745 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6746 rn = "WatchLo";
6747 break;
9c2149c8
TS
6748 default:
6749 goto die;
6750 }
6751 break;
6752 case 19:
6753 switch (sel) {
fd88b6ab 6754 case 0 ... 7:
895c2d04 6755 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6756 rn = "WatchHi";
6757 break;
9c2149c8
TS
6758 default:
6759 goto die;
6760 }
6761 break;
6762 case 20:
6763 switch (sel) {
6764 case 0:
d75c135e 6765 check_insn(ctx, ISA_MIPS3);
895c2d04 6766 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6767 rn = "XContext";
6768 break;
9c2149c8
TS
6769 default:
6770 goto die;
6771 }
6772 break;
6773 case 21:
6774 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6775 switch (sel) {
6776 case 0:
895c2d04 6777 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6778 rn = "Framemask";
6779 break;
9c2149c8
TS
6780 default:
6781 goto die;
6782 }
6783 break;
6784 case 22:
6785 /* ignored */
6786 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6787 break;
9c2149c8
TS
6788 case 23:
6789 switch (sel) {
6790 case 0:
895c2d04 6791 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6792 /* BS_STOP isn't good enough here, hflags may have changed. */
6793 gen_save_pc(ctx->pc + 4);
6794 ctx->bstate = BS_EXCP;
2423f660
TS
6795 rn = "Debug";
6796 break;
9c2149c8 6797 case 1:
895c2d04 6798// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6799 /* Stop translation as we may have switched the execution mode */
6800 ctx->bstate = BS_STOP;
2423f660
TS
6801 rn = "TraceControl";
6802// break;
9c2149c8 6803 case 2:
895c2d04 6804// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6805 /* Stop translation as we may have switched the execution mode */
6806 ctx->bstate = BS_STOP;
2423f660
TS
6807 rn = "TraceControl2";
6808// break;
9c2149c8 6809 case 3:
895c2d04 6810// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6811 /* Stop translation as we may have switched the execution mode */
6812 ctx->bstate = BS_STOP;
2423f660
TS
6813 rn = "UserTraceData";
6814// break;
9c2149c8 6815 case 4:
895c2d04 6816// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6817 /* Stop translation as we may have switched the execution mode */
6818 ctx->bstate = BS_STOP;
2423f660
TS
6819 rn = "TraceBPC";
6820// break;
9c2149c8
TS
6821 default:
6822 goto die;
6823 }
9c2149c8
TS
6824 break;
6825 case 24:
6826 switch (sel) {
6827 case 0:
f1aa6320 6828 /* EJTAG support */
7db13fae 6829 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6830 rn = "DEPC";
6831 break;
9c2149c8
TS
6832 default:
6833 goto die;
6834 }
6835 break;
6836 case 25:
6837 switch (sel) {
6838 case 0:
895c2d04 6839 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6840 rn = "Performance0";
6841 break;
9c2149c8 6842 case 1:
895c2d04 6843// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6844 rn = "Performance1";
6845// break;
9c2149c8 6846 case 2:
895c2d04 6847// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6848 rn = "Performance2";
6849// break;
9c2149c8 6850 case 3:
895c2d04 6851// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6852 rn = "Performance3";
6853// break;
9c2149c8 6854 case 4:
895c2d04 6855// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6856 rn = "Performance4";
6857// break;
9c2149c8 6858 case 5:
895c2d04 6859// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6860 rn = "Performance5";
6861// break;
9c2149c8 6862 case 6:
895c2d04 6863// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6864 rn = "Performance6";
6865// break;
9c2149c8 6866 case 7:
895c2d04 6867// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6868 rn = "Performance7";
6869// break;
9c2149c8
TS
6870 default:
6871 goto die;
6872 }
876d4b07 6873 break;
9c2149c8 6874 case 26:
876d4b07 6875 /* ignored */
9c2149c8 6876 rn = "ECC";
876d4b07 6877 break;
9c2149c8
TS
6878 case 27:
6879 switch (sel) {
6880 case 0 ... 3:
2423f660
TS
6881 /* ignored */
6882 rn = "CacheErr";
6883 break;
9c2149c8
TS
6884 default:
6885 goto die;
6886 }
876d4b07 6887 break;
9c2149c8
TS
6888 case 28:
6889 switch (sel) {
6890 case 0:
6891 case 2:
6892 case 4:
6893 case 6:
895c2d04 6894 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6895 rn = "TagLo";
6896 break;
6897 case 1:
6898 case 3:
6899 case 5:
6900 case 7:
895c2d04 6901 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6902 rn = "DataLo";
6903 break;
6904 default:
6905 goto die;
6906 }
6907 break;
6908 case 29:
6909 switch (sel) {
6910 case 0:
6911 case 2:
6912 case 4:
6913 case 6:
895c2d04 6914 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6915 rn = "TagHi";
6916 break;
6917 case 1:
6918 case 3:
6919 case 5:
6920 case 7:
895c2d04 6921 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6922 rn = "DataHi";
6923 break;
6924 default:
6925 rn = "invalid sel";
6926 goto die;
6927 }
876d4b07 6928 break;
9c2149c8
TS
6929 case 30:
6930 switch (sel) {
6931 case 0:
7db13fae 6932 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6933 rn = "ErrorEPC";
6934 break;
9c2149c8
TS
6935 default:
6936 goto die;
6937 }
6938 break;
6939 case 31:
6940 switch (sel) {
6941 case 0:
f1aa6320 6942 /* EJTAG support */
7db13fae 6943 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6944 rn = "DESAVE";
6945 break;
9c2149c8
TS
6946 default:
6947 goto die;
6948 }
876d4b07
TS
6949 /* Stop translation as we may have switched the execution mode */
6950 ctx->bstate = BS_STOP;
9c2149c8
TS
6951 break;
6952 default:
876d4b07 6953 goto die;
9c2149c8 6954 }
2abf314d 6955 (void)rn; /* avoid a compiler warning */
d12d51d5 6956 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6957 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6958 if (use_icount) {
6959 gen_io_end();
6960 ctx->bstate = BS_STOP;
6961 }
9c2149c8
TS
6962 return;
6963
6964die:
d12d51d5 6965 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6966 generate_exception(ctx, EXCP_RI);
6967}
d26bc211 6968#endif /* TARGET_MIPS64 */
9c2149c8 6969
7db13fae 6970static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6971 int u, int sel, int h)
6972{
6973 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6974 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6975
6976 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6977 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6978 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6979 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6980 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6981 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6982 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6983 else if (u == 0) {
6984 switch (rt) {
5a25ce94
EI
6985 case 1:
6986 switch (sel) {
6987 case 1:
895c2d04 6988 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6989 break;
6990 case 2:
895c2d04 6991 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6992 break;
6993 default:
6994 goto die;
6995 break;
6996 }
6997 break;
ead9360e
TS
6998 case 2:
6999 switch (sel) {
7000 case 1:
895c2d04 7001 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7002 break;
7003 case 2:
895c2d04 7004 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7005 break;
7006 case 3:
895c2d04 7007 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7008 break;
7009 case 4:
895c2d04 7010 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7011 break;
7012 case 5:
895c2d04 7013 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7014 break;
7015 case 6:
895c2d04 7016 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7017 break;
7018 case 7:
895c2d04 7019 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7020 break;
7021 default:
d75c135e 7022 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7023 break;
7024 }
7025 break;
7026 case 10:
7027 switch (sel) {
7028 case 0:
895c2d04 7029 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7030 break;
7031 default:
d75c135e 7032 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7033 break;
7034 }
7035 case 12:
7036 switch (sel) {
7037 case 0:
895c2d04 7038 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7039 break;
7040 default:
d75c135e 7041 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7042 break;
7043 }
5a25ce94
EI
7044 case 13:
7045 switch (sel) {
7046 case 0:
895c2d04 7047 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7048 break;
7049 default:
7050 goto die;
7051 break;
7052 }
7053 break;
7054 case 14:
7055 switch (sel) {
7056 case 0:
895c2d04 7057 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7058 break;
7059 default:
7060 goto die;
7061 break;
7062 }
7063 break;
7064 case 15:
7065 switch (sel) {
7066 case 1:
895c2d04 7067 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7068 break;
7069 default:
7070 goto die;
7071 break;
7072 }
7073 break;
7074 case 16:
7075 switch (sel) {
7076 case 0 ... 7:
895c2d04 7077 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7078 break;
7079 default:
7080 goto die;
7081 break;
7082 }
7083 break;
ead9360e
TS
7084 case 23:
7085 switch (sel) {
7086 case 0:
895c2d04 7087 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7088 break;
7089 default:
d75c135e 7090 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7091 break;
7092 }
7093 break;
7094 default:
d75c135e 7095 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7096 }
7097 } else switch (sel) {
7098 /* GPR registers. */
7099 case 0:
895c2d04 7100 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7101 break;
7102 /* Auxiliary CPU registers */
7103 case 1:
7104 switch (rt) {
7105 case 0:
895c2d04 7106 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7107 break;
7108 case 1:
895c2d04 7109 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7110 break;
7111 case 2:
895c2d04 7112 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7113 break;
7114 case 4:
895c2d04 7115 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7116 break;
7117 case 5:
895c2d04 7118 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7119 break;
7120 case 6:
895c2d04 7121 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7122 break;
7123 case 8:
895c2d04 7124 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7125 break;
7126 case 9:
895c2d04 7127 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7128 break;
7129 case 10:
895c2d04 7130 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7131 break;
7132 case 12:
895c2d04 7133 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7134 break;
7135 case 13:
895c2d04 7136 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7137 break;
7138 case 14:
895c2d04 7139 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7140 break;
7141 case 16:
895c2d04 7142 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7143 break;
7144 default:
7145 goto die;
7146 }
7147 break;
7148 /* Floating point (COP1). */
7149 case 2:
7150 /* XXX: For now we support only a single FPU context. */
7151 if (h == 0) {
a7812ae4 7152 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7153
7154 gen_load_fpr32(fp0, rt);
7155 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7156 tcg_temp_free_i32(fp0);
ead9360e 7157 } else {
a7812ae4 7158 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7159
7f6613ce 7160 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7161 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7162 tcg_temp_free_i32(fp0);
ead9360e
TS
7163 }
7164 break;
7165 case 3:
7166 /* XXX: For now we support only a single FPU context. */
895c2d04 7167 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7168 break;
7169 /* COP2: Not implemented. */
7170 case 4:
7171 case 5:
7172 /* fall through */
7173 default:
7174 goto die;
7175 }
d12d51d5 7176 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7177 gen_store_gpr(t0, rd);
7178 tcg_temp_free(t0);
ead9360e
TS
7179 return;
7180
7181die:
1a3fd9c3 7182 tcg_temp_free(t0);
d12d51d5 7183 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7184 generate_exception(ctx, EXCP_RI);
7185}
7186
7db13fae 7187static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7188 int u, int sel, int h)
7189{
7190 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7191 TCGv t0 = tcg_temp_local_new();
ead9360e 7192
1a3fd9c3 7193 gen_load_gpr(t0, rt);
ead9360e 7194 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7195 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7196 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7197 /* NOP */ ;
7198 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7199 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7200 /* NOP */ ;
7201 else if (u == 0) {
7202 switch (rd) {
5a25ce94
EI
7203 case 1:
7204 switch (sel) {
7205 case 1:
895c2d04 7206 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7207 break;
7208 case 2:
895c2d04 7209 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7210 break;
7211 default:
7212 goto die;
7213 break;
7214 }
7215 break;
ead9360e
TS
7216 case 2:
7217 switch (sel) {
7218 case 1:
895c2d04 7219 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7220 break;
7221 case 2:
895c2d04 7222 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7223 break;
7224 case 3:
895c2d04 7225 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7226 break;
7227 case 4:
895c2d04 7228 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7229 break;
7230 case 5:
895c2d04 7231 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7232 break;
7233 case 6:
895c2d04 7234 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7235 break;
7236 case 7:
895c2d04 7237 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7238 break;
7239 default:
d75c135e 7240 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7241 break;
7242 }
7243 break;
7244 case 10:
7245 switch (sel) {
7246 case 0:
895c2d04 7247 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7248 break;
7249 default:
d75c135e 7250 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7251 break;
7252 }
7253 case 12:
7254 switch (sel) {
7255 case 0:
895c2d04 7256 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7257 break;
7258 default:
d75c135e 7259 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7260 break;
7261 }
5a25ce94
EI
7262 case 13:
7263 switch (sel) {
7264 case 0:
895c2d04 7265 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7266 break;
7267 default:
7268 goto die;
7269 break;
7270 }
7271 break;
7272 case 15:
7273 switch (sel) {
7274 case 1:
895c2d04 7275 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7276 break;
7277 default:
7278 goto die;
7279 break;
7280 }
7281 break;
ead9360e
TS
7282 case 23:
7283 switch (sel) {
7284 case 0:
895c2d04 7285 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7286 break;
7287 default:
d75c135e 7288 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7289 break;
7290 }
7291 break;
7292 default:
d75c135e 7293 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7294 }
7295 } else switch (sel) {
7296 /* GPR registers. */
7297 case 0:
895c2d04 7298 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7299 break;
7300 /* Auxiliary CPU registers */
7301 case 1:
7302 switch (rd) {
7303 case 0:
895c2d04 7304 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7305 break;
7306 case 1:
895c2d04 7307 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7308 break;
7309 case 2:
895c2d04 7310 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7311 break;
7312 case 4:
895c2d04 7313 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7314 break;
7315 case 5:
895c2d04 7316 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7317 break;
7318 case 6:
895c2d04 7319 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7320 break;
7321 case 8:
895c2d04 7322 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7323 break;
7324 case 9:
895c2d04 7325 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7326 break;
7327 case 10:
895c2d04 7328 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7329 break;
7330 case 12:
895c2d04 7331 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7332 break;
7333 case 13:
895c2d04 7334 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7335 break;
7336 case 14:
895c2d04 7337 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7338 break;
7339 case 16:
895c2d04 7340 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7341 break;
7342 default:
7343 goto die;
7344 }
7345 break;
7346 /* Floating point (COP1). */
7347 case 2:
7348 /* XXX: For now we support only a single FPU context. */
7349 if (h == 0) {
a7812ae4 7350 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7351
7352 tcg_gen_trunc_tl_i32(fp0, t0);
7353 gen_store_fpr32(fp0, rd);
a7812ae4 7354 tcg_temp_free_i32(fp0);
ead9360e 7355 } else {
a7812ae4 7356 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7357
7358 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7359 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7360 tcg_temp_free_i32(fp0);
ead9360e
TS
7361 }
7362 break;
7363 case 3:
7364 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7365 {
7366 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7367
7368 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7369 tcg_temp_free_i32(fs_tmp);
7370 }
ead9360e
TS
7371 break;
7372 /* COP2: Not implemented. */
7373 case 4:
7374 case 5:
7375 /* fall through */
7376 default:
7377 goto die;
7378 }
d12d51d5 7379 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7380 tcg_temp_free(t0);
ead9360e
TS
7381 return;
7382
7383die:
1a3fd9c3 7384 tcg_temp_free(t0);
d12d51d5 7385 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7386 generate_exception(ctx, EXCP_RI);
7387}
7388
7db13fae 7389static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7390{
287c4b84 7391 const char *opn = "ldst";
6af0bf9c 7392
2e15497c 7393 check_cp0_enabled(ctx);
6af0bf9c
FB
7394 switch (opc) {
7395 case OPC_MFC0:
7396 if (rt == 0) {
ead9360e 7397 /* Treat as NOP. */
6af0bf9c
FB
7398 return;
7399 }
d75c135e 7400 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7401 opn = "mfc0";
7402 break;
7403 case OPC_MTC0:
1a3fd9c3 7404 {
1fc7bf6e 7405 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7406
7407 gen_load_gpr(t0, rt);
d75c135e 7408 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7409 tcg_temp_free(t0);
7410 }
6af0bf9c
FB
7411 opn = "mtc0";
7412 break;
d26bc211 7413#if defined(TARGET_MIPS64)
9c2149c8 7414 case OPC_DMFC0:
d75c135e 7415 check_insn(ctx, ISA_MIPS3);
9c2149c8 7416 if (rt == 0) {
ead9360e 7417 /* Treat as NOP. */
9c2149c8
TS
7418 return;
7419 }
d75c135e 7420 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7421 opn = "dmfc0";
7422 break;
7423 case OPC_DMTC0:
d75c135e 7424 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7425 {
1fc7bf6e 7426 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7427
7428 gen_load_gpr(t0, rt);
d75c135e 7429 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7430 tcg_temp_free(t0);
7431 }
9c2149c8
TS
7432 opn = "dmtc0";
7433 break;
534ce69f 7434#endif
ead9360e 7435 case OPC_MFTR:
d75c135e 7436 check_insn(ctx, ASE_MT);
ead9360e
TS
7437 if (rd == 0) {
7438 /* Treat as NOP. */
7439 return;
7440 }
6c5c1e20 7441 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7442 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7443 opn = "mftr";
7444 break;
7445 case OPC_MTTR:
d75c135e 7446 check_insn(ctx, ASE_MT);
6c5c1e20 7447 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7448 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7449 opn = "mttr";
7450 break;
6af0bf9c 7451 case OPC_TLBWI:
6af0bf9c 7452 opn = "tlbwi";
c01fccd2 7453 if (!env->tlb->helper_tlbwi)
29929e34 7454 goto die;
895c2d04 7455 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
7456 break;
7457 case OPC_TLBWR:
6af0bf9c 7458 opn = "tlbwr";
c01fccd2 7459 if (!env->tlb->helper_tlbwr)
29929e34 7460 goto die;
895c2d04 7461 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7462 break;
7463 case OPC_TLBP:
6af0bf9c 7464 opn = "tlbp";
c01fccd2 7465 if (!env->tlb->helper_tlbp)
29929e34 7466 goto die;
895c2d04 7467 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7468 break;
7469 case OPC_TLBR:
6af0bf9c 7470 opn = "tlbr";
c01fccd2 7471 if (!env->tlb->helper_tlbr)
29929e34 7472 goto die;
895c2d04 7473 gen_helper_tlbr(cpu_env);
6af0bf9c 7474 break;
6af0bf9c
FB
7475 case OPC_ERET:
7476 opn = "eret";
d75c135e 7477 check_insn(ctx, ISA_MIPS2);
895c2d04 7478 gen_helper_eret(cpu_env);
6af0bf9c
FB
7479 ctx->bstate = BS_EXCP;
7480 break;
7481 case OPC_DERET:
7482 opn = "deret";
d75c135e 7483 check_insn(ctx, ISA_MIPS32);
6af0bf9c 7484 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7485 MIPS_INVAL(opn);
6af0bf9c
FB
7486 generate_exception(ctx, EXCP_RI);
7487 } else {
895c2d04 7488 gen_helper_deret(cpu_env);
6af0bf9c
FB
7489 ctx->bstate = BS_EXCP;
7490 }
7491 break;
4ad40f36
FB
7492 case OPC_WAIT:
7493 opn = "wait";
d75c135e 7494 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
7495 /* If we get an exception, we want to restart at next instruction */
7496 ctx->pc += 4;
7497 save_cpu_state(ctx, 1);
7498 ctx->pc -= 4;
895c2d04 7499 gen_helper_wait(cpu_env);
4ad40f36
FB
7500 ctx->bstate = BS_EXCP;
7501 break;
6af0bf9c 7502 default:
29929e34 7503 die:
923617a3 7504 MIPS_INVAL(opn);
6af0bf9c
FB
7505 generate_exception(ctx, EXCP_RI);
7506 return;
7507 }
2abf314d 7508 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7509 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7510}
f1aa6320 7511#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7512
6ea83fed 7513/* CP1 Branches (before delay slot) */
d75c135e
AJ
7514static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7515 int32_t cc, int32_t offset)
6ea83fed
FB
7516{
7517 target_ulong btarget;
923617a3 7518 const char *opn = "cp1 cond branch";
a7812ae4 7519 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7520
e189e748 7521 if (cc != 0)
d75c135e 7522 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7523
6ea83fed
FB
7524 btarget = ctx->pc + 4 + offset;
7525
7a387fff
TS
7526 switch (op) {
7527 case OPC_BC1F:
d94536f4
AJ
7528 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7529 tcg_gen_not_i32(t0, t0);
7530 tcg_gen_andi_i32(t0, t0, 1);
7531 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7532 opn = "bc1f";
6ea83fed 7533 goto not_likely;
7a387fff 7534 case OPC_BC1FL:
d94536f4
AJ
7535 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7536 tcg_gen_not_i32(t0, t0);
7537 tcg_gen_andi_i32(t0, t0, 1);
7538 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7539 opn = "bc1fl";
6ea83fed 7540 goto likely;
7a387fff 7541 case OPC_BC1T:
d94536f4
AJ
7542 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7543 tcg_gen_andi_i32(t0, t0, 1);
7544 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7545 opn = "bc1t";
5a5012ec 7546 goto not_likely;
7a387fff 7547 case OPC_BC1TL:
d94536f4
AJ
7548 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7549 tcg_gen_andi_i32(t0, t0, 1);
7550 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7551 opn = "bc1tl";
6ea83fed
FB
7552 likely:
7553 ctx->hflags |= MIPS_HFLAG_BL;
7554 break;
5a5012ec 7555 case OPC_BC1FANY2:
a16336e4 7556 {
d94536f4
AJ
7557 TCGv_i32 t1 = tcg_temp_new_i32();
7558 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7559 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7560 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7561 tcg_temp_free_i32(t1);
d94536f4
AJ
7562 tcg_gen_andi_i32(t0, t0, 1);
7563 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7564 }
fd4a04eb 7565 opn = "bc1any2f";
5a5012ec
TS
7566 goto not_likely;
7567 case OPC_BC1TANY2:
a16336e4 7568 {
d94536f4
AJ
7569 TCGv_i32 t1 = tcg_temp_new_i32();
7570 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7571 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7572 tcg_gen_or_i32(t0, t0, t1);
7573 tcg_temp_free_i32(t1);
7574 tcg_gen_andi_i32(t0, t0, 1);
7575 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7576 }
fd4a04eb 7577 opn = "bc1any2t";
5a5012ec
TS
7578 goto not_likely;
7579 case OPC_BC1FANY4:
a16336e4 7580 {
d94536f4
AJ
7581 TCGv_i32 t1 = tcg_temp_new_i32();
7582 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7583 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7584 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7585 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7586 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7587 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7588 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7589 tcg_temp_free_i32(t1);
d94536f4
AJ
7590 tcg_gen_andi_i32(t0, t0, 1);
7591 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7592 }
fd4a04eb 7593 opn = "bc1any4f";
5a5012ec
TS
7594 goto not_likely;
7595 case OPC_BC1TANY4:
a16336e4 7596 {
d94536f4
AJ
7597 TCGv_i32 t1 = tcg_temp_new_i32();
7598 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7599 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7600 tcg_gen_or_i32(t0, t0, t1);
7601 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7602 tcg_gen_or_i32(t0, t0, t1);
7603 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7604 tcg_gen_or_i32(t0, t0, t1);
7605 tcg_temp_free_i32(t1);
7606 tcg_gen_andi_i32(t0, t0, 1);
7607 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7608 }
fd4a04eb 7609 opn = "bc1any4t";
5a5012ec
TS
7610 not_likely:
7611 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7612 break;
7613 default:
923617a3 7614 MIPS_INVAL(opn);
e397ee33 7615 generate_exception (ctx, EXCP_RI);
6c5c1e20 7616 goto out;
6ea83fed 7617 }
2abf314d 7618 (void)opn; /* avoid a compiler warning */
923617a3 7619 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7620 ctx->hflags, btarget);
7621 ctx->btarget = btarget;
b231c103 7622 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 7623 out:
a7812ae4 7624 tcg_temp_free_i32(t0);
6ea83fed
FB
7625}
7626
31837be3
YK
7627/* R6 CP1 Branches */
7628static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
7629 int32_t ft, int32_t offset)
7630{
7631 target_ulong btarget;
7632 const char *opn = "cp1 cond branch";
7633 TCGv_i64 t0 = tcg_temp_new_i64();
7634
7635 if (ctx->hflags & MIPS_HFLAG_BMASK) {
7636#ifdef MIPS_DEBUG_DISAS
7637 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
7638#endif
7639 generate_exception(ctx, EXCP_RI);
7640 goto out;
7641 }
7642
7643 gen_load_fpr64(ctx, t0, ft);
7644 tcg_gen_andi_i64(t0, t0, 1);
7645
7646 btarget = addr_add(ctx, ctx->pc + 4, offset);
7647
7648 switch (op) {
7649 case OPC_BC1EQZ:
7650 tcg_gen_xori_i64(t0, t0, 1);
7651 opn = "bc1eqz";
7652 ctx->hflags |= MIPS_HFLAG_BC;
7653 break;
7654 case OPC_BC1NEZ:
7655 /* t0 already set */
7656 opn = "bc1nez";
7657 ctx->hflags |= MIPS_HFLAG_BC;
7658 break;
7659 default:
7660 MIPS_INVAL(opn);
7661 generate_exception(ctx, EXCP_RI);
7662 goto out;
7663 }
7664
7665 tcg_gen_trunc_i64_tl(bcond, t0);
7666
7667 (void)opn; /* avoid a compiler warning */
7668 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7669 ctx->hflags, btarget);
7670 ctx->btarget = btarget;
7671
7672out:
7673 tcg_temp_free_i64(t0);
7674}
7675
6af0bf9c 7676/* Coprocessor 1 (FPU) */
5a5012ec 7677
5a5012ec
TS
7678#define FOP(func, fmt) (((fmt) << 21) | (func))
7679
bf4120ad
NF
7680enum fopcode {
7681 OPC_ADD_S = FOP(0, FMT_S),
7682 OPC_SUB_S = FOP(1, FMT_S),
7683 OPC_MUL_S = FOP(2, FMT_S),
7684 OPC_DIV_S = FOP(3, FMT_S),
7685 OPC_SQRT_S = FOP(4, FMT_S),
7686 OPC_ABS_S = FOP(5, FMT_S),
7687 OPC_MOV_S = FOP(6, FMT_S),
7688 OPC_NEG_S = FOP(7, FMT_S),
7689 OPC_ROUND_L_S = FOP(8, FMT_S),
7690 OPC_TRUNC_L_S = FOP(9, FMT_S),
7691 OPC_CEIL_L_S = FOP(10, FMT_S),
7692 OPC_FLOOR_L_S = FOP(11, FMT_S),
7693 OPC_ROUND_W_S = FOP(12, FMT_S),
7694 OPC_TRUNC_W_S = FOP(13, FMT_S),
7695 OPC_CEIL_W_S = FOP(14, FMT_S),
7696 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 7697 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
7698 OPC_MOVCF_S = FOP(17, FMT_S),
7699 OPC_MOVZ_S = FOP(18, FMT_S),
7700 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 7701 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
7702 OPC_RECIP_S = FOP(21, FMT_S),
7703 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
7704 OPC_SELNEZ_S = FOP(23, FMT_S),
7705 OPC_MADDF_S = FOP(24, FMT_S),
7706 OPC_MSUBF_S = FOP(25, FMT_S),
7707 OPC_RINT_S = FOP(26, FMT_S),
7708 OPC_CLASS_S = FOP(27, FMT_S),
7709 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 7710 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 7711 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 7712 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 7713 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 7714 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 7715 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
7716 OPC_RSQRT2_S = FOP(31, FMT_S),
7717 OPC_CVT_D_S = FOP(33, FMT_S),
7718 OPC_CVT_W_S = FOP(36, FMT_S),
7719 OPC_CVT_L_S = FOP(37, FMT_S),
7720 OPC_CVT_PS_S = FOP(38, FMT_S),
7721 OPC_CMP_F_S = FOP (48, FMT_S),
7722 OPC_CMP_UN_S = FOP (49, FMT_S),
7723 OPC_CMP_EQ_S = FOP (50, FMT_S),
7724 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7725 OPC_CMP_OLT_S = FOP (52, FMT_S),
7726 OPC_CMP_ULT_S = FOP (53, FMT_S),
7727 OPC_CMP_OLE_S = FOP (54, FMT_S),
7728 OPC_CMP_ULE_S = FOP (55, FMT_S),
7729 OPC_CMP_SF_S = FOP (56, FMT_S),
7730 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7731 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7732 OPC_CMP_NGL_S = FOP (59, FMT_S),
7733 OPC_CMP_LT_S = FOP (60, FMT_S),
7734 OPC_CMP_NGE_S = FOP (61, FMT_S),
7735 OPC_CMP_LE_S = FOP (62, FMT_S),
7736 OPC_CMP_NGT_S = FOP (63, FMT_S),
7737
7738 OPC_ADD_D = FOP(0, FMT_D),
7739 OPC_SUB_D = FOP(1, FMT_D),
7740 OPC_MUL_D = FOP(2, FMT_D),
7741 OPC_DIV_D = FOP(3, FMT_D),
7742 OPC_SQRT_D = FOP(4, FMT_D),
7743 OPC_ABS_D = FOP(5, FMT_D),
7744 OPC_MOV_D = FOP(6, FMT_D),
7745 OPC_NEG_D = FOP(7, FMT_D),
7746 OPC_ROUND_L_D = FOP(8, FMT_D),
7747 OPC_TRUNC_L_D = FOP(9, FMT_D),
7748 OPC_CEIL_L_D = FOP(10, FMT_D),
7749 OPC_FLOOR_L_D = FOP(11, FMT_D),
7750 OPC_ROUND_W_D = FOP(12, FMT_D),
7751 OPC_TRUNC_W_D = FOP(13, FMT_D),
7752 OPC_CEIL_W_D = FOP(14, FMT_D),
7753 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 7754 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
7755 OPC_MOVCF_D = FOP(17, FMT_D),
7756 OPC_MOVZ_D = FOP(18, FMT_D),
7757 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 7758 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
7759 OPC_RECIP_D = FOP(21, FMT_D),
7760 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
7761 OPC_SELNEZ_D = FOP(23, FMT_D),
7762 OPC_MADDF_D = FOP(24, FMT_D),
7763 OPC_MSUBF_D = FOP(25, FMT_D),
7764 OPC_RINT_D = FOP(26, FMT_D),
7765 OPC_CLASS_D = FOP(27, FMT_D),
7766 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 7767 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 7768 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 7769 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 7770 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 7771 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 7772 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
7773 OPC_RSQRT2_D = FOP(31, FMT_D),
7774 OPC_CVT_S_D = FOP(32, FMT_D),
7775 OPC_CVT_W_D = FOP(36, FMT_D),
7776 OPC_CVT_L_D = FOP(37, FMT_D),
7777 OPC_CMP_F_D = FOP (48, FMT_D),
7778 OPC_CMP_UN_D = FOP (49, FMT_D),
7779 OPC_CMP_EQ_D = FOP (50, FMT_D),
7780 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7781 OPC_CMP_OLT_D = FOP (52, FMT_D),
7782 OPC_CMP_ULT_D = FOP (53, FMT_D),
7783 OPC_CMP_OLE_D = FOP (54, FMT_D),
7784 OPC_CMP_ULE_D = FOP (55, FMT_D),
7785 OPC_CMP_SF_D = FOP (56, FMT_D),
7786 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7787 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7788 OPC_CMP_NGL_D = FOP (59, FMT_D),
7789 OPC_CMP_LT_D = FOP (60, FMT_D),
7790 OPC_CMP_NGE_D = FOP (61, FMT_D),
7791 OPC_CMP_LE_D = FOP (62, FMT_D),
7792 OPC_CMP_NGT_D = FOP (63, FMT_D),
7793
7794 OPC_CVT_S_W = FOP(32, FMT_W),
7795 OPC_CVT_D_W = FOP(33, FMT_W),
7796 OPC_CVT_S_L = FOP(32, FMT_L),
7797 OPC_CVT_D_L = FOP(33, FMT_L),
7798 OPC_CVT_PS_PW = FOP(38, FMT_W),
7799
7800 OPC_ADD_PS = FOP(0, FMT_PS),
7801 OPC_SUB_PS = FOP(1, FMT_PS),
7802 OPC_MUL_PS = FOP(2, FMT_PS),
7803 OPC_DIV_PS = FOP(3, FMT_PS),
7804 OPC_ABS_PS = FOP(5, FMT_PS),
7805 OPC_MOV_PS = FOP(6, FMT_PS),
7806 OPC_NEG_PS = FOP(7, FMT_PS),
7807 OPC_MOVCF_PS = FOP(17, FMT_PS),
7808 OPC_MOVZ_PS = FOP(18, FMT_PS),
7809 OPC_MOVN_PS = FOP(19, FMT_PS),
7810 OPC_ADDR_PS = FOP(24, FMT_PS),
7811 OPC_MULR_PS = FOP(26, FMT_PS),
7812 OPC_RECIP2_PS = FOP(28, FMT_PS),
7813 OPC_RECIP1_PS = FOP(29, FMT_PS),
7814 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7815 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7816
7817 OPC_CVT_S_PU = FOP(32, FMT_PS),
7818 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7819 OPC_CVT_S_PL = FOP(40, FMT_PS),
7820 OPC_PLL_PS = FOP(44, FMT_PS),
7821 OPC_PLU_PS = FOP(45, FMT_PS),
7822 OPC_PUL_PS = FOP(46, FMT_PS),
7823 OPC_PUU_PS = FOP(47, FMT_PS),
7824 OPC_CMP_F_PS = FOP (48, FMT_PS),
7825 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7826 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7827 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7828 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7829 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7830 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7831 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7832 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7833 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7834 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7835 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7836 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7837 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7838 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7839 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7840};
7841
3f493883
YK
7842enum r6_f_cmp_op {
7843 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
7844 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
7845 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
7846 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
7847 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
7848 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
7849 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
7850 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
7851 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
7852 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
7853 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
7854 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
7855 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
7856 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
7857 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
7858 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
7859 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
7860 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
7861 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
7862 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
7863 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
7864 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
7865
7866 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
7867 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
7868 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
7869 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
7870 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
7871 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
7872 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
7873 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
7874 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
7875 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
7876 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
7877 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
7878 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
7879 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
7880 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
7881 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
7882 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
7883 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
7884 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
7885 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
7886 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
7887 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
7888};
7a387fff 7889static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7890{
923617a3 7891 const char *opn = "cp1 move";
72c3a3ee 7892 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7893
7894 switch (opc) {
7895 case OPC_MFC1:
b6d96bed 7896 {
a7812ae4 7897 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7898
7899 gen_load_fpr32(fp0, fs);
7900 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7901 tcg_temp_free_i32(fp0);
6958549d 7902 }
6c5c1e20 7903 gen_store_gpr(t0, rt);
6ea83fed
FB
7904 opn = "mfc1";
7905 break;
7906 case OPC_MTC1:
6c5c1e20 7907 gen_load_gpr(t0, rt);
b6d96bed 7908 {
a7812ae4 7909 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7910
7911 tcg_gen_trunc_tl_i32(fp0, t0);
7912 gen_store_fpr32(fp0, fs);
a7812ae4 7913 tcg_temp_free_i32(fp0);
6958549d 7914 }
6ea83fed
FB
7915 opn = "mtc1";
7916 break;
7917 case OPC_CFC1:
895c2d04 7918 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7919 gen_store_gpr(t0, rt);
6ea83fed
FB
7920 opn = "cfc1";
7921 break;
7922 case OPC_CTC1:
6c5c1e20 7923 gen_load_gpr(t0, rt);
736d120a
PJ
7924 {
7925 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7926
7927 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7928 tcg_temp_free_i32(fs_tmp);
7929 }
6ea83fed
FB
7930 opn = "ctc1";
7931 break;
72c3a3ee 7932#if defined(TARGET_MIPS64)
9c2149c8 7933 case OPC_DMFC1:
72c3a3ee 7934 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7935 gen_store_gpr(t0, rt);
5a5012ec
TS
7936 opn = "dmfc1";
7937 break;
9c2149c8 7938 case OPC_DMTC1:
6c5c1e20 7939 gen_load_gpr(t0, rt);
72c3a3ee 7940 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7941 opn = "dmtc1";
7942 break;
72c3a3ee 7943#endif
5a5012ec 7944 case OPC_MFHC1:
b6d96bed 7945 {
a7812ae4 7946 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7947
7f6613ce 7948 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7949 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7950 tcg_temp_free_i32(fp0);
6958549d 7951 }
6c5c1e20 7952 gen_store_gpr(t0, rt);
5a5012ec
TS
7953 opn = "mfhc1";
7954 break;
7955 case OPC_MTHC1:
6c5c1e20 7956 gen_load_gpr(t0, rt);
b6d96bed 7957 {
a7812ae4 7958 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7959
7960 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7961 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 7962 tcg_temp_free_i32(fp0);
6958549d 7963 }
5a5012ec
TS
7964 opn = "mthc1";
7965 break;
6ea83fed 7966 default:
923617a3 7967 MIPS_INVAL(opn);
e397ee33 7968 generate_exception (ctx, EXCP_RI);
6c5c1e20 7969 goto out;
6ea83fed 7970 }
2abf314d 7971 (void)opn; /* avoid a compiler warning */
6ea83fed 7972 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7973
7974 out:
7975 tcg_temp_free(t0);
6ea83fed
FB
7976}
7977
5a5012ec
TS
7978static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7979{
af58f9ca 7980 int l1;
e214b9bb 7981 TCGCond cond;
af58f9ca
AJ
7982 TCGv_i32 t0;
7983
7984 if (rd == 0) {
7985 /* Treat as NOP. */
7986 return;
7987 }
6ea83fed 7988
e214b9bb 7989 if (tf)
e214b9bb 7990 cond = TCG_COND_EQ;
27848470
TS
7991 else
7992 cond = TCG_COND_NE;
7993
af58f9ca
AJ
7994 l1 = gen_new_label();
7995 t0 = tcg_temp_new_i32();
fa31af0e 7996 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7997 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7998 tcg_temp_free_i32(t0);
af58f9ca
AJ
7999 if (rs == 0) {
8000 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8001 } else {
8002 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8003 }
e214b9bb 8004 gen_set_label(l1);
5a5012ec
TS
8005}
8006
b6d96bed 8007static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 8008{
a16336e4 8009 int cond;
cbc37b28 8010 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8011 int l1 = gen_new_label();
8012
a16336e4
TS
8013 if (tf)
8014 cond = TCG_COND_EQ;
8015 else
8016 cond = TCG_COND_NE;
8017
fa31af0e 8018 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8019 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8020 gen_load_fpr32(t0, fs);
8021 gen_store_fpr32(t0, fd);
a16336e4 8022 gen_set_label(l1);
cbc37b28 8023 tcg_temp_free_i32(t0);
5a5012ec 8024}
a16336e4 8025
b6d96bed 8026static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8027{
a16336e4 8028 int cond;
cbc37b28
AJ
8029 TCGv_i32 t0 = tcg_temp_new_i32();
8030 TCGv_i64 fp0;
a16336e4
TS
8031 int l1 = gen_new_label();
8032
a16336e4
TS
8033 if (tf)
8034 cond = TCG_COND_EQ;
8035 else
8036 cond = TCG_COND_NE;
8037
fa31af0e 8038 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8039 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8040 tcg_temp_free_i32(t0);
11f94258 8041 fp0 = tcg_temp_new_i64();
9bf3eb2c 8042 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8043 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8044 tcg_temp_free_i64(fp0);
cbc37b28 8045 gen_set_label(l1);
a16336e4
TS
8046}
8047
7f6613ce
PJ
8048static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8049 int cc, int tf)
a16336e4
TS
8050{
8051 int cond;
cbc37b28 8052 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8053 int l1 = gen_new_label();
8054 int l2 = gen_new_label();
8055
8056 if (tf)
8057 cond = TCG_COND_EQ;
8058 else
8059 cond = TCG_COND_NE;
8060
fa31af0e 8061 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8062 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8063 gen_load_fpr32(t0, fs);
8064 gen_store_fpr32(t0, fd);
a16336e4 8065 gen_set_label(l1);
9bf3eb2c 8066
fa31af0e 8067 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8068 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8069 gen_load_fpr32h(ctx, t0, fs);
8070 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8071 tcg_temp_free_i32(t0);
a16336e4 8072 gen_set_label(l2);
a16336e4
TS
8073}
8074
e7f16abb
LA
8075static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8076 int fs)
8077{
8078 TCGv_i32 t1 = tcg_const_i32(0);
8079 TCGv_i32 fp0 = tcg_temp_new_i32();
8080 TCGv_i32 fp1 = tcg_temp_new_i32();
8081 TCGv_i32 fp2 = tcg_temp_new_i32();
8082 gen_load_fpr32(fp0, fd);
8083 gen_load_fpr32(fp1, ft);
8084 gen_load_fpr32(fp2, fs);
8085
8086 switch (op1) {
8087 case OPC_SEL_S:
8088 tcg_gen_andi_i32(fp0, fp0, 1);
8089 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8090 break;
8091 case OPC_SELEQZ_S:
8092 tcg_gen_andi_i32(fp1, fp1, 1);
8093 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8094 break;
8095 case OPC_SELNEZ_S:
8096 tcg_gen_andi_i32(fp1, fp1, 1);
8097 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8098 break;
8099 default:
8100 MIPS_INVAL("gen_sel_s");
8101 generate_exception (ctx, EXCP_RI);
8102 break;
8103 }
8104
8105 gen_store_fpr32(fp0, fd);
8106 tcg_temp_free_i32(fp2);
8107 tcg_temp_free_i32(fp1);
8108 tcg_temp_free_i32(fp0);
8109 tcg_temp_free_i32(t1);
8110}
8111
8112static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8113 int fs)
8114{
8115 TCGv_i64 t1 = tcg_const_i64(0);
8116 TCGv_i64 fp0 = tcg_temp_new_i64();
8117 TCGv_i64 fp1 = tcg_temp_new_i64();
8118 TCGv_i64 fp2 = tcg_temp_new_i64();
8119 gen_load_fpr64(ctx, fp0, fd);
8120 gen_load_fpr64(ctx, fp1, ft);
8121 gen_load_fpr64(ctx, fp2, fs);
8122
8123 switch (op1) {
8124 case OPC_SEL_D:
8125 tcg_gen_andi_i64(fp0, fp0, 1);
8126 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8127 break;
8128 case OPC_SELEQZ_D:
8129 tcg_gen_andi_i64(fp1, fp1, 1);
8130 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8131 break;
8132 case OPC_SELNEZ_D:
8133 tcg_gen_andi_i64(fp1, fp1, 1);
8134 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8135 break;
8136 default:
8137 MIPS_INVAL("gen_sel_d");
8138 generate_exception (ctx, EXCP_RI);
8139 break;
8140 }
8141
8142 gen_store_fpr64(ctx, fp0, fd);
8143 tcg_temp_free_i64(fp2);
8144 tcg_temp_free_i64(fp1);
8145 tcg_temp_free_i64(fp0);
8146 tcg_temp_free_i64(t1);
8147}
6ea83fed 8148
bf4120ad 8149static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8150 int ft, int fs, int fd, int cc)
6ea83fed 8151{
923617a3 8152 const char *opn = "farith";
6ea83fed
FB
8153 const char *condnames[] = {
8154 "c.f",
8155 "c.un",
8156 "c.eq",
8157 "c.ueq",
8158 "c.olt",
8159 "c.ult",
8160 "c.ole",
8161 "c.ule",
8162 "c.sf",
8163 "c.ngle",
8164 "c.seq",
8165 "c.ngl",
8166 "c.lt",
8167 "c.nge",
8168 "c.le",
8169 "c.ngt",
8170 };
5a1e8ffb
TS
8171 const char *condnames_abs[] = {
8172 "cabs.f",
8173 "cabs.un",
8174 "cabs.eq",
8175 "cabs.ueq",
8176 "cabs.olt",
8177 "cabs.ult",
8178 "cabs.ole",
8179 "cabs.ule",
8180 "cabs.sf",
8181 "cabs.ngle",
8182 "cabs.seq",
8183 "cabs.ngl",
8184 "cabs.lt",
8185 "cabs.nge",
8186 "cabs.le",
8187 "cabs.ngt",
8188 };
8189 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8190 uint32_t func = ctx->opcode & 0x3f;
8191
bf4120ad
NF
8192 switch (op1) {
8193 case OPC_ADD_S:
b6d96bed 8194 {
a7812ae4
PB
8195 TCGv_i32 fp0 = tcg_temp_new_i32();
8196 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8197
8198 gen_load_fpr32(fp0, fs);
8199 gen_load_fpr32(fp1, ft);
895c2d04 8200 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8201 tcg_temp_free_i32(fp1);
b6d96bed 8202 gen_store_fpr32(fp0, fd);
a7812ae4 8203 tcg_temp_free_i32(fp0);
b6d96bed 8204 }
5a5012ec 8205 opn = "add.s";
5a1e8ffb 8206 optype = BINOP;
5a5012ec 8207 break;
bf4120ad 8208 case OPC_SUB_S:
b6d96bed 8209 {
a7812ae4
PB
8210 TCGv_i32 fp0 = tcg_temp_new_i32();
8211 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8212
8213 gen_load_fpr32(fp0, fs);
8214 gen_load_fpr32(fp1, ft);
895c2d04 8215 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8216 tcg_temp_free_i32(fp1);
b6d96bed 8217 gen_store_fpr32(fp0, fd);
a7812ae4 8218 tcg_temp_free_i32(fp0);
b6d96bed 8219 }
5a5012ec 8220 opn = "sub.s";
5a1e8ffb 8221 optype = BINOP;
5a5012ec 8222 break;
bf4120ad 8223 case OPC_MUL_S:
b6d96bed 8224 {
a7812ae4
PB
8225 TCGv_i32 fp0 = tcg_temp_new_i32();
8226 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8227
8228 gen_load_fpr32(fp0, fs);
8229 gen_load_fpr32(fp1, ft);
895c2d04 8230 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8231 tcg_temp_free_i32(fp1);
b6d96bed 8232 gen_store_fpr32(fp0, fd);
a7812ae4 8233 tcg_temp_free_i32(fp0);
b6d96bed 8234 }
5a5012ec 8235 opn = "mul.s";
5a1e8ffb 8236 optype = BINOP;
5a5012ec 8237 break;
bf4120ad 8238 case OPC_DIV_S:
b6d96bed 8239 {
a7812ae4
PB
8240 TCGv_i32 fp0 = tcg_temp_new_i32();
8241 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8242
8243 gen_load_fpr32(fp0, fs);
8244 gen_load_fpr32(fp1, ft);
895c2d04 8245 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8246 tcg_temp_free_i32(fp1);
b6d96bed 8247 gen_store_fpr32(fp0, fd);
a7812ae4 8248 tcg_temp_free_i32(fp0);
b6d96bed 8249 }
5a5012ec 8250 opn = "div.s";
5a1e8ffb 8251 optype = BINOP;
5a5012ec 8252 break;
bf4120ad 8253 case OPC_SQRT_S:
b6d96bed 8254 {
a7812ae4 8255 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8256
8257 gen_load_fpr32(fp0, fs);
895c2d04 8258 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 8259 gen_store_fpr32(fp0, fd);
a7812ae4 8260 tcg_temp_free_i32(fp0);
b6d96bed 8261 }
5a5012ec
TS
8262 opn = "sqrt.s";
8263 break;
bf4120ad 8264 case OPC_ABS_S:
b6d96bed 8265 {
a7812ae4 8266 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8267
8268 gen_load_fpr32(fp0, fs);
a7812ae4 8269 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 8270 gen_store_fpr32(fp0, fd);
a7812ae4 8271 tcg_temp_free_i32(fp0);
b6d96bed 8272 }
5a5012ec
TS
8273 opn = "abs.s";
8274 break;
bf4120ad 8275 case OPC_MOV_S:
b6d96bed 8276 {
a7812ae4 8277 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8278
8279 gen_load_fpr32(fp0, fs);
8280 gen_store_fpr32(fp0, fd);
a7812ae4 8281 tcg_temp_free_i32(fp0);
b6d96bed 8282 }
5a5012ec
TS
8283 opn = "mov.s";
8284 break;
bf4120ad 8285 case OPC_NEG_S:
b6d96bed 8286 {
a7812ae4 8287 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8288
8289 gen_load_fpr32(fp0, fs);
a7812ae4 8290 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 8291 gen_store_fpr32(fp0, fd);
a7812ae4 8292 tcg_temp_free_i32(fp0);
b6d96bed 8293 }
5a5012ec
TS
8294 opn = "neg.s";
8295 break;
bf4120ad 8296 case OPC_ROUND_L_S:
5e755519 8297 check_cp1_64bitmode(ctx);
b6d96bed 8298 {
a7812ae4
PB
8299 TCGv_i32 fp32 = tcg_temp_new_i32();
8300 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8301
8302 gen_load_fpr32(fp32, fs);
895c2d04 8303 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8304 tcg_temp_free_i32(fp32);
b6d96bed 8305 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8306 tcg_temp_free_i64(fp64);
b6d96bed 8307 }
5a5012ec
TS
8308 opn = "round.l.s";
8309 break;
bf4120ad 8310 case OPC_TRUNC_L_S:
5e755519 8311 check_cp1_64bitmode(ctx);
b6d96bed 8312 {
a7812ae4
PB
8313 TCGv_i32 fp32 = tcg_temp_new_i32();
8314 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8315
8316 gen_load_fpr32(fp32, fs);
895c2d04 8317 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8318 tcg_temp_free_i32(fp32);
b6d96bed 8319 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8320 tcg_temp_free_i64(fp64);
b6d96bed 8321 }
5a5012ec
TS
8322 opn = "trunc.l.s";
8323 break;
bf4120ad 8324 case OPC_CEIL_L_S:
5e755519 8325 check_cp1_64bitmode(ctx);
b6d96bed 8326 {
a7812ae4
PB
8327 TCGv_i32 fp32 = tcg_temp_new_i32();
8328 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8329
8330 gen_load_fpr32(fp32, fs);
895c2d04 8331 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8332 tcg_temp_free_i32(fp32);
b6d96bed 8333 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8334 tcg_temp_free_i64(fp64);
b6d96bed 8335 }
5a5012ec
TS
8336 opn = "ceil.l.s";
8337 break;
bf4120ad 8338 case OPC_FLOOR_L_S:
5e755519 8339 check_cp1_64bitmode(ctx);
b6d96bed 8340 {
a7812ae4
PB
8341 TCGv_i32 fp32 = tcg_temp_new_i32();
8342 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8343
8344 gen_load_fpr32(fp32, fs);
895c2d04 8345 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8346 tcg_temp_free_i32(fp32);
b6d96bed 8347 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8348 tcg_temp_free_i64(fp64);
b6d96bed 8349 }
5a5012ec
TS
8350 opn = "floor.l.s";
8351 break;
bf4120ad 8352 case OPC_ROUND_W_S:
b6d96bed 8353 {
a7812ae4 8354 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8355
8356 gen_load_fpr32(fp0, fs);
895c2d04 8357 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 8358 gen_store_fpr32(fp0, fd);
a7812ae4 8359 tcg_temp_free_i32(fp0);
b6d96bed 8360 }
5a5012ec
TS
8361 opn = "round.w.s";
8362 break;
bf4120ad 8363 case OPC_TRUNC_W_S:
b6d96bed 8364 {
a7812ae4 8365 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8366
8367 gen_load_fpr32(fp0, fs);
895c2d04 8368 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 8369 gen_store_fpr32(fp0, fd);
a7812ae4 8370 tcg_temp_free_i32(fp0);
b6d96bed 8371 }
5a5012ec
TS
8372 opn = "trunc.w.s";
8373 break;
bf4120ad 8374 case OPC_CEIL_W_S:
b6d96bed 8375 {
a7812ae4 8376 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8377
8378 gen_load_fpr32(fp0, fs);
895c2d04 8379 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 8380 gen_store_fpr32(fp0, fd);
a7812ae4 8381 tcg_temp_free_i32(fp0);
b6d96bed 8382 }
5a5012ec
TS
8383 opn = "ceil.w.s";
8384 break;
bf4120ad 8385 case OPC_FLOOR_W_S:
b6d96bed 8386 {
a7812ae4 8387 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8388
8389 gen_load_fpr32(fp0, fs);
895c2d04 8390 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8391 gen_store_fpr32(fp0, fd);
a7812ae4 8392 tcg_temp_free_i32(fp0);
b6d96bed 8393 }
5a5012ec
TS
8394 opn = "floor.w.s";
8395 break;
e7f16abb
LA
8396 case OPC_SEL_S:
8397 check_insn(ctx, ISA_MIPS32R6);
8398 gen_sel_s(ctx, op1, fd, ft, fs);
8399 opn = "sel.s";
8400 break;
8401 case OPC_SELEQZ_S:
8402 check_insn(ctx, ISA_MIPS32R6);
8403 gen_sel_s(ctx, op1, fd, ft, fs);
8404 opn = "seleqz.s";
8405 break;
8406 case OPC_SELNEZ_S:
8407 check_insn(ctx, ISA_MIPS32R6);
8408 gen_sel_s(ctx, op1, fd, ft, fs);
8409 opn = "selnez.s";
8410 break;
bf4120ad 8411 case OPC_MOVCF_S:
fecd2646 8412 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8413 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8414 opn = "movcf.s";
8415 break;
bf4120ad 8416 case OPC_MOVZ_S:
fecd2646 8417 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8418 {
8419 int l1 = gen_new_label();
c9297f4d 8420 TCGv_i32 fp0;
a16336e4 8421
c9297f4d
AJ
8422 if (ft != 0) {
8423 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8424 }
8425 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8426 gen_load_fpr32(fp0, fs);
8427 gen_store_fpr32(fp0, fd);
a7812ae4 8428 tcg_temp_free_i32(fp0);
a16336e4
TS
8429 gen_set_label(l1);
8430 }
5a5012ec
TS
8431 opn = "movz.s";
8432 break;
bf4120ad 8433 case OPC_MOVN_S:
fecd2646 8434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8435 {
8436 int l1 = gen_new_label();
c9297f4d
AJ
8437 TCGv_i32 fp0;
8438
8439 if (ft != 0) {
8440 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8441 fp0 = tcg_temp_new_i32();
8442 gen_load_fpr32(fp0, fs);
8443 gen_store_fpr32(fp0, fd);
8444 tcg_temp_free_i32(fp0);
8445 gen_set_label(l1);
8446 }
a16336e4 8447 }
5a5012ec
TS
8448 opn = "movn.s";
8449 break;
bf4120ad 8450 case OPC_RECIP_S:
b8aa4598 8451 check_cop1x(ctx);
b6d96bed 8452 {
a7812ae4 8453 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8454
8455 gen_load_fpr32(fp0, fs);
895c2d04 8456 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8457 gen_store_fpr32(fp0, fd);
a7812ae4 8458 tcg_temp_free_i32(fp0);
b6d96bed 8459 }
57fa1fb3
TS
8460 opn = "recip.s";
8461 break;
bf4120ad 8462 case OPC_RSQRT_S:
b8aa4598 8463 check_cop1x(ctx);
b6d96bed 8464 {
a7812ae4 8465 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8466
8467 gen_load_fpr32(fp0, fs);
895c2d04 8468 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8469 gen_store_fpr32(fp0, fd);
a7812ae4 8470 tcg_temp_free_i32(fp0);
b6d96bed 8471 }
57fa1fb3
TS
8472 opn = "rsqrt.s";
8473 break;
e7f16abb
LA
8474 case OPC_MADDF_S:
8475 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8476 {
a7812ae4
PB
8477 TCGv_i32 fp0 = tcg_temp_new_i32();
8478 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8479 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8480 gen_load_fpr32(fp0, fs);
d22d7289 8481 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8482 gen_load_fpr32(fp2, fd);
8483 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8484 gen_store_fpr32(fp2, fd);
8485 tcg_temp_free_i32(fp2);
a7812ae4 8486 tcg_temp_free_i32(fp1);
a7812ae4 8487 tcg_temp_free_i32(fp0);
e7f16abb 8488 opn = "maddf.s";
b6d96bed 8489 }
57fa1fb3 8490 break;
e7f16abb
LA
8491 case OPC_MSUBF_S:
8492 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8493 {
a7812ae4 8494 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8495 TCGv_i32 fp1 = tcg_temp_new_i32();
8496 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8497 gen_load_fpr32(fp0, fs);
e7f16abb
LA
8498 gen_load_fpr32(fp1, ft);
8499 gen_load_fpr32(fp2, fd);
8500 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8501 gen_store_fpr32(fp2, fd);
8502 tcg_temp_free_i32(fp2);
8503 tcg_temp_free_i32(fp1);
a7812ae4 8504 tcg_temp_free_i32(fp0);
e7f16abb 8505 opn = "msubf.s";
b6d96bed 8506 }
57fa1fb3 8507 break;
e7f16abb
LA
8508 case OPC_RINT_S:
8509 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8510 {
a7812ae4 8511 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8512 gen_load_fpr32(fp0, fs);
e7f16abb 8513 gen_helper_float_rint_s(fp0, cpu_env, fp0);
b6d96bed 8514 gen_store_fpr32(fp0, fd);
a7812ae4 8515 tcg_temp_free_i32(fp0);
e7f16abb 8516 opn = "rint.s";
b6d96bed 8517 }
57fa1fb3 8518 break;
e7f16abb
LA
8519 case OPC_CLASS_S:
8520 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8521 {
e7f16abb
LA
8522 TCGv_i32 fp0 = tcg_temp_new_i32();
8523 gen_load_fpr32(fp0, fs);
8524 gen_helper_float_class_s(fp0, fp0);
8525 gen_store_fpr32(fp0, fd);
8526 tcg_temp_free_i32(fp0);
8527 opn = "class.s";
8528 }
8529 break;
8530 case OPC_MIN_S: /* OPC_RECIP2_S */
8531 if (ctx->insn_flags & ISA_MIPS32R6) {
8532 /* OPC_MIN_S */
a7812ae4
PB
8533 TCGv_i32 fp0 = tcg_temp_new_i32();
8534 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb
LA
8535 TCGv_i32 fp2 = tcg_temp_new_i32();
8536 gen_load_fpr32(fp0, fs);
8537 gen_load_fpr32(fp1, ft);
8538 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8539 gen_store_fpr32(fp2, fd);
8540 tcg_temp_free_i32(fp2);
8541 tcg_temp_free_i32(fp1);
8542 tcg_temp_free_i32(fp0);
8543 opn = "min.s";
8544 } else {
8545 /* OPC_RECIP2_S */
8546 check_cp1_64bitmode(ctx);
8547 {
8548 TCGv_i32 fp0 = tcg_temp_new_i32();
8549 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8550
e7f16abb
LA
8551 gen_load_fpr32(fp0, fs);
8552 gen_load_fpr32(fp1, ft);
8553 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
8554 tcg_temp_free_i32(fp1);
8555 gen_store_fpr32(fp0, fd);
8556 tcg_temp_free_i32(fp0);
8557 }
8558 opn = "recip2.s";
8559 }
8560 break;
8561 case OPC_MINA_S: /* OPC_RECIP1_S */
8562 if (ctx->insn_flags & ISA_MIPS32R6) {
8563 /* OPC_MINA_S */
8564 TCGv_i32 fp0 = tcg_temp_new_i32();
8565 TCGv_i32 fp1 = tcg_temp_new_i32();
8566 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8567 gen_load_fpr32(fp0, fs);
8568 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8569 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
8570 gen_store_fpr32(fp2, fd);
8571 tcg_temp_free_i32(fp2);
8572 tcg_temp_free_i32(fp1);
8573 tcg_temp_free_i32(fp0);
8574 opn = "mina.s";
8575 } else {
8576 /* OPC_RECIP1_S */
8577 check_cp1_64bitmode(ctx);
8578 {
8579 TCGv_i32 fp0 = tcg_temp_new_i32();
8580
8581 gen_load_fpr32(fp0, fs);
8582 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
8583 gen_store_fpr32(fp0, fd);
8584 tcg_temp_free_i32(fp0);
8585 }
8586 opn = "recip1.s";
8587 }
8588 break;
8589 case OPC_MAX_S: /* OPC_RSQRT1_S */
8590 if (ctx->insn_flags & ISA_MIPS32R6) {
8591 /* OPC_MAX_S */
8592 TCGv_i32 fp0 = tcg_temp_new_i32();
8593 TCGv_i32 fp1 = tcg_temp_new_i32();
8594 gen_load_fpr32(fp0, fs);
8595 gen_load_fpr32(fp1, ft);
8596 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
8597 gen_store_fpr32(fp1, fd);
8598 tcg_temp_free_i32(fp1);
8599 tcg_temp_free_i32(fp0);
8600 opn = "max.s";
8601 } else {
8602 /* OPC_RSQRT1_S */
8603 check_cp1_64bitmode(ctx);
8604 {
8605 TCGv_i32 fp0 = tcg_temp_new_i32();
8606
8607 gen_load_fpr32(fp0, fs);
8608 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
8609 gen_store_fpr32(fp0, fd);
8610 tcg_temp_free_i32(fp0);
8611 }
8612 opn = "rsqrt1.s";
8613 }
8614 break;
8615 case OPC_MAXA_S: /* OPC_RSQRT2_S */
8616 if (ctx->insn_flags & ISA_MIPS32R6) {
8617 /* OPC_MAXA_S */
8618 TCGv_i32 fp0 = tcg_temp_new_i32();
8619 TCGv_i32 fp1 = tcg_temp_new_i32();
8620 gen_load_fpr32(fp0, fs);
8621 gen_load_fpr32(fp1, ft);
8622 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
8623 gen_store_fpr32(fp1, fd);
a7812ae4 8624 tcg_temp_free_i32(fp1);
a7812ae4 8625 tcg_temp_free_i32(fp0);
e7f16abb
LA
8626 opn = "maxa.s";
8627 } else {
8628 /* OPC_RSQRT2_S */
8629 check_cp1_64bitmode(ctx);
8630 {
8631 TCGv_i32 fp0 = tcg_temp_new_i32();
8632 TCGv_i32 fp1 = tcg_temp_new_i32();
8633
8634 gen_load_fpr32(fp0, fs);
8635 gen_load_fpr32(fp1, ft);
8636 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
8637 tcg_temp_free_i32(fp1);
8638 gen_store_fpr32(fp0, fd);
8639 tcg_temp_free_i32(fp0);
8640 }
8641 opn = "rsqrt2.s";
b6d96bed 8642 }
57fa1fb3 8643 break;
bf4120ad 8644 case OPC_CVT_D_S:
5e755519 8645 check_cp1_registers(ctx, fd);
b6d96bed 8646 {
a7812ae4
PB
8647 TCGv_i32 fp32 = tcg_temp_new_i32();
8648 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8649
8650 gen_load_fpr32(fp32, fs);
895c2d04 8651 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 8652 tcg_temp_free_i32(fp32);
b6d96bed 8653 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8654 tcg_temp_free_i64(fp64);
b6d96bed 8655 }
5a5012ec
TS
8656 opn = "cvt.d.s";
8657 break;
bf4120ad 8658 case OPC_CVT_W_S:
b6d96bed 8659 {
a7812ae4 8660 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8661
8662 gen_load_fpr32(fp0, fs);
895c2d04 8663 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 8664 gen_store_fpr32(fp0, fd);
a7812ae4 8665 tcg_temp_free_i32(fp0);
b6d96bed 8666 }
5a5012ec
TS
8667 opn = "cvt.w.s";
8668 break;
bf4120ad 8669 case OPC_CVT_L_S:
5e755519 8670 check_cp1_64bitmode(ctx);
b6d96bed 8671 {
a7812ae4
PB
8672 TCGv_i32 fp32 = tcg_temp_new_i32();
8673 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8674
8675 gen_load_fpr32(fp32, fs);
895c2d04 8676 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 8677 tcg_temp_free_i32(fp32);
b6d96bed 8678 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8679 tcg_temp_free_i64(fp64);
b6d96bed 8680 }
5a5012ec
TS
8681 opn = "cvt.l.s";
8682 break;
bf4120ad 8683 case OPC_CVT_PS_S:
fecd2646 8684 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 8685 check_cp1_64bitmode(ctx);
b6d96bed 8686 {
a7812ae4
PB
8687 TCGv_i64 fp64 = tcg_temp_new_i64();
8688 TCGv_i32 fp32_0 = tcg_temp_new_i32();
8689 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
8690
8691 gen_load_fpr32(fp32_0, fs);
8692 gen_load_fpr32(fp32_1, ft);
13d24f49 8693 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
8694 tcg_temp_free_i32(fp32_1);
8695 tcg_temp_free_i32(fp32_0);
36aa55dc 8696 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8697 tcg_temp_free_i64(fp64);
b6d96bed 8698 }
5a5012ec
TS
8699 opn = "cvt.ps.s";
8700 break;
bf4120ad
NF
8701 case OPC_CMP_F_S:
8702 case OPC_CMP_UN_S:
8703 case OPC_CMP_EQ_S:
8704 case OPC_CMP_UEQ_S:
8705 case OPC_CMP_OLT_S:
8706 case OPC_CMP_ULT_S:
8707 case OPC_CMP_OLE_S:
8708 case OPC_CMP_ULE_S:
8709 case OPC_CMP_SF_S:
8710 case OPC_CMP_NGLE_S:
8711 case OPC_CMP_SEQ_S:
8712 case OPC_CMP_NGL_S:
8713 case OPC_CMP_LT_S:
8714 case OPC_CMP_NGE_S:
8715 case OPC_CMP_LE_S:
8716 case OPC_CMP_NGT_S:
fecd2646 8717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
8718 if (ctx->opcode & (1 << 6)) {
8719 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8720 opn = condnames_abs[func-48];
8721 } else {
8722 gen_cmp_s(ctx, func-48, ft, fs, cc);
8723 opn = condnames[func-48];
5a1e8ffb 8724 }
5a5012ec 8725 break;
bf4120ad 8726 case OPC_ADD_D:
5e755519 8727 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8728 {
a7812ae4
PB
8729 TCGv_i64 fp0 = tcg_temp_new_i64();
8730 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8731
8732 gen_load_fpr64(ctx, fp0, fs);
8733 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8734 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8735 tcg_temp_free_i64(fp1);
b6d96bed 8736 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8737 tcg_temp_free_i64(fp0);
b6d96bed 8738 }
6ea83fed 8739 opn = "add.d";
5a1e8ffb 8740 optype = BINOP;
6ea83fed 8741 break;
bf4120ad 8742 case OPC_SUB_D:
5e755519 8743 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8744 {
a7812ae4
PB
8745 TCGv_i64 fp0 = tcg_temp_new_i64();
8746 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8747
8748 gen_load_fpr64(ctx, fp0, fs);
8749 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8750 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8751 tcg_temp_free_i64(fp1);
b6d96bed 8752 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8753 tcg_temp_free_i64(fp0);
b6d96bed 8754 }
6ea83fed 8755 opn = "sub.d";
5a1e8ffb 8756 optype = BINOP;
6ea83fed 8757 break;
bf4120ad 8758 case OPC_MUL_D:
5e755519 8759 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8760 {
a7812ae4
PB
8761 TCGv_i64 fp0 = tcg_temp_new_i64();
8762 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8763
8764 gen_load_fpr64(ctx, fp0, fs);
8765 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8766 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8767 tcg_temp_free_i64(fp1);
b6d96bed 8768 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8769 tcg_temp_free_i64(fp0);
b6d96bed 8770 }
6ea83fed 8771 opn = "mul.d";
5a1e8ffb 8772 optype = BINOP;
6ea83fed 8773 break;
bf4120ad 8774 case OPC_DIV_D:
5e755519 8775 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8776 {
a7812ae4
PB
8777 TCGv_i64 fp0 = tcg_temp_new_i64();
8778 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8779
8780 gen_load_fpr64(ctx, fp0, fs);
8781 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8782 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8783 tcg_temp_free_i64(fp1);
b6d96bed 8784 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8785 tcg_temp_free_i64(fp0);
b6d96bed 8786 }
6ea83fed 8787 opn = "div.d";
5a1e8ffb 8788 optype = BINOP;
6ea83fed 8789 break;
bf4120ad 8790 case OPC_SQRT_D:
5e755519 8791 check_cp1_registers(ctx, fs | fd);
b6d96bed 8792 {
a7812ae4 8793 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8794
8795 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8796 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 8797 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8798 tcg_temp_free_i64(fp0);
b6d96bed 8799 }
6ea83fed
FB
8800 opn = "sqrt.d";
8801 break;
bf4120ad 8802 case OPC_ABS_D:
5e755519 8803 check_cp1_registers(ctx, fs | fd);
b6d96bed 8804 {
a7812ae4 8805 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8806
8807 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8808 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 8809 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8810 tcg_temp_free_i64(fp0);
b6d96bed 8811 }
6ea83fed
FB
8812 opn = "abs.d";
8813 break;
bf4120ad 8814 case OPC_MOV_D:
5e755519 8815 check_cp1_registers(ctx, fs | fd);
b6d96bed 8816 {
a7812ae4 8817 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8818
8819 gen_load_fpr64(ctx, fp0, fs);
8820 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8821 tcg_temp_free_i64(fp0);
b6d96bed 8822 }
6ea83fed
FB
8823 opn = "mov.d";
8824 break;
bf4120ad 8825 case OPC_NEG_D:
5e755519 8826 check_cp1_registers(ctx, fs | fd);
b6d96bed 8827 {
a7812ae4 8828 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8829
8830 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8831 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 8832 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8833 tcg_temp_free_i64(fp0);
b6d96bed 8834 }
6ea83fed
FB
8835 opn = "neg.d";
8836 break;
bf4120ad 8837 case OPC_ROUND_L_D:
5e755519 8838 check_cp1_64bitmode(ctx);
b6d96bed 8839 {
a7812ae4 8840 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8841
8842 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8843 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8844 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8845 tcg_temp_free_i64(fp0);
b6d96bed 8846 }
5a5012ec
TS
8847 opn = "round.l.d";
8848 break;
bf4120ad 8849 case OPC_TRUNC_L_D:
5e755519 8850 check_cp1_64bitmode(ctx);
b6d96bed 8851 {
a7812ae4 8852 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8853
8854 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8855 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8856 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8857 tcg_temp_free_i64(fp0);
b6d96bed 8858 }
5a5012ec
TS
8859 opn = "trunc.l.d";
8860 break;
bf4120ad 8861 case OPC_CEIL_L_D:
5e755519 8862 check_cp1_64bitmode(ctx);
b6d96bed 8863 {
a7812ae4 8864 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8865
8866 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8867 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8868 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8869 tcg_temp_free_i64(fp0);
b6d96bed 8870 }
5a5012ec
TS
8871 opn = "ceil.l.d";
8872 break;
bf4120ad 8873 case OPC_FLOOR_L_D:
5e755519 8874 check_cp1_64bitmode(ctx);
b6d96bed 8875 {
a7812ae4 8876 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8877
8878 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8879 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8880 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8881 tcg_temp_free_i64(fp0);
b6d96bed 8882 }
5a5012ec
TS
8883 opn = "floor.l.d";
8884 break;
bf4120ad 8885 case OPC_ROUND_W_D:
5e755519 8886 check_cp1_registers(ctx, fs);
b6d96bed 8887 {
a7812ae4
PB
8888 TCGv_i32 fp32 = tcg_temp_new_i32();
8889 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8890
8891 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8892 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8893 tcg_temp_free_i64(fp64);
b6d96bed 8894 gen_store_fpr32(fp32, fd);
a7812ae4 8895 tcg_temp_free_i32(fp32);
b6d96bed 8896 }
6ea83fed
FB
8897 opn = "round.w.d";
8898 break;
bf4120ad 8899 case OPC_TRUNC_W_D:
5e755519 8900 check_cp1_registers(ctx, fs);
b6d96bed 8901 {
a7812ae4
PB
8902 TCGv_i32 fp32 = tcg_temp_new_i32();
8903 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8904
8905 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8906 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8907 tcg_temp_free_i64(fp64);
b6d96bed 8908 gen_store_fpr32(fp32, fd);
a7812ae4 8909 tcg_temp_free_i32(fp32);
b6d96bed 8910 }
6ea83fed
FB
8911 opn = "trunc.w.d";
8912 break;
bf4120ad 8913 case OPC_CEIL_W_D:
5e755519 8914 check_cp1_registers(ctx, fs);
b6d96bed 8915 {
a7812ae4
PB
8916 TCGv_i32 fp32 = tcg_temp_new_i32();
8917 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8918
8919 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8920 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8921 tcg_temp_free_i64(fp64);
b6d96bed 8922 gen_store_fpr32(fp32, fd);
a7812ae4 8923 tcg_temp_free_i32(fp32);
b6d96bed 8924 }
6ea83fed
FB
8925 opn = "ceil.w.d";
8926 break;
bf4120ad 8927 case OPC_FLOOR_W_D:
5e755519 8928 check_cp1_registers(ctx, fs);
b6d96bed 8929 {
a7812ae4
PB
8930 TCGv_i32 fp32 = tcg_temp_new_i32();
8931 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8932
8933 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8934 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8935 tcg_temp_free_i64(fp64);
b6d96bed 8936 gen_store_fpr32(fp32, fd);
a7812ae4 8937 tcg_temp_free_i32(fp32);
b6d96bed 8938 }
7a387fff 8939 opn = "floor.w.d";
6ea83fed 8940 break;
e7f16abb
LA
8941 case OPC_SEL_D:
8942 check_insn(ctx, ISA_MIPS32R6);
8943 gen_sel_d(ctx, op1, fd, ft, fs);
8944 opn = "sel.d";
8945 break;
8946 case OPC_SELEQZ_D:
8947 check_insn(ctx, ISA_MIPS32R6);
8948 gen_sel_d(ctx, op1, fd, ft, fs);
8949 opn = "seleqz.d";
8950 break;
8951 case OPC_SELNEZ_D:
8952 check_insn(ctx, ISA_MIPS32R6);
8953 gen_sel_d(ctx, op1, fd, ft, fs);
8954 opn = "selnez.d";
8955 break;
bf4120ad 8956 case OPC_MOVCF_D:
fecd2646 8957 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8958 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8959 opn = "movcf.d";
dd016883 8960 break;
bf4120ad 8961 case OPC_MOVZ_D:
fecd2646 8962 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8963 {
8964 int l1 = gen_new_label();
c9297f4d 8965 TCGv_i64 fp0;
a16336e4 8966
c9297f4d
AJ
8967 if (ft != 0) {
8968 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8969 }
8970 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8971 gen_load_fpr64(ctx, fp0, fs);
8972 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8973 tcg_temp_free_i64(fp0);
a16336e4
TS
8974 gen_set_label(l1);
8975 }
5a5012ec
TS
8976 opn = "movz.d";
8977 break;
bf4120ad 8978 case OPC_MOVN_D:
fecd2646 8979 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8980 {
8981 int l1 = gen_new_label();
c9297f4d
AJ
8982 TCGv_i64 fp0;
8983
8984 if (ft != 0) {
8985 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8986 fp0 = tcg_temp_new_i64();
8987 gen_load_fpr64(ctx, fp0, fs);
8988 gen_store_fpr64(ctx, fp0, fd);
8989 tcg_temp_free_i64(fp0);
8990 gen_set_label(l1);
8991 }
a16336e4 8992 }
5a5012ec 8993 opn = "movn.d";
6ea83fed 8994 break;
bf4120ad 8995 case OPC_RECIP_D:
b8aa4598 8996 check_cp1_64bitmode(ctx);
b6d96bed 8997 {
a7812ae4 8998 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8999
9000 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9001 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9002 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9003 tcg_temp_free_i64(fp0);
b6d96bed 9004 }
57fa1fb3
TS
9005 opn = "recip.d";
9006 break;
bf4120ad 9007 case OPC_RSQRT_D:
b8aa4598 9008 check_cp1_64bitmode(ctx);
b6d96bed 9009 {
a7812ae4 9010 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9011
9012 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9013 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9014 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9015 tcg_temp_free_i64(fp0);
b6d96bed 9016 }
57fa1fb3
TS
9017 opn = "rsqrt.d";
9018 break;
e7f16abb
LA
9019 case OPC_MADDF_D:
9020 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9021 {
a7812ae4
PB
9022 TCGv_i64 fp0 = tcg_temp_new_i64();
9023 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9024 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9025 gen_load_fpr64(ctx, fp0, fs);
9026 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9027 gen_load_fpr64(ctx, fp2, fd);
9028 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9029 gen_store_fpr64(ctx, fp2, fd);
9030 tcg_temp_free_i64(fp2);
a7812ae4 9031 tcg_temp_free_i64(fp1);
a7812ae4 9032 tcg_temp_free_i64(fp0);
e7f16abb 9033 opn = "maddf.d";
b6d96bed 9034 }
57fa1fb3 9035 break;
e7f16abb
LA
9036 case OPC_MSUBF_D:
9037 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9038 {
a7812ae4 9039 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9040 TCGv_i64 fp1 = tcg_temp_new_i64();
9041 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9042 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9043 gen_load_fpr64(ctx, fp1, ft);
9044 gen_load_fpr64(ctx, fp2, fd);
9045 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9046 gen_store_fpr64(ctx, fp2, fd);
9047 tcg_temp_free_i64(fp2);
9048 tcg_temp_free_i64(fp1);
a7812ae4 9049 tcg_temp_free_i64(fp0);
e7f16abb 9050 opn = "msubf.d";
b6d96bed 9051 }
57fa1fb3 9052 break;
e7f16abb
LA
9053 case OPC_RINT_D:
9054 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9055 {
a7812ae4 9056 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9057 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9058 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9059 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9060 tcg_temp_free_i64(fp0);
e7f16abb 9061 opn = "rint.d";
b6d96bed 9062 }
57fa1fb3 9063 break;
e7f16abb
LA
9064 case OPC_CLASS_D:
9065 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9066 {
e7f16abb
LA
9067 TCGv_i64 fp0 = tcg_temp_new_i64();
9068 gen_load_fpr64(ctx, fp0, fs);
9069 gen_helper_float_class_d(fp0, fp0);
9070 gen_store_fpr64(ctx, fp0, fd);
9071 tcg_temp_free_i64(fp0);
9072 opn = "class.d";
9073 }
9074 break;
9075 case OPC_MIN_D: /* OPC_RECIP2_D */
9076 if (ctx->insn_flags & ISA_MIPS32R6) {
9077 /* OPC_MIN_D */
a7812ae4
PB
9078 TCGv_i64 fp0 = tcg_temp_new_i64();
9079 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9080 gen_load_fpr64(ctx, fp0, fs);
9081 gen_load_fpr64(ctx, fp1, ft);
9082 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9083 gen_store_fpr64(ctx, fp1, fd);
9084 tcg_temp_free_i64(fp1);
9085 tcg_temp_free_i64(fp0);
9086 opn = "min.d";
9087 } else {
9088 /* OPC_RECIP2_D */
9089 check_cp1_64bitmode(ctx);
9090 {
9091 TCGv_i64 fp0 = tcg_temp_new_i64();
9092 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9093
e7f16abb
LA
9094 gen_load_fpr64(ctx, fp0, fs);
9095 gen_load_fpr64(ctx, fp1, ft);
9096 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9097 tcg_temp_free_i64(fp1);
9098 gen_store_fpr64(ctx, fp0, fd);
9099 tcg_temp_free_i64(fp0);
9100 }
9101 opn = "recip2.d";
9102 }
9103 break;
9104 case OPC_MINA_D: /* OPC_RECIP1_D */
9105 if (ctx->insn_flags & ISA_MIPS32R6) {
9106 /* OPC_MINA_D */
9107 TCGv_i64 fp0 = tcg_temp_new_i64();
9108 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9109 gen_load_fpr64(ctx, fp0, fs);
9110 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9111 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9112 gen_store_fpr64(ctx, fp1, fd);
9113 tcg_temp_free_i64(fp1);
9114 tcg_temp_free_i64(fp0);
9115 opn = "mina.d";
9116 } else {
9117 /* OPC_RECIP1_D */
9118 check_cp1_64bitmode(ctx);
9119 {
9120 TCGv_i64 fp0 = tcg_temp_new_i64();
9121
9122 gen_load_fpr64(ctx, fp0, fs);
9123 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9124 gen_store_fpr64(ctx, fp0, fd);
9125 tcg_temp_free_i64(fp0);
9126 }
9127 opn = "recip1.d";
9128 }
9129 break;
9130 case OPC_MAX_D: /* OPC_RSQRT1_D */
9131 if (ctx->insn_flags & ISA_MIPS32R6) {
9132 /* OPC_MAX_D */
9133 TCGv_i64 fp0 = tcg_temp_new_i64();
9134 TCGv_i64 fp1 = tcg_temp_new_i64();
9135 gen_load_fpr64(ctx, fp0, fs);
9136 gen_load_fpr64(ctx, fp1, ft);
9137 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9138 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9139 tcg_temp_free_i64(fp1);
a7812ae4 9140 tcg_temp_free_i64(fp0);
e7f16abb
LA
9141 opn = "max.d";
9142 } else {
9143 /* OPC_RSQRT1_D */
9144 check_cp1_64bitmode(ctx);
9145 {
9146 TCGv_i64 fp0 = tcg_temp_new_i64();
9147
9148 gen_load_fpr64(ctx, fp0, fs);
9149 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9150 gen_store_fpr64(ctx, fp0, fd);
9151 tcg_temp_free_i64(fp0);
9152 }
9153 opn = "rsqrt1.d";
9154 }
9155 break;
9156 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9157 if (ctx->insn_flags & ISA_MIPS32R6) {
9158 /* OPC_MAXA_D */
9159 TCGv_i64 fp0 = tcg_temp_new_i64();
9160 TCGv_i64 fp1 = tcg_temp_new_i64();
9161 gen_load_fpr64(ctx, fp0, fs);
9162 gen_load_fpr64(ctx, fp1, ft);
9163 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9164 gen_store_fpr64(ctx, fp1, fd);
9165 tcg_temp_free_i64(fp1);
9166 tcg_temp_free_i64(fp0);
9167 opn = "maxa.d";
9168 } else {
9169 /* OPC_RSQRT2_D */
9170 check_cp1_64bitmode(ctx);
9171 {
9172 TCGv_i64 fp0 = tcg_temp_new_i64();
9173 TCGv_i64 fp1 = tcg_temp_new_i64();
9174
9175 gen_load_fpr64(ctx, fp0, fs);
9176 gen_load_fpr64(ctx, fp1, ft);
9177 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9178 tcg_temp_free_i64(fp1);
9179 gen_store_fpr64(ctx, fp0, fd);
9180 tcg_temp_free_i64(fp0);
9181 }
9182 opn = "rsqrt2.d";
b6d96bed 9183 }
57fa1fb3 9184 break;
bf4120ad
NF
9185 case OPC_CMP_F_D:
9186 case OPC_CMP_UN_D:
9187 case OPC_CMP_EQ_D:
9188 case OPC_CMP_UEQ_D:
9189 case OPC_CMP_OLT_D:
9190 case OPC_CMP_ULT_D:
9191 case OPC_CMP_OLE_D:
9192 case OPC_CMP_ULE_D:
9193 case OPC_CMP_SF_D:
9194 case OPC_CMP_NGLE_D:
9195 case OPC_CMP_SEQ_D:
9196 case OPC_CMP_NGL_D:
9197 case OPC_CMP_LT_D:
9198 case OPC_CMP_NGE_D:
9199 case OPC_CMP_LE_D:
9200 case OPC_CMP_NGT_D:
fecd2646 9201 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9202 if (ctx->opcode & (1 << 6)) {
9203 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9204 opn = condnames_abs[func-48];
9205 } else {
9206 gen_cmp_d(ctx, func-48, ft, fs, cc);
9207 opn = condnames[func-48];
5a1e8ffb 9208 }
6ea83fed 9209 break;
bf4120ad 9210 case OPC_CVT_S_D:
5e755519 9211 check_cp1_registers(ctx, fs);
b6d96bed 9212 {
a7812ae4
PB
9213 TCGv_i32 fp32 = tcg_temp_new_i32();
9214 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9215
9216 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9217 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9218 tcg_temp_free_i64(fp64);
b6d96bed 9219 gen_store_fpr32(fp32, fd);
a7812ae4 9220 tcg_temp_free_i32(fp32);
b6d96bed 9221 }
5a5012ec
TS
9222 opn = "cvt.s.d";
9223 break;
bf4120ad 9224 case OPC_CVT_W_D:
5e755519 9225 check_cp1_registers(ctx, fs);
b6d96bed 9226 {
a7812ae4
PB
9227 TCGv_i32 fp32 = tcg_temp_new_i32();
9228 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9229
9230 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9231 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9232 tcg_temp_free_i64(fp64);
b6d96bed 9233 gen_store_fpr32(fp32, fd);
a7812ae4 9234 tcg_temp_free_i32(fp32);
b6d96bed 9235 }
5a5012ec
TS
9236 opn = "cvt.w.d";
9237 break;
bf4120ad 9238 case OPC_CVT_L_D:
5e755519 9239 check_cp1_64bitmode(ctx);
b6d96bed 9240 {
a7812ae4 9241 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9242
9243 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9244 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9245 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9246 tcg_temp_free_i64(fp0);
b6d96bed 9247 }
5a5012ec
TS
9248 opn = "cvt.l.d";
9249 break;
bf4120ad 9250 case OPC_CVT_S_W:
b6d96bed 9251 {
a7812ae4 9252 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9253
9254 gen_load_fpr32(fp0, fs);
895c2d04 9255 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 9256 gen_store_fpr32(fp0, fd);
a7812ae4 9257 tcg_temp_free_i32(fp0);
b6d96bed 9258 }
5a5012ec 9259 opn = "cvt.s.w";
6ea83fed 9260 break;
bf4120ad 9261 case OPC_CVT_D_W:
5e755519 9262 check_cp1_registers(ctx, fd);
b6d96bed 9263 {
a7812ae4
PB
9264 TCGv_i32 fp32 = tcg_temp_new_i32();
9265 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9266
9267 gen_load_fpr32(fp32, fs);
895c2d04 9268 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9269 tcg_temp_free_i32(fp32);
b6d96bed 9270 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9271 tcg_temp_free_i64(fp64);
b6d96bed 9272 }
5a5012ec
TS
9273 opn = "cvt.d.w";
9274 break;
bf4120ad 9275 case OPC_CVT_S_L:
5e755519 9276 check_cp1_64bitmode(ctx);
b6d96bed 9277 {
a7812ae4
PB
9278 TCGv_i32 fp32 = tcg_temp_new_i32();
9279 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9280
9281 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9282 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9283 tcg_temp_free_i64(fp64);
b6d96bed 9284 gen_store_fpr32(fp32, fd);
a7812ae4 9285 tcg_temp_free_i32(fp32);
b6d96bed 9286 }
5a5012ec
TS
9287 opn = "cvt.s.l";
9288 break;
bf4120ad 9289 case OPC_CVT_D_L:
5e755519 9290 check_cp1_64bitmode(ctx);
b6d96bed 9291 {
a7812ae4 9292 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9293
9294 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9295 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9296 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9297 tcg_temp_free_i64(fp0);
b6d96bed 9298 }
5a5012ec
TS
9299 opn = "cvt.d.l";
9300 break;
bf4120ad 9301 case OPC_CVT_PS_PW:
fecd2646 9302 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9303 check_cp1_64bitmode(ctx);
b6d96bed 9304 {
a7812ae4 9305 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9306
9307 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9308 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9309 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9310 tcg_temp_free_i64(fp0);
b6d96bed 9311 }
5a5012ec
TS
9312 opn = "cvt.ps.pw";
9313 break;
bf4120ad 9314 case OPC_ADD_PS:
5e755519 9315 check_cp1_64bitmode(ctx);
b6d96bed 9316 {
a7812ae4
PB
9317 TCGv_i64 fp0 = tcg_temp_new_i64();
9318 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9319
9320 gen_load_fpr64(ctx, fp0, fs);
9321 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9322 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9323 tcg_temp_free_i64(fp1);
b6d96bed 9324 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9325 tcg_temp_free_i64(fp0);
b6d96bed 9326 }
5a5012ec 9327 opn = "add.ps";
6ea83fed 9328 break;
bf4120ad 9329 case OPC_SUB_PS:
5e755519 9330 check_cp1_64bitmode(ctx);
b6d96bed 9331 {
a7812ae4
PB
9332 TCGv_i64 fp0 = tcg_temp_new_i64();
9333 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9334
9335 gen_load_fpr64(ctx, fp0, fs);
9336 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9337 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9338 tcg_temp_free_i64(fp1);
b6d96bed 9339 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9340 tcg_temp_free_i64(fp0);
b6d96bed 9341 }
5a5012ec 9342 opn = "sub.ps";
6ea83fed 9343 break;
bf4120ad 9344 case OPC_MUL_PS:
5e755519 9345 check_cp1_64bitmode(ctx);
b6d96bed 9346 {
a7812ae4
PB
9347 TCGv_i64 fp0 = tcg_temp_new_i64();
9348 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9349
9350 gen_load_fpr64(ctx, fp0, fs);
9351 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9352 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9353 tcg_temp_free_i64(fp1);
b6d96bed 9354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9355 tcg_temp_free_i64(fp0);
b6d96bed 9356 }
5a5012ec 9357 opn = "mul.ps";
6ea83fed 9358 break;
bf4120ad 9359 case OPC_ABS_PS:
5e755519 9360 check_cp1_64bitmode(ctx);
b6d96bed 9361 {
a7812ae4 9362 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9363
9364 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9365 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9366 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9367 tcg_temp_free_i64(fp0);
b6d96bed 9368 }
5a5012ec 9369 opn = "abs.ps";
6ea83fed 9370 break;
bf4120ad 9371 case OPC_MOV_PS:
5e755519 9372 check_cp1_64bitmode(ctx);
b6d96bed 9373 {
a7812ae4 9374 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9375
9376 gen_load_fpr64(ctx, fp0, fs);
9377 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9378 tcg_temp_free_i64(fp0);
b6d96bed 9379 }
5a5012ec 9380 opn = "mov.ps";
6ea83fed 9381 break;
bf4120ad 9382 case OPC_NEG_PS:
5e755519 9383 check_cp1_64bitmode(ctx);
b6d96bed 9384 {
a7812ae4 9385 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9386
9387 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9388 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9389 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9390 tcg_temp_free_i64(fp0);
b6d96bed 9391 }
5a5012ec 9392 opn = "neg.ps";
6ea83fed 9393 break;
bf4120ad 9394 case OPC_MOVCF_PS:
5e755519 9395 check_cp1_64bitmode(ctx);
7f6613ce 9396 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9397 opn = "movcf.ps";
6ea83fed 9398 break;
bf4120ad 9399 case OPC_MOVZ_PS:
5e755519 9400 check_cp1_64bitmode(ctx);
a16336e4
TS
9401 {
9402 int l1 = gen_new_label();
30a3848b 9403 TCGv_i64 fp0;
a16336e4 9404
c9297f4d
AJ
9405 if (ft != 0)
9406 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9407 fp0 = tcg_temp_new_i64();
9408 gen_load_fpr64(ctx, fp0, fs);
9409 gen_store_fpr64(ctx, fp0, fd);
9410 tcg_temp_free_i64(fp0);
a16336e4
TS
9411 gen_set_label(l1);
9412 }
5a5012ec 9413 opn = "movz.ps";
6ea83fed 9414 break;
bf4120ad 9415 case OPC_MOVN_PS:
5e755519 9416 check_cp1_64bitmode(ctx);
a16336e4
TS
9417 {
9418 int l1 = gen_new_label();
30a3848b 9419 TCGv_i64 fp0;
c9297f4d
AJ
9420
9421 if (ft != 0) {
9422 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9423 fp0 = tcg_temp_new_i64();
9424 gen_load_fpr64(ctx, fp0, fs);
9425 gen_store_fpr64(ctx, fp0, fd);
9426 tcg_temp_free_i64(fp0);
9427 gen_set_label(l1);
9428 }
a16336e4 9429 }
5a5012ec 9430 opn = "movn.ps";
6ea83fed 9431 break;
bf4120ad 9432 case OPC_ADDR_PS:
5e755519 9433 check_cp1_64bitmode(ctx);
b6d96bed 9434 {
a7812ae4
PB
9435 TCGv_i64 fp0 = tcg_temp_new_i64();
9436 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9437
9438 gen_load_fpr64(ctx, fp0, ft);
9439 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9440 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9441 tcg_temp_free_i64(fp1);
b6d96bed 9442 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9443 tcg_temp_free_i64(fp0);
b6d96bed 9444 }
fbcc6828
TS
9445 opn = "addr.ps";
9446 break;
bf4120ad 9447 case OPC_MULR_PS:
5e755519 9448 check_cp1_64bitmode(ctx);
b6d96bed 9449 {
a7812ae4
PB
9450 TCGv_i64 fp0 = tcg_temp_new_i64();
9451 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9452
9453 gen_load_fpr64(ctx, fp0, ft);
9454 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9455 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9456 tcg_temp_free_i64(fp1);
b6d96bed 9457 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9458 tcg_temp_free_i64(fp0);
b6d96bed 9459 }
57fa1fb3
TS
9460 opn = "mulr.ps";
9461 break;
bf4120ad 9462 case OPC_RECIP2_PS:
5e755519 9463 check_cp1_64bitmode(ctx);
b6d96bed 9464 {
a7812ae4
PB
9465 TCGv_i64 fp0 = tcg_temp_new_i64();
9466 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9467
9468 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9469 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9470 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9471 tcg_temp_free_i64(fp1);
b6d96bed 9472 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9473 tcg_temp_free_i64(fp0);
b6d96bed 9474 }
57fa1fb3
TS
9475 opn = "recip2.ps";
9476 break;
bf4120ad 9477 case OPC_RECIP1_PS:
5e755519 9478 check_cp1_64bitmode(ctx);
b6d96bed 9479 {
a7812ae4 9480 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9481
9482 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9483 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9484 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9485 tcg_temp_free_i64(fp0);
b6d96bed 9486 }
57fa1fb3
TS
9487 opn = "recip1.ps";
9488 break;
bf4120ad 9489 case OPC_RSQRT1_PS:
5e755519 9490 check_cp1_64bitmode(ctx);
b6d96bed 9491 {
a7812ae4 9492 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9493
9494 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9495 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9496 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9497 tcg_temp_free_i64(fp0);
b6d96bed 9498 }
57fa1fb3
TS
9499 opn = "rsqrt1.ps";
9500 break;
bf4120ad 9501 case OPC_RSQRT2_PS:
5e755519 9502 check_cp1_64bitmode(ctx);
b6d96bed 9503 {
a7812ae4
PB
9504 TCGv_i64 fp0 = tcg_temp_new_i64();
9505 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9506
9507 gen_load_fpr64(ctx, fp0, fs);
9508 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9509 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9510 tcg_temp_free_i64(fp1);
b6d96bed 9511 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9512 tcg_temp_free_i64(fp0);
b6d96bed 9513 }
57fa1fb3
TS
9514 opn = "rsqrt2.ps";
9515 break;
bf4120ad 9516 case OPC_CVT_S_PU:
5e755519 9517 check_cp1_64bitmode(ctx);
b6d96bed 9518 {
a7812ae4 9519 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9520
7f6613ce 9521 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9522 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 9523 gen_store_fpr32(fp0, fd);
a7812ae4 9524 tcg_temp_free_i32(fp0);
b6d96bed 9525 }
5a5012ec 9526 opn = "cvt.s.pu";
dd016883 9527 break;
bf4120ad 9528 case OPC_CVT_PW_PS:
5e755519 9529 check_cp1_64bitmode(ctx);
b6d96bed 9530 {
a7812ae4 9531 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9532
9533 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9534 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9535 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9536 tcg_temp_free_i64(fp0);
b6d96bed 9537 }
5a5012ec 9538 opn = "cvt.pw.ps";
6ea83fed 9539 break;
bf4120ad 9540 case OPC_CVT_S_PL:
5e755519 9541 check_cp1_64bitmode(ctx);
b6d96bed 9542 {
a7812ae4 9543 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9544
9545 gen_load_fpr32(fp0, fs);
895c2d04 9546 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 9547 gen_store_fpr32(fp0, fd);
a7812ae4 9548 tcg_temp_free_i32(fp0);
b6d96bed 9549 }
5a5012ec 9550 opn = "cvt.s.pl";
6ea83fed 9551 break;
bf4120ad 9552 case OPC_PLL_PS:
5e755519 9553 check_cp1_64bitmode(ctx);
b6d96bed 9554 {
a7812ae4
PB
9555 TCGv_i32 fp0 = tcg_temp_new_i32();
9556 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9557
9558 gen_load_fpr32(fp0, fs);
9559 gen_load_fpr32(fp1, ft);
7f6613ce 9560 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 9561 gen_store_fpr32(fp1, fd);
a7812ae4
PB
9562 tcg_temp_free_i32(fp0);
9563 tcg_temp_free_i32(fp1);
b6d96bed 9564 }
5a5012ec 9565 opn = "pll.ps";
6ea83fed 9566 break;
bf4120ad 9567 case OPC_PLU_PS:
5e755519 9568 check_cp1_64bitmode(ctx);
b6d96bed 9569 {
a7812ae4
PB
9570 TCGv_i32 fp0 = tcg_temp_new_i32();
9571 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9572
9573 gen_load_fpr32(fp0, fs);
7f6613ce 9574 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 9575 gen_store_fpr32(fp1, fd);
7f6613ce 9576 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9577 tcg_temp_free_i32(fp0);
9578 tcg_temp_free_i32(fp1);
b6d96bed 9579 }
5a5012ec
TS
9580 opn = "plu.ps";
9581 break;
bf4120ad 9582 case OPC_PUL_PS:
5e755519 9583 check_cp1_64bitmode(ctx);
b6d96bed 9584 {
a7812ae4
PB
9585 TCGv_i32 fp0 = tcg_temp_new_i32();
9586 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9587
7f6613ce 9588 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
9589 gen_load_fpr32(fp1, ft);
9590 gen_store_fpr32(fp1, fd);
7f6613ce 9591 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9592 tcg_temp_free_i32(fp0);
9593 tcg_temp_free_i32(fp1);
b6d96bed 9594 }
5a5012ec
TS
9595 opn = "pul.ps";
9596 break;
bf4120ad 9597 case OPC_PUU_PS:
5e755519 9598 check_cp1_64bitmode(ctx);
b6d96bed 9599 {
a7812ae4
PB
9600 TCGv_i32 fp0 = tcg_temp_new_i32();
9601 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9602
7f6613ce
PJ
9603 gen_load_fpr32h(ctx, fp0, fs);
9604 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 9605 gen_store_fpr32(fp1, fd);
7f6613ce 9606 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9607 tcg_temp_free_i32(fp0);
9608 tcg_temp_free_i32(fp1);
b6d96bed 9609 }
5a5012ec
TS
9610 opn = "puu.ps";
9611 break;
bf4120ad
NF
9612 case OPC_CMP_F_PS:
9613 case OPC_CMP_UN_PS:
9614 case OPC_CMP_EQ_PS:
9615 case OPC_CMP_UEQ_PS:
9616 case OPC_CMP_OLT_PS:
9617 case OPC_CMP_ULT_PS:
9618 case OPC_CMP_OLE_PS:
9619 case OPC_CMP_ULE_PS:
9620 case OPC_CMP_SF_PS:
9621 case OPC_CMP_NGLE_PS:
9622 case OPC_CMP_SEQ_PS:
9623 case OPC_CMP_NGL_PS:
9624 case OPC_CMP_LT_PS:
9625 case OPC_CMP_NGE_PS:
9626 case OPC_CMP_LE_PS:
9627 case OPC_CMP_NGT_PS:
8153667c
NF
9628 if (ctx->opcode & (1 << 6)) {
9629 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
9630 opn = condnames_abs[func-48];
9631 } else {
9632 gen_cmp_ps(ctx, func-48, ft, fs, cc);
9633 opn = condnames[func-48];
5a1e8ffb 9634 }
6ea83fed 9635 break;
5a5012ec 9636 default:
923617a3 9637 MIPS_INVAL(opn);
e397ee33 9638 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
9639 return;
9640 }
2abf314d 9641 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
9642 switch (optype) {
9643 case BINOP:
6ea83fed 9644 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
9645 break;
9646 case CMPOP:
9647 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
9648 break;
9649 default:
6ea83fed 9650 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
9651 break;
9652 }
6ea83fed 9653}
6af0bf9c 9654
5a5012ec 9655/* Coprocessor 3 (FPU) */
5e755519
TS
9656static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
9657 int fd, int fs, int base, int index)
7a387fff 9658{
923617a3 9659 const char *opn = "extended float load/store";
93b12ccc 9660 int store = 0;
4e2474d6 9661 TCGv t0 = tcg_temp_new();
7a387fff 9662
93b12ccc 9663 if (base == 0) {
6c5c1e20 9664 gen_load_gpr(t0, index);
93b12ccc 9665 } else if (index == 0) {
6c5c1e20 9666 gen_load_gpr(t0, base);
93b12ccc 9667 } else {
05168674 9668 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 9669 }
5a5012ec 9670 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 9671 memory access. */
5a5012ec
TS
9672 switch (opc) {
9673 case OPC_LWXC1:
8c0ab41f 9674 check_cop1x(ctx);
b6d96bed 9675 {
a7812ae4 9676 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9677
5f68f5ae 9678 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 9679 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 9680 gen_store_fpr32(fp0, fd);
a7812ae4 9681 tcg_temp_free_i32(fp0);
b6d96bed 9682 }
5a5012ec
TS
9683 opn = "lwxc1";
9684 break;
9685 case OPC_LDXC1:
8c0ab41f
AJ
9686 check_cop1x(ctx);
9687 check_cp1_registers(ctx, fd);
b6d96bed 9688 {
a7812ae4 9689 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 9690 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9691 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9692 tcg_temp_free_i64(fp0);
b6d96bed 9693 }
5a5012ec
TS
9694 opn = "ldxc1";
9695 break;
9696 case OPC_LUXC1:
8c0ab41f 9697 check_cp1_64bitmode(ctx);
6c5c1e20 9698 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9699 {
a7812ae4 9700 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9701
5f68f5ae 9702 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9703 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9704 tcg_temp_free_i64(fp0);
b6d96bed 9705 }
5a5012ec
TS
9706 opn = "luxc1";
9707 break;
9708 case OPC_SWXC1:
8c0ab41f 9709 check_cop1x(ctx);
b6d96bed 9710 {
a7812ae4 9711 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9712 gen_load_fpr32(fp0, fs);
5f68f5ae 9713 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 9714 tcg_temp_free_i32(fp0);
b6d96bed 9715 }
5a5012ec 9716 opn = "swxc1";
93b12ccc 9717 store = 1;
5a5012ec
TS
9718 break;
9719 case OPC_SDXC1:
8c0ab41f
AJ
9720 check_cop1x(ctx);
9721 check_cp1_registers(ctx, fs);
b6d96bed 9722 {
a7812ae4 9723 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9724 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9725 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9726 tcg_temp_free_i64(fp0);
b6d96bed 9727 }
5a5012ec 9728 opn = "sdxc1";
93b12ccc 9729 store = 1;
5a5012ec
TS
9730 break;
9731 case OPC_SUXC1:
8c0ab41f 9732 check_cp1_64bitmode(ctx);
6c5c1e20 9733 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9734 {
a7812ae4 9735 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9736 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9737 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9738 tcg_temp_free_i64(fp0);
b6d96bed 9739 }
5a5012ec 9740 opn = "suxc1";
93b12ccc 9741 store = 1;
5a5012ec 9742 break;
5a5012ec 9743 }
6c5c1e20 9744 tcg_temp_free(t0);
2abf314d 9745 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
9746 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
9747 regnames[index], regnames[base]);
5a5012ec
TS
9748}
9749
5e755519
TS
9750static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
9751 int fd, int fr, int fs, int ft)
5a5012ec 9752{
923617a3 9753 const char *opn = "flt3_arith";
5a5012ec 9754
5a5012ec
TS
9755 switch (opc) {
9756 case OPC_ALNV_PS:
b8aa4598 9757 check_cp1_64bitmode(ctx);
a16336e4 9758 {
a7812ae4 9759 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
9760 TCGv_i32 fp = tcg_temp_new_i32();
9761 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
9762 int l1 = gen_new_label();
9763 int l2 = gen_new_label();
9764
6c5c1e20
TS
9765 gen_load_gpr(t0, fr);
9766 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
9767
9768 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 9769 gen_load_fpr32(fp, fs);
7f6613ce 9770 gen_load_fpr32h(ctx, fph, fs);
c905fdac 9771 gen_store_fpr32(fp, fd);
7f6613ce 9772 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
9773 tcg_gen_br(l2);
9774 gen_set_label(l1);
6c5c1e20
TS
9775 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
9776 tcg_temp_free(t0);
a16336e4 9777#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 9778 gen_load_fpr32(fp, fs);
7f6613ce
PJ
9779 gen_load_fpr32h(ctx, fph, ft);
9780 gen_store_fpr32h(ctx, fp, fd);
c905fdac 9781 gen_store_fpr32(fph, fd);
a16336e4 9782#else
7f6613ce 9783 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
9784 gen_load_fpr32(fp, ft);
9785 gen_store_fpr32(fph, fd);
7f6613ce 9786 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
9787#endif
9788 gen_set_label(l2);
c905fdac
AJ
9789 tcg_temp_free_i32(fp);
9790 tcg_temp_free_i32(fph);
a16336e4 9791 }
5a5012ec
TS
9792 opn = "alnv.ps";
9793 break;
9794 case OPC_MADD_S:
b8aa4598 9795 check_cop1x(ctx);
b6d96bed 9796 {
a7812ae4
PB
9797 TCGv_i32 fp0 = tcg_temp_new_i32();
9798 TCGv_i32 fp1 = tcg_temp_new_i32();
9799 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9800
9801 gen_load_fpr32(fp0, fs);
9802 gen_load_fpr32(fp1, ft);
9803 gen_load_fpr32(fp2, fr);
b3d6cd44 9804 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9805 tcg_temp_free_i32(fp0);
9806 tcg_temp_free_i32(fp1);
b6d96bed 9807 gen_store_fpr32(fp2, fd);
a7812ae4 9808 tcg_temp_free_i32(fp2);
b6d96bed 9809 }
5a5012ec
TS
9810 opn = "madd.s";
9811 break;
9812 case OPC_MADD_D:
b8aa4598
TS
9813 check_cop1x(ctx);
9814 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9815 {
a7812ae4
PB
9816 TCGv_i64 fp0 = tcg_temp_new_i64();
9817 TCGv_i64 fp1 = tcg_temp_new_i64();
9818 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9819
9820 gen_load_fpr64(ctx, fp0, fs);
9821 gen_load_fpr64(ctx, fp1, ft);
9822 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9823 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9824 tcg_temp_free_i64(fp0);
9825 tcg_temp_free_i64(fp1);
b6d96bed 9826 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9827 tcg_temp_free_i64(fp2);
b6d96bed 9828 }
5a5012ec
TS
9829 opn = "madd.d";
9830 break;
9831 case OPC_MADD_PS:
b8aa4598 9832 check_cp1_64bitmode(ctx);
b6d96bed 9833 {
a7812ae4
PB
9834 TCGv_i64 fp0 = tcg_temp_new_i64();
9835 TCGv_i64 fp1 = tcg_temp_new_i64();
9836 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9837
9838 gen_load_fpr64(ctx, fp0, fs);
9839 gen_load_fpr64(ctx, fp1, ft);
9840 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9841 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9842 tcg_temp_free_i64(fp0);
9843 tcg_temp_free_i64(fp1);
b6d96bed 9844 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9845 tcg_temp_free_i64(fp2);
b6d96bed 9846 }
5a5012ec
TS
9847 opn = "madd.ps";
9848 break;
9849 case OPC_MSUB_S:
b8aa4598 9850 check_cop1x(ctx);
b6d96bed 9851 {
a7812ae4
PB
9852 TCGv_i32 fp0 = tcg_temp_new_i32();
9853 TCGv_i32 fp1 = tcg_temp_new_i32();
9854 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9855
9856 gen_load_fpr32(fp0, fs);
9857 gen_load_fpr32(fp1, ft);
9858 gen_load_fpr32(fp2, fr);
b3d6cd44 9859 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9860 tcg_temp_free_i32(fp0);
9861 tcg_temp_free_i32(fp1);
b6d96bed 9862 gen_store_fpr32(fp2, fd);
a7812ae4 9863 tcg_temp_free_i32(fp2);
b6d96bed 9864 }
5a5012ec
TS
9865 opn = "msub.s";
9866 break;
9867 case OPC_MSUB_D:
b8aa4598
TS
9868 check_cop1x(ctx);
9869 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9870 {
a7812ae4
PB
9871 TCGv_i64 fp0 = tcg_temp_new_i64();
9872 TCGv_i64 fp1 = tcg_temp_new_i64();
9873 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9874
9875 gen_load_fpr64(ctx, fp0, fs);
9876 gen_load_fpr64(ctx, fp1, ft);
9877 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9878 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9879 tcg_temp_free_i64(fp0);
9880 tcg_temp_free_i64(fp1);
b6d96bed 9881 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9882 tcg_temp_free_i64(fp2);
b6d96bed 9883 }
5a5012ec
TS
9884 opn = "msub.d";
9885 break;
9886 case OPC_MSUB_PS:
b8aa4598 9887 check_cp1_64bitmode(ctx);
b6d96bed 9888 {
a7812ae4
PB
9889 TCGv_i64 fp0 = tcg_temp_new_i64();
9890 TCGv_i64 fp1 = tcg_temp_new_i64();
9891 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9892
9893 gen_load_fpr64(ctx, fp0, fs);
9894 gen_load_fpr64(ctx, fp1, ft);
9895 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9896 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9897 tcg_temp_free_i64(fp0);
9898 tcg_temp_free_i64(fp1);
b6d96bed 9899 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9900 tcg_temp_free_i64(fp2);
b6d96bed 9901 }
5a5012ec
TS
9902 opn = "msub.ps";
9903 break;
9904 case OPC_NMADD_S:
b8aa4598 9905 check_cop1x(ctx);
b6d96bed 9906 {
a7812ae4
PB
9907 TCGv_i32 fp0 = tcg_temp_new_i32();
9908 TCGv_i32 fp1 = tcg_temp_new_i32();
9909 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9910
9911 gen_load_fpr32(fp0, fs);
9912 gen_load_fpr32(fp1, ft);
9913 gen_load_fpr32(fp2, fr);
b3d6cd44 9914 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9915 tcg_temp_free_i32(fp0);
9916 tcg_temp_free_i32(fp1);
b6d96bed 9917 gen_store_fpr32(fp2, fd);
a7812ae4 9918 tcg_temp_free_i32(fp2);
b6d96bed 9919 }
5a5012ec
TS
9920 opn = "nmadd.s";
9921 break;
9922 case OPC_NMADD_D:
b8aa4598
TS
9923 check_cop1x(ctx);
9924 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9925 {
a7812ae4
PB
9926 TCGv_i64 fp0 = tcg_temp_new_i64();
9927 TCGv_i64 fp1 = tcg_temp_new_i64();
9928 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9929
9930 gen_load_fpr64(ctx, fp0, fs);
9931 gen_load_fpr64(ctx, fp1, ft);
9932 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9933 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9934 tcg_temp_free_i64(fp0);
9935 tcg_temp_free_i64(fp1);
b6d96bed 9936 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9937 tcg_temp_free_i64(fp2);
b6d96bed 9938 }
5a5012ec
TS
9939 opn = "nmadd.d";
9940 break;
9941 case OPC_NMADD_PS:
b8aa4598 9942 check_cp1_64bitmode(ctx);
b6d96bed 9943 {
a7812ae4
PB
9944 TCGv_i64 fp0 = tcg_temp_new_i64();
9945 TCGv_i64 fp1 = tcg_temp_new_i64();
9946 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9947
9948 gen_load_fpr64(ctx, fp0, fs);
9949 gen_load_fpr64(ctx, fp1, ft);
9950 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9951 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9952 tcg_temp_free_i64(fp0);
9953 tcg_temp_free_i64(fp1);
b6d96bed 9954 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9955 tcg_temp_free_i64(fp2);
b6d96bed 9956 }
5a5012ec
TS
9957 opn = "nmadd.ps";
9958 break;
9959 case OPC_NMSUB_S:
b8aa4598 9960 check_cop1x(ctx);
b6d96bed 9961 {
a7812ae4
PB
9962 TCGv_i32 fp0 = tcg_temp_new_i32();
9963 TCGv_i32 fp1 = tcg_temp_new_i32();
9964 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9965
9966 gen_load_fpr32(fp0, fs);
9967 gen_load_fpr32(fp1, ft);
9968 gen_load_fpr32(fp2, fr);
b3d6cd44 9969 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9970 tcg_temp_free_i32(fp0);
9971 tcg_temp_free_i32(fp1);
b6d96bed 9972 gen_store_fpr32(fp2, fd);
a7812ae4 9973 tcg_temp_free_i32(fp2);
b6d96bed 9974 }
5a5012ec
TS
9975 opn = "nmsub.s";
9976 break;
9977 case OPC_NMSUB_D:
b8aa4598
TS
9978 check_cop1x(ctx);
9979 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9980 {
a7812ae4
PB
9981 TCGv_i64 fp0 = tcg_temp_new_i64();
9982 TCGv_i64 fp1 = tcg_temp_new_i64();
9983 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9984
9985 gen_load_fpr64(ctx, fp0, fs);
9986 gen_load_fpr64(ctx, fp1, ft);
9987 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9988 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9989 tcg_temp_free_i64(fp0);
9990 tcg_temp_free_i64(fp1);
b6d96bed 9991 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9992 tcg_temp_free_i64(fp2);
b6d96bed 9993 }
5a5012ec
TS
9994 opn = "nmsub.d";
9995 break;
9996 case OPC_NMSUB_PS:
b8aa4598 9997 check_cp1_64bitmode(ctx);
b6d96bed 9998 {
a7812ae4
PB
9999 TCGv_i64 fp0 = tcg_temp_new_i64();
10000 TCGv_i64 fp1 = tcg_temp_new_i64();
10001 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10002
10003 gen_load_fpr64(ctx, fp0, fs);
10004 gen_load_fpr64(ctx, fp1, ft);
10005 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10006 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10007 tcg_temp_free_i64(fp0);
10008 tcg_temp_free_i64(fp1);
b6d96bed 10009 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10010 tcg_temp_free_i64(fp2);
b6d96bed 10011 }
5a5012ec
TS
10012 opn = "nmsub.ps";
10013 break;
923617a3
TS
10014 default:
10015 MIPS_INVAL(opn);
5a5012ec
TS
10016 generate_exception (ctx, EXCP_RI);
10017 return;
10018 }
2abf314d 10019 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10020 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10021 fregnames[fs], fregnames[ft]);
7a387fff
TS
10022}
10023
d75c135e 10024static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10025{
10026 TCGv t0;
10027
b3167288
RH
10028#if !defined(CONFIG_USER_ONLY)
10029 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10030 Therefore only check the ISA in system mode. */
d75c135e 10031 check_insn(ctx, ISA_MIPS32R2);
b3167288 10032#endif
26ebe468
NF
10033 t0 = tcg_temp_new();
10034
10035 switch (rd) {
10036 case 0:
10037 save_cpu_state(ctx, 1);
895c2d04 10038 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10039 gen_store_gpr(t0, rt);
10040 break;
10041 case 1:
10042 save_cpu_state(ctx, 1);
895c2d04 10043 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10044 gen_store_gpr(t0, rt);
10045 break;
10046 case 2:
10047 save_cpu_state(ctx, 1);
895c2d04 10048 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10049 gen_store_gpr(t0, rt);
10050 break;
10051 case 3:
10052 save_cpu_state(ctx, 1);
895c2d04 10053 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10054 gen_store_gpr(t0, rt);
10055 break;
10056 case 29:
10057#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10058 tcg_gen_ld_tl(t0, cpu_env,
10059 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10060 gen_store_gpr(t0, rt);
10061 break;
10062#else
d279279e
PJ
10063 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10064 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10065 tcg_gen_ld_tl(t0, cpu_env,
10066 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10067 gen_store_gpr(t0, rt);
10068 } else {
10069 generate_exception(ctx, EXCP_RI);
10070 }
10071 break;
26ebe468
NF
10072#endif
10073 default: /* Invalid */
10074 MIPS_INVAL("rdhwr");
10075 generate_exception(ctx, EXCP_RI);
10076 break;
10077 }
10078 tcg_temp_free(t0);
10079}
10080
31837be3 10081static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10082{
10083 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10084 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
10085 /* Branches completion */
10086 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10087 ctx->bstate = BS_BRANCH;
10088 save_cpu_state(ctx, 0);
10089 /* FIXME: Need to clear can_do_io. */
364d4831 10090 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
10091 case MIPS_HFLAG_B:
10092 /* unconditional branch */
10093 MIPS_DEBUG("unconditional branch");
364d4831
NF
10094 if (proc_hflags & MIPS_HFLAG_BX) {
10095 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10096 }
c9602061
NF
10097 gen_goto_tb(ctx, 0, ctx->btarget);
10098 break;
10099 case MIPS_HFLAG_BL:
10100 /* blikely taken case */
10101 MIPS_DEBUG("blikely branch taken");
10102 gen_goto_tb(ctx, 0, ctx->btarget);
10103 break;
10104 case MIPS_HFLAG_BC:
10105 /* Conditional branch */
10106 MIPS_DEBUG("conditional branch");
10107 {
10108 int l1 = gen_new_label();
10109
10110 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10111 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10112 gen_set_label(l1);
10113 gen_goto_tb(ctx, 0, ctx->btarget);
10114 }
10115 break;
10116 case MIPS_HFLAG_BR:
10117 /* unconditional branch to register */
10118 MIPS_DEBUG("branch to register");
d75c135e 10119 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10120 TCGv t0 = tcg_temp_new();
10121 TCGv_i32 t1 = tcg_temp_new_i32();
10122
10123 tcg_gen_andi_tl(t0, btarget, 0x1);
10124 tcg_gen_trunc_tl_i32(t1, t0);
10125 tcg_temp_free(t0);
10126 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10127 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10128 tcg_gen_or_i32(hflags, hflags, t1);
10129 tcg_temp_free_i32(t1);
10130
10131 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10132 } else {
10133 tcg_gen_mov_tl(cpu_PC, btarget);
10134 }
c9602061
NF
10135 if (ctx->singlestep_enabled) {
10136 save_cpu_state(ctx, 0);
895c2d04 10137 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10138 }
10139 tcg_gen_exit_tb(0);
10140 break;
10141 default:
10142 MIPS_DEBUG("unknown branch");
10143 break;
10144 }
10145 }
10146}
10147
7a387fff 10148/* ISA extensions (ASEs) */
6af0bf9c 10149/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10150
10151/* MIPS16 major opcodes */
10152enum {
10153 M16_OPC_ADDIUSP = 0x00,
10154 M16_OPC_ADDIUPC = 0x01,
10155 M16_OPC_B = 0x02,
10156 M16_OPC_JAL = 0x03,
10157 M16_OPC_BEQZ = 0x04,
10158 M16_OPC_BNEQZ = 0x05,
10159 M16_OPC_SHIFT = 0x06,
10160 M16_OPC_LD = 0x07,
10161 M16_OPC_RRIA = 0x08,
10162 M16_OPC_ADDIU8 = 0x09,
10163 M16_OPC_SLTI = 0x0a,
10164 M16_OPC_SLTIU = 0x0b,
10165 M16_OPC_I8 = 0x0c,
10166 M16_OPC_LI = 0x0d,
10167 M16_OPC_CMPI = 0x0e,
10168 M16_OPC_SD = 0x0f,
10169 M16_OPC_LB = 0x10,
10170 M16_OPC_LH = 0x11,
10171 M16_OPC_LWSP = 0x12,
10172 M16_OPC_LW = 0x13,
10173 M16_OPC_LBU = 0x14,
10174 M16_OPC_LHU = 0x15,
10175 M16_OPC_LWPC = 0x16,
10176 M16_OPC_LWU = 0x17,
10177 M16_OPC_SB = 0x18,
10178 M16_OPC_SH = 0x19,
10179 M16_OPC_SWSP = 0x1a,
10180 M16_OPC_SW = 0x1b,
10181 M16_OPC_RRR = 0x1c,
10182 M16_OPC_RR = 0x1d,
10183 M16_OPC_EXTEND = 0x1e,
10184 M16_OPC_I64 = 0x1f
10185};
10186
10187/* I8 funct field */
10188enum {
10189 I8_BTEQZ = 0x0,
10190 I8_BTNEZ = 0x1,
10191 I8_SWRASP = 0x2,
10192 I8_ADJSP = 0x3,
10193 I8_SVRS = 0x4,
10194 I8_MOV32R = 0x5,
10195 I8_MOVR32 = 0x7
10196};
10197
10198/* RRR f field */
10199enum {
10200 RRR_DADDU = 0x0,
10201 RRR_ADDU = 0x1,
10202 RRR_DSUBU = 0x2,
10203 RRR_SUBU = 0x3
10204};
10205
10206/* RR funct field */
10207enum {
10208 RR_JR = 0x00,
10209 RR_SDBBP = 0x01,
10210 RR_SLT = 0x02,
10211 RR_SLTU = 0x03,
10212 RR_SLLV = 0x04,
10213 RR_BREAK = 0x05,
10214 RR_SRLV = 0x06,
10215 RR_SRAV = 0x07,
10216 RR_DSRL = 0x08,
10217 RR_CMP = 0x0a,
10218 RR_NEG = 0x0b,
10219 RR_AND = 0x0c,
10220 RR_OR = 0x0d,
10221 RR_XOR = 0x0e,
10222 RR_NOT = 0x0f,
10223 RR_MFHI = 0x10,
10224 RR_CNVT = 0x11,
10225 RR_MFLO = 0x12,
10226 RR_DSRA = 0x13,
10227 RR_DSLLV = 0x14,
10228 RR_DSRLV = 0x16,
10229 RR_DSRAV = 0x17,
10230 RR_MULT = 0x18,
10231 RR_MULTU = 0x19,
10232 RR_DIV = 0x1a,
10233 RR_DIVU = 0x1b,
10234 RR_DMULT = 0x1c,
10235 RR_DMULTU = 0x1d,
10236 RR_DDIV = 0x1e,
10237 RR_DDIVU = 0x1f
10238};
10239
10240/* I64 funct field */
10241enum {
10242 I64_LDSP = 0x0,
10243 I64_SDSP = 0x1,
10244 I64_SDRASP = 0x2,
10245 I64_DADJSP = 0x3,
10246 I64_LDPC = 0x4,
364d4831 10247 I64_DADDIU5 = 0x5,
6ea219d0
NF
10248 I64_DADDIUPC = 0x6,
10249 I64_DADDIUSP = 0x7
10250};
10251
10252/* RR ry field for CNVT */
10253enum {
10254 RR_RY_CNVT_ZEB = 0x0,
10255 RR_RY_CNVT_ZEH = 0x1,
10256 RR_RY_CNVT_ZEW = 0x2,
10257 RR_RY_CNVT_SEB = 0x4,
10258 RR_RY_CNVT_SEH = 0x5,
10259 RR_RY_CNVT_SEW = 0x6,
10260};
10261
364d4831
NF
10262static int xlat (int r)
10263{
10264 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10265
10266 return map[r];
10267}
10268
10269static void gen_mips16_save (DisasContext *ctx,
10270 int xsregs, int aregs,
10271 int do_ra, int do_s0, int do_s1,
10272 int framesize)
10273{
10274 TCGv t0 = tcg_temp_new();
10275 TCGv t1 = tcg_temp_new();
10276 int args, astatic;
10277
10278 switch (aregs) {
10279 case 0:
10280 case 1:
10281 case 2:
10282 case 3:
10283 case 11:
10284 args = 0;
10285 break;
10286 case 4:
10287 case 5:
10288 case 6:
10289 case 7:
10290 args = 1;
10291 break;
10292 case 8:
10293 case 9:
10294 case 10:
10295 args = 2;
10296 break;
10297 case 12:
10298 case 13:
10299 args = 3;
10300 break;
10301 case 14:
10302 args = 4;
10303 break;
10304 default:
10305 generate_exception(ctx, EXCP_RI);
10306 return;
10307 }
10308
10309 switch (args) {
10310 case 4:
10311 gen_base_offset_addr(ctx, t0, 29, 12);
10312 gen_load_gpr(t1, 7);
5f68f5ae 10313 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10314 /* Fall through */
10315 case 3:
10316 gen_base_offset_addr(ctx, t0, 29, 8);
10317 gen_load_gpr(t1, 6);
5f68f5ae 10318 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10319 /* Fall through */
10320 case 2:
10321 gen_base_offset_addr(ctx, t0, 29, 4);
10322 gen_load_gpr(t1, 5);
5f68f5ae 10323 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10324 /* Fall through */
10325 case 1:
10326 gen_base_offset_addr(ctx, t0, 29, 0);
10327 gen_load_gpr(t1, 4);
5f68f5ae 10328 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10329 }
10330
10331 gen_load_gpr(t0, 29);
10332
5f68f5ae
AJ
10333#define DECR_AND_STORE(reg) do { \
10334 tcg_gen_subi_tl(t0, t0, 4); \
10335 gen_load_gpr(t1, reg); \
10336 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10337 } while (0)
10338
10339 if (do_ra) {
10340 DECR_AND_STORE(31);
10341 }
10342
10343 switch (xsregs) {
10344 case 7:
10345 DECR_AND_STORE(30);
10346 /* Fall through */
10347 case 6:
10348 DECR_AND_STORE(23);
10349 /* Fall through */
10350 case 5:
10351 DECR_AND_STORE(22);
10352 /* Fall through */
10353 case 4:
10354 DECR_AND_STORE(21);
10355 /* Fall through */
10356 case 3:
10357 DECR_AND_STORE(20);
10358 /* Fall through */
10359 case 2:
10360 DECR_AND_STORE(19);
10361 /* Fall through */
10362 case 1:
10363 DECR_AND_STORE(18);
10364 }
10365
10366 if (do_s1) {
10367 DECR_AND_STORE(17);
10368 }
10369 if (do_s0) {
10370 DECR_AND_STORE(16);
10371 }
10372
10373 switch (aregs) {
10374 case 0:
10375 case 4:
10376 case 8:
10377 case 12:
10378 case 14:
10379 astatic = 0;
10380 break;
10381 case 1:
10382 case 5:
10383 case 9:
10384 case 13:
10385 astatic = 1;
10386 break;
10387 case 2:
10388 case 6:
10389 case 10:
10390 astatic = 2;
10391 break;
10392 case 3:
10393 case 7:
10394 astatic = 3;
10395 break;
10396 case 11:
10397 astatic = 4;
10398 break;
10399 default:
10400 generate_exception(ctx, EXCP_RI);
10401 return;
10402 }
10403
10404 if (astatic > 0) {
10405 DECR_AND_STORE(7);
10406 if (astatic > 1) {
10407 DECR_AND_STORE(6);
10408 if (astatic > 2) {
10409 DECR_AND_STORE(5);
10410 if (astatic > 3) {
10411 DECR_AND_STORE(4);
10412 }
10413 }
10414 }
10415 }
10416#undef DECR_AND_STORE
10417
10418 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10419 tcg_temp_free(t0);
10420 tcg_temp_free(t1);
10421}
10422
10423static void gen_mips16_restore (DisasContext *ctx,
10424 int xsregs, int aregs,
10425 int do_ra, int do_s0, int do_s1,
10426 int framesize)
10427{
10428 int astatic;
10429 TCGv t0 = tcg_temp_new();
10430 TCGv t1 = tcg_temp_new();
10431
10432 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
10433
5f68f5ae
AJ
10434#define DECR_AND_LOAD(reg) do { \
10435 tcg_gen_subi_tl(t0, t0, 4); \
10436 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10437 gen_store_gpr(t1, reg); \
364d4831
NF
10438 } while (0)
10439
10440 if (do_ra) {
10441 DECR_AND_LOAD(31);
10442 }
10443
10444 switch (xsregs) {
10445 case 7:
10446 DECR_AND_LOAD(30);
10447 /* Fall through */
10448 case 6:
10449 DECR_AND_LOAD(23);
10450 /* Fall through */
10451 case 5:
10452 DECR_AND_LOAD(22);
10453 /* Fall through */
10454 case 4:
10455 DECR_AND_LOAD(21);
10456 /* Fall through */
10457 case 3:
10458 DECR_AND_LOAD(20);
10459 /* Fall through */
10460 case 2:
10461 DECR_AND_LOAD(19);
10462 /* Fall through */
10463 case 1:
10464 DECR_AND_LOAD(18);
10465 }
10466
10467 if (do_s1) {
10468 DECR_AND_LOAD(17);
10469 }
10470 if (do_s0) {
10471 DECR_AND_LOAD(16);
10472 }
10473
10474 switch (aregs) {
10475 case 0:
10476 case 4:
10477 case 8:
10478 case 12:
10479 case 14:
10480 astatic = 0;
10481 break;
10482 case 1:
10483 case 5:
10484 case 9:
10485 case 13:
10486 astatic = 1;
10487 break;
10488 case 2:
10489 case 6:
10490 case 10:
10491 astatic = 2;
10492 break;
10493 case 3:
10494 case 7:
10495 astatic = 3;
10496 break;
10497 case 11:
10498 astatic = 4;
10499 break;
10500 default:
10501 generate_exception(ctx, EXCP_RI);
10502 return;
10503 }
10504
10505 if (astatic > 0) {
10506 DECR_AND_LOAD(7);
10507 if (astatic > 1) {
10508 DECR_AND_LOAD(6);
10509 if (astatic > 2) {
10510 DECR_AND_LOAD(5);
10511 if (astatic > 3) {
10512 DECR_AND_LOAD(4);
10513 }
10514 }
10515 }
10516 }
10517#undef DECR_AND_LOAD
10518
10519 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10520 tcg_temp_free(t0);
10521 tcg_temp_free(t1);
10522}
10523
10524static void gen_addiupc (DisasContext *ctx, int rx, int imm,
10525 int is_64_bit, int extended)
10526{
10527 TCGv t0;
10528
10529 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10530 generate_exception(ctx, EXCP_RI);
10531 return;
10532 }
10533
10534 t0 = tcg_temp_new();
10535
10536 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
10537 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
10538 if (!is_64_bit) {
10539 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10540 }
10541
10542 tcg_temp_free(t0);
10543}
10544
10545#if defined(TARGET_MIPS64)
d75c135e 10546static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
10547 int ry, int funct, int16_t offset,
10548 int extended)
10549{
10550 switch (funct) {
10551 case I64_LDSP:
10552 check_mips_64(ctx);
10553 offset = extended ? offset : offset << 3;
d75c135e 10554 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
10555 break;
10556 case I64_SDSP:
10557 check_mips_64(ctx);
10558 offset = extended ? offset : offset << 3;
5c13fdfd 10559 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
10560 break;
10561 case I64_SDRASP:
10562 check_mips_64(ctx);
10563 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 10564 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
10565 break;
10566 case I64_DADJSP:
10567 check_mips_64(ctx);
10568 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 10569 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
10570 break;
10571 case I64_LDPC:
10572 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10573 generate_exception(ctx, EXCP_RI);
10574 } else {
10575 offset = extended ? offset : offset << 3;
d75c135e 10576 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
10577 }
10578 break;
10579 case I64_DADDIU5:
10580 check_mips_64(ctx);
10581 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 10582 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
10583 break;
10584 case I64_DADDIUPC:
10585 check_mips_64(ctx);
10586 offset = extended ? offset : offset << 2;
10587 gen_addiupc(ctx, ry, offset, 1, extended);
10588 break;
10589 case I64_DADDIUSP:
10590 check_mips_64(ctx);
10591 offset = extended ? offset : offset << 2;
d75c135e 10592 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
10593 break;
10594 }
10595}
10596#endif
10597
240ce26a 10598static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 10599{
895c2d04 10600 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
10601 int op, rx, ry, funct, sa;
10602 int16_t imm, offset;
10603
10604 ctx->opcode = (ctx->opcode << 16) | extend;
10605 op = (ctx->opcode >> 11) & 0x1f;
10606 sa = (ctx->opcode >> 22) & 0x1f;
10607 funct = (ctx->opcode >> 8) & 0x7;
10608 rx = xlat((ctx->opcode >> 8) & 0x7);
10609 ry = xlat((ctx->opcode >> 5) & 0x7);
10610 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
10611 | ((ctx->opcode >> 21) & 0x3f) << 5
10612 | (ctx->opcode & 0x1f));
10613
10614 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
10615 counterparts. */
10616 switch (op) {
10617 case M16_OPC_ADDIUSP:
d75c135e 10618 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
10619 break;
10620 case M16_OPC_ADDIUPC:
10621 gen_addiupc(ctx, rx, imm, 0, 1);
10622 break;
10623 case M16_OPC_B:
b231c103 10624 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
10625 /* No delay slot, so just process as a normal instruction */
10626 break;
10627 case M16_OPC_BEQZ:
b231c103 10628 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
10629 /* No delay slot, so just process as a normal instruction */
10630 break;
10631 case M16_OPC_BNEQZ:
b231c103 10632 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
10633 /* No delay slot, so just process as a normal instruction */
10634 break;
10635 case M16_OPC_SHIFT:
10636 switch (ctx->opcode & 0x3) {
10637 case 0x0:
d75c135e 10638 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
10639 break;
10640 case 0x1:
10641#if defined(TARGET_MIPS64)
10642 check_mips_64(ctx);
d75c135e 10643 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10644#else
10645 generate_exception(ctx, EXCP_RI);
10646#endif
10647 break;
10648 case 0x2:
d75c135e 10649 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10650 break;
10651 case 0x3:
d75c135e 10652 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10653 break;
10654 }
10655 break;
10656#if defined(TARGET_MIPS64)
10657 case M16_OPC_LD:
10658 check_mips_64(ctx);
d75c135e 10659 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
10660 break;
10661#endif
10662 case M16_OPC_RRIA:
10663 imm = ctx->opcode & 0xf;
10664 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
10665 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
10666 imm = (int16_t) (imm << 1) >> 1;
10667 if ((ctx->opcode >> 4) & 0x1) {
10668#if defined(TARGET_MIPS64)
10669 check_mips_64(ctx);
d75c135e 10670 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10671#else
10672 generate_exception(ctx, EXCP_RI);
10673#endif
10674 } else {
d75c135e 10675 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10676 }
10677 break;
10678 case M16_OPC_ADDIU8:
d75c135e 10679 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10680 break;
10681 case M16_OPC_SLTI:
d75c135e 10682 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10683 break;
10684 case M16_OPC_SLTIU:
d75c135e 10685 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10686 break;
10687 case M16_OPC_I8:
10688 switch (funct) {
10689 case I8_BTEQZ:
b231c103 10690 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
10691 break;
10692 case I8_BTNEZ:
b231c103 10693 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
10694 break;
10695 case I8_SWRASP:
5c13fdfd 10696 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
10697 break;
10698 case I8_ADJSP:
d75c135e 10699 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
10700 break;
10701 case I8_SVRS:
10702 {
10703 int xsregs = (ctx->opcode >> 24) & 0x7;
10704 int aregs = (ctx->opcode >> 16) & 0xf;
10705 int do_ra = (ctx->opcode >> 6) & 0x1;
10706 int do_s0 = (ctx->opcode >> 5) & 0x1;
10707 int do_s1 = (ctx->opcode >> 4) & 0x1;
10708 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
10709 | (ctx->opcode & 0xf)) << 3;
10710
10711 if (ctx->opcode & (1 << 7)) {
10712 gen_mips16_save(ctx, xsregs, aregs,
10713 do_ra, do_s0, do_s1,
10714 framesize);
10715 } else {
10716 gen_mips16_restore(ctx, xsregs, aregs,
10717 do_ra, do_s0, do_s1,
10718 framesize);
10719 }
10720 }
10721 break;
10722 default:
10723 generate_exception(ctx, EXCP_RI);
10724 break;
10725 }
10726 break;
10727 case M16_OPC_LI:
10728 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
10729 break;
10730 case M16_OPC_CMPI:
10731 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
10732 break;
10733#if defined(TARGET_MIPS64)
10734 case M16_OPC_SD:
5c13fdfd 10735 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
10736 break;
10737#endif
10738 case M16_OPC_LB:
d75c135e 10739 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10740 break;
10741 case M16_OPC_LH:
d75c135e 10742 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
10743 break;
10744 case M16_OPC_LWSP:
d75c135e 10745 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
10746 break;
10747 case M16_OPC_LW:
d75c135e 10748 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
10749 break;
10750 case M16_OPC_LBU:
d75c135e 10751 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10752 break;
10753 case M16_OPC_LHU:
d75c135e 10754 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
10755 break;
10756 case M16_OPC_LWPC:
d75c135e 10757 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
10758 break;
10759#if defined(TARGET_MIPS64)
10760 case M16_OPC_LWU:
d75c135e 10761 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
10762 break;
10763#endif
10764 case M16_OPC_SB:
5c13fdfd 10765 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10766 break;
10767 case M16_OPC_SH:
5c13fdfd 10768 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
10769 break;
10770 case M16_OPC_SWSP:
5c13fdfd 10771 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
10772 break;
10773 case M16_OPC_SW:
5c13fdfd 10774 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
10775 break;
10776#if defined(TARGET_MIPS64)
10777 case M16_OPC_I64:
d75c135e 10778 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
10779 break;
10780#endif
10781 default:
10782 generate_exception(ctx, EXCP_RI);
10783 break;
10784 }
10785
10786 return 4;
10787}
10788
240ce26a 10789static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
10790{
10791 int rx, ry;
10792 int sa;
10793 int op, cnvt_op, op1, offset;
10794 int funct;
10795 int n_bytes;
10796
10797 op = (ctx->opcode >> 11) & 0x1f;
10798 sa = (ctx->opcode >> 2) & 0x7;
10799 sa = sa == 0 ? 8 : sa;
10800 rx = xlat((ctx->opcode >> 8) & 0x7);
10801 cnvt_op = (ctx->opcode >> 5) & 0x7;
10802 ry = xlat((ctx->opcode >> 5) & 0x7);
10803 op1 = offset = ctx->opcode & 0x1f;
10804
10805 n_bytes = 2;
10806
10807 switch (op) {
10808 case M16_OPC_ADDIUSP:
10809 {
10810 int16_t imm = ((uint8_t) ctx->opcode) << 2;
10811
d75c135e 10812 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
10813 }
10814 break;
10815 case M16_OPC_ADDIUPC:
10816 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
10817 break;
10818 case M16_OPC_B:
10819 offset = (ctx->opcode & 0x7ff) << 1;
10820 offset = (int16_t)(offset << 4) >> 4;
b231c103 10821 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
10822 /* No delay slot, so just process as a normal instruction */
10823 break;
10824 case M16_OPC_JAL:
895c2d04 10825 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
10826 offset = (((ctx->opcode & 0x1f) << 21)
10827 | ((ctx->opcode >> 5) & 0x1f) << 16
10828 | offset) << 2;
b231c103
YK
10829 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
10830 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 10831 n_bytes = 4;
364d4831
NF
10832 break;
10833 case M16_OPC_BEQZ:
b231c103
YK
10834 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
10835 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
10836 /* No delay slot, so just process as a normal instruction */
10837 break;
10838 case M16_OPC_BNEQZ:
b231c103
YK
10839 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
10840 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
10841 /* No delay slot, so just process as a normal instruction */
10842 break;
10843 case M16_OPC_SHIFT:
10844 switch (ctx->opcode & 0x3) {
10845 case 0x0:
d75c135e 10846 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
10847 break;
10848 case 0x1:
10849#if defined(TARGET_MIPS64)
10850 check_mips_64(ctx);
d75c135e 10851 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10852#else
10853 generate_exception(ctx, EXCP_RI);
10854#endif
10855 break;
10856 case 0x2:
d75c135e 10857 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10858 break;
10859 case 0x3:
d75c135e 10860 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10861 break;
10862 }
10863 break;
10864#if defined(TARGET_MIPS64)
10865 case M16_OPC_LD:
10866 check_mips_64(ctx);
d75c135e 10867 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
10868 break;
10869#endif
10870 case M16_OPC_RRIA:
10871 {
10872 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
10873
10874 if ((ctx->opcode >> 4) & 1) {
10875#if defined(TARGET_MIPS64)
10876 check_mips_64(ctx);
d75c135e 10877 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10878#else
10879 generate_exception(ctx, EXCP_RI);
10880#endif
10881 } else {
d75c135e 10882 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10883 }
10884 }
10885 break;
10886 case M16_OPC_ADDIU8:
10887 {
10888 int16_t imm = (int8_t) ctx->opcode;
10889
d75c135e 10890 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10891 }
10892 break;
10893 case M16_OPC_SLTI:
10894 {
10895 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10896 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10897 }
10898 break;
10899 case M16_OPC_SLTIU:
10900 {
10901 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10902 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10903 }
10904 break;
10905 case M16_OPC_I8:
10906 {
10907 int reg32;
10908
10909 funct = (ctx->opcode >> 8) & 0x7;
10910 switch (funct) {
10911 case I8_BTEQZ:
10912 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 10913 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
10914 break;
10915 case I8_BTNEZ:
10916 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 10917 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
10918 break;
10919 case I8_SWRASP:
5c13fdfd 10920 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
10921 break;
10922 case I8_ADJSP:
d75c135e 10923 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
10924 ((int8_t)ctx->opcode) << 3);
10925 break;
10926 case I8_SVRS:
10927 {
10928 int do_ra = ctx->opcode & (1 << 6);
10929 int do_s0 = ctx->opcode & (1 << 5);
10930 int do_s1 = ctx->opcode & (1 << 4);
10931 int framesize = ctx->opcode & 0xf;
10932
10933 if (framesize == 0) {
10934 framesize = 128;
10935 } else {
10936 framesize = framesize << 3;
10937 }
10938
10939 if (ctx->opcode & (1 << 7)) {
10940 gen_mips16_save(ctx, 0, 0,
10941 do_ra, do_s0, do_s1, framesize);
10942 } else {
10943 gen_mips16_restore(ctx, 0, 0,
10944 do_ra, do_s0, do_s1, framesize);
10945 }
10946 }
10947 break;
10948 case I8_MOV32R:
10949 {
10950 int rz = xlat(ctx->opcode & 0x7);
10951
10952 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10953 ((ctx->opcode >> 5) & 0x7);
d75c135e 10954 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
10955 }
10956 break;
10957 case I8_MOVR32:
10958 reg32 = ctx->opcode & 0x1f;
d75c135e 10959 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
10960 break;
10961 default:
10962 generate_exception(ctx, EXCP_RI);
10963 break;
10964 }
10965 }
10966 break;
10967 case M16_OPC_LI:
10968 {
10969 int16_t imm = (uint8_t) ctx->opcode;
10970
d75c135e 10971 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
10972 }
10973 break;
10974 case M16_OPC_CMPI:
10975 {
10976 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10977 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
10978 }
10979 break;
10980#if defined(TARGET_MIPS64)
10981 case M16_OPC_SD:
10982 check_mips_64(ctx);
5c13fdfd 10983 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
10984 break;
10985#endif
10986 case M16_OPC_LB:
d75c135e 10987 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10988 break;
10989 case M16_OPC_LH:
d75c135e 10990 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10991 break;
10992 case M16_OPC_LWSP:
d75c135e 10993 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10994 break;
10995 case M16_OPC_LW:
d75c135e 10996 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10997 break;
10998 case M16_OPC_LBU:
d75c135e 10999 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11000 break;
11001 case M16_OPC_LHU:
d75c135e 11002 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11003 break;
11004 case M16_OPC_LWPC:
d75c135e 11005 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11006 break;
11007#if defined (TARGET_MIPS64)
11008 case M16_OPC_LWU:
11009 check_mips_64(ctx);
d75c135e 11010 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11011 break;
11012#endif
11013 case M16_OPC_SB:
5c13fdfd 11014 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11015 break;
11016 case M16_OPC_SH:
5c13fdfd 11017 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11018 break;
11019 case M16_OPC_SWSP:
5c13fdfd 11020 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11021 break;
11022 case M16_OPC_SW:
5c13fdfd 11023 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11024 break;
11025 case M16_OPC_RRR:
11026 {
11027 int rz = xlat((ctx->opcode >> 2) & 0x7);
11028 int mips32_op;
11029
11030 switch (ctx->opcode & 0x3) {
11031 case RRR_ADDU:
11032 mips32_op = OPC_ADDU;
11033 break;
11034 case RRR_SUBU:
11035 mips32_op = OPC_SUBU;
11036 break;
11037#if defined(TARGET_MIPS64)
11038 case RRR_DADDU:
11039 mips32_op = OPC_DADDU;
11040 check_mips_64(ctx);
11041 break;
11042 case RRR_DSUBU:
11043 mips32_op = OPC_DSUBU;
11044 check_mips_64(ctx);
11045 break;
11046#endif
11047 default:
11048 generate_exception(ctx, EXCP_RI);
11049 goto done;
11050 }
11051
d75c135e 11052 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11053 done:
11054 ;
11055 }
11056 break;
11057 case M16_OPC_RR:
11058 switch (op1) {
11059 case RR_JR:
11060 {
11061 int nd = (ctx->opcode >> 7) & 0x1;
11062 int link = (ctx->opcode >> 6) & 0x1;
11063 int ra = (ctx->opcode >> 5) & 0x1;
11064
11065 if (link) {
b231c103 11066 op = OPC_JALR;
364d4831
NF
11067 } else {
11068 op = OPC_JR;
11069 }
11070
b231c103
YK
11071 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11072 (nd ? 0 : 2));
364d4831
NF
11073 }
11074 break;
11075 case RR_SDBBP:
11076 /* XXX: not clear which exception should be raised
11077 * when in debug mode...
11078 */
d75c135e 11079 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11080 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11081 generate_exception(ctx, EXCP_DBp);
11082 } else {
11083 generate_exception(ctx, EXCP_DBp);
11084 }
11085 break;
11086 case RR_SLT:
d75c135e 11087 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11088 break;
11089 case RR_SLTU:
d75c135e 11090 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11091 break;
11092 case RR_BREAK:
11093 generate_exception(ctx, EXCP_BREAK);
11094 break;
11095 case RR_SLLV:
d75c135e 11096 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11097 break;
11098 case RR_SRLV:
d75c135e 11099 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11100 break;
11101 case RR_SRAV:
d75c135e 11102 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11103 break;
11104#if defined (TARGET_MIPS64)
11105 case RR_DSRL:
11106 check_mips_64(ctx);
d75c135e 11107 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11108 break;
11109#endif
11110 case RR_CMP:
d75c135e 11111 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11112 break;
11113 case RR_NEG:
d75c135e 11114 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11115 break;
11116 case RR_AND:
d75c135e 11117 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11118 break;
11119 case RR_OR:
d75c135e 11120 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11121 break;
11122 case RR_XOR:
d75c135e 11123 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11124 break;
11125 case RR_NOT:
d75c135e 11126 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11127 break;
11128 case RR_MFHI:
26135ead 11129 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11130 break;
11131 case RR_CNVT:
11132 switch (cnvt_op) {
11133 case RR_RY_CNVT_ZEB:
11134 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11135 break;
11136 case RR_RY_CNVT_ZEH:
11137 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11138 break;
11139 case RR_RY_CNVT_SEB:
11140 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11141 break;
11142 case RR_RY_CNVT_SEH:
11143 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11144 break;
11145#if defined (TARGET_MIPS64)
11146 case RR_RY_CNVT_ZEW:
11147 check_mips_64(ctx);
11148 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11149 break;
11150 case RR_RY_CNVT_SEW:
11151 check_mips_64(ctx);
11152 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11153 break;
11154#endif
11155 default:
11156 generate_exception(ctx, EXCP_RI);
11157 break;
11158 }
11159 break;
11160 case RR_MFLO:
26135ead 11161 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11162 break;
11163#if defined (TARGET_MIPS64)
11164 case RR_DSRA:
11165 check_mips_64(ctx);
d75c135e 11166 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11167 break;
11168 case RR_DSLLV:
11169 check_mips_64(ctx);
d75c135e 11170 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11171 break;
11172 case RR_DSRLV:
11173 check_mips_64(ctx);
d75c135e 11174 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11175 break;
11176 case RR_DSRAV:
11177 check_mips_64(ctx);
d75c135e 11178 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11179 break;
11180#endif
11181 case RR_MULT:
26135ead 11182 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11183 break;
11184 case RR_MULTU:
26135ead 11185 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11186 break;
11187 case RR_DIV:
26135ead 11188 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11189 break;
11190 case RR_DIVU:
26135ead 11191 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11192 break;
11193#if defined (TARGET_MIPS64)
11194 case RR_DMULT:
11195 check_mips_64(ctx);
26135ead 11196 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11197 break;
11198 case RR_DMULTU:
11199 check_mips_64(ctx);
26135ead 11200 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11201 break;
11202 case RR_DDIV:
11203 check_mips_64(ctx);
26135ead 11204 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11205 break;
11206 case RR_DDIVU:
11207 check_mips_64(ctx);
26135ead 11208 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11209 break;
11210#endif
11211 default:
11212 generate_exception(ctx, EXCP_RI);
11213 break;
11214 }
11215 break;
11216 case M16_OPC_EXTEND:
240ce26a 11217 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11218 n_bytes = 4;
11219 break;
11220#if defined(TARGET_MIPS64)
11221 case M16_OPC_I64:
11222 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11223 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11224 break;
11225#endif
11226 default:
11227 generate_exception(ctx, EXCP_RI);
11228 break;
11229 }
11230
11231 return n_bytes;
11232}
11233
211da992 11234/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11235
211da992
CWR
11236/*
11237 * microMIPS32/microMIPS64 major opcodes
11238 *
11239 * 1. MIPS Architecture for Programmers Volume II-B:
11240 * The microMIPS32 Instruction Set (Revision 3.05)
11241 *
11242 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11243 *
11244 * 2. MIPS Architecture For Programmers Volume II-A:
11245 * The MIPS64 Instruction Set (Revision 3.51)
11246 */
6af0bf9c 11247
3c824109
NF
11248enum {
11249 POOL32A = 0x00,
11250 POOL16A = 0x01,
11251 LBU16 = 0x02,
11252 MOVE16 = 0x03,
11253 ADDI32 = 0x04,
11254 LBU32 = 0x05,
11255 SB32 = 0x06,
11256 LB32 = 0x07,
11257
11258 POOL32B = 0x08,
11259 POOL16B = 0x09,
11260 LHU16 = 0x0a,
11261 ANDI16 = 0x0b,
11262 ADDIU32 = 0x0c,
11263 LHU32 = 0x0d,
11264 SH32 = 0x0e,
11265 LH32 = 0x0f,
11266
11267 POOL32I = 0x10,
11268 POOL16C = 0x11,
11269 LWSP16 = 0x12,
11270 POOL16D = 0x13,
11271 ORI32 = 0x14,
11272 POOL32F = 0x15,
211da992
CWR
11273 POOL32S = 0x16, /* MIPS64 */
11274 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11275
211da992 11276 /* 0x1f is reserved */
3c824109
NF
11277 POOL32C = 0x18,
11278 LWGP16 = 0x19,
11279 LW16 = 0x1a,
11280 POOL16E = 0x1b,
11281 XORI32 = 0x1c,
11282 JALS32 = 0x1d,
11283 ADDIUPC = 0x1e,
3c824109
NF
11284
11285 /* 0x20 is reserved */
11286 RES_20 = 0x20,
11287 POOL16F = 0x21,
11288 SB16 = 0x22,
11289 BEQZ16 = 0x23,
11290 SLTI32 = 0x24,
11291 BEQ32 = 0x25,
11292 SWC132 = 0x26,
11293 LWC132 = 0x27,
11294
11295 /* 0x28 and 0x29 are reserved */
11296 RES_28 = 0x28,
11297 RES_29 = 0x29,
11298 SH16 = 0x2a,
11299 BNEZ16 = 0x2b,
11300 SLTIU32 = 0x2c,
11301 BNE32 = 0x2d,
11302 SDC132 = 0x2e,
11303 LDC132 = 0x2f,
11304
11305 /* 0x30 and 0x31 are reserved */
11306 RES_30 = 0x30,
11307 RES_31 = 0x31,
11308 SWSP16 = 0x32,
11309 B16 = 0x33,
11310 ANDI32 = 0x34,
11311 J32 = 0x35,
211da992
CWR
11312 SD32 = 0x36, /* MIPS64 */
11313 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11314
11315 /* 0x38 and 0x39 are reserved */
11316 RES_38 = 0x38,
11317 RES_39 = 0x39,
11318 SW16 = 0x3a,
11319 LI16 = 0x3b,
11320 JALX32 = 0x3c,
11321 JAL32 = 0x3d,
11322 SW32 = 0x3e,
11323 LW32 = 0x3f
11324};
11325
11326/* POOL32A encoding of minor opcode field */
11327
11328enum {
11329 /* These opcodes are distinguished only by bits 9..6; those bits are
11330 * what are recorded below. */
11331 SLL32 = 0x0,
11332 SRL32 = 0x1,
11333 SRA = 0x2,
11334 ROTR = 0x3,
11335
11336 SLLV = 0x0,
11337 SRLV = 0x1,
11338 SRAV = 0x2,
11339 ROTRV = 0x3,
11340 ADD = 0x4,
11341 ADDU32 = 0x5,
11342 SUB = 0x6,
11343 SUBU32 = 0x7,
11344 MUL = 0x8,
11345 AND = 0x9,
11346 OR32 = 0xa,
11347 NOR = 0xb,
11348 XOR32 = 0xc,
11349 SLT = 0xd,
11350 SLTU = 0xe,
11351
11352 MOVN = 0x0,
11353 MOVZ = 0x1,
11354 LWXS = 0x4,
11355
11356 /* The following can be distinguished by their lower 6 bits. */
11357 INS = 0x0c,
11358 EXT = 0x2c,
11359 POOL32AXF = 0x3c
11360};
11361
11362/* POOL32AXF encoding of minor opcode field extension */
11363
d132c79f
CWR
11364/*
11365 * 1. MIPS Architecture for Programmers Volume II-B:
11366 * The microMIPS32 Instruction Set (Revision 3.05)
11367 *
11368 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11369 *
11370 * 2. MIPS Architecture for Programmers VolumeIV-e:
11371 * The MIPS DSP Application-Specific Extension
11372 * to the microMIPS32 Architecture (Revision 2.34)
11373 *
11374 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11375 */
11376
3c824109
NF
11377enum {
11378 /* bits 11..6 */
11379 TEQ = 0x00,
11380 TGE = 0x08,
11381 TGEU = 0x10,
11382 TLT = 0x20,
11383 TLTU = 0x28,
11384 TNE = 0x30,
11385
11386 MFC0 = 0x03,
11387 MTC0 = 0x0b,
11388
d132c79f
CWR
11389 /* begin of microMIPS32 DSP */
11390
3c824109
NF
11391 /* bits 13..12 for 0x01 */
11392 MFHI_ACC = 0x0,
11393 MFLO_ACC = 0x1,
11394 MTHI_ACC = 0x2,
11395 MTLO_ACC = 0x3,
11396
11397 /* bits 13..12 for 0x2a */
11398 MADD_ACC = 0x0,
11399 MADDU_ACC = 0x1,
11400 MSUB_ACC = 0x2,
11401 MSUBU_ACC = 0x3,
11402
11403 /* bits 13..12 for 0x32 */
11404 MULT_ACC = 0x0,
6801038b 11405 MULTU_ACC = 0x1,
3c824109 11406
d132c79f
CWR
11407 /* end of microMIPS32 DSP */
11408
3c824109
NF
11409 /* bits 15..12 for 0x2c */
11410 SEB = 0x2,
11411 SEH = 0x3,
11412 CLO = 0x4,
11413 CLZ = 0x5,
11414 RDHWR = 0x6,
11415 WSBH = 0x7,
11416 MULT = 0x8,
11417 MULTU = 0x9,
11418 DIV = 0xa,
11419 DIVU = 0xb,
11420 MADD = 0xc,
11421 MADDU = 0xd,
11422 MSUB = 0xe,
11423 MSUBU = 0xf,
11424
11425 /* bits 15..12 for 0x34 */
11426 MFC2 = 0x4,
11427 MTC2 = 0x5,
11428 MFHC2 = 0x8,
11429 MTHC2 = 0x9,
11430 CFC2 = 0xc,
11431 CTC2 = 0xd,
11432
11433 /* bits 15..12 for 0x3c */
11434 JALR = 0x0,
11435 JR = 0x0, /* alias */
11436 JALR_HB = 0x1,
11437 JALRS = 0x4,
11438 JALRS_HB = 0x5,
11439
11440 /* bits 15..12 for 0x05 */
11441 RDPGPR = 0xe,
11442 WRPGPR = 0xf,
11443
11444 /* bits 15..12 for 0x0d */
11445 TLBP = 0x0,
11446 TLBR = 0x1,
11447 TLBWI = 0x2,
11448 TLBWR = 0x3,
11449 WAIT = 0x9,
11450 IRET = 0xd,
11451 DERET = 0xe,
11452 ERET = 0xf,
11453
11454 /* bits 15..12 for 0x15 */
11455 DMT = 0x0,
11456 DVPE = 0x1,
11457 EMT = 0x2,
11458 EVPE = 0x3,
11459
11460 /* bits 15..12 for 0x1d */
11461 DI = 0x4,
11462 EI = 0x5,
11463
11464 /* bits 15..12 for 0x2d */
11465 SYNC = 0x6,
11466 SYSCALL = 0x8,
11467 SDBBP = 0xd,
11468
11469 /* bits 15..12 for 0x35 */
11470 MFHI32 = 0x0,
11471 MFLO32 = 0x1,
11472 MTHI32 = 0x2,
11473 MTLO32 = 0x3,
11474};
11475
11476/* POOL32B encoding of minor opcode field (bits 15..12) */
11477
11478enum {
11479 LWC2 = 0x0,
11480 LWP = 0x1,
11481 LDP = 0x4,
11482 LWM32 = 0x5,
11483 CACHE = 0x6,
11484 LDM = 0x7,
11485 SWC2 = 0x8,
11486 SWP = 0x9,
11487 SDP = 0xc,
11488 SWM32 = 0xd,
11489 SDM = 0xf
11490};
11491
11492/* POOL32C encoding of minor opcode field (bits 15..12) */
11493
11494enum {
11495 LWL = 0x0,
11496 SWL = 0x8,
11497 LWR = 0x1,
11498 SWR = 0x9,
11499 PREF = 0x2,
11500 /* 0xa is reserved */
11501 LL = 0x3,
11502 SC = 0xb,
11503 LDL = 0x4,
11504 SDL = 0xc,
11505 LDR = 0x5,
11506 SDR = 0xd,
11507 /* 0x6 is reserved */
11508 LWU = 0xe,
11509 LLD = 0x7,
11510 SCD = 0xf
11511};
11512
11513/* POOL32F encoding of minor opcode field (bits 5..0) */
11514
11515enum {
11516 /* These are the bit 7..6 values */
11517 ADD_FMT = 0x0,
11518 MOVN_FMT = 0x0,
11519
11520 SUB_FMT = 0x1,
11521 MOVZ_FMT = 0x1,
11522
11523 MUL_FMT = 0x2,
11524
11525 DIV_FMT = 0x3,
11526
11527 /* These are the bit 8..6 values */
11528 RSQRT2_FMT = 0x0,
11529 MOVF_FMT = 0x0,
11530
11531 LWXC1 = 0x1,
11532 MOVT_FMT = 0x1,
11533
11534 PLL_PS = 0x2,
11535 SWXC1 = 0x2,
11536
11537 PLU_PS = 0x3,
11538 LDXC1 = 0x3,
11539
11540 PUL_PS = 0x4,
11541 SDXC1 = 0x4,
11542 RECIP2_FMT = 0x4,
11543
11544 PUU_PS = 0x5,
11545 LUXC1 = 0x5,
11546
11547 CVT_PS_S = 0x6,
11548 SUXC1 = 0x6,
11549 ADDR_PS = 0x6,
11550 PREFX = 0x6,
11551
11552 MULR_PS = 0x7,
11553
11554 MADD_S = 0x01,
11555 MADD_D = 0x09,
11556 MADD_PS = 0x11,
11557 ALNV_PS = 0x19,
11558 MSUB_S = 0x21,
11559 MSUB_D = 0x29,
11560 MSUB_PS = 0x31,
11561
11562 NMADD_S = 0x02,
11563 NMADD_D = 0x0a,
11564 NMADD_PS = 0x12,
11565 NMSUB_S = 0x22,
11566 NMSUB_D = 0x2a,
11567 NMSUB_PS = 0x32,
11568
11569 POOL32FXF = 0x3b,
11570
11571 CABS_COND_FMT = 0x1c, /* MIPS3D */
11572 C_COND_FMT = 0x3c
11573};
11574
11575/* POOL32Fxf encoding of minor opcode extension field */
11576
11577enum {
11578 CVT_L = 0x04,
11579 RSQRT_FMT = 0x08,
11580 FLOOR_L = 0x0c,
11581 CVT_PW_PS = 0x1c,
11582 CVT_W = 0x24,
11583 SQRT_FMT = 0x28,
11584 FLOOR_W = 0x2c,
11585 CVT_PS_PW = 0x3c,
11586 CFC1 = 0x40,
11587 RECIP_FMT = 0x48,
11588 CEIL_L = 0x4c,
11589 CTC1 = 0x60,
11590 CEIL_W = 0x6c,
11591 MFC1 = 0x80,
11592 CVT_S_PL = 0x84,
11593 TRUNC_L = 0x8c,
11594 MTC1 = 0xa0,
11595 CVT_S_PU = 0xa4,
11596 TRUNC_W = 0xac,
11597 MFHC1 = 0xc0,
11598 ROUND_L = 0xcc,
11599 MTHC1 = 0xe0,
11600 ROUND_W = 0xec,
11601
11602 MOV_FMT = 0x01,
11603 MOVF = 0x05,
11604 ABS_FMT = 0x0d,
11605 RSQRT1_FMT = 0x1d,
11606 MOVT = 0x25,
11607 NEG_FMT = 0x2d,
11608 CVT_D = 0x4d,
11609 RECIP1_FMT = 0x5d,
11610 CVT_S = 0x6d
11611};
11612
11613/* POOL32I encoding of minor opcode field (bits 25..21) */
11614
11615enum {
11616 BLTZ = 0x00,
11617 BLTZAL = 0x01,
11618 BGEZ = 0x02,
11619 BGEZAL = 0x03,
11620 BLEZ = 0x04,
11621 BNEZC = 0x05,
11622 BGTZ = 0x06,
11623 BEQZC = 0x07,
11624 TLTI = 0x08,
11625 TGEI = 0x09,
11626 TLTIU = 0x0a,
11627 TGEIU = 0x0b,
11628 TNEI = 0x0c,
11629 LUI = 0x0d,
11630 TEQI = 0x0e,
11631 SYNCI = 0x10,
11632 BLTZALS = 0x11,
11633 BGEZALS = 0x13,
11634 BC2F = 0x14,
11635 BC2T = 0x15,
11636 BPOSGE64 = 0x1a,
11637 BPOSGE32 = 0x1b,
11638 /* These overlap and are distinguished by bit16 of the instruction */
11639 BC1F = 0x1c,
11640 BC1T = 0x1d,
11641 BC1ANY2F = 0x1c,
11642 BC1ANY2T = 0x1d,
11643 BC1ANY4F = 0x1e,
11644 BC1ANY4T = 0x1f
11645};
11646
11647/* POOL16A encoding of minor opcode field */
11648
11649enum {
11650 ADDU16 = 0x0,
11651 SUBU16 = 0x1
11652};
11653
11654/* POOL16B encoding of minor opcode field */
11655
11656enum {
11657 SLL16 = 0x0,
11658 SRL16 = 0x1
11659};
11660
11661/* POOL16C encoding of minor opcode field */
11662
11663enum {
11664 NOT16 = 0x00,
11665 XOR16 = 0x04,
11666 AND16 = 0x08,
11667 OR16 = 0x0c,
11668 LWM16 = 0x10,
11669 SWM16 = 0x14,
11670 JR16 = 0x18,
11671 JRC16 = 0x1a,
11672 JALR16 = 0x1c,
11673 JALR16S = 0x1e,
11674 MFHI16 = 0x20,
11675 MFLO16 = 0x24,
11676 BREAK16 = 0x28,
11677 SDBBP16 = 0x2c,
11678 JRADDIUSP = 0x30
11679};
11680
11681/* POOL16D encoding of minor opcode field */
11682
11683enum {
11684 ADDIUS5 = 0x0,
11685 ADDIUSP = 0x1
11686};
11687
11688/* POOL16E encoding of minor opcode field */
11689
11690enum {
11691 ADDIUR2 = 0x0,
11692 ADDIUR1SP = 0x1
11693};
11694
11695static int mmreg (int r)
11696{
11697 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11698
11699 return map[r];
11700}
11701
11702/* Used for 16-bit store instructions. */
11703static int mmreg2 (int r)
11704{
11705 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11706
11707 return map[r];
11708}
11709
11710#define uMIPS_RD(op) ((op >> 7) & 0x7)
11711#define uMIPS_RS(op) ((op >> 4) & 0x7)
11712#define uMIPS_RS2(op) uMIPS_RS(op)
11713#define uMIPS_RS1(op) ((op >> 1) & 0x7)
11714#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11715#define uMIPS_RS5(op) (op & 0x1f)
11716
11717/* Signed immediate */
11718#define SIMM(op, start, width) \
11719 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11720 << (32-width)) \
11721 >> (32-width))
11722/* Zero-extended immediate */
11723#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11724
d75c135e 11725static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
11726{
11727 int rd = mmreg(uMIPS_RD(ctx->opcode));
11728
d75c135e 11729 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
11730}
11731
d75c135e 11732static void gen_addiur2(DisasContext *ctx)
3c824109
NF
11733{
11734 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11735 int rd = mmreg(uMIPS_RD(ctx->opcode));
11736 int rs = mmreg(uMIPS_RS(ctx->opcode));
11737
d75c135e 11738 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
11739}
11740
d75c135e 11741static void gen_addiusp(DisasContext *ctx)
3c824109
NF
11742{
11743 int encoded = ZIMM(ctx->opcode, 1, 9);
11744 int decoded;
11745
11746 if (encoded <= 1) {
11747 decoded = 256 + encoded;
11748 } else if (encoded <= 255) {
11749 decoded = encoded;
11750 } else if (encoded <= 509) {
11751 decoded = encoded - 512;
11752 } else {
11753 decoded = encoded - 768;
11754 }
11755
d75c135e 11756 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
11757}
11758
d75c135e 11759static void gen_addius5(DisasContext *ctx)
3c824109
NF
11760{
11761 int imm = SIMM(ctx->opcode, 1, 4);
11762 int rd = (ctx->opcode >> 5) & 0x1f;
11763
d75c135e 11764 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
11765}
11766
d75c135e 11767static void gen_andi16(DisasContext *ctx)
3c824109
NF
11768{
11769 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11770 31, 32, 63, 64, 255, 32768, 65535 };
11771 int rd = mmreg(uMIPS_RD(ctx->opcode));
11772 int rs = mmreg(uMIPS_RS(ctx->opcode));
11773 int encoded = ZIMM(ctx->opcode, 0, 4);
11774
d75c135e 11775 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
11776}
11777
11778static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
11779 int base, int16_t offset)
11780{
e1050a76 11781 const char *opn = "ldst_multiple";
3c824109
NF
11782 TCGv t0, t1;
11783 TCGv_i32 t2;
11784
11785 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11786 generate_exception(ctx, EXCP_RI);
11787 return;
11788 }
11789
11790 t0 = tcg_temp_new();
11791
11792 gen_base_offset_addr(ctx, t0, base, offset);
11793
11794 t1 = tcg_const_tl(reglist);
11795 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 11796
3c824109
NF
11797 save_cpu_state(ctx, 1);
11798 switch (opc) {
11799 case LWM32:
895c2d04 11800 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 11801 opn = "lwm";
3c824109
NF
11802 break;
11803 case SWM32:
895c2d04 11804 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 11805 opn = "swm";
3c824109
NF
11806 break;
11807#ifdef TARGET_MIPS64
11808 case LDM:
895c2d04 11809 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 11810 opn = "ldm";
3c824109
NF
11811 break;
11812 case SDM:
895c2d04 11813 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 11814 opn = "sdm";
3c824109 11815 break;
6af0bf9c 11816#endif
3c824109 11817 }
e1050a76 11818 (void)opn;
3c824109
NF
11819 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
11820 tcg_temp_free(t0);
33087598 11821 tcg_temp_free(t1);
3c824109
NF
11822 tcg_temp_free_i32(t2);
11823}
6af0bf9c 11824
3c824109 11825
240ce26a 11826static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 11827{
3c824109
NF
11828 int rd = mmreg((ctx->opcode >> 3) & 0x7);
11829 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 11830
3c824109
NF
11831 switch (((ctx->opcode) >> 4) & 0x3f) {
11832 case NOT16 + 0:
11833 case NOT16 + 1:
11834 case NOT16 + 2:
11835 case NOT16 + 3:
d75c135e 11836 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
11837 break;
11838 case XOR16 + 0:
11839 case XOR16 + 1:
11840 case XOR16 + 2:
11841 case XOR16 + 3:
d75c135e 11842 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
11843 break;
11844 case AND16 + 0:
11845 case AND16 + 1:
11846 case AND16 + 2:
11847 case AND16 + 3:
d75c135e 11848 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
11849 break;
11850 case OR16 + 0:
11851 case OR16 + 1:
11852 case OR16 + 2:
11853 case OR16 + 3:
d75c135e 11854 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
11855 break;
11856 case LWM16 + 0:
11857 case LWM16 + 1:
11858 case LWM16 + 2:
11859 case LWM16 + 3:
11860 {
11861 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11862 int offset = ZIMM(ctx->opcode, 0, 4);
11863
11864 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
11865 29, offset << 2);
11866 }
11867 break;
11868 case SWM16 + 0:
11869 case SWM16 + 1:
11870 case SWM16 + 2:
11871 case SWM16 + 3:
11872 {
11873 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11874 int offset = ZIMM(ctx->opcode, 0, 4);
11875
11876 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
11877 29, offset << 2);
11878 }
11879 break;
11880 case JR16 + 0:
11881 case JR16 + 1:
11882 {
11883 int reg = ctx->opcode & 0x1f;
11884
b231c103 11885 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 11886 }
3c824109
NF
11887 break;
11888 case JRC16 + 0:
11889 case JRC16 + 1:
11890 {
11891 int reg = ctx->opcode & 0x1f;
b231c103 11892 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
11893 /* Let normal delay slot handling in our caller take us
11894 to the branch target. */
11895 }
11896 break;
11897 case JALR16 + 0:
11898 case JALR16 + 1:
b231c103
YK
11899 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
11900 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
11901 break;
3c824109
NF
11902 case JALR16S + 0:
11903 case JALR16S + 1:
b231c103
YK
11904 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
11905 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
11906 break;
11907 case MFHI16 + 0:
11908 case MFHI16 + 1:
26135ead 11909 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11910 break;
11911 case MFLO16 + 0:
11912 case MFLO16 + 1:
26135ead 11913 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11914 break;
11915 case BREAK16:
11916 generate_exception(ctx, EXCP_BREAK);
11917 break;
11918 case SDBBP16:
11919 /* XXX: not clear which exception should be raised
11920 * when in debug mode...
11921 */
d75c135e 11922 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11923 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11924 generate_exception(ctx, EXCP_DBp);
11925 } else {
11926 generate_exception(ctx, EXCP_DBp);
11927 }
11928 break;
11929 case JRADDIUSP + 0:
11930 case JRADDIUSP + 1:
11931 {
11932 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 11933 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 11934 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
11935 /* Let normal delay slot handling in our caller take us
11936 to the branch target. */
11937 }
11938 break;
11939 default:
11940 generate_exception(ctx, EXCP_RI);
11941 break;
11942 }
11943}
11944
11945static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
11946{
11947 TCGv t0 = tcg_temp_new();
11948 TCGv t1 = tcg_temp_new();
11949
11950 gen_load_gpr(t0, base);
11951
11952 if (index != 0) {
11953 gen_load_gpr(t1, index);
11954 tcg_gen_shli_tl(t1, t1, 2);
11955 gen_op_addr_add(ctx, t0, t1, t0);
11956 }
11957
5f68f5ae 11958 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11959 gen_store_gpr(t1, rd);
11960
11961 tcg_temp_free(t0);
11962 tcg_temp_free(t1);
11963}
11964
11965static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11966 int base, int16_t offset)
11967{
11968 const char *opn = "ldst_pair";
11969 TCGv t0, t1;
11970
36c6711b 11971 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 11972 generate_exception(ctx, EXCP_RI);
d796321b
FB
11973 return;
11974 }
11975
3c824109
NF
11976 t0 = tcg_temp_new();
11977 t1 = tcg_temp_new();
8e9ade68 11978
3c824109
NF
11979 gen_base_offset_addr(ctx, t0, base, offset);
11980
11981 switch (opc) {
11982 case LWP:
36c6711b
EJ
11983 if (rd == base) {
11984 generate_exception(ctx, EXCP_RI);
11985 return;
11986 }
5f68f5ae 11987 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11988 gen_store_gpr(t1, rd);
11989 tcg_gen_movi_tl(t1, 4);
11990 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11991 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11992 gen_store_gpr(t1, rd+1);
11993 opn = "lwp";
11994 break;
11995 case SWP:
3c824109 11996 gen_load_gpr(t1, rd);
5f68f5ae 11997 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11998 tcg_gen_movi_tl(t1, 4);
11999 gen_op_addr_add(ctx, t0, t0, t1);
12000 gen_load_gpr(t1, rd+1);
5f68f5ae 12001 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12002 opn = "swp";
12003 break;
12004#ifdef TARGET_MIPS64
12005 case LDP:
36c6711b
EJ
12006 if (rd == base) {
12007 generate_exception(ctx, EXCP_RI);
12008 return;
12009 }
5f68f5ae 12010 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12011 gen_store_gpr(t1, rd);
12012 tcg_gen_movi_tl(t1, 8);
12013 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12014 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12015 gen_store_gpr(t1, rd+1);
12016 opn = "ldp";
12017 break;
12018 case SDP:
3c824109 12019 gen_load_gpr(t1, rd);
5f68f5ae 12020 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12021 tcg_gen_movi_tl(t1, 8);
12022 gen_op_addr_add(ctx, t0, t0, t1);
12023 gen_load_gpr(t1, rd+1);
5f68f5ae 12024 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12025 opn = "sdp";
12026 break;
12027#endif
6af0bf9c 12028 }
2abf314d 12029 (void)opn; /* avoid a compiler warning */
3c824109
NF
12030 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12031 tcg_temp_free(t0);
12032 tcg_temp_free(t1);
12033}
618b0fe9 12034
240ce26a 12035static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12036{
12037 int extension = (ctx->opcode >> 6) & 0x3f;
12038 int minor = (ctx->opcode >> 12) & 0xf;
12039 uint32_t mips32_op;
12040
12041 switch (extension) {
12042 case TEQ:
12043 mips32_op = OPC_TEQ;
12044 goto do_trap;
12045 case TGE:
12046 mips32_op = OPC_TGE;
12047 goto do_trap;
12048 case TGEU:
12049 mips32_op = OPC_TGEU;
12050 goto do_trap;
12051 case TLT:
12052 mips32_op = OPC_TLT;
12053 goto do_trap;
12054 case TLTU:
12055 mips32_op = OPC_TLTU;
12056 goto do_trap;
12057 case TNE:
12058 mips32_op = OPC_TNE;
12059 do_trap:
12060 gen_trap(ctx, mips32_op, rs, rt, -1);
12061 break;
12062#ifndef CONFIG_USER_ONLY
12063 case MFC0:
12064 case MFC0 + 32:
2e15497c 12065 check_cp0_enabled(ctx);
3c824109
NF
12066 if (rt == 0) {
12067 /* Treat as NOP. */
12068 break;
12069 }
d75c135e 12070 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12071 break;
12072 case MTC0:
12073 case MTC0 + 32:
2e15497c 12074 check_cp0_enabled(ctx);
3c824109
NF
12075 {
12076 TCGv t0 = tcg_temp_new();
618b0fe9 12077
3c824109 12078 gen_load_gpr(t0, rt);
d75c135e 12079 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12080 tcg_temp_free(t0);
12081 }
12082 break;
12083#endif
a1fc6246
LA
12084 case 0x2a:
12085 switch (minor & 3) {
12086 case MADD_ACC:
12087 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12088 break;
12089 case MADDU_ACC:
12090 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12091 break;
12092 case MSUB_ACC:
12093 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12094 break;
12095 case MSUBU_ACC:
12096 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12097 break;
12098 default:
12099 goto pool32axf_invalid;
12100 }
12101 break;
12102 case 0x32:
12103 switch (minor & 3) {
12104 case MULT_ACC:
12105 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12106 break;
12107 case MULTU_ACC:
12108 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12109 break;
12110 default:
12111 goto pool32axf_invalid;
12112 }
12113 break;
3c824109
NF
12114 case 0x2c:
12115 switch (minor) {
12116 case SEB:
12117 gen_bshfl(ctx, OPC_SEB, rs, rt);
12118 break;
12119 case SEH:
12120 gen_bshfl(ctx, OPC_SEH, rs, rt);
12121 break;
12122 case CLO:
12123 mips32_op = OPC_CLO;
12124 goto do_cl;
12125 case CLZ:
12126 mips32_op = OPC_CLZ;
12127 do_cl:
d75c135e 12128 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12129 gen_cl(ctx, mips32_op, rt, rs);
12130 break;
12131 case RDHWR:
d75c135e 12132 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12133 break;
12134 case WSBH:
12135 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12136 break;
12137 case MULT:
12138 mips32_op = OPC_MULT;
26135ead 12139 goto do_mul;
3c824109
NF
12140 case MULTU:
12141 mips32_op = OPC_MULTU;
26135ead 12142 goto do_mul;
3c824109
NF
12143 case DIV:
12144 mips32_op = OPC_DIV;
26135ead 12145 goto do_div;
3c824109
NF
12146 case DIVU:
12147 mips32_op = OPC_DIVU;
26135ead
RS
12148 goto do_div;
12149 do_div:
12150 check_insn(ctx, ISA_MIPS32);
12151 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12152 break;
3c824109
NF
12153 case MADD:
12154 mips32_op = OPC_MADD;
26135ead 12155 goto do_mul;
3c824109
NF
12156 case MADDU:
12157 mips32_op = OPC_MADDU;
26135ead 12158 goto do_mul;
3c824109
NF
12159 case MSUB:
12160 mips32_op = OPC_MSUB;
26135ead 12161 goto do_mul;
3c824109
NF
12162 case MSUBU:
12163 mips32_op = OPC_MSUBU;
26135ead 12164 do_mul:
d75c135e 12165 check_insn(ctx, ISA_MIPS32);
a1fc6246 12166 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12167 break;
12168 default:
12169 goto pool32axf_invalid;
12170 }
12171 break;
12172 case 0x34:
12173 switch (minor) {
12174 case MFC2:
12175 case MTC2:
12176 case MFHC2:
12177 case MTHC2:
12178 case CFC2:
12179 case CTC2:
12180 generate_exception_err(ctx, EXCP_CpU, 2);
12181 break;
12182 default:
12183 goto pool32axf_invalid;
12184 }
12185 break;
12186 case 0x3c:
12187 switch (minor) {
12188 case JALR:
12189 case JALR_HB:
b231c103
YK
12190 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
12191 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12192 break;
12193 case JALRS:
12194 case JALRS_HB:
b231c103
YK
12195 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
12196 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
12197 break;
12198 default:
12199 goto pool32axf_invalid;
12200 }
12201 break;
12202 case 0x05:
12203 switch (minor) {
12204 case RDPGPR:
2e15497c 12205 check_cp0_enabled(ctx);
d75c135e 12206 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12207 gen_load_srsgpr(rt, rs);
12208 break;
12209 case WRPGPR:
2e15497c 12210 check_cp0_enabled(ctx);
d75c135e 12211 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12212 gen_store_srsgpr(rt, rs);
12213 break;
12214 default:
12215 goto pool32axf_invalid;
12216 }
12217 break;
12218#ifndef CONFIG_USER_ONLY
12219 case 0x0d:
12220 switch (minor) {
12221 case TLBP:
12222 mips32_op = OPC_TLBP;
12223 goto do_cp0;
12224 case TLBR:
12225 mips32_op = OPC_TLBR;
12226 goto do_cp0;
12227 case TLBWI:
12228 mips32_op = OPC_TLBWI;
12229 goto do_cp0;
12230 case TLBWR:
12231 mips32_op = OPC_TLBWR;
12232 goto do_cp0;
12233 case WAIT:
12234 mips32_op = OPC_WAIT;
12235 goto do_cp0;
12236 case DERET:
12237 mips32_op = OPC_DERET;
12238 goto do_cp0;
12239 case ERET:
12240 mips32_op = OPC_ERET;
12241 do_cp0:
12242 gen_cp0(env, ctx, mips32_op, rt, rs);
12243 break;
12244 default:
12245 goto pool32axf_invalid;
12246 }
12247 break;
12248 case 0x1d:
12249 switch (minor) {
12250 case DI:
2e15497c 12251 check_cp0_enabled(ctx);
3c824109
NF
12252 {
12253 TCGv t0 = tcg_temp_new();
12254
12255 save_cpu_state(ctx, 1);
895c2d04 12256 gen_helper_di(t0, cpu_env);
3c824109
NF
12257 gen_store_gpr(t0, rs);
12258 /* Stop translation as we may have switched the execution mode */
12259 ctx->bstate = BS_STOP;
12260 tcg_temp_free(t0);
12261 }
12262 break;
12263 case EI:
2e15497c 12264 check_cp0_enabled(ctx);
3c824109
NF
12265 {
12266 TCGv t0 = tcg_temp_new();
12267
12268 save_cpu_state(ctx, 1);
895c2d04 12269 gen_helper_ei(t0, cpu_env);
3c824109
NF
12270 gen_store_gpr(t0, rs);
12271 /* Stop translation as we may have switched the execution mode */
12272 ctx->bstate = BS_STOP;
12273 tcg_temp_free(t0);
12274 }
12275 break;
12276 default:
12277 goto pool32axf_invalid;
12278 }
12279 break;
12280#endif
12281 case 0x2d:
12282 switch (minor) {
12283 case SYNC:
12284 /* NOP */
12285 break;
12286 case SYSCALL:
12287 generate_exception(ctx, EXCP_SYSCALL);
12288 ctx->bstate = BS_STOP;
12289 break;
12290 case SDBBP:
d75c135e 12291 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12292 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12293 generate_exception(ctx, EXCP_DBp);
12294 } else {
12295 generate_exception(ctx, EXCP_DBp);
12296 }
12297 break;
12298 default:
12299 goto pool32axf_invalid;
12300 }
12301 break;
a1fc6246 12302 case 0x01:
26135ead 12303 switch (minor & 3) {
a1fc6246 12304 case MFHI_ACC:
26135ead 12305 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12306 break;
a1fc6246 12307 case MFLO_ACC:
26135ead 12308 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12309 break;
a1fc6246 12310 case MTHI_ACC:
26135ead 12311 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12312 break;
a1fc6246 12313 case MTLO_ACC:
26135ead 12314 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12315 break;
12316 default:
12317 goto pool32axf_invalid;
12318 }
12319 break;
a1fc6246
LA
12320 case 0x35:
12321 switch (minor) {
12322 case MFHI32:
12323 gen_HILO(ctx, OPC_MFHI, 0, rs);
12324 break;
12325 case MFLO32:
12326 gen_HILO(ctx, OPC_MFLO, 0, rs);
12327 break;
12328 case MTHI32:
12329 gen_HILO(ctx, OPC_MTHI, 0, rs);
12330 break;
12331 case MTLO32:
12332 gen_HILO(ctx, OPC_MTLO, 0, rs);
12333 break;
12334 default:
12335 goto pool32axf_invalid;
12336 }
12337 break;
3c824109
NF
12338 default:
12339 pool32axf_invalid:
12340 MIPS_INVAL("pool32axf");
12341 generate_exception(ctx, EXCP_RI);
12342 break;
12343 }
12344}
12345
12346/* Values for microMIPS fmt field. Variable-width, depending on which
12347 formats the instruction supports. */
12348
12349enum {
12350 FMT_SD_S = 0,
12351 FMT_SD_D = 1,
12352
12353 FMT_SDPS_S = 0,
12354 FMT_SDPS_D = 1,
12355 FMT_SDPS_PS = 2,
12356
12357 FMT_SWL_S = 0,
12358 FMT_SWL_W = 1,
12359 FMT_SWL_L = 2,
12360
12361 FMT_DWL_D = 0,
12362 FMT_DWL_W = 1,
12363 FMT_DWL_L = 2
12364};
12365
d75c135e 12366static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12367{
12368 int extension = (ctx->opcode >> 6) & 0x3ff;
12369 uint32_t mips32_op;
12370
12371#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12372#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12373#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12374
12375 switch (extension) {
12376 case FLOAT_1BIT_FMT(CFC1, 0):
12377 mips32_op = OPC_CFC1;
12378 goto do_cp1;
12379 case FLOAT_1BIT_FMT(CTC1, 0):
12380 mips32_op = OPC_CTC1;
12381 goto do_cp1;
12382 case FLOAT_1BIT_FMT(MFC1, 0):
12383 mips32_op = OPC_MFC1;
12384 goto do_cp1;
12385 case FLOAT_1BIT_FMT(MTC1, 0):
12386 mips32_op = OPC_MTC1;
12387 goto do_cp1;
12388 case FLOAT_1BIT_FMT(MFHC1, 0):
12389 mips32_op = OPC_MFHC1;
12390 goto do_cp1;
12391 case FLOAT_1BIT_FMT(MTHC1, 0):
12392 mips32_op = OPC_MTHC1;
12393 do_cp1:
12394 gen_cp1(ctx, mips32_op, rt, rs);
12395 break;
12396
12397 /* Reciprocal square root */
12398 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12399 mips32_op = OPC_RSQRT_S;
12400 goto do_unaryfp;
12401 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12402 mips32_op = OPC_RSQRT_D;
12403 goto do_unaryfp;
12404
12405 /* Square root */
12406 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12407 mips32_op = OPC_SQRT_S;
12408 goto do_unaryfp;
12409 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12410 mips32_op = OPC_SQRT_D;
12411 goto do_unaryfp;
12412
12413 /* Reciprocal */
12414 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12415 mips32_op = OPC_RECIP_S;
12416 goto do_unaryfp;
12417 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12418 mips32_op = OPC_RECIP_D;
12419 goto do_unaryfp;
12420
12421 /* Floor */
12422 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12423 mips32_op = OPC_FLOOR_L_S;
12424 goto do_unaryfp;
12425 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12426 mips32_op = OPC_FLOOR_L_D;
12427 goto do_unaryfp;
12428 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12429 mips32_op = OPC_FLOOR_W_S;
12430 goto do_unaryfp;
12431 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12432 mips32_op = OPC_FLOOR_W_D;
12433 goto do_unaryfp;
12434
12435 /* Ceiling */
12436 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12437 mips32_op = OPC_CEIL_L_S;
12438 goto do_unaryfp;
12439 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12440 mips32_op = OPC_CEIL_L_D;
12441 goto do_unaryfp;
12442 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12443 mips32_op = OPC_CEIL_W_S;
12444 goto do_unaryfp;
12445 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12446 mips32_op = OPC_CEIL_W_D;
12447 goto do_unaryfp;
12448
12449 /* Truncation */
12450 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12451 mips32_op = OPC_TRUNC_L_S;
12452 goto do_unaryfp;
12453 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12454 mips32_op = OPC_TRUNC_L_D;
12455 goto do_unaryfp;
12456 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12457 mips32_op = OPC_TRUNC_W_S;
12458 goto do_unaryfp;
12459 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12460 mips32_op = OPC_TRUNC_W_D;
12461 goto do_unaryfp;
12462
12463 /* Round */
12464 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12465 mips32_op = OPC_ROUND_L_S;
12466 goto do_unaryfp;
12467 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12468 mips32_op = OPC_ROUND_L_D;
12469 goto do_unaryfp;
12470 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12471 mips32_op = OPC_ROUND_W_S;
12472 goto do_unaryfp;
12473 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12474 mips32_op = OPC_ROUND_W_D;
12475 goto do_unaryfp;
12476
12477 /* Integer to floating-point conversion */
12478 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12479 mips32_op = OPC_CVT_L_S;
12480 goto do_unaryfp;
12481 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12482 mips32_op = OPC_CVT_L_D;
12483 goto do_unaryfp;
12484 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
12485 mips32_op = OPC_CVT_W_S;
12486 goto do_unaryfp;
12487 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
12488 mips32_op = OPC_CVT_W_D;
12489 goto do_unaryfp;
12490
12491 /* Paired-foo conversions */
12492 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
12493 mips32_op = OPC_CVT_S_PL;
12494 goto do_unaryfp;
12495 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
12496 mips32_op = OPC_CVT_S_PU;
12497 goto do_unaryfp;
12498 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
12499 mips32_op = OPC_CVT_PW_PS;
12500 goto do_unaryfp;
12501 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
12502 mips32_op = OPC_CVT_PS_PW;
12503 goto do_unaryfp;
12504
12505 /* Floating-point moves */
12506 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
12507 mips32_op = OPC_MOV_S;
12508 goto do_unaryfp;
12509 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
12510 mips32_op = OPC_MOV_D;
12511 goto do_unaryfp;
12512 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
12513 mips32_op = OPC_MOV_PS;
12514 goto do_unaryfp;
12515
12516 /* Absolute value */
12517 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
12518 mips32_op = OPC_ABS_S;
12519 goto do_unaryfp;
12520 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
12521 mips32_op = OPC_ABS_D;
12522 goto do_unaryfp;
12523 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
12524 mips32_op = OPC_ABS_PS;
12525 goto do_unaryfp;
12526
12527 /* Negation */
12528 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
12529 mips32_op = OPC_NEG_S;
12530 goto do_unaryfp;
12531 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
12532 mips32_op = OPC_NEG_D;
12533 goto do_unaryfp;
12534 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
12535 mips32_op = OPC_NEG_PS;
12536 goto do_unaryfp;
12537
12538 /* Reciprocal square root step */
12539 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
12540 mips32_op = OPC_RSQRT1_S;
12541 goto do_unaryfp;
12542 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
12543 mips32_op = OPC_RSQRT1_D;
12544 goto do_unaryfp;
12545 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
12546 mips32_op = OPC_RSQRT1_PS;
12547 goto do_unaryfp;
12548
12549 /* Reciprocal step */
12550 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
12551 mips32_op = OPC_RECIP1_S;
12552 goto do_unaryfp;
12553 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
12554 mips32_op = OPC_RECIP1_S;
12555 goto do_unaryfp;
12556 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
12557 mips32_op = OPC_RECIP1_PS;
12558 goto do_unaryfp;
12559
12560 /* Conversions from double */
12561 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
12562 mips32_op = OPC_CVT_D_S;
12563 goto do_unaryfp;
12564 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
12565 mips32_op = OPC_CVT_D_W;
12566 goto do_unaryfp;
12567 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
12568 mips32_op = OPC_CVT_D_L;
12569 goto do_unaryfp;
12570
12571 /* Conversions from single */
12572 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
12573 mips32_op = OPC_CVT_S_D;
12574 goto do_unaryfp;
12575 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
12576 mips32_op = OPC_CVT_S_W;
12577 goto do_unaryfp;
12578 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
12579 mips32_op = OPC_CVT_S_L;
12580 do_unaryfp:
12581 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
12582 break;
12583
12584 /* Conditional moves on floating-point codes */
12585 case COND_FLOAT_MOV(MOVT, 0):
12586 case COND_FLOAT_MOV(MOVT, 1):
12587 case COND_FLOAT_MOV(MOVT, 2):
12588 case COND_FLOAT_MOV(MOVT, 3):
12589 case COND_FLOAT_MOV(MOVT, 4):
12590 case COND_FLOAT_MOV(MOVT, 5):
12591 case COND_FLOAT_MOV(MOVT, 6):
12592 case COND_FLOAT_MOV(MOVT, 7):
12593 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
12594 break;
12595 case COND_FLOAT_MOV(MOVF, 0):
12596 case COND_FLOAT_MOV(MOVF, 1):
12597 case COND_FLOAT_MOV(MOVF, 2):
12598 case COND_FLOAT_MOV(MOVF, 3):
12599 case COND_FLOAT_MOV(MOVF, 4):
12600 case COND_FLOAT_MOV(MOVF, 5):
12601 case COND_FLOAT_MOV(MOVF, 6):
12602 case COND_FLOAT_MOV(MOVF, 7):
12603 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
12604 break;
12605 default:
12606 MIPS_INVAL("pool32fxf");
12607 generate_exception(ctx, EXCP_RI);
12608 break;
12609 }
12610}
12611
7db13fae 12612static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 12613 uint16_t insn_hw1)
3c824109
NF
12614{
12615 int32_t offset;
12616 uint16_t insn;
12617 int rt, rs, rd, rr;
12618 int16_t imm;
12619 uint32_t op, minor, mips32_op;
12620 uint32_t cond, fmt, cc;
12621
895c2d04 12622 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
12623 ctx->opcode = (ctx->opcode << 16) | insn;
12624
12625 rt = (ctx->opcode >> 21) & 0x1f;
12626 rs = (ctx->opcode >> 16) & 0x1f;
12627 rd = (ctx->opcode >> 11) & 0x1f;
12628 rr = (ctx->opcode >> 6) & 0x1f;
12629 imm = (int16_t) ctx->opcode;
12630
12631 op = (ctx->opcode >> 26) & 0x3f;
12632 switch (op) {
12633 case POOL32A:
12634 minor = ctx->opcode & 0x3f;
12635 switch (minor) {
12636 case 0x00:
12637 minor = (ctx->opcode >> 6) & 0xf;
12638 switch (minor) {
12639 case SLL32:
12640 mips32_op = OPC_SLL;
12641 goto do_shifti;
12642 case SRA:
12643 mips32_op = OPC_SRA;
12644 goto do_shifti;
12645 case SRL32:
12646 mips32_op = OPC_SRL;
12647 goto do_shifti;
12648 case ROTR:
12649 mips32_op = OPC_ROTR;
12650 do_shifti:
d75c135e 12651 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
12652 break;
12653 default:
12654 goto pool32a_invalid;
12655 }
12656 break;
12657 case 0x10:
12658 minor = (ctx->opcode >> 6) & 0xf;
12659 switch (minor) {
12660 /* Arithmetic */
12661 case ADD:
12662 mips32_op = OPC_ADD;
12663 goto do_arith;
12664 case ADDU32:
12665 mips32_op = OPC_ADDU;
12666 goto do_arith;
12667 case SUB:
12668 mips32_op = OPC_SUB;
12669 goto do_arith;
12670 case SUBU32:
12671 mips32_op = OPC_SUBU;
12672 goto do_arith;
12673 case MUL:
12674 mips32_op = OPC_MUL;
12675 do_arith:
d75c135e 12676 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12677 break;
12678 /* Shifts */
12679 case SLLV:
12680 mips32_op = OPC_SLLV;
12681 goto do_shift;
12682 case SRLV:
12683 mips32_op = OPC_SRLV;
12684 goto do_shift;
12685 case SRAV:
12686 mips32_op = OPC_SRAV;
12687 goto do_shift;
12688 case ROTRV:
12689 mips32_op = OPC_ROTRV;
12690 do_shift:
d75c135e 12691 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12692 break;
12693 /* Logical operations */
12694 case AND:
12695 mips32_op = OPC_AND;
12696 goto do_logic;
12697 case OR32:
12698 mips32_op = OPC_OR;
12699 goto do_logic;
12700 case NOR:
12701 mips32_op = OPC_NOR;
12702 goto do_logic;
12703 case XOR32:
12704 mips32_op = OPC_XOR;
12705 do_logic:
d75c135e 12706 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12707 break;
12708 /* Set less than */
12709 case SLT:
12710 mips32_op = OPC_SLT;
12711 goto do_slt;
12712 case SLTU:
12713 mips32_op = OPC_SLTU;
12714 do_slt:
d75c135e 12715 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12716 break;
12717 default:
12718 goto pool32a_invalid;
12719 }
12720 break;
12721 case 0x18:
12722 minor = (ctx->opcode >> 6) & 0xf;
12723 switch (minor) {
12724 /* Conditional moves */
12725 case MOVN:
12726 mips32_op = OPC_MOVN;
12727 goto do_cmov;
12728 case MOVZ:
12729 mips32_op = OPC_MOVZ;
12730 do_cmov:
d75c135e 12731 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12732 break;
12733 case LWXS:
12734 gen_ldxs(ctx, rs, rt, rd);
12735 break;
12736 default:
12737 goto pool32a_invalid;
12738 }
12739 break;
12740 case INS:
12741 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
12742 return;
12743 case EXT:
12744 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
12745 return;
12746 case POOL32AXF:
240ce26a 12747 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
12748 break;
12749 case 0x07:
12750 generate_exception(ctx, EXCP_BREAK);
12751 break;
12752 default:
12753 pool32a_invalid:
12754 MIPS_INVAL("pool32a");
12755 generate_exception(ctx, EXCP_RI);
12756 break;
12757 }
12758 break;
12759 case POOL32B:
12760 minor = (ctx->opcode >> 12) & 0xf;
12761 switch (minor) {
12762 case CACHE:
2e15497c 12763 check_cp0_enabled(ctx);
3c824109
NF
12764 /* Treat as no-op. */
12765 break;
12766 case LWC2:
12767 case SWC2:
12768 /* COP2: Not implemented. */
12769 generate_exception_err(ctx, EXCP_CpU, 2);
12770 break;
12771 case LWP:
12772 case SWP:
12773#ifdef TARGET_MIPS64
12774 case LDP:
12775 case SDP:
12776#endif
12777 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12778 break;
12779 case LWM32:
12780 case SWM32:
12781#ifdef TARGET_MIPS64
12782 case LDM:
12783 case SDM:
12784#endif
12785 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12786 break;
12787 default:
12788 MIPS_INVAL("pool32b");
12789 generate_exception(ctx, EXCP_RI);
12790 break;
12791 }
12792 break;
12793 case POOL32F:
5ab5c041 12794 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
12795 minor = ctx->opcode & 0x3f;
12796 check_cp1_enabled(ctx);
12797 switch (minor) {
12798 case ALNV_PS:
12799 mips32_op = OPC_ALNV_PS;
12800 goto do_madd;
12801 case MADD_S:
12802 mips32_op = OPC_MADD_S;
12803 goto do_madd;
12804 case MADD_D:
12805 mips32_op = OPC_MADD_D;
12806 goto do_madd;
12807 case MADD_PS:
12808 mips32_op = OPC_MADD_PS;
12809 goto do_madd;
12810 case MSUB_S:
12811 mips32_op = OPC_MSUB_S;
12812 goto do_madd;
12813 case MSUB_D:
12814 mips32_op = OPC_MSUB_D;
12815 goto do_madd;
12816 case MSUB_PS:
12817 mips32_op = OPC_MSUB_PS;
12818 goto do_madd;
12819 case NMADD_S:
12820 mips32_op = OPC_NMADD_S;
12821 goto do_madd;
12822 case NMADD_D:
12823 mips32_op = OPC_NMADD_D;
12824 goto do_madd;
12825 case NMADD_PS:
12826 mips32_op = OPC_NMADD_PS;
12827 goto do_madd;
12828 case NMSUB_S:
12829 mips32_op = OPC_NMSUB_S;
12830 goto do_madd;
12831 case NMSUB_D:
12832 mips32_op = OPC_NMSUB_D;
12833 goto do_madd;
12834 case NMSUB_PS:
12835 mips32_op = OPC_NMSUB_PS;
12836 do_madd:
12837 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
12838 break;
12839 case CABS_COND_FMT:
12840 cond = (ctx->opcode >> 6) & 0xf;
12841 cc = (ctx->opcode >> 13) & 0x7;
12842 fmt = (ctx->opcode >> 10) & 0x3;
12843 switch (fmt) {
12844 case 0x0:
12845 gen_cmpabs_s(ctx, cond, rt, rs, cc);
12846 break;
12847 case 0x1:
12848 gen_cmpabs_d(ctx, cond, rt, rs, cc);
12849 break;
12850 case 0x2:
12851 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
12852 break;
12853 default:
12854 goto pool32f_invalid;
12855 }
12856 break;
12857 case C_COND_FMT:
12858 cond = (ctx->opcode >> 6) & 0xf;
12859 cc = (ctx->opcode >> 13) & 0x7;
12860 fmt = (ctx->opcode >> 10) & 0x3;
12861 switch (fmt) {
12862 case 0x0:
12863 gen_cmp_s(ctx, cond, rt, rs, cc);
12864 break;
12865 case 0x1:
12866 gen_cmp_d(ctx, cond, rt, rs, cc);
12867 break;
12868 case 0x2:
12869 gen_cmp_ps(ctx, cond, rt, rs, cc);
12870 break;
12871 default:
12872 goto pool32f_invalid;
12873 }
12874 break;
12875 case POOL32FXF:
d75c135e 12876 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
12877 break;
12878 case 0x00:
12879 /* PLL foo */
12880 switch ((ctx->opcode >> 6) & 0x7) {
12881 case PLL_PS:
12882 mips32_op = OPC_PLL_PS;
12883 goto do_ps;
12884 case PLU_PS:
12885 mips32_op = OPC_PLU_PS;
12886 goto do_ps;
12887 case PUL_PS:
12888 mips32_op = OPC_PUL_PS;
12889 goto do_ps;
12890 case PUU_PS:
12891 mips32_op = OPC_PUU_PS;
12892 goto do_ps;
12893 case CVT_PS_S:
12894 mips32_op = OPC_CVT_PS_S;
12895 do_ps:
12896 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12897 break;
12898 default:
12899 goto pool32f_invalid;
12900 }
12901 break;
12902 case 0x08:
12903 /* [LS][WDU]XC1 */
12904 switch ((ctx->opcode >> 6) & 0x7) {
12905 case LWXC1:
12906 mips32_op = OPC_LWXC1;
12907 goto do_ldst_cp1;
12908 case SWXC1:
12909 mips32_op = OPC_SWXC1;
12910 goto do_ldst_cp1;
12911 case LDXC1:
12912 mips32_op = OPC_LDXC1;
12913 goto do_ldst_cp1;
12914 case SDXC1:
12915 mips32_op = OPC_SDXC1;
12916 goto do_ldst_cp1;
12917 case LUXC1:
12918 mips32_op = OPC_LUXC1;
12919 goto do_ldst_cp1;
12920 case SUXC1:
12921 mips32_op = OPC_SUXC1;
12922 do_ldst_cp1:
12923 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
12924 break;
12925 default:
12926 goto pool32f_invalid;
12927 }
12928 break;
12929 case 0x18:
12930 /* 3D insns */
12931 fmt = (ctx->opcode >> 9) & 0x3;
12932 switch ((ctx->opcode >> 6) & 0x7) {
12933 case RSQRT2_FMT:
12934 switch (fmt) {
12935 case FMT_SDPS_S:
12936 mips32_op = OPC_RSQRT2_S;
12937 goto do_3d;
12938 case FMT_SDPS_D:
12939 mips32_op = OPC_RSQRT2_D;
12940 goto do_3d;
12941 case FMT_SDPS_PS:
12942 mips32_op = OPC_RSQRT2_PS;
12943 goto do_3d;
12944 default:
12945 goto pool32f_invalid;
12946 }
12947 break;
12948 case RECIP2_FMT:
12949 switch (fmt) {
12950 case FMT_SDPS_S:
12951 mips32_op = OPC_RECIP2_S;
12952 goto do_3d;
12953 case FMT_SDPS_D:
12954 mips32_op = OPC_RECIP2_D;
12955 goto do_3d;
12956 case FMT_SDPS_PS:
12957 mips32_op = OPC_RECIP2_PS;
12958 goto do_3d;
12959 default:
12960 goto pool32f_invalid;
12961 }
12962 break;
12963 case ADDR_PS:
12964 mips32_op = OPC_ADDR_PS;
12965 goto do_3d;
12966 case MULR_PS:
12967 mips32_op = OPC_MULR_PS;
12968 do_3d:
12969 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12970 break;
12971 default:
12972 goto pool32f_invalid;
12973 }
12974 break;
12975 case 0x20:
12976 /* MOV[FT].fmt and PREFX */
12977 cc = (ctx->opcode >> 13) & 0x7;
12978 fmt = (ctx->opcode >> 9) & 0x3;
12979 switch ((ctx->opcode >> 6) & 0x7) {
12980 case MOVF_FMT:
12981 switch (fmt) {
12982 case FMT_SDPS_S:
12983 gen_movcf_s(rs, rt, cc, 0);
12984 break;
12985 case FMT_SDPS_D:
12986 gen_movcf_d(ctx, rs, rt, cc, 0);
12987 break;
12988 case FMT_SDPS_PS:
7f6613ce 12989 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
12990 break;
12991 default:
12992 goto pool32f_invalid;
12993 }
12994 break;
12995 case MOVT_FMT:
12996 switch (fmt) {
12997 case FMT_SDPS_S:
12998 gen_movcf_s(rs, rt, cc, 1);
12999 break;
13000 case FMT_SDPS_D:
13001 gen_movcf_d(ctx, rs, rt, cc, 1);
13002 break;
13003 case FMT_SDPS_PS:
7f6613ce 13004 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13005 break;
13006 default:
13007 goto pool32f_invalid;
13008 }
13009 break;
13010 case PREFX:
13011 break;
13012 default:
13013 goto pool32f_invalid;
13014 }
13015 break;
13016#define FINSN_3ARG_SDPS(prfx) \
13017 switch ((ctx->opcode >> 8) & 0x3) { \
13018 case FMT_SDPS_S: \
13019 mips32_op = OPC_##prfx##_S; \
13020 goto do_fpop; \
13021 case FMT_SDPS_D: \
13022 mips32_op = OPC_##prfx##_D; \
13023 goto do_fpop; \
13024 case FMT_SDPS_PS: \
13025 mips32_op = OPC_##prfx##_PS; \
13026 goto do_fpop; \
13027 default: \
13028 goto pool32f_invalid; \
13029 }
13030 case 0x30:
13031 /* regular FP ops */
13032 switch ((ctx->opcode >> 6) & 0x3) {
13033 case ADD_FMT:
13034 FINSN_3ARG_SDPS(ADD);
13035 break;
13036 case SUB_FMT:
13037 FINSN_3ARG_SDPS(SUB);
13038 break;
13039 case MUL_FMT:
13040 FINSN_3ARG_SDPS(MUL);
13041 break;
13042 case DIV_FMT:
13043 fmt = (ctx->opcode >> 8) & 0x3;
13044 if (fmt == 1) {
13045 mips32_op = OPC_DIV_D;
13046 } else if (fmt == 0) {
13047 mips32_op = OPC_DIV_S;
13048 } else {
13049 goto pool32f_invalid;
13050 }
13051 goto do_fpop;
13052 default:
13053 goto pool32f_invalid;
13054 }
13055 break;
13056 case 0x38:
13057 /* cmovs */
13058 switch ((ctx->opcode >> 6) & 0x3) {
13059 case MOVN_FMT:
13060 FINSN_3ARG_SDPS(MOVN);
13061 break;
13062 case MOVZ_FMT:
13063 FINSN_3ARG_SDPS(MOVZ);
13064 break;
13065 default:
13066 goto pool32f_invalid;
13067 }
13068 break;
13069 do_fpop:
13070 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13071 break;
13072 default:
13073 pool32f_invalid:
13074 MIPS_INVAL("pool32f");
13075 generate_exception(ctx, EXCP_RI);
13076 break;
13077 }
13078 } else {
13079 generate_exception_err(ctx, EXCP_CpU, 1);
13080 }
13081 break;
13082 case POOL32I:
13083 minor = (ctx->opcode >> 21) & 0x1f;
13084 switch (minor) {
13085 case BLTZ:
b231c103
YK
13086 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
13087 break;
3c824109 13088 case BLTZAL:
b231c103
YK
13089 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
13090 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13091 break;
3c824109 13092 case BLTZALS:
b231c103
YK
13093 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
13094 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13095 break;
3c824109 13096 case BGEZ:
b231c103
YK
13097 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
13098 break;
3c824109 13099 case BGEZAL:
b231c103
YK
13100 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
13101 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13102 break;
3c824109 13103 case BGEZALS:
b231c103
YK
13104 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
13105 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13106 break;
3c824109 13107 case BLEZ:
b231c103
YK
13108 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
13109 break;
3c824109 13110 case BGTZ:
b231c103 13111 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
13112 break;
13113
13114 /* Traps */
13115 case TLTI:
13116 mips32_op = OPC_TLTI;
13117 goto do_trapi;
13118 case TGEI:
13119 mips32_op = OPC_TGEI;
13120 goto do_trapi;
13121 case TLTIU:
13122 mips32_op = OPC_TLTIU;
13123 goto do_trapi;
13124 case TGEIU:
13125 mips32_op = OPC_TGEIU;
13126 goto do_trapi;
13127 case TNEI:
13128 mips32_op = OPC_TNEI;
13129 goto do_trapi;
13130 case TEQI:
13131 mips32_op = OPC_TEQI;
13132 do_trapi:
13133 gen_trap(ctx, mips32_op, rs, -1, imm);
13134 break;
13135
13136 case BNEZC:
13137 case BEQZC:
13138 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 13139 4, rs, 0, imm << 1, 0);
3c824109
NF
13140 /* Compact branches don't have a delay slot, so just let
13141 the normal delay slot handling take us to the branch
13142 target. */
13143 break;
13144 case LUI:
d75c135e 13145 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
13146 break;
13147 case SYNCI:
a83bddd6
DZ
13148 /* Break the TB to be able to sync copied instructions
13149 immediately */
13150 ctx->bstate = BS_STOP;
3c824109
NF
13151 break;
13152 case BC2F:
13153 case BC2T:
13154 /* COP2: Not implemented. */
13155 generate_exception_err(ctx, EXCP_CpU, 2);
13156 break;
13157 case BC1F:
13158 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13159 goto do_cp1branch;
13160 case BC1T:
13161 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13162 goto do_cp1branch;
13163 case BC1ANY4F:
13164 mips32_op = OPC_BC1FANY4;
13165 goto do_cp1mips3d;
13166 case BC1ANY4T:
13167 mips32_op = OPC_BC1TANY4;
13168 do_cp1mips3d:
13169 check_cop1x(ctx);
d75c135e 13170 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13171 /* Fall through */
13172 do_cp1branch:
d75c135e 13173 gen_compute_branch1(ctx, mips32_op,
3c824109 13174 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
13175 break;
13176 case BPOSGE64:
13177 case BPOSGE32:
13178 /* MIPS DSP: not implemented */
13179 /* Fall through */
13180 default:
13181 MIPS_INVAL("pool32i");
13182 generate_exception(ctx, EXCP_RI);
13183 break;
13184 }
13185 break;
13186 case POOL32C:
13187 minor = (ctx->opcode >> 12) & 0xf;
13188 switch (minor) {
13189 case LWL:
13190 mips32_op = OPC_LWL;
5c13fdfd 13191 goto do_ld_lr;
3c824109
NF
13192 case SWL:
13193 mips32_op = OPC_SWL;
5c13fdfd 13194 goto do_st_lr;
3c824109
NF
13195 case LWR:
13196 mips32_op = OPC_LWR;
5c13fdfd 13197 goto do_ld_lr;
3c824109
NF
13198 case SWR:
13199 mips32_op = OPC_SWR;
5c13fdfd 13200 goto do_st_lr;
3c824109
NF
13201#if defined(TARGET_MIPS64)
13202 case LDL:
13203 mips32_op = OPC_LDL;
5c13fdfd 13204 goto do_ld_lr;
3c824109
NF
13205 case SDL:
13206 mips32_op = OPC_SDL;
5c13fdfd 13207 goto do_st_lr;
3c824109
NF
13208 case LDR:
13209 mips32_op = OPC_LDR;
5c13fdfd 13210 goto do_ld_lr;
3c824109
NF
13211 case SDR:
13212 mips32_op = OPC_SDR;
5c13fdfd 13213 goto do_st_lr;
3c824109
NF
13214 case LWU:
13215 mips32_op = OPC_LWU;
5c13fdfd 13216 goto do_ld_lr;
3c824109
NF
13217 case LLD:
13218 mips32_op = OPC_LLD;
5c13fdfd 13219 goto do_ld_lr;
3c824109
NF
13220#endif
13221 case LL:
13222 mips32_op = OPC_LL;
5c13fdfd
AJ
13223 goto do_ld_lr;
13224 do_ld_lr:
d75c135e 13225 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13226 break;
13227 do_st_lr:
13228 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13229 break;
13230 case SC:
13231 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13232 break;
13233#if defined(TARGET_MIPS64)
13234 case SCD:
13235 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13236 break;
13237#endif
13238 case PREF:
13239 /* Treat as no-op */
13240 break;
13241 default:
13242 MIPS_INVAL("pool32c");
13243 generate_exception(ctx, EXCP_RI);
13244 break;
13245 }
13246 break;
13247 case ADDI32:
13248 mips32_op = OPC_ADDI;
13249 goto do_addi;
13250 case ADDIU32:
13251 mips32_op = OPC_ADDIU;
13252 do_addi:
d75c135e 13253 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13254 break;
13255
13256 /* Logical operations */
13257 case ORI32:
13258 mips32_op = OPC_ORI;
13259 goto do_logici;
13260 case XORI32:
13261 mips32_op = OPC_XORI;
13262 goto do_logici;
13263 case ANDI32:
13264 mips32_op = OPC_ANDI;
13265 do_logici:
d75c135e 13266 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13267 break;
13268
13269 /* Set less than immediate */
13270 case SLTI32:
13271 mips32_op = OPC_SLTI;
13272 goto do_slti;
13273 case SLTIU32:
13274 mips32_op = OPC_SLTIU;
13275 do_slti:
d75c135e 13276 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13277 break;
13278 case JALX32:
13279 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
13280 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
13281 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13282 break;
13283 case JALS32:
13284 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
b231c103
YK
13285 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
13286 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13287 break;
13288 case BEQ32:
b231c103 13289 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
3c824109
NF
13290 break;
13291 case BNE32:
b231c103 13292 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
3c824109
NF
13293 break;
13294 case J32:
13295 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
b231c103 13296 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
3c824109
NF
13297 break;
13298 case JAL32:
13299 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
b231c103
YK
13300 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
13301 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13302 break;
13303 /* Floating point (COP1) */
13304 case LWC132:
13305 mips32_op = OPC_LWC1;
13306 goto do_cop1;
13307 case LDC132:
13308 mips32_op = OPC_LDC1;
13309 goto do_cop1;
13310 case SWC132:
13311 mips32_op = OPC_SWC1;
13312 goto do_cop1;
13313 case SDC132:
13314 mips32_op = OPC_SDC1;
13315 do_cop1:
5ab5c041 13316 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13317 break;
13318 case ADDIUPC:
13319 {
13320 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13321 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13322
13323 gen_addiupc(ctx, reg, offset, 0, 0);
13324 }
13325 break;
13326 /* Loads and stores */
13327 case LB32:
13328 mips32_op = OPC_LB;
5c13fdfd 13329 goto do_ld;
3c824109
NF
13330 case LBU32:
13331 mips32_op = OPC_LBU;
5c13fdfd 13332 goto do_ld;
3c824109
NF
13333 case LH32:
13334 mips32_op = OPC_LH;
5c13fdfd 13335 goto do_ld;
3c824109
NF
13336 case LHU32:
13337 mips32_op = OPC_LHU;
5c13fdfd 13338 goto do_ld;
3c824109
NF
13339 case LW32:
13340 mips32_op = OPC_LW;
5c13fdfd 13341 goto do_ld;
3c824109
NF
13342#ifdef TARGET_MIPS64
13343 case LD32:
13344 mips32_op = OPC_LD;
5c13fdfd 13345 goto do_ld;
3c824109
NF
13346 case SD32:
13347 mips32_op = OPC_SD;
5c13fdfd 13348 goto do_st;
3c824109
NF
13349#endif
13350 case SB32:
13351 mips32_op = OPC_SB;
5c13fdfd 13352 goto do_st;
3c824109
NF
13353 case SH32:
13354 mips32_op = OPC_SH;
5c13fdfd 13355 goto do_st;
3c824109
NF
13356 case SW32:
13357 mips32_op = OPC_SW;
5c13fdfd
AJ
13358 goto do_st;
13359 do_ld:
d75c135e 13360 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13361 break;
13362 do_st:
13363 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13364 break;
13365 default:
13366 generate_exception(ctx, EXCP_RI);
13367 break;
13368 }
13369}
13370
240ce26a 13371static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13372{
13373 uint32_t op;
13374
13375 /* make sure instructions are on a halfword boundary */
13376 if (ctx->pc & 0x1) {
13377 env->CP0_BadVAddr = ctx->pc;
13378 generate_exception(ctx, EXCP_AdEL);
13379 ctx->bstate = BS_STOP;
13380 return 2;
13381 }
13382
13383 op = (ctx->opcode >> 10) & 0x3f;
13384 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
13385 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
13386 switch (op & 0x7) { /* MSB-3..MSB-5 */
13387 case 0:
13388 /* POOL32A, POOL32B, POOL32I, POOL32C */
13389 case 4:
13390 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13391 case 5:
13392 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13393 case 6:
13394 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13395 case 7:
13396 /* LB32, LH32, LWC132, LDC132, LW32 */
13397 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3c824109
NF
13398 generate_exception(ctx, EXCP_RI);
13399 /* Just stop translation; the user is confused. */
13400 ctx->bstate = BS_STOP;
13401 return 2;
13402 }
13403 break;
b231c103
YK
13404 case 1:
13405 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13406 case 2:
13407 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13408 case 3:
13409 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13410 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3c824109
NF
13411 generate_exception(ctx, EXCP_RI);
13412 /* Just stop translation; the user is confused. */
13413 ctx->bstate = BS_STOP;
13414 return 2;
13415 }
13416 break;
3c824109
NF
13417 }
13418 }
b231c103 13419
3c824109
NF
13420 switch (op) {
13421 case POOL16A:
13422 {
13423 int rd = mmreg(uMIPS_RD(ctx->opcode));
13424 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13425 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13426 uint32_t opc = 0;
13427
13428 switch (ctx->opcode & 0x1) {
13429 case ADDU16:
13430 opc = OPC_ADDU;
13431 break;
13432 case SUBU16:
13433 opc = OPC_SUBU;
13434 break;
13435 }
13436
d75c135e 13437 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
13438 }
13439 break;
13440 case POOL16B:
13441 {
13442 int rd = mmreg(uMIPS_RD(ctx->opcode));
13443 int rs = mmreg(uMIPS_RS(ctx->opcode));
13444 int amount = (ctx->opcode >> 1) & 0x7;
13445 uint32_t opc = 0;
13446 amount = amount == 0 ? 8 : amount;
13447
13448 switch (ctx->opcode & 0x1) {
13449 case SLL16:
13450 opc = OPC_SLL;
13451 break;
13452 case SRL16:
13453 opc = OPC_SRL;
13454 break;
13455 }
13456
d75c135e 13457 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
13458 }
13459 break;
13460 case POOL16C:
240ce26a 13461 gen_pool16c_insn(ctx);
3c824109
NF
13462 break;
13463 case LWGP16:
13464 {
13465 int rd = mmreg(uMIPS_RD(ctx->opcode));
13466 int rb = 28; /* GP */
13467 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
13468
d75c135e 13469 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13470 }
13471 break;
13472 case POOL16F:
13473 if (ctx->opcode & 1) {
13474 generate_exception(ctx, EXCP_RI);
13475 } else {
13476 /* MOVEP */
13477 int enc_dest = uMIPS_RD(ctx->opcode);
13478 int enc_rt = uMIPS_RS2(ctx->opcode);
13479 int enc_rs = uMIPS_RS1(ctx->opcode);
13480 int rd, rs, re, rt;
13481 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13482 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13483 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13484
13485 rd = rd_enc[enc_dest];
13486 re = re_enc[enc_dest];
13487 rs = rs_rt_enc[enc_rs];
13488 rt = rs_rt_enc[enc_rt];
13489
d75c135e
AJ
13490 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
13491 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
13492 }
13493 break;
13494 case LBU16:
13495 {
13496 int rd = mmreg(uMIPS_RD(ctx->opcode));
13497 int rb = mmreg(uMIPS_RS(ctx->opcode));
13498 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13499 offset = (offset == 0xf ? -1 : offset);
13500
d75c135e 13501 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
13502 }
13503 break;
13504 case LHU16:
13505 {
13506 int rd = mmreg(uMIPS_RD(ctx->opcode));
13507 int rb = mmreg(uMIPS_RS(ctx->opcode));
13508 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13509
d75c135e 13510 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
13511 }
13512 break;
13513 case LWSP16:
13514 {
13515 int rd = (ctx->opcode >> 5) & 0x1f;
13516 int rb = 29; /* SP */
13517 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13518
d75c135e 13519 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13520 }
13521 break;
13522 case LW16:
13523 {
13524 int rd = mmreg(uMIPS_RD(ctx->opcode));
13525 int rb = mmreg(uMIPS_RS(ctx->opcode));
13526 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13527
d75c135e 13528 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13529 }
13530 break;
13531 case SB16:
13532 {
13533 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13534 int rb = mmreg(uMIPS_RS(ctx->opcode));
13535 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13536
5c13fdfd 13537 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
13538 }
13539 break;
13540 case SH16:
13541 {
13542 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13543 int rb = mmreg(uMIPS_RS(ctx->opcode));
13544 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13545
5c13fdfd 13546 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
13547 }
13548 break;
13549 case SWSP16:
13550 {
13551 int rd = (ctx->opcode >> 5) & 0x1f;
13552 int rb = 29; /* SP */
13553 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13554
5c13fdfd 13555 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13556 }
13557 break;
13558 case SW16:
13559 {
13560 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13561 int rb = mmreg(uMIPS_RS(ctx->opcode));
13562 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13563
5c13fdfd 13564 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13565 }
13566 break;
13567 case MOVE16:
13568 {
13569 int rd = uMIPS_RD5(ctx->opcode);
13570 int rs = uMIPS_RS5(ctx->opcode);
13571
d75c135e 13572 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
13573 }
13574 break;
13575 case ANDI16:
d75c135e 13576 gen_andi16(ctx);
3c824109
NF
13577 break;
13578 case POOL16D:
13579 switch (ctx->opcode & 0x1) {
13580 case ADDIUS5:
d75c135e 13581 gen_addius5(ctx);
3c824109
NF
13582 break;
13583 case ADDIUSP:
d75c135e 13584 gen_addiusp(ctx);
3c824109
NF
13585 break;
13586 }
13587 break;
13588 case POOL16E:
13589 switch (ctx->opcode & 0x1) {
13590 case ADDIUR2:
d75c135e 13591 gen_addiur2(ctx);
3c824109
NF
13592 break;
13593 case ADDIUR1SP:
d75c135e 13594 gen_addiur1sp(ctx);
3c824109
NF
13595 break;
13596 }
13597 break;
13598 case B16:
13599 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
b231c103 13600 SIMM(ctx->opcode, 0, 10) << 1, 4);
3c824109
NF
13601 break;
13602 case BNEZ16:
13603 case BEQZ16:
13604 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
13605 mmreg(uMIPS_RD(ctx->opcode)),
b231c103 13606 0, SIMM(ctx->opcode, 0, 7) << 1, 4);
3c824109
NF
13607 break;
13608 case LI16:
13609 {
13610 int reg = mmreg(uMIPS_RD(ctx->opcode));
13611 int imm = ZIMM(ctx->opcode, 0, 7);
13612
13613 imm = (imm == 0x7f ? -1 : imm);
13614 tcg_gen_movi_tl(cpu_gpr[reg], imm);
13615 }
13616 break;
13617 case RES_20:
13618 case RES_28:
13619 case RES_29:
13620 case RES_30:
13621 case RES_31:
13622 case RES_38:
13623 case RES_39:
13624 generate_exception(ctx, EXCP_RI);
13625 break;
13626 default:
240ce26a 13627 decode_micromips32_opc (env, ctx, op);
3c824109
NF
13628 return 4;
13629 }
13630
13631 return 2;
13632}
13633
13634/* SmartMIPS extension to MIPS32 */
13635
13636#if defined(TARGET_MIPS64)
13637
13638/* MDMX extension to MIPS64 */
13639
13640#endif
13641
9b1a1d68 13642/* MIPSDSP functions. */
d75c135e 13643static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
13644 int rd, int base, int offset)
13645{
13646 const char *opn = "ldx";
13647 TCGv t0;
13648
9b1a1d68
JL
13649 check_dsp(ctx);
13650 t0 = tcg_temp_new();
13651
13652 if (base == 0) {
13653 gen_load_gpr(t0, offset);
13654 } else if (offset == 0) {
13655 gen_load_gpr(t0, base);
13656 } else {
13657 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
13658 }
13659
9b1a1d68
JL
13660 switch (opc) {
13661 case OPC_LBUX:
5f68f5ae 13662 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
13663 gen_store_gpr(t0, rd);
13664 opn = "lbux";
13665 break;
13666 case OPC_LHX:
5f68f5ae 13667 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
13668 gen_store_gpr(t0, rd);
13669 opn = "lhx";
13670 break;
13671 case OPC_LWX:
5f68f5ae 13672 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
13673 gen_store_gpr(t0, rd);
13674 opn = "lwx";
13675 break;
13676#if defined(TARGET_MIPS64)
13677 case OPC_LDX:
5f68f5ae 13678 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
13679 gen_store_gpr(t0, rd);
13680 opn = "ldx";
13681 break;
13682#endif
13683 }
13684 (void)opn; /* avoid a compiler warning */
13685 MIPS_DEBUG("%s %s, %s(%s)", opn,
13686 regnames[rd], regnames[offset], regnames[base]);
13687 tcg_temp_free(t0);
13688}
13689
461c08df
JL
13690static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
13691 int ret, int v1, int v2)
13692{
13693 const char *opn = "mipsdsp arith";
13694 TCGv v1_t;
13695 TCGv v2_t;
13696
13697 if (ret == 0) {
13698 /* Treat as NOP. */
13699 MIPS_DEBUG("NOP");
13700 return;
13701 }
13702
13703 v1_t = tcg_temp_new();
13704 v2_t = tcg_temp_new();
13705
13706 gen_load_gpr(v1_t, v1);
13707 gen_load_gpr(v2_t, v2);
13708
13709 switch (op1) {
13710 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13711 case OPC_MULT_G_2E:
13712 check_dspr2(ctx);
13713 switch (op2) {
13714 case OPC_ADDUH_QB:
13715 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
13716 break;
13717 case OPC_ADDUH_R_QB:
13718 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13719 break;
13720 case OPC_ADDQH_PH:
13721 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
13722 break;
13723 case OPC_ADDQH_R_PH:
13724 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13725 break;
13726 case OPC_ADDQH_W:
13727 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
13728 break;
13729 case OPC_ADDQH_R_W:
13730 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13731 break;
13732 case OPC_SUBUH_QB:
13733 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
13734 break;
13735 case OPC_SUBUH_R_QB:
13736 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13737 break;
13738 case OPC_SUBQH_PH:
13739 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
13740 break;
13741 case OPC_SUBQH_R_PH:
13742 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13743 break;
13744 case OPC_SUBQH_W:
13745 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
13746 break;
13747 case OPC_SUBQH_R_W:
13748 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13749 break;
13750 }
13751 break;
13752 case OPC_ABSQ_S_PH_DSP:
13753 switch (op2) {
13754 case OPC_ABSQ_S_QB:
13755 check_dspr2(ctx);
13756 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
13757 break;
13758 case OPC_ABSQ_S_PH:
13759 check_dsp(ctx);
13760 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
13761 break;
13762 case OPC_ABSQ_S_W:
13763 check_dsp(ctx);
13764 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
13765 break;
13766 case OPC_PRECEQ_W_PHL:
13767 check_dsp(ctx);
13768 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
13769 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13770 break;
13771 case OPC_PRECEQ_W_PHR:
13772 check_dsp(ctx);
13773 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
13774 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
13775 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13776 break;
13777 case OPC_PRECEQU_PH_QBL:
13778 check_dsp(ctx);
13779 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
13780 break;
13781 case OPC_PRECEQU_PH_QBR:
13782 check_dsp(ctx);
13783 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
13784 break;
13785 case OPC_PRECEQU_PH_QBLA:
13786 check_dsp(ctx);
13787 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
13788 break;
13789 case OPC_PRECEQU_PH_QBRA:
13790 check_dsp(ctx);
13791 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
13792 break;
13793 case OPC_PRECEU_PH_QBL:
13794 check_dsp(ctx);
13795 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
13796 break;
13797 case OPC_PRECEU_PH_QBR:
13798 check_dsp(ctx);
13799 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
13800 break;
13801 case OPC_PRECEU_PH_QBLA:
13802 check_dsp(ctx);
13803 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
13804 break;
13805 case OPC_PRECEU_PH_QBRA:
13806 check_dsp(ctx);
13807 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
13808 break;
13809 }
13810 break;
13811 case OPC_ADDU_QB_DSP:
13812 switch (op2) {
13813 case OPC_ADDQ_PH:
13814 check_dsp(ctx);
13815 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13816 break;
13817 case OPC_ADDQ_S_PH:
13818 check_dsp(ctx);
13819 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13820 break;
13821 case OPC_ADDQ_S_W:
13822 check_dsp(ctx);
13823 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13824 break;
13825 case OPC_ADDU_QB:
13826 check_dsp(ctx);
13827 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13828 break;
13829 case OPC_ADDU_S_QB:
13830 check_dsp(ctx);
13831 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13832 break;
13833 case OPC_ADDU_PH:
13834 check_dspr2(ctx);
13835 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13836 break;
13837 case OPC_ADDU_S_PH:
13838 check_dspr2(ctx);
13839 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13840 break;
13841 case OPC_SUBQ_PH:
13842 check_dsp(ctx);
13843 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13844 break;
13845 case OPC_SUBQ_S_PH:
13846 check_dsp(ctx);
13847 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13848 break;
13849 case OPC_SUBQ_S_W:
13850 check_dsp(ctx);
13851 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13852 break;
13853 case OPC_SUBU_QB:
13854 check_dsp(ctx);
13855 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13856 break;
13857 case OPC_SUBU_S_QB:
13858 check_dsp(ctx);
13859 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13860 break;
13861 case OPC_SUBU_PH:
13862 check_dspr2(ctx);
13863 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13864 break;
13865 case OPC_SUBU_S_PH:
13866 check_dspr2(ctx);
13867 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13868 break;
13869 case OPC_ADDSC:
13870 check_dsp(ctx);
13871 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13872 break;
13873 case OPC_ADDWC:
13874 check_dsp(ctx);
13875 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13876 break;
13877 case OPC_MODSUB:
13878 check_dsp(ctx);
13879 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
13880 break;
13881 case OPC_RADDU_W_QB:
13882 check_dsp(ctx);
13883 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
13884 break;
13885 }
13886 break;
13887 case OPC_CMPU_EQ_QB_DSP:
13888 switch (op2) {
13889 case OPC_PRECR_QB_PH:
13890 check_dspr2(ctx);
13891 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13892 break;
13893 case OPC_PRECRQ_QB_PH:
13894 check_dsp(ctx);
13895 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13896 break;
13897 case OPC_PRECR_SRA_PH_W:
13898 check_dspr2(ctx);
13899 {
13900 TCGv_i32 sa_t = tcg_const_i32(v2);
13901 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
13902 cpu_gpr[ret]);
13903 tcg_temp_free_i32(sa_t);
13904 break;
13905 }
13906 case OPC_PRECR_SRA_R_PH_W:
13907 check_dspr2(ctx);
13908 {
13909 TCGv_i32 sa_t = tcg_const_i32(v2);
13910 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
13911 cpu_gpr[ret]);
13912 tcg_temp_free_i32(sa_t);
13913 break;
13914 }
13915 case OPC_PRECRQ_PH_W:
13916 check_dsp(ctx);
13917 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
13918 break;
13919 case OPC_PRECRQ_RS_PH_W:
13920 check_dsp(ctx);
13921 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_PRECRQU_S_QB_PH:
13924 check_dsp(ctx);
13925 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13926 break;
13927 }
13928 break;
13929#ifdef TARGET_MIPS64
13930 case OPC_ABSQ_S_QH_DSP:
13931 switch (op2) {
13932 case OPC_PRECEQ_L_PWL:
13933 check_dsp(ctx);
13934 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
13935 break;
13936 case OPC_PRECEQ_L_PWR:
13937 check_dsp(ctx);
13938 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
13939 break;
13940 case OPC_PRECEQ_PW_QHL:
13941 check_dsp(ctx);
13942 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
13943 break;
13944 case OPC_PRECEQ_PW_QHR:
13945 check_dsp(ctx);
13946 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
13947 break;
13948 case OPC_PRECEQ_PW_QHLA:
13949 check_dsp(ctx);
13950 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13951 break;
13952 case OPC_PRECEQ_PW_QHRA:
13953 check_dsp(ctx);
13954 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13955 break;
13956 case OPC_PRECEQU_QH_OBL:
13957 check_dsp(ctx);
13958 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13959 break;
13960 case OPC_PRECEQU_QH_OBR:
13961 check_dsp(ctx);
13962 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13963 break;
13964 case OPC_PRECEQU_QH_OBLA:
13965 check_dsp(ctx);
13966 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13967 break;
13968 case OPC_PRECEQU_QH_OBRA:
13969 check_dsp(ctx);
13970 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13971 break;
13972 case OPC_PRECEU_QH_OBL:
13973 check_dsp(ctx);
13974 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13975 break;
13976 case OPC_PRECEU_QH_OBR:
13977 check_dsp(ctx);
13978 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13979 break;
13980 case OPC_PRECEU_QH_OBLA:
13981 check_dsp(ctx);
13982 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13983 break;
13984 case OPC_PRECEU_QH_OBRA:
13985 check_dsp(ctx);
13986 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13987 break;
13988 case OPC_ABSQ_S_OB:
13989 check_dspr2(ctx);
13990 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13991 break;
13992 case OPC_ABSQ_S_PW:
13993 check_dsp(ctx);
13994 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13995 break;
13996 case OPC_ABSQ_S_QH:
13997 check_dsp(ctx);
13998 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13999 break;
14000 }
14001 break;
14002 case OPC_ADDU_OB_DSP:
14003 switch (op2) {
14004 case OPC_RADDU_L_OB:
14005 check_dsp(ctx);
14006 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14007 break;
14008 case OPC_SUBQ_PW:
14009 check_dsp(ctx);
14010 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14011 break;
14012 case OPC_SUBQ_S_PW:
14013 check_dsp(ctx);
14014 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_SUBQ_QH:
14017 check_dsp(ctx);
14018 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_SUBQ_S_QH:
14021 check_dsp(ctx);
14022 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 break;
14024 case OPC_SUBU_OB:
14025 check_dsp(ctx);
14026 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14027 break;
14028 case OPC_SUBU_S_OB:
14029 check_dsp(ctx);
14030 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14031 break;
14032 case OPC_SUBU_QH:
14033 check_dspr2(ctx);
14034 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14035 break;
14036 case OPC_SUBU_S_QH:
14037 check_dspr2(ctx);
14038 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14039 break;
14040 case OPC_SUBUH_OB:
14041 check_dspr2(ctx);
14042 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14043 break;
14044 case OPC_SUBUH_R_OB:
14045 check_dspr2(ctx);
14046 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14047 break;
14048 case OPC_ADDQ_PW:
14049 check_dsp(ctx);
14050 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14051 break;
14052 case OPC_ADDQ_S_PW:
14053 check_dsp(ctx);
14054 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14055 break;
14056 case OPC_ADDQ_QH:
14057 check_dsp(ctx);
14058 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14060 case OPC_ADDQ_S_QH:
14061 check_dsp(ctx);
14062 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 break;
14064 case OPC_ADDU_OB:
14065 check_dsp(ctx);
14066 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14067 break;
14068 case OPC_ADDU_S_OB:
14069 check_dsp(ctx);
14070 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14071 break;
14072 case OPC_ADDU_QH:
14073 check_dspr2(ctx);
14074 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14075 break;
14076 case OPC_ADDU_S_QH:
14077 check_dspr2(ctx);
14078 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14079 break;
14080 case OPC_ADDUH_OB:
14081 check_dspr2(ctx);
14082 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14083 break;
14084 case OPC_ADDUH_R_OB:
14085 check_dspr2(ctx);
14086 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14087 break;
14088 }
14089 break;
14090 case OPC_CMPU_EQ_OB_DSP:
14091 switch (op2) {
14092 case OPC_PRECR_OB_QH:
14093 check_dspr2(ctx);
14094 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14095 break;
14096 case OPC_PRECR_SRA_QH_PW:
14097 check_dspr2(ctx);
14098 {
14099 TCGv_i32 ret_t = tcg_const_i32(ret);
14100 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14101 tcg_temp_free_i32(ret_t);
14102 break;
14103 }
14104 case OPC_PRECR_SRA_R_QH_PW:
14105 check_dspr2(ctx);
14106 {
14107 TCGv_i32 sa_v = tcg_const_i32(ret);
14108 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14109 tcg_temp_free_i32(sa_v);
14110 break;
14111 }
14112 case OPC_PRECRQ_OB_QH:
14113 check_dsp(ctx);
14114 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14115 break;
14116 case OPC_PRECRQ_PW_L:
14117 check_dsp(ctx);
14118 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14119 break;
14120 case OPC_PRECRQ_QH_PW:
14121 check_dsp(ctx);
14122 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14123 break;
14124 case OPC_PRECRQ_RS_QH_PW:
14125 check_dsp(ctx);
14126 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14127 break;
14128 case OPC_PRECRQU_S_OB_QH:
14129 check_dsp(ctx);
14130 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14131 break;
14132 }
14133 break;
14134#endif
14135 }
14136
14137 tcg_temp_free(v1_t);
14138 tcg_temp_free(v2_t);
14139
14140 (void)opn; /* avoid a compiler warning */
14141 MIPS_DEBUG("%s", opn);
14142}
9b1a1d68 14143
77c5fa8b
JL
14144static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14145 int ret, int v1, int v2)
14146{
14147 uint32_t op2;
14148 const char *opn = "mipsdsp shift";
14149 TCGv t0;
14150 TCGv v1_t;
14151 TCGv v2_t;
14152
14153 if (ret == 0) {
14154 /* Treat as NOP. */
14155 MIPS_DEBUG("NOP");
14156 return;
14157 }
14158
14159 t0 = tcg_temp_new();
14160 v1_t = tcg_temp_new();
14161 v2_t = tcg_temp_new();
14162
14163 tcg_gen_movi_tl(t0, v1);
14164 gen_load_gpr(v1_t, v1);
14165 gen_load_gpr(v2_t, v2);
14166
14167 switch (opc) {
14168 case OPC_SHLL_QB_DSP:
14169 {
14170 op2 = MASK_SHLL_QB(ctx->opcode);
14171 switch (op2) {
14172 case OPC_SHLL_QB:
14173 check_dsp(ctx);
14174 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14175 break;
14176 case OPC_SHLLV_QB:
14177 check_dsp(ctx);
14178 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14179 break;
14180 case OPC_SHLL_PH:
14181 check_dsp(ctx);
14182 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14183 break;
14184 case OPC_SHLLV_PH:
14185 check_dsp(ctx);
14186 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14187 break;
14188 case OPC_SHLL_S_PH:
14189 check_dsp(ctx);
14190 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14191 break;
14192 case OPC_SHLLV_S_PH:
14193 check_dsp(ctx);
14194 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14195 break;
14196 case OPC_SHLL_S_W:
14197 check_dsp(ctx);
14198 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14199 break;
14200 case OPC_SHLLV_S_W:
14201 check_dsp(ctx);
14202 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14203 break;
14204 case OPC_SHRL_QB:
14205 check_dsp(ctx);
14206 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14207 break;
14208 case OPC_SHRLV_QB:
14209 check_dsp(ctx);
14210 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14211 break;
14212 case OPC_SHRL_PH:
14213 check_dspr2(ctx);
14214 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14215 break;
14216 case OPC_SHRLV_PH:
14217 check_dspr2(ctx);
14218 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14219 break;
14220 case OPC_SHRA_QB:
14221 check_dspr2(ctx);
14222 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14223 break;
14224 case OPC_SHRA_R_QB:
14225 check_dspr2(ctx);
14226 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14227 break;
14228 case OPC_SHRAV_QB:
14229 check_dspr2(ctx);
14230 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14231 break;
14232 case OPC_SHRAV_R_QB:
14233 check_dspr2(ctx);
14234 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14235 break;
14236 case OPC_SHRA_PH:
14237 check_dsp(ctx);
14238 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14239 break;
14240 case OPC_SHRA_R_PH:
14241 check_dsp(ctx);
14242 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14243 break;
14244 case OPC_SHRAV_PH:
14245 check_dsp(ctx);
14246 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14247 break;
14248 case OPC_SHRAV_R_PH:
14249 check_dsp(ctx);
14250 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14251 break;
14252 case OPC_SHRA_R_W:
14253 check_dsp(ctx);
14254 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14255 break;
14256 case OPC_SHRAV_R_W:
14257 check_dsp(ctx);
14258 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14259 break;
14260 default: /* Invalid */
14261 MIPS_INVAL("MASK SHLL.QB");
14262 generate_exception(ctx, EXCP_RI);
14263 break;
14264 }
14265 break;
14266 }
14267#ifdef TARGET_MIPS64
14268 case OPC_SHLL_OB_DSP:
14269 op2 = MASK_SHLL_OB(ctx->opcode);
14270 switch (op2) {
14271 case OPC_SHLL_PW:
14272 check_dsp(ctx);
14273 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14274 break;
14275 case OPC_SHLLV_PW:
14276 check_dsp(ctx);
14277 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14278 break;
14279 case OPC_SHLL_S_PW:
14280 check_dsp(ctx);
14281 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14282 break;
14283 case OPC_SHLLV_S_PW:
14284 check_dsp(ctx);
14285 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14286 break;
14287 case OPC_SHLL_OB:
14288 check_dsp(ctx);
14289 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14290 break;
14291 case OPC_SHLLV_OB:
14292 check_dsp(ctx);
14293 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14294 break;
14295 case OPC_SHLL_QH:
14296 check_dsp(ctx);
14297 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14298 break;
14299 case OPC_SHLLV_QH:
14300 check_dsp(ctx);
14301 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14302 break;
14303 case OPC_SHLL_S_QH:
14304 check_dsp(ctx);
14305 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14306 break;
14307 case OPC_SHLLV_S_QH:
14308 check_dsp(ctx);
14309 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14310 break;
14311 case OPC_SHRA_OB:
14312 check_dspr2(ctx);
14313 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14314 break;
14315 case OPC_SHRAV_OB:
14316 check_dspr2(ctx);
14317 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14318 break;
14319 case OPC_SHRA_R_OB:
14320 check_dspr2(ctx);
14321 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14322 break;
14323 case OPC_SHRAV_R_OB:
14324 check_dspr2(ctx);
14325 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14326 break;
14327 case OPC_SHRA_PW:
14328 check_dsp(ctx);
14329 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14330 break;
14331 case OPC_SHRAV_PW:
14332 check_dsp(ctx);
14333 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14334 break;
14335 case OPC_SHRA_R_PW:
14336 check_dsp(ctx);
14337 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14338 break;
14339 case OPC_SHRAV_R_PW:
14340 check_dsp(ctx);
14341 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14342 break;
14343 case OPC_SHRA_QH:
14344 check_dsp(ctx);
14345 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14346 break;
14347 case OPC_SHRAV_QH:
14348 check_dsp(ctx);
14349 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14350 break;
14351 case OPC_SHRA_R_QH:
14352 check_dsp(ctx);
14353 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14354 break;
14355 case OPC_SHRAV_R_QH:
14356 check_dsp(ctx);
14357 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14358 break;
14359 case OPC_SHRL_OB:
14360 check_dsp(ctx);
14361 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14362 break;
14363 case OPC_SHRLV_OB:
14364 check_dsp(ctx);
14365 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14366 break;
14367 case OPC_SHRL_QH:
14368 check_dspr2(ctx);
14369 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14370 break;
14371 case OPC_SHRLV_QH:
14372 check_dspr2(ctx);
14373 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14374 break;
14375 default: /* Invalid */
14376 MIPS_INVAL("MASK SHLL.OB");
14377 generate_exception(ctx, EXCP_RI);
14378 break;
14379 }
14380 break;
14381#endif
14382 }
14383
14384 tcg_temp_free(t0);
14385 tcg_temp_free(v1_t);
14386 tcg_temp_free(v2_t);
14387 (void)opn; /* avoid a compiler warning */
14388 MIPS_DEBUG("%s", opn);
14389}
14390
a22260ae
JL
14391static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14392 int ret, int v1, int v2, int check_ret)
14393{
14394 const char *opn = "mipsdsp multiply";
14395 TCGv_i32 t0;
14396 TCGv v1_t;
14397 TCGv v2_t;
14398
14399 if ((ret == 0) && (check_ret == 1)) {
14400 /* Treat as NOP. */
14401 MIPS_DEBUG("NOP");
14402 return;
14403 }
14404
14405 t0 = tcg_temp_new_i32();
14406 v1_t = tcg_temp_new();
14407 v2_t = tcg_temp_new();
14408
14409 tcg_gen_movi_i32(t0, ret);
14410 gen_load_gpr(v1_t, v1);
14411 gen_load_gpr(v2_t, v2);
14412
14413 switch (op1) {
14414 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14415 * the same mask and op1. */
14416 case OPC_MULT_G_2E:
639eadb9 14417 check_dspr2(ctx);
a22260ae
JL
14418 switch (op2) {
14419 case OPC_MUL_PH:
14420 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14421 break;
14422 case OPC_MUL_S_PH:
14423 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14424 break;
14425 case OPC_MULQ_S_W:
14426 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14427 break;
14428 case OPC_MULQ_RS_W:
14429 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14430 break;
14431 }
14432 break;
14433 case OPC_DPA_W_PH_DSP:
14434 switch (op2) {
14435 case OPC_DPAU_H_QBL:
14436 check_dsp(ctx);
14437 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14438 break;
14439 case OPC_DPAU_H_QBR:
14440 check_dsp(ctx);
14441 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14442 break;
14443 case OPC_DPSU_H_QBL:
14444 check_dsp(ctx);
14445 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14446 break;
14447 case OPC_DPSU_H_QBR:
14448 check_dsp(ctx);
14449 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14450 break;
14451 case OPC_DPA_W_PH:
14452 check_dspr2(ctx);
14453 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14454 break;
14455 case OPC_DPAX_W_PH:
14456 check_dspr2(ctx);
14457 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
14458 break;
14459 case OPC_DPAQ_S_W_PH:
14460 check_dsp(ctx);
14461 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14462 break;
14463 case OPC_DPAQX_S_W_PH:
14464 check_dspr2(ctx);
14465 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14466 break;
14467 case OPC_DPAQX_SA_W_PH:
14468 check_dspr2(ctx);
14469 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14470 break;
14471 case OPC_DPS_W_PH:
14472 check_dspr2(ctx);
14473 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
14474 break;
14475 case OPC_DPSX_W_PH:
14476 check_dspr2(ctx);
14477 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
14478 break;
14479 case OPC_DPSQ_S_W_PH:
14480 check_dsp(ctx);
14481 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14482 break;
14483 case OPC_DPSQX_S_W_PH:
14484 check_dspr2(ctx);
14485 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14486 break;
14487 case OPC_DPSQX_SA_W_PH:
14488 check_dspr2(ctx);
14489 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14490 break;
14491 case OPC_MULSAQ_S_W_PH:
14492 check_dsp(ctx);
14493 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14494 break;
14495 case OPC_DPAQ_SA_L_W:
14496 check_dsp(ctx);
14497 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14498 break;
14499 case OPC_DPSQ_SA_L_W:
14500 check_dsp(ctx);
14501 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14502 break;
14503 case OPC_MAQ_S_W_PHL:
14504 check_dsp(ctx);
14505 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
14506 break;
14507 case OPC_MAQ_S_W_PHR:
14508 check_dsp(ctx);
14509 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
14510 break;
14511 case OPC_MAQ_SA_W_PHL:
14512 check_dsp(ctx);
14513 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
14514 break;
14515 case OPC_MAQ_SA_W_PHR:
14516 check_dsp(ctx);
14517 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
14518 break;
14519 case OPC_MULSA_W_PH:
14520 check_dspr2(ctx);
14521 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
14522 break;
14523 }
14524 break;
14525#ifdef TARGET_MIPS64
14526 case OPC_DPAQ_W_QH_DSP:
14527 {
14528 int ac = ret & 0x03;
14529 tcg_gen_movi_i32(t0, ac);
14530
14531 switch (op2) {
14532 case OPC_DMADD:
14533 check_dsp(ctx);
14534 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
14535 break;
14536 case OPC_DMADDU:
14537 check_dsp(ctx);
14538 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
14539 break;
14540 case OPC_DMSUB:
14541 check_dsp(ctx);
14542 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
14543 break;
14544 case OPC_DMSUBU:
14545 check_dsp(ctx);
14546 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
14547 break;
14548 case OPC_DPA_W_QH:
14549 check_dspr2(ctx);
14550 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
14551 break;
14552 case OPC_DPAQ_S_W_QH:
14553 check_dsp(ctx);
14554 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14555 break;
14556 case OPC_DPAQ_SA_L_PW:
14557 check_dsp(ctx);
14558 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14559 break;
14560 case OPC_DPAU_H_OBL:
14561 check_dsp(ctx);
14562 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
14563 break;
14564 case OPC_DPAU_H_OBR:
14565 check_dsp(ctx);
14566 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
14567 break;
14568 case OPC_DPS_W_QH:
14569 check_dspr2(ctx);
14570 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
14571 break;
14572 case OPC_DPSQ_S_W_QH:
14573 check_dsp(ctx);
14574 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14575 break;
14576 case OPC_DPSQ_SA_L_PW:
14577 check_dsp(ctx);
14578 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14579 break;
14580 case OPC_DPSU_H_OBL:
14581 check_dsp(ctx);
14582 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
14583 break;
14584 case OPC_DPSU_H_OBR:
14585 check_dsp(ctx);
14586 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
14587 break;
14588 case OPC_MAQ_S_L_PWL:
14589 check_dsp(ctx);
14590 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
14591 break;
14592 case OPC_MAQ_S_L_PWR:
14593 check_dsp(ctx);
14594 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
14595 break;
14596 case OPC_MAQ_S_W_QHLL:
14597 check_dsp(ctx);
14598 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
14599 break;
14600 case OPC_MAQ_SA_W_QHLL:
14601 check_dsp(ctx);
14602 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
14603 break;
14604 case OPC_MAQ_S_W_QHLR:
14605 check_dsp(ctx);
14606 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
14607 break;
14608 case OPC_MAQ_SA_W_QHLR:
14609 check_dsp(ctx);
14610 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
14611 break;
14612 case OPC_MAQ_S_W_QHRL:
14613 check_dsp(ctx);
14614 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
14615 break;
14616 case OPC_MAQ_SA_W_QHRL:
14617 check_dsp(ctx);
14618 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
14619 break;
14620 case OPC_MAQ_S_W_QHRR:
14621 check_dsp(ctx);
14622 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
14623 break;
14624 case OPC_MAQ_SA_W_QHRR:
14625 check_dsp(ctx);
14626 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
14627 break;
14628 case OPC_MULSAQ_S_L_PW:
14629 check_dsp(ctx);
14630 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
14631 break;
14632 case OPC_MULSAQ_S_W_QH:
14633 check_dsp(ctx);
14634 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14635 break;
14636 }
14637 }
14638 break;
14639#endif
14640 case OPC_ADDU_QB_DSP:
14641 switch (op2) {
14642 case OPC_MULEU_S_PH_QBL:
14643 check_dsp(ctx);
14644 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14645 break;
14646 case OPC_MULEU_S_PH_QBR:
14647 check_dsp(ctx);
14648 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14649 break;
14650 case OPC_MULQ_RS_PH:
14651 check_dsp(ctx);
14652 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14653 break;
14654 case OPC_MULEQ_S_W_PHL:
14655 check_dsp(ctx);
14656 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14657 break;
14658 case OPC_MULEQ_S_W_PHR:
14659 check_dsp(ctx);
14660 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14661 break;
14662 case OPC_MULQ_S_PH:
14663 check_dspr2(ctx);
14664 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14665 break;
14666 }
14667 break;
14668#ifdef TARGET_MIPS64
14669 case OPC_ADDU_OB_DSP:
14670 switch (op2) {
14671 case OPC_MULEQ_S_PW_QHL:
14672 check_dsp(ctx);
14673 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14674 break;
14675 case OPC_MULEQ_S_PW_QHR:
14676 check_dsp(ctx);
14677 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14678 break;
14679 case OPC_MULEU_S_QH_OBL:
14680 check_dsp(ctx);
14681 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14682 break;
14683 case OPC_MULEU_S_QH_OBR:
14684 check_dsp(ctx);
14685 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14686 break;
14687 case OPC_MULQ_RS_QH:
14688 check_dsp(ctx);
14689 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14690 break;
14691 }
14692 break;
14693#endif
14694 }
14695
14696 tcg_temp_free_i32(t0);
14697 tcg_temp_free(v1_t);
14698 tcg_temp_free(v2_t);
14699
14700 (void)opn; /* avoid a compiler warning */
14701 MIPS_DEBUG("%s", opn);
14702
14703}
14704
d75c135e 14705static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
14706 int ret, int val)
14707{
14708 const char *opn = "mipsdsp Bit/ Manipulation";
14709 int16_t imm;
14710 TCGv t0;
14711 TCGv val_t;
14712
14713 if (ret == 0) {
14714 /* Treat as NOP. */
14715 MIPS_DEBUG("NOP");
14716 return;
14717 }
14718
14719 t0 = tcg_temp_new();
14720 val_t = tcg_temp_new();
14721 gen_load_gpr(val_t, val);
14722
14723 switch (op1) {
14724 case OPC_ABSQ_S_PH_DSP:
14725 switch (op2) {
14726 case OPC_BITREV:
14727 check_dsp(ctx);
14728 gen_helper_bitrev(cpu_gpr[ret], val_t);
14729 break;
14730 case OPC_REPL_QB:
14731 check_dsp(ctx);
14732 {
14733 target_long result;
14734 imm = (ctx->opcode >> 16) & 0xFF;
14735 result = (uint32_t)imm << 24 |
14736 (uint32_t)imm << 16 |
14737 (uint32_t)imm << 8 |
14738 (uint32_t)imm;
14739 result = (int32_t)result;
14740 tcg_gen_movi_tl(cpu_gpr[ret], result);
14741 }
14742 break;
14743 case OPC_REPLV_QB:
14744 check_dsp(ctx);
14745 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14746 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14747 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14748 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14749 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14750 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14751 break;
14752 case OPC_REPL_PH:
14753 check_dsp(ctx);
14754 {
14755 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 14756 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
14757 tcg_gen_movi_tl(cpu_gpr[ret], \
14758 (target_long)((int32_t)imm << 16 | \
c4aaba92 14759 (uint16_t)imm));
1cb6686c
JL
14760 }
14761 break;
14762 case OPC_REPLV_PH:
14763 check_dsp(ctx);
14764 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14765 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14766 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14767 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14768 break;
14769 }
14770 break;
14771#ifdef TARGET_MIPS64
14772 case OPC_ABSQ_S_QH_DSP:
14773 switch (op2) {
14774 case OPC_REPL_OB:
14775 check_dsp(ctx);
14776 {
14777 target_long temp;
14778
14779 imm = (ctx->opcode >> 16) & 0xFF;
14780 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
14781 temp = (temp << 16) | temp;
14782 temp = (temp << 32) | temp;
14783 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14784 break;
14785 }
14786 case OPC_REPL_PW:
14787 check_dsp(ctx);
14788 {
14789 target_long temp;
14790
14791 imm = (ctx->opcode >> 16) & 0x03FF;
14792 imm = (int16_t)(imm << 6) >> 6;
14793 temp = ((target_long)imm << 32) \
14794 | ((target_long)imm & 0xFFFFFFFF);
14795 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14796 break;
14797 }
14798 case OPC_REPL_QH:
14799 check_dsp(ctx);
14800 {
14801 target_long temp;
14802
14803 imm = (ctx->opcode >> 16) & 0x03FF;
14804 imm = (int16_t)(imm << 6) >> 6;
14805
14806 temp = ((uint64_t)(uint16_t)imm << 48) |
14807 ((uint64_t)(uint16_t)imm << 32) |
14808 ((uint64_t)(uint16_t)imm << 16) |
14809 (uint64_t)(uint16_t)imm;
14810 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14811 break;
14812 }
14813 case OPC_REPLV_OB:
14814 check_dsp(ctx);
14815 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14816 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14817 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14818 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14819 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14820 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14821 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14822 break;
14823 case OPC_REPLV_PW:
14824 check_dsp(ctx);
14825 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
14826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14828 break;
14829 case OPC_REPLV_QH:
14830 check_dsp(ctx);
14831 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14832 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14833 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14834 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14835 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14836 break;
14837 }
14838 break;
14839#endif
14840 }
14841 tcg_temp_free(t0);
14842 tcg_temp_free(val_t);
14843
14844 (void)opn; /* avoid a compiler warning */
14845 MIPS_DEBUG("%s", opn);
14846}
14847
26690560
JL
14848static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
14849 uint32_t op1, uint32_t op2,
14850 int ret, int v1, int v2, int check_ret)
14851{
14852 const char *opn = "mipsdsp add compare pick";
26690560
JL
14853 TCGv t1;
14854 TCGv v1_t;
14855 TCGv v2_t;
14856
14857 if ((ret == 0) && (check_ret == 1)) {
14858 /* Treat as NOP. */
14859 MIPS_DEBUG("NOP");
14860 return;
14861 }
14862
26690560
JL
14863 t1 = tcg_temp_new();
14864 v1_t = tcg_temp_new();
14865 v2_t = tcg_temp_new();
14866
14867 gen_load_gpr(v1_t, v1);
14868 gen_load_gpr(v2_t, v2);
14869
14870 switch (op1) {
26690560
JL
14871 case OPC_CMPU_EQ_QB_DSP:
14872 switch (op2) {
14873 case OPC_CMPU_EQ_QB:
14874 check_dsp(ctx);
14875 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
14876 break;
14877 case OPC_CMPU_LT_QB:
14878 check_dsp(ctx);
14879 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
14880 break;
14881 case OPC_CMPU_LE_QB:
14882 check_dsp(ctx);
14883 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
14884 break;
14885 case OPC_CMPGU_EQ_QB:
14886 check_dsp(ctx);
14887 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
14888 break;
14889 case OPC_CMPGU_LT_QB:
14890 check_dsp(ctx);
14891 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
14892 break;
14893 case OPC_CMPGU_LE_QB:
14894 check_dsp(ctx);
14895 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
14896 break;
14897 case OPC_CMPGDU_EQ_QB:
14898 check_dspr2(ctx);
14899 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
14900 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14901 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14902 tcg_gen_shli_tl(t1, t1, 24);
14903 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14904 break;
14905 case OPC_CMPGDU_LT_QB:
14906 check_dspr2(ctx);
14907 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
14908 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14909 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14910 tcg_gen_shli_tl(t1, t1, 24);
14911 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14912 break;
14913 case OPC_CMPGDU_LE_QB:
14914 check_dspr2(ctx);
14915 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14916 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14917 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14918 tcg_gen_shli_tl(t1, t1, 24);
14919 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14920 break;
14921 case OPC_CMP_EQ_PH:
14922 check_dsp(ctx);
14923 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
14924 break;
14925 case OPC_CMP_LT_PH:
14926 check_dsp(ctx);
14927 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14928 break;
14929 case OPC_CMP_LE_PH:
14930 check_dsp(ctx);
14931 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14932 break;
14933 case OPC_PICK_QB:
14934 check_dsp(ctx);
14935 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14936 break;
14937 case OPC_PICK_PH:
14938 check_dsp(ctx);
14939 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14940 break;
14941 case OPC_PACKRL_PH:
14942 check_dsp(ctx);
14943 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14944 break;
14945 }
14946 break;
14947#ifdef TARGET_MIPS64
14948 case OPC_CMPU_EQ_OB_DSP:
14949 switch (op2) {
14950 case OPC_CMP_EQ_PW:
14951 check_dsp(ctx);
14952 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14953 break;
14954 case OPC_CMP_LT_PW:
14955 check_dsp(ctx);
14956 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14957 break;
14958 case OPC_CMP_LE_PW:
14959 check_dsp(ctx);
14960 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14961 break;
14962 case OPC_CMP_EQ_QH:
14963 check_dsp(ctx);
14964 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14965 break;
14966 case OPC_CMP_LT_QH:
14967 check_dsp(ctx);
14968 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14969 break;
14970 case OPC_CMP_LE_QH:
14971 check_dsp(ctx);
14972 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14973 break;
14974 case OPC_CMPGDU_EQ_OB:
14975 check_dspr2(ctx);
14976 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14977 break;
14978 case OPC_CMPGDU_LT_OB:
14979 check_dspr2(ctx);
14980 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14981 break;
14982 case OPC_CMPGDU_LE_OB:
14983 check_dspr2(ctx);
14984 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14985 break;
14986 case OPC_CMPGU_EQ_OB:
14987 check_dsp(ctx);
14988 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14989 break;
14990 case OPC_CMPGU_LT_OB:
14991 check_dsp(ctx);
14992 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14993 break;
14994 case OPC_CMPGU_LE_OB:
14995 check_dsp(ctx);
14996 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14997 break;
14998 case OPC_CMPU_EQ_OB:
14999 check_dsp(ctx);
15000 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15001 break;
15002 case OPC_CMPU_LT_OB:
15003 check_dsp(ctx);
15004 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15005 break;
15006 case OPC_CMPU_LE_OB:
15007 check_dsp(ctx);
15008 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15009 break;
15010 case OPC_PACKRL_PW:
15011 check_dsp(ctx);
15012 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15013 break;
15014 case OPC_PICK_OB:
15015 check_dsp(ctx);
15016 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15017 break;
15018 case OPC_PICK_PW:
15019 check_dsp(ctx);
15020 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15021 break;
15022 case OPC_PICK_QH:
15023 check_dsp(ctx);
15024 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15025 break;
15026 }
15027 break;
df6126a7
AJ
15028#endif
15029 }
15030
15031 tcg_temp_free(t1);
15032 tcg_temp_free(v1_t);
15033 tcg_temp_free(v2_t);
15034
15035 (void)opn; /* avoid a compiler warning */
15036 MIPS_DEBUG("%s", opn);
15037}
15038
15039static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15040 uint32_t op1, int rt, int rs, int sa)
15041{
15042 const char *opn = "mipsdsp append/dappend";
15043 TCGv t0;
15044
15045 check_dspr2(ctx);
15046
15047 if (rt == 0) {
15048 /* Treat as NOP. */
15049 MIPS_DEBUG("NOP");
15050 return;
15051 }
15052
15053 t0 = tcg_temp_new();
15054 gen_load_gpr(t0, rs);
15055
15056 switch (op1) {
15057 case OPC_APPEND_DSP:
15058 switch (MASK_APPEND(ctx->opcode)) {
15059 case OPC_APPEND:
15060 if (sa != 0) {
15061 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15062 }
15063 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15064 break;
15065 case OPC_PREPEND:
15066 if (sa != 0) {
15067 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15068 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15069 tcg_gen_shli_tl(t0, t0, 32 - sa);
15070 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15071 }
15072 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15073 break;
15074 case OPC_BALIGN:
15075 sa &= 3;
15076 if (sa != 0 && sa != 2) {
15077 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15078 tcg_gen_ext32u_tl(t0, t0);
15079 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15080 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15081 }
15082 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15083 break;
15084 default: /* Invalid */
15085 MIPS_INVAL("MASK APPEND");
15086 generate_exception(ctx, EXCP_RI);
15087 break;
15088 }
15089 break;
15090#ifdef TARGET_MIPS64
26690560 15091 case OPC_DAPPEND_DSP:
df6126a7 15092 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15093 case OPC_DAPPEND:
df6126a7
AJ
15094 if (sa != 0) {
15095 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15096 }
26690560
JL
15097 break;
15098 case OPC_PREPENDD:
df6126a7
AJ
15099 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15100 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15101 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15102 break;
15103 case OPC_PREPENDW:
df6126a7
AJ
15104 if (sa != 0) {
15105 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15106 tcg_gen_shli_tl(t0, t0, 64 - sa);
15107 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15108 }
26690560
JL
15109 break;
15110 case OPC_DBALIGN:
df6126a7
AJ
15111 sa &= 7;
15112 if (sa != 0 && sa != 2 && sa != 4) {
15113 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15114 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15115 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15116 }
26690560
JL
15117 break;
15118 default: /* Invalid */
15119 MIPS_INVAL("MASK DAPPEND");
15120 generate_exception(ctx, EXCP_RI);
15121 break;
15122 }
15123 break;
15124#endif
15125 }
df6126a7 15126 tcg_temp_free(t0);
26690560
JL
15127 (void)opn; /* avoid a compiler warning */
15128 MIPS_DEBUG("%s", opn);
15129}
15130
b53371ed
JL
15131static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15132 int ret, int v1, int v2, int check_ret)
15133
15134{
15135 const char *opn = "mipsdsp accumulator";
15136 TCGv t0;
15137 TCGv t1;
15138 TCGv v1_t;
15139 TCGv v2_t;
15140 int16_t imm;
15141
15142 if ((ret == 0) && (check_ret == 1)) {
15143 /* Treat as NOP. */
15144 MIPS_DEBUG("NOP");
15145 return;
15146 }
15147
15148 t0 = tcg_temp_new();
15149 t1 = tcg_temp_new();
15150 v1_t = tcg_temp_new();
15151 v2_t = tcg_temp_new();
15152
15153 gen_load_gpr(v1_t, v1);
15154 gen_load_gpr(v2_t, v2);
15155
15156 switch (op1) {
15157 case OPC_EXTR_W_DSP:
15158 check_dsp(ctx);
15159 switch (op2) {
15160 case OPC_EXTR_W:
15161 tcg_gen_movi_tl(t0, v2);
15162 tcg_gen_movi_tl(t1, v1);
15163 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15164 break;
15165 case OPC_EXTR_R_W:
15166 tcg_gen_movi_tl(t0, v2);
15167 tcg_gen_movi_tl(t1, v1);
15168 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15169 break;
15170 case OPC_EXTR_RS_W:
15171 tcg_gen_movi_tl(t0, v2);
15172 tcg_gen_movi_tl(t1, v1);
15173 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15174 break;
15175 case OPC_EXTR_S_H:
15176 tcg_gen_movi_tl(t0, v2);
15177 tcg_gen_movi_tl(t1, v1);
15178 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15179 break;
15180 case OPC_EXTRV_S_H:
15181 tcg_gen_movi_tl(t0, v2);
15182 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15183 break;
15184 case OPC_EXTRV_W:
15185 tcg_gen_movi_tl(t0, v2);
15186 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15187 break;
15188 case OPC_EXTRV_R_W:
15189 tcg_gen_movi_tl(t0, v2);
15190 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15191 break;
15192 case OPC_EXTRV_RS_W:
15193 tcg_gen_movi_tl(t0, v2);
15194 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15195 break;
15196 case OPC_EXTP:
15197 tcg_gen_movi_tl(t0, v2);
15198 tcg_gen_movi_tl(t1, v1);
15199 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15200 break;
15201 case OPC_EXTPV:
15202 tcg_gen_movi_tl(t0, v2);
15203 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15204 break;
15205 case OPC_EXTPDP:
15206 tcg_gen_movi_tl(t0, v2);
15207 tcg_gen_movi_tl(t1, v1);
15208 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15209 break;
15210 case OPC_EXTPDPV:
15211 tcg_gen_movi_tl(t0, v2);
15212 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15213 break;
15214 case OPC_SHILO:
15215 imm = (ctx->opcode >> 20) & 0x3F;
15216 tcg_gen_movi_tl(t0, ret);
15217 tcg_gen_movi_tl(t1, imm);
15218 gen_helper_shilo(t0, t1, cpu_env);
15219 break;
15220 case OPC_SHILOV:
15221 tcg_gen_movi_tl(t0, ret);
15222 gen_helper_shilo(t0, v1_t, cpu_env);
15223 break;
15224 case OPC_MTHLIP:
15225 tcg_gen_movi_tl(t0, ret);
15226 gen_helper_mthlip(t0, v1_t, cpu_env);
15227 break;
15228 case OPC_WRDSP:
15229 imm = (ctx->opcode >> 11) & 0x3FF;
15230 tcg_gen_movi_tl(t0, imm);
15231 gen_helper_wrdsp(v1_t, t0, cpu_env);
15232 break;
15233 case OPC_RDDSP:
15234 imm = (ctx->opcode >> 16) & 0x03FF;
15235 tcg_gen_movi_tl(t0, imm);
15236 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15237 break;
15238 }
15239 break;
15240#ifdef TARGET_MIPS64
15241 case OPC_DEXTR_W_DSP:
15242 check_dsp(ctx);
15243 switch (op2) {
15244 case OPC_DMTHLIP:
15245 tcg_gen_movi_tl(t0, ret);
15246 gen_helper_dmthlip(v1_t, t0, cpu_env);
15247 break;
15248 case OPC_DSHILO:
15249 {
15250 int shift = (ctx->opcode >> 19) & 0x7F;
15251 int ac = (ctx->opcode >> 11) & 0x03;
15252 tcg_gen_movi_tl(t0, shift);
15253 tcg_gen_movi_tl(t1, ac);
15254 gen_helper_dshilo(t0, t1, cpu_env);
15255 break;
15256 }
15257 case OPC_DSHILOV:
15258 {
15259 int ac = (ctx->opcode >> 11) & 0x03;
15260 tcg_gen_movi_tl(t0, ac);
15261 gen_helper_dshilo(v1_t, t0, cpu_env);
15262 break;
15263 }
15264 case OPC_DEXTP:
15265 tcg_gen_movi_tl(t0, v2);
15266 tcg_gen_movi_tl(t1, v1);
15267
15268 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15269 break;
15270 case OPC_DEXTPV:
15271 tcg_gen_movi_tl(t0, v2);
15272 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15273 break;
15274 case OPC_DEXTPDP:
15275 tcg_gen_movi_tl(t0, v2);
15276 tcg_gen_movi_tl(t1, v1);
15277 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15278 break;
15279 case OPC_DEXTPDPV:
15280 tcg_gen_movi_tl(t0, v2);
15281 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15282 break;
15283 case OPC_DEXTR_L:
15284 tcg_gen_movi_tl(t0, v2);
15285 tcg_gen_movi_tl(t1, v1);
15286 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15287 break;
15288 case OPC_DEXTR_R_L:
15289 tcg_gen_movi_tl(t0, v2);
15290 tcg_gen_movi_tl(t1, v1);
15291 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15292 break;
15293 case OPC_DEXTR_RS_L:
15294 tcg_gen_movi_tl(t0, v2);
15295 tcg_gen_movi_tl(t1, v1);
15296 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15297 break;
15298 case OPC_DEXTR_W:
15299 tcg_gen_movi_tl(t0, v2);
15300 tcg_gen_movi_tl(t1, v1);
15301 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15302 break;
15303 case OPC_DEXTR_R_W:
15304 tcg_gen_movi_tl(t0, v2);
15305 tcg_gen_movi_tl(t1, v1);
15306 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15307 break;
15308 case OPC_DEXTR_RS_W:
15309 tcg_gen_movi_tl(t0, v2);
15310 tcg_gen_movi_tl(t1, v1);
15311 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15312 break;
15313 case OPC_DEXTR_S_H:
15314 tcg_gen_movi_tl(t0, v2);
15315 tcg_gen_movi_tl(t1, v1);
15316 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15317 break;
15318 case OPC_DEXTRV_S_H:
15319 tcg_gen_movi_tl(t0, v2);
15320 tcg_gen_movi_tl(t1, v1);
15321 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15322 break;
15323 case OPC_DEXTRV_L:
15324 tcg_gen_movi_tl(t0, v2);
15325 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15326 break;
15327 case OPC_DEXTRV_R_L:
15328 tcg_gen_movi_tl(t0, v2);
15329 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15330 break;
15331 case OPC_DEXTRV_RS_L:
15332 tcg_gen_movi_tl(t0, v2);
15333 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15334 break;
15335 case OPC_DEXTRV_W:
15336 tcg_gen_movi_tl(t0, v2);
15337 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15338 break;
15339 case OPC_DEXTRV_R_W:
15340 tcg_gen_movi_tl(t0, v2);
15341 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15342 break;
15343 case OPC_DEXTRV_RS_W:
15344 tcg_gen_movi_tl(t0, v2);
15345 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15346 break;
15347 }
15348 break;
15349#endif
15350 }
15351
15352 tcg_temp_free(t0);
15353 tcg_temp_free(t1);
15354 tcg_temp_free(v1_t);
15355 tcg_temp_free(v2_t);
15356
15357 (void)opn; /* avoid a compiler warning */
15358 MIPS_DEBUG("%s", opn);
15359}
15360
9b1a1d68
JL
15361/* End MIPSDSP functions. */
15362
31837be3
YK
15363/* Compact Branches */
15364static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15365 int rs, int rt, int32_t offset)
15366{
15367 int bcond_compute = 0;
15368 TCGv t0 = tcg_temp_new();
15369 TCGv t1 = tcg_temp_new();
15370
15371 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15372#ifdef MIPS_DEBUG_DISAS
15373 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
15374#endif
15375 generate_exception(ctx, EXCP_RI);
15376 goto out;
15377 }
15378
15379 /* Load needed operands and calculate btarget */
15380 switch (opc) {
15381 /* compact branch */
15382 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15383 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15384 gen_load_gpr(t0, rs);
15385 gen_load_gpr(t1, rt);
15386 bcond_compute = 1;
15387 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15388 if (rs <= rt && rs == 0) {
15389 /* OPC_BEQZALC, OPC_BNEZALC */
15390 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15391 }
15392 break;
15393 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15394 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15395 gen_load_gpr(t0, rs);
15396 gen_load_gpr(t1, rt);
15397 bcond_compute = 1;
15398 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15399 break;
15400 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15401 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15402 if (rs == 0 || rs == rt) {
15403 /* OPC_BLEZALC, OPC_BGEZALC */
15404 /* OPC_BGTZALC, OPC_BLTZALC */
15405 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15406 }
15407 gen_load_gpr(t0, rs);
15408 gen_load_gpr(t1, rt);
15409 bcond_compute = 1;
15410 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15411 break;
15412 case OPC_BC:
15413 case OPC_BALC:
15414 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15415 break;
15416 case OPC_BEQZC:
15417 case OPC_BNEZC:
15418 if (rs != 0) {
15419 /* OPC_BEQZC, OPC_BNEZC */
15420 gen_load_gpr(t0, rs);
15421 bcond_compute = 1;
15422 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15423 } else {
15424 /* OPC_JIC, OPC_JIALC */
15425 TCGv tbase = tcg_temp_new();
15426 TCGv toffset = tcg_temp_new();
15427
15428 gen_load_gpr(tbase, rt);
15429 tcg_gen_movi_tl(toffset, offset);
15430 gen_op_addr_add(ctx, btarget, tbase, toffset);
15431 tcg_temp_free(tbase);
15432 tcg_temp_free(toffset);
15433 }
15434 break;
15435 default:
15436 MIPS_INVAL("Compact branch/jump");
15437 generate_exception(ctx, EXCP_RI);
15438 goto out;
15439 }
15440
15441 if (bcond_compute == 0) {
15442 /* Uncoditional compact branch */
15443 switch (opc) {
15444 case OPC_JIALC:
15445 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15446 /* Fallthrough */
15447 case OPC_JIC:
15448 ctx->hflags |= MIPS_HFLAG_BR;
15449 break;
15450 case OPC_BALC:
15451 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15452 /* Fallthrough */
15453 case OPC_BC:
15454 ctx->hflags |= MIPS_HFLAG_B;
15455 break;
15456 default:
15457 MIPS_INVAL("Compact branch/jump");
15458 generate_exception(ctx, EXCP_RI);
15459 goto out;
15460 }
15461
15462 /* Generating branch here as compact branches don't have delay slot */
15463 gen_branch(ctx, 4);
15464 } else {
15465 /* Conditional compact branch */
15466 int l1 = gen_new_label();
15467 save_cpu_state(ctx, 0);
15468
15469 switch (opc) {
15470 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15471 if (rs == 0 && rt != 0) {
15472 /* OPC_BLEZALC */
15473 tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
15474 } else if (rs != 0 && rt != 0 && rs == rt) {
15475 /* OPC_BGEZALC */
15476 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
15477 } else {
15478 /* OPC_BGEUC */
15479 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
15480 }
15481 break;
15482 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15483 if (rs == 0 && rt != 0) {
15484 /* OPC_BGTZALC */
15485 tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
15486 } else if (rs != 0 && rt != 0 && rs == rt) {
15487 /* OPC_BLTZALC */
15488 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
15489 } else {
15490 /* OPC_BLTUC */
15491 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
15492 }
15493 break;
15494 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15495 if (rs == 0 && rt != 0) {
15496 /* OPC_BLEZC */
15497 tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
15498 } else if (rs != 0 && rt != 0 && rs == rt) {
15499 /* OPC_BGEZC */
15500 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
15501 } else {
15502 /* OPC_BGEC */
15503 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
15504 }
15505 break;
15506 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15507 if (rs == 0 && rt != 0) {
15508 /* OPC_BGTZC */
15509 tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
15510 } else if (rs != 0 && rt != 0 && rs == rt) {
15511 /* OPC_BLTZC */
15512 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
15513 } else {
15514 /* OPC_BLTC */
15515 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
15516 }
15517 break;
15518 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15519 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15520 if (rs >= rt) {
15521 /* OPC_BOVC, OPC_BNVC */
15522 TCGv t2 = tcg_temp_new();
15523 TCGv t3 = tcg_temp_new();
15524 TCGv t4 = tcg_temp_new();
15525 TCGv input_overflow = tcg_temp_new();
15526
15527 gen_load_gpr(t0, rs);
15528 gen_load_gpr(t1, rt);
15529 tcg_gen_ext32s_tl(t2, t0);
15530 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
15531 tcg_gen_ext32s_tl(t3, t1);
15532 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
15533 tcg_gen_or_tl(input_overflow, input_overflow, t4);
15534
15535 tcg_gen_add_tl(t4, t2, t3);
15536 tcg_gen_ext32s_tl(t4, t4);
15537 tcg_gen_xor_tl(t2, t2, t3);
15538 tcg_gen_xor_tl(t3, t4, t3);
15539 tcg_gen_andc_tl(t2, t3, t2);
15540 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
15541 tcg_gen_or_tl(t4, t4, input_overflow);
15542 if (opc == OPC_BOVC) {
15543 /* OPC_BOVC */
15544 tcg_gen_brcondi_tl(TCG_COND_NE, t4, 0, l1);
15545 } else {
15546 /* OPC_BNVC */
15547 tcg_gen_brcondi_tl(TCG_COND_EQ, t4, 0, l1);
15548 }
15549 tcg_temp_free(input_overflow);
15550 tcg_temp_free(t4);
15551 tcg_temp_free(t3);
15552 tcg_temp_free(t2);
15553 } else if (rs < rt && rs == 0) {
15554 /* OPC_BEQZALC, OPC_BNEZALC */
15555 if (opc == OPC_BEQZALC) {
15556 /* OPC_BEQZALC */
15557 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
15558 } else {
15559 /* OPC_BNEZALC */
15560 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
15561 }
15562 } else {
15563 /* OPC_BEQC, OPC_BNEC */
15564 if (opc == OPC_BEQC) {
15565 /* OPC_BEQC */
15566 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
15567 } else {
15568 /* OPC_BNEC */
15569 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
15570 }
15571 }
15572 break;
15573 case OPC_BEQZC:
15574 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
15575 break;
15576 case OPC_BNEZC:
15577 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
15578 break;
15579 default:
15580 MIPS_INVAL("Compact conditional branch/jump");
15581 generate_exception(ctx, EXCP_RI);
15582 goto out;
15583 }
15584
15585 /* Generating branch here as compact branches don't have delay slot */
15586 /* TODO: implement forbidden slot */
15587 gen_goto_tb(ctx, 1, ctx->pc + 4);
15588 gen_set_label(l1);
15589 gen_goto_tb(ctx, 0, ctx->btarget);
15590 MIPS_DEBUG("Compact conditional branch");
15591 ctx->bstate = BS_BRANCH;
15592 }
15593
15594out:
15595 tcg_temp_free(t0);
15596 tcg_temp_free(t1);
15597}
15598
10dc65db
LA
15599static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
15600{
4267d3e6 15601 int rs, rt, rd, sa;
b42ee5e1 15602 uint32_t op1, op2;
10dc65db
LA
15603
15604 rs = (ctx->opcode >> 21) & 0x1f;
15605 rt = (ctx->opcode >> 16) & 0x1f;
15606 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 15607 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
15608
15609 op1 = MASK_SPECIAL(ctx->opcode);
15610 switch (op1) {
d4ea6acd
LA
15611 case OPC_LSA:
15612 if (rd != 0) {
15613 int imm2 = extract32(ctx->opcode, 6, 3);
15614 TCGv t0 = tcg_temp_new();
15615 TCGv t1 = tcg_temp_new();
15616 gen_load_gpr(t0, rs);
15617 gen_load_gpr(t1, rt);
15618 tcg_gen_shli_tl(t0, t0, imm2 + 1);
15619 tcg_gen_add_tl(t0, t0, t1);
15620 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
15621 tcg_temp_free(t1);
15622 tcg_temp_free(t0);
15623 }
15624 break;
b42ee5e1
LA
15625 case OPC_MULT ... OPC_DIVU:
15626 op2 = MASK_R6_MULDIV(ctx->opcode);
15627 switch (op2) {
15628 case R6_OPC_MUL:
15629 case R6_OPC_MUH:
15630 case R6_OPC_MULU:
15631 case R6_OPC_MUHU:
15632 case R6_OPC_DIV:
15633 case R6_OPC_MOD:
15634 case R6_OPC_DIVU:
15635 case R6_OPC_MODU:
15636 gen_r6_muldiv(ctx, op2, rd, rs, rt);
15637 break;
15638 default:
15639 MIPS_INVAL("special_r6 muldiv");
15640 generate_exception(ctx, EXCP_RI);
15641 break;
15642 }
15643 break;
10dc65db
LA
15644 case OPC_SELEQZ:
15645 case OPC_SELNEZ:
15646 gen_cond_move(ctx, op1, rd, rs, rt);
15647 break;
4267d3e6
LA
15648 case R6_OPC_CLO:
15649 case R6_OPC_CLZ:
15650 if (rt == 0 && sa == 1) {
15651 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15652 We need additionally to check other fields */
15653 gen_cl(ctx, op1, rd, rs);
15654 } else {
15655 generate_exception(ctx, EXCP_RI);
15656 }
15657 break;
15658 case R6_OPC_SDBBP:
15659 generate_exception(ctx, EXCP_DBp);
15660 break;
b42ee5e1 15661#if defined(TARGET_MIPS64)
d4ea6acd
LA
15662 case OPC_DLSA:
15663 check_mips_64(ctx);
15664 if (rd != 0) {
15665 int imm2 = extract32(ctx->opcode, 6, 3);
15666 TCGv t0 = tcg_temp_new();
15667 TCGv t1 = tcg_temp_new();
15668 gen_load_gpr(t0, rs);
15669 gen_load_gpr(t1, rt);
15670 tcg_gen_shli_tl(t0, t0, imm2 + 1);
15671 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
15672 tcg_temp_free(t1);
15673 tcg_temp_free(t0);
15674 }
15675 break;
4267d3e6
LA
15676 case R6_OPC_DCLO:
15677 case R6_OPC_DCLZ:
15678 if (rt == 0 && sa == 1) {
15679 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15680 We need additionally to check other fields */
15681 check_mips_64(ctx);
15682 gen_cl(ctx, op1, rd, rs);
15683 } else {
15684 generate_exception(ctx, EXCP_RI);
15685 }
15686 break;
b42ee5e1
LA
15687 case OPC_DMULT ... OPC_DDIVU:
15688 op2 = MASK_R6_MULDIV(ctx->opcode);
15689 switch (op2) {
15690 case R6_OPC_DMUL:
15691 case R6_OPC_DMUH:
15692 case R6_OPC_DMULU:
15693 case R6_OPC_DMUHU:
15694 case R6_OPC_DDIV:
15695 case R6_OPC_DMOD:
15696 case R6_OPC_DDIVU:
15697 case R6_OPC_DMODU:
15698 check_mips_64(ctx);
15699 gen_r6_muldiv(ctx, op2, rd, rs, rt);
15700 break;
15701 default:
15702 MIPS_INVAL("special_r6 muldiv");
15703 generate_exception(ctx, EXCP_RI);
15704 break;
15705 }
15706 break;
15707#endif
10dc65db
LA
15708 default: /* Invalid */
15709 MIPS_INVAL("special_r6");
15710 generate_exception(ctx, EXCP_RI);
15711 break;
15712 }
15713}
15714
15715static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
15716{
b42ee5e1 15717 int rs, rt, rd, sa;
10dc65db
LA
15718 uint32_t op1;
15719
15720 rs = (ctx->opcode >> 21) & 0x1f;
15721 rt = (ctx->opcode >> 16) & 0x1f;
15722 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 15723 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
15724
15725 op1 = MASK_SPECIAL(ctx->opcode);
15726 switch (op1) {
15727 case OPC_MOVN: /* Conditional move */
15728 case OPC_MOVZ:
15729 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
15730 INSN_LOONGSON2E | INSN_LOONGSON2F);
15731 gen_cond_move(ctx, op1, rd, rs, rt);
15732 break;
15733 case OPC_MFHI: /* Move from HI/LO */
15734 case OPC_MFLO:
15735 gen_HILO(ctx, op1, rs & 3, rd);
15736 break;
15737 case OPC_MTHI:
15738 case OPC_MTLO: /* Move to HI/LO */
15739 gen_HILO(ctx, op1, rd & 3, rs);
15740 break;
15741 case OPC_MOVCI:
15742 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15743 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15744 check_cp1_enabled(ctx);
15745 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
15746 (ctx->opcode >> 16) & 1);
15747 } else {
15748 generate_exception_err(ctx, EXCP_CpU, 1);
15749 }
15750 break;
b42ee5e1
LA
15751 case OPC_MULT:
15752 case OPC_MULTU:
15753 if (sa) {
15754 check_insn(ctx, INSN_VR54XX);
15755 op1 = MASK_MUL_VR54XX(ctx->opcode);
15756 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
15757 } else {
15758 gen_muldiv(ctx, op1, rd & 3, rs, rt);
15759 }
15760 break;
15761 case OPC_DIV:
15762 case OPC_DIVU:
15763 gen_muldiv(ctx, op1, 0, rs, rt);
15764 break;
15765#if defined(TARGET_MIPS64)
15766 case OPC_DMULT ... OPC_DDIVU:
15767 check_insn(ctx, ISA_MIPS3);
15768 check_mips_64(ctx);
15769 gen_muldiv(ctx, op1, 0, rs, rt);
15770 break;
15771#endif
0aefa333 15772 case OPC_JR:
b231c103 15773 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 15774 break;
4267d3e6
LA
15775 case OPC_SPIM:
15776#ifdef MIPS_STRICT_STANDARD
15777 MIPS_INVAL("SPIM");
15778 generate_exception(ctx, EXCP_RI);
15779#else
15780 /* Implemented as RI exception for now. */
15781 MIPS_INVAL("spim (unofficial)");
15782 generate_exception(ctx, EXCP_RI);
15783#endif
15784 break;
10dc65db
LA
15785 default: /* Invalid */
15786 MIPS_INVAL("special_legacy");
15787 generate_exception(ctx, EXCP_RI);
15788 break;
15789 }
15790}
15791
099e5b4d 15792static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 15793{
3c824109 15794 int rs, rt, rd, sa;
099e5b4d 15795 uint32_t op1;
3c824109 15796
3c824109
NF
15797 rs = (ctx->opcode >> 21) & 0x1f;
15798 rt = (ctx->opcode >> 16) & 0x1f;
15799 rd = (ctx->opcode >> 11) & 0x1f;
15800 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
15801
15802 op1 = MASK_SPECIAL(ctx->opcode);
15803 switch (op1) {
15804 case OPC_SLL: /* Shift with immediate */
15805 case OPC_SRA:
15806 gen_shift_imm(ctx, op1, rd, rt, sa);
15807 break;
15808 case OPC_SRL:
15809 switch ((ctx->opcode >> 21) & 0x1f) {
15810 case 1:
15811 /* rotr is decoded as srl on non-R2 CPUs */
15812 if (ctx->insn_flags & ISA_MIPS32R2) {
15813 op1 = OPC_ROTR;
ea63e2c3 15814 }
099e5b4d
LA
15815 /* Fallthrough */
15816 case 0:
15817 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 15818 break;
099e5b4d
LA
15819 default:
15820 generate_exception(ctx, EXCP_RI);
ea63e2c3 15821 break;
099e5b4d
LA
15822 }
15823 break;
099e5b4d
LA
15824 case OPC_ADD ... OPC_SUBU:
15825 gen_arith(ctx, op1, rd, rs, rt);
15826 break;
15827 case OPC_SLLV: /* Shifts */
15828 case OPC_SRAV:
15829 gen_shift(ctx, op1, rd, rs, rt);
15830 break;
15831 case OPC_SRLV:
15832 switch ((ctx->opcode >> 6) & 0x1f) {
15833 case 1:
15834 /* rotrv is decoded as srlv on non-R2 CPUs */
15835 if (ctx->insn_flags & ISA_MIPS32R2) {
15836 op1 = OPC_ROTRV;
26135ead 15837 }
099e5b4d
LA
15838 /* Fallthrough */
15839 case 0:
15840 gen_shift(ctx, op1, rd, rs, rt);
26135ead 15841 break;
099e5b4d
LA
15842 default:
15843 generate_exception(ctx, EXCP_RI);
6af0bf9c 15844 break;
099e5b4d
LA
15845 }
15846 break;
15847 case OPC_SLT: /* Set on less than */
15848 case OPC_SLTU:
15849 gen_slt(ctx, op1, rd, rs, rt);
15850 break;
15851 case OPC_AND: /* Logic*/
15852 case OPC_OR:
15853 case OPC_NOR:
15854 case OPC_XOR:
15855 gen_logic(ctx, op1, rd, rs, rt);
15856 break;
0aefa333 15857 case OPC_JALR:
b231c103 15858 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
15859 break;
15860 case OPC_TGE ... OPC_TEQ: /* Traps */
15861 case OPC_TNE:
15862 gen_trap(ctx, op1, rs, rt, -1);
15863 break;
d4ea6acd
LA
15864 case OPC_LSA: /* OPC_PMON */
15865 if (ctx->insn_flags & ISA_MIPS32R6) {
15866 decode_opc_special_r6(env, ctx);
15867 } else {
15868 /* Pmon entry point, also R4010 selsl */
b48cfdff 15869#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
15870 MIPS_INVAL("PMON / selsl");
15871 generate_exception(ctx, EXCP_RI);
b48cfdff 15872#else
d4ea6acd 15873 gen_helper_0e0i(pmon, sa);
b48cfdff 15874#endif
d4ea6acd 15875 }
099e5b4d
LA
15876 break;
15877 case OPC_SYSCALL:
15878 generate_exception(ctx, EXCP_SYSCALL);
15879 ctx->bstate = BS_STOP;
15880 break;
15881 case OPC_BREAK:
15882 generate_exception(ctx, EXCP_BREAK);
15883 break;
099e5b4d
LA
15884 case OPC_SYNC:
15885 /* Treat as NOP. */
15886 break;
4ad40f36 15887
d26bc211 15888#if defined(TARGET_MIPS64)
099e5b4d
LA
15889 /* MIPS64 specific opcodes */
15890 case OPC_DSLL:
15891 case OPC_DSRA:
15892 case OPC_DSLL32:
15893 case OPC_DSRA32:
15894 check_insn(ctx, ISA_MIPS3);
15895 check_mips_64(ctx);
15896 gen_shift_imm(ctx, op1, rd, rt, sa);
15897 break;
15898 case OPC_DSRL:
15899 switch ((ctx->opcode >> 21) & 0x1f) {
15900 case 1:
15901 /* drotr is decoded as dsrl on non-R2 CPUs */
15902 if (ctx->insn_flags & ISA_MIPS32R2) {
15903 op1 = OPC_DROTR;
ea63e2c3 15904 }
099e5b4d
LA
15905 /* Fallthrough */
15906 case 0:
d75c135e 15907 check_insn(ctx, ISA_MIPS3);
e189e748 15908 check_mips_64(ctx);
099e5b4d 15909 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 15910 break;
099e5b4d
LA
15911 default:
15912 generate_exception(ctx, EXCP_RI);
460f00c4 15913 break;
099e5b4d
LA
15914 }
15915 break;
15916 case OPC_DSRL32:
15917 switch ((ctx->opcode >> 21) & 0x1f) {
15918 case 1:
15919 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
15920 if (ctx->insn_flags & ISA_MIPS32R2) {
15921 op1 = OPC_DROTR32;
ea63e2c3 15922 }
099e5b4d
LA
15923 /* Fallthrough */
15924 case 0:
d75c135e 15925 check_insn(ctx, ISA_MIPS3);
e189e748 15926 check_mips_64(ctx);
099e5b4d 15927 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 15928 break;
099e5b4d 15929 default:
6af0bf9c
FB
15930 generate_exception(ctx, EXCP_RI);
15931 break;
15932 }
15933 break;
099e5b4d
LA
15934 case OPC_DADD ... OPC_DSUBU:
15935 check_insn(ctx, ISA_MIPS3);
15936 check_mips_64(ctx);
15937 gen_arith(ctx, op1, rd, rs, rt);
15938 break;
15939 case OPC_DSLLV:
15940 case OPC_DSRAV:
15941 check_insn(ctx, ISA_MIPS3);
15942 check_mips_64(ctx);
15943 gen_shift(ctx, op1, rd, rs, rt);
15944 break;
15945 case OPC_DSRLV:
15946 switch ((ctx->opcode >> 6) & 0x1f) {
15947 case 1:
15948 /* drotrv is decoded as dsrlv on non-R2 CPUs */
15949 if (ctx->insn_flags & ISA_MIPS32R2) {
15950 op1 = OPC_DROTRV;
6af0bf9c 15951 }
099e5b4d
LA
15952 /* Fallthrough */
15953 case 0:
15954 check_insn(ctx, ISA_MIPS3);
e189e748 15955 check_mips_64(ctx);
099e5b4d 15956 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 15957 break;
099e5b4d 15958 default:
6af0bf9c
FB
15959 generate_exception(ctx, EXCP_RI);
15960 break;
15961 }
15962 break;
099e5b4d 15963#endif
10dc65db
LA
15964 default:
15965 if (ctx->insn_flags & ISA_MIPS32R6) {
15966 decode_opc_special_r6(env, ctx);
15967 } else {
15968 decode_opc_special_legacy(env, ctx);
15969 }
15970 }
15971}
15972
10dc65db 15973static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
15974{
15975 int rs, rt, rd;
15976 uint32_t op1;
6c5c1e20 15977
4267d3e6
LA
15978 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15979
099e5b4d
LA
15980 rs = (ctx->opcode >> 21) & 0x1f;
15981 rt = (ctx->opcode >> 16) & 0x1f;
15982 rd = (ctx->opcode >> 11) & 0x1f;
15983
15984 op1 = MASK_SPECIAL2(ctx->opcode);
15985 switch (op1) {
15986 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
15987 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
15988 check_insn(ctx, ISA_MIPS32);
15989 gen_muldiv(ctx, op1, rd & 3, rs, rt);
15990 break;
15991 case OPC_MUL:
099e5b4d
LA
15992 gen_arith(ctx, op1, rd, rs, rt);
15993 break;
fac5a073
LA
15994 case OPC_DIV_G_2F:
15995 case OPC_DIVU_G_2F:
15996 case OPC_MULT_G_2F:
15997 case OPC_MULTU_G_2F:
15998 case OPC_MOD_G_2F:
15999 case OPC_MODU_G_2F:
16000 check_insn(ctx, INSN_LOONGSON2F);
16001 gen_loongson_integer(ctx, op1, rd, rs, rt);
16002 break;
099e5b4d
LA
16003 case OPC_CLO:
16004 case OPC_CLZ:
16005 check_insn(ctx, ISA_MIPS32);
16006 gen_cl(ctx, op1, rd, rs);
16007 break;
16008 case OPC_SDBBP:
16009 /* XXX: not clear which exception should be raised
16010 * when in debug mode...
16011 */
16012 check_insn(ctx, ISA_MIPS32);
16013 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16014 generate_exception(ctx, EXCP_DBp);
16015 } else {
16016 generate_exception(ctx, EXCP_DBp);
16017 }
16018 /* Treat as NOP. */
16019 break;
9b1a1d68 16020#if defined(TARGET_MIPS64)
099e5b4d
LA
16021 case OPC_DCLO:
16022 case OPC_DCLZ:
16023 check_insn(ctx, ISA_MIPS64);
16024 check_mips_64(ctx);
16025 gen_cl(ctx, op1, rd, rs);
16026 break;
4267d3e6
LA
16027 case OPC_DMULT_G_2F:
16028 case OPC_DMULTU_G_2F:
16029 case OPC_DDIV_G_2F:
16030 case OPC_DDIVU_G_2F:
16031 case OPC_DMOD_G_2F:
16032 case OPC_DMODU_G_2F:
16033 check_insn(ctx, INSN_LOONGSON2F);
16034 gen_loongson_integer(ctx, op1, rd, rs, rt);
16035 break;
10dc65db 16036#endif
4267d3e6
LA
16037 default: /* Invalid */
16038 MIPS_INVAL("special2_legacy");
16039 generate_exception(ctx, EXCP_RI);
16040 break;
10dc65db
LA
16041 }
16042}
16043
16044static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16045{
15eacb9b
YK
16046 int rs, rt, rd, sa;
16047 uint32_t op1, op2;
10dc65db
LA
16048 int16_t imm;
16049
16050 rs = (ctx->opcode >> 21) & 0x1f;
16051 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16052 rd = (ctx->opcode >> 11) & 0x1f;
16053 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16054 imm = (int16_t)ctx->opcode >> 7;
16055
16056 op1 = MASK_SPECIAL3(ctx->opcode);
16057 switch (op1) {
bf7910c6
LA
16058 case R6_OPC_PREF:
16059 if (rt >= 24) {
16060 /* hint codes 24-31 are reserved and signal RI */
16061 generate_exception(ctx, EXCP_RI);
16062 }
16063 /* Treat as NOP. */
16064 break;
16065 case R6_OPC_CACHE:
16066 /* Treat as NOP. */
16067 break;
10dc65db
LA
16068 case R6_OPC_SC:
16069 gen_st_cond(ctx, op1, rt, rs, imm);
16070 break;
16071 case R6_OPC_LL:
16072 gen_ld(ctx, op1, rt, rs, imm);
16073 break;
15eacb9b
YK
16074 case OPC_BSHFL:
16075 {
16076 if (rd == 0) {
16077 /* Treat as NOP. */
16078 break;
16079 }
16080 TCGv t0 = tcg_temp_new();
16081 gen_load_gpr(t0, rt);
16082
16083 op2 = MASK_BSHFL(ctx->opcode);
16084 switch (op2) {
16085 case OPC_ALIGN ... OPC_ALIGN_END:
16086 sa &= 3;
16087 if (sa == 0) {
16088 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16089 } else {
16090 TCGv t1 = tcg_temp_new();
16091 TCGv_i64 t2 = tcg_temp_new_i64();
16092 gen_load_gpr(t1, rs);
16093 tcg_gen_concat_tl_i64(t2, t1, t0);
16094 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16095#if defined(TARGET_MIPS64)
16096 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16097#else
16098 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16099#endif
16100 tcg_temp_free_i64(t2);
16101 tcg_temp_free(t1);
16102 }
16103 break;
16104 case OPC_BITSWAP:
16105 gen_helper_bitswap(cpu_gpr[rd], t0);
16106 break;
16107 }
16108 tcg_temp_free(t0);
16109 }
16110 break;
bf7910c6
LA
16111#if defined(TARGET_MIPS64)
16112 case R6_OPC_SCD:
16113 gen_st_cond(ctx, op1, rt, rs, imm);
16114 break;
16115 case R6_OPC_LLD:
16116 gen_ld(ctx, op1, rt, rs, imm);
16117 break;
15eacb9b
YK
16118 case OPC_DBSHFL:
16119 check_mips_64(ctx);
16120 {
16121 if (rd == 0) {
16122 /* Treat as NOP. */
16123 break;
16124 }
16125 TCGv t0 = tcg_temp_new();
16126 gen_load_gpr(t0, rt);
16127
16128 op2 = MASK_DBSHFL(ctx->opcode);
16129 switch (op2) {
16130 case OPC_DALIGN ... OPC_DALIGN_END:
16131 sa &= 7;
16132 if (sa == 0) {
16133 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16134 } else {
16135 TCGv t1 = tcg_temp_new();
16136 gen_load_gpr(t1, rs);
16137 tcg_gen_shli_tl(t0, t0, 8 * sa);
16138 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16139 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16140 tcg_temp_free(t1);
16141 }
16142 break;
16143 case OPC_DBITSWAP:
16144 gen_helper_dbitswap(cpu_gpr[rd], t0);
16145 break;
16146 }
16147 tcg_temp_free(t0);
16148 }
16149 break;
bf7910c6 16150#endif
10dc65db
LA
16151 default: /* Invalid */
16152 MIPS_INVAL("special3_r6");
16153 generate_exception(ctx, EXCP_RI);
16154 break;
16155 }
16156}
16157
16158static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16159{
fac5a073 16160 int rs, rt, rd;
099e5b4d 16161 uint32_t op1, op2;
099e5b4d
LA
16162
16163 rs = (ctx->opcode >> 21) & 0x1f;
16164 rt = (ctx->opcode >> 16) & 0x1f;
16165 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16166
16167 op1 = MASK_SPECIAL3(ctx->opcode);
16168 switch (op1) {
099e5b4d
LA
16169 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16170 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16171 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16172 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16173 * the same mask and op1. */
16174 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16175 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16176 switch (op2) {
099e5b4d
LA
16177 case OPC_ADDUH_QB:
16178 case OPC_ADDUH_R_QB:
16179 case OPC_ADDQH_PH:
16180 case OPC_ADDQH_R_PH:
16181 case OPC_ADDQH_W:
16182 case OPC_ADDQH_R_W:
16183 case OPC_SUBUH_QB:
16184 case OPC_SUBUH_R_QB:
16185 case OPC_SUBQH_PH:
16186 case OPC_SUBQH_R_PH:
16187 case OPC_SUBQH_W:
16188 case OPC_SUBQH_R_W:
461c08df
JL
16189 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16190 break;
099e5b4d
LA
16191 case OPC_MUL_PH:
16192 case OPC_MUL_S_PH:
16193 case OPC_MULQ_S_W:
16194 case OPC_MULQ_RS_W:
16195 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16196 break;
461c08df 16197 default:
099e5b4d 16198 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16199 generate_exception(ctx, EXCP_RI);
16200 break;
16201 }
099e5b4d
LA
16202 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16203 gen_loongson_integer(ctx, op1, rd, rs, rt);
16204 } else {
16205 generate_exception(ctx, EXCP_RI);
16206 }
16207 break;
16208 case OPC_LX_DSP:
16209 op2 = MASK_LX(ctx->opcode);
16210 switch (op2) {
16211#if defined(TARGET_MIPS64)
16212 case OPC_LDX:
16213#endif
16214 case OPC_LBUX:
16215 case OPC_LHX:
16216 case OPC_LWX:
16217 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16218 break;
16219 default: /* Invalid */
16220 MIPS_INVAL("MASK LX");
16221 generate_exception(ctx, EXCP_RI);
16222 break;
16223 }
16224 break;
16225 case OPC_ABSQ_S_PH_DSP:
16226 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16227 switch (op2) {
16228 case OPC_ABSQ_S_QB:
16229 case OPC_ABSQ_S_PH:
16230 case OPC_ABSQ_S_W:
16231 case OPC_PRECEQ_W_PHL:
16232 case OPC_PRECEQ_W_PHR:
16233 case OPC_PRECEQU_PH_QBL:
16234 case OPC_PRECEQU_PH_QBR:
16235 case OPC_PRECEQU_PH_QBLA:
16236 case OPC_PRECEQU_PH_QBRA:
16237 case OPC_PRECEU_PH_QBL:
16238 case OPC_PRECEU_PH_QBR:
16239 case OPC_PRECEU_PH_QBLA:
16240 case OPC_PRECEU_PH_QBRA:
16241 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16242 break;
16243 case OPC_BITREV:
16244 case OPC_REPL_QB:
16245 case OPC_REPLV_QB:
16246 case OPC_REPL_PH:
16247 case OPC_REPLV_PH:
16248 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16249 break;
16250 default:
16251 MIPS_INVAL("MASK ABSQ_S.PH");
16252 generate_exception(ctx, EXCP_RI);
16253 break;
16254 }
16255 break;
16256 case OPC_ADDU_QB_DSP:
16257 op2 = MASK_ADDU_QB(ctx->opcode);
16258 switch (op2) {
16259 case OPC_ADDQ_PH:
16260 case OPC_ADDQ_S_PH:
16261 case OPC_ADDQ_S_W:
16262 case OPC_ADDU_QB:
16263 case OPC_ADDU_S_QB:
16264 case OPC_ADDU_PH:
16265 case OPC_ADDU_S_PH:
16266 case OPC_SUBQ_PH:
16267 case OPC_SUBQ_S_PH:
16268 case OPC_SUBQ_S_W:
16269 case OPC_SUBU_QB:
16270 case OPC_SUBU_S_QB:
16271 case OPC_SUBU_PH:
16272 case OPC_SUBU_S_PH:
16273 case OPC_ADDSC:
16274 case OPC_ADDWC:
16275 case OPC_MODSUB:
16276 case OPC_RADDU_W_QB:
16277 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16278 break;
16279 case OPC_MULEU_S_PH_QBL:
16280 case OPC_MULEU_S_PH_QBR:
16281 case OPC_MULQ_RS_PH:
16282 case OPC_MULEQ_S_W_PHL:
16283 case OPC_MULEQ_S_W_PHR:
16284 case OPC_MULQ_S_PH:
16285 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16286 break;
16287 default: /* Invalid */
16288 MIPS_INVAL("MASK ADDU.QB");
16289 generate_exception(ctx, EXCP_RI);
461c08df 16290 break;
461c08df 16291
099e5b4d
LA
16292 }
16293 break;
16294 case OPC_CMPU_EQ_QB_DSP:
16295 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16296 switch (op2) {
16297 case OPC_PRECR_SRA_PH_W:
16298 case OPC_PRECR_SRA_R_PH_W:
16299 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16300 break;
099e5b4d
LA
16301 case OPC_PRECR_QB_PH:
16302 case OPC_PRECRQ_QB_PH:
16303 case OPC_PRECRQ_PH_W:
16304 case OPC_PRECRQ_RS_PH_W:
16305 case OPC_PRECRQU_S_QB_PH:
16306 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16307 break;
099e5b4d
LA
16308 case OPC_CMPU_EQ_QB:
16309 case OPC_CMPU_LT_QB:
16310 case OPC_CMPU_LE_QB:
16311 case OPC_CMP_EQ_PH:
16312 case OPC_CMP_LT_PH:
16313 case OPC_CMP_LE_PH:
16314 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16315 break;
099e5b4d
LA
16316 case OPC_CMPGU_EQ_QB:
16317 case OPC_CMPGU_LT_QB:
16318 case OPC_CMPGU_LE_QB:
16319 case OPC_CMPGDU_EQ_QB:
16320 case OPC_CMPGDU_LT_QB:
16321 case OPC_CMPGDU_LE_QB:
16322 case OPC_PICK_QB:
16323 case OPC_PICK_PH:
16324 case OPC_PACKRL_PH:
16325 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16326 break;
16327 default: /* Invalid */
16328 MIPS_INVAL("MASK CMPU.EQ.QB");
16329 generate_exception(ctx, EXCP_RI);
16330 break;
16331 }
16332 break;
16333 case OPC_SHLL_QB_DSP:
16334 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16335 break;
16336 case OPC_DPA_W_PH_DSP:
16337 op2 = MASK_DPA_W_PH(ctx->opcode);
16338 switch (op2) {
16339 case OPC_DPAU_H_QBL:
16340 case OPC_DPAU_H_QBR:
16341 case OPC_DPSU_H_QBL:
16342 case OPC_DPSU_H_QBR:
16343 case OPC_DPA_W_PH:
16344 case OPC_DPAX_W_PH:
16345 case OPC_DPAQ_S_W_PH:
16346 case OPC_DPAQX_S_W_PH:
16347 case OPC_DPAQX_SA_W_PH:
16348 case OPC_DPS_W_PH:
16349 case OPC_DPSX_W_PH:
16350 case OPC_DPSQ_S_W_PH:
16351 case OPC_DPSQX_S_W_PH:
16352 case OPC_DPSQX_SA_W_PH:
16353 case OPC_MULSAQ_S_W_PH:
16354 case OPC_DPAQ_SA_L_W:
16355 case OPC_DPSQ_SA_L_W:
16356 case OPC_MAQ_S_W_PHL:
16357 case OPC_MAQ_S_W_PHR:
16358 case OPC_MAQ_SA_W_PHL:
16359 case OPC_MAQ_SA_W_PHR:
16360 case OPC_MULSA_W_PH:
16361 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16362 break;
16363 default: /* Invalid */
16364 MIPS_INVAL("MASK DPAW.PH");
16365 generate_exception(ctx, EXCP_RI);
16366 break;
16367 }
16368 break;
16369 case OPC_INSV_DSP:
16370 op2 = MASK_INSV(ctx->opcode);
16371 switch (op2) {
16372 case OPC_INSV:
16373 check_dsp(ctx);
16374 {
16375 TCGv t0, t1;
16376
16377 if (rt == 0) {
16378 MIPS_DEBUG("NOP");
16379 break;
16380 }
16381
16382 t0 = tcg_temp_new();
16383 t1 = tcg_temp_new();
16384
16385 gen_load_gpr(t0, rt);
16386 gen_load_gpr(t1, rs);
16387
16388 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16389
16390 tcg_temp_free(t0);
16391 tcg_temp_free(t1);
a22260ae
JL
16392 break;
16393 }
099e5b4d
LA
16394 default: /* Invalid */
16395 MIPS_INVAL("MASK INSV");
16396 generate_exception(ctx, EXCP_RI);
16397 break;
16398 }
16399 break;
16400 case OPC_APPEND_DSP:
16401 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16402 break;
16403 case OPC_EXTR_W_DSP:
16404 op2 = MASK_EXTR_W(ctx->opcode);
16405 switch (op2) {
16406 case OPC_EXTR_W:
16407 case OPC_EXTR_R_W:
16408 case OPC_EXTR_RS_W:
16409 case OPC_EXTR_S_H:
16410 case OPC_EXTRV_S_H:
16411 case OPC_EXTRV_W:
16412 case OPC_EXTRV_R_W:
16413 case OPC_EXTRV_RS_W:
16414 case OPC_EXTP:
16415 case OPC_EXTPV:
16416 case OPC_EXTPDP:
16417 case OPC_EXTPDPV:
16418 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16419 break;
16420 case OPC_RDDSP:
16421 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16422 break;
16423 case OPC_SHILO:
16424 case OPC_SHILOV:
16425 case OPC_MTHLIP:
16426 case OPC_WRDSP:
16427 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16428 break;
16429 default: /* Invalid */
16430 MIPS_INVAL("MASK EXTR.W");
16431 generate_exception(ctx, EXCP_RI);
16432 break;
16433 }
16434 break;
099e5b4d 16435#if defined(TARGET_MIPS64)
fac5a073
LA
16436 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
16437 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
16438 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
16439 check_insn(ctx, INSN_LOONGSON2E);
16440 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 16441 break;
099e5b4d
LA
16442 case OPC_ABSQ_S_QH_DSP:
16443 op2 = MASK_ABSQ_S_QH(ctx->opcode);
16444 switch (op2) {
16445 case OPC_PRECEQ_L_PWL:
16446 case OPC_PRECEQ_L_PWR:
16447 case OPC_PRECEQ_PW_QHL:
16448 case OPC_PRECEQ_PW_QHR:
16449 case OPC_PRECEQ_PW_QHLA:
16450 case OPC_PRECEQ_PW_QHRA:
16451 case OPC_PRECEQU_QH_OBL:
16452 case OPC_PRECEQU_QH_OBR:
16453 case OPC_PRECEQU_QH_OBLA:
16454 case OPC_PRECEQU_QH_OBRA:
16455 case OPC_PRECEU_QH_OBL:
16456 case OPC_PRECEU_QH_OBR:
16457 case OPC_PRECEU_QH_OBLA:
16458 case OPC_PRECEU_QH_OBRA:
16459 case OPC_ABSQ_S_OB:
16460 case OPC_ABSQ_S_PW:
16461 case OPC_ABSQ_S_QH:
16462 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16463 break;
16464 case OPC_REPL_OB:
16465 case OPC_REPL_PW:
16466 case OPC_REPL_QH:
16467 case OPC_REPLV_OB:
16468 case OPC_REPLV_PW:
16469 case OPC_REPLV_QH:
16470 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16471 break;
16472 default: /* Invalid */
16473 MIPS_INVAL("MASK ABSQ_S.QH");
16474 generate_exception(ctx, EXCP_RI);
16475 break;
16476 }
16477 break;
16478 case OPC_ADDU_OB_DSP:
16479 op2 = MASK_ADDU_OB(ctx->opcode);
16480 switch (op2) {
16481 case OPC_RADDU_L_OB:
16482 case OPC_SUBQ_PW:
16483 case OPC_SUBQ_S_PW:
16484 case OPC_SUBQ_QH:
16485 case OPC_SUBQ_S_QH:
16486 case OPC_SUBU_OB:
16487 case OPC_SUBU_S_OB:
16488 case OPC_SUBU_QH:
16489 case OPC_SUBU_S_QH:
16490 case OPC_SUBUH_OB:
16491 case OPC_SUBUH_R_OB:
16492 case OPC_ADDQ_PW:
16493 case OPC_ADDQ_S_PW:
16494 case OPC_ADDQ_QH:
16495 case OPC_ADDQ_S_QH:
16496 case OPC_ADDU_OB:
16497 case OPC_ADDU_S_OB:
16498 case OPC_ADDU_QH:
16499 case OPC_ADDU_S_QH:
16500 case OPC_ADDUH_OB:
16501 case OPC_ADDUH_R_OB:
16502 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 16503 break;
099e5b4d
LA
16504 case OPC_MULEQ_S_PW_QHL:
16505 case OPC_MULEQ_S_PW_QHR:
16506 case OPC_MULEU_S_QH_OBL:
16507 case OPC_MULEU_S_QH_OBR:
16508 case OPC_MULQ_RS_QH:
16509 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16510 break;
099e5b4d
LA
16511 default: /* Invalid */
16512 MIPS_INVAL("MASK ADDU.OB");
16513 generate_exception(ctx, EXCP_RI);
26690560 16514 break;
099e5b4d
LA
16515 }
16516 break;
16517 case OPC_CMPU_EQ_OB_DSP:
16518 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
16519 switch (op2) {
16520 case OPC_PRECR_SRA_QH_PW:
16521 case OPC_PRECR_SRA_R_QH_PW:
16522 /* Return value is rt. */
16523 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 16524 break;
099e5b4d
LA
16525 case OPC_PRECR_OB_QH:
16526 case OPC_PRECRQ_OB_QH:
16527 case OPC_PRECRQ_PW_L:
16528 case OPC_PRECRQ_QH_PW:
16529 case OPC_PRECRQ_RS_QH_PW:
16530 case OPC_PRECRQU_S_OB_QH:
16531 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 16532 break;
099e5b4d
LA
16533 case OPC_CMPU_EQ_OB:
16534 case OPC_CMPU_LT_OB:
16535 case OPC_CMPU_LE_OB:
16536 case OPC_CMP_EQ_QH:
16537 case OPC_CMP_LT_QH:
16538 case OPC_CMP_LE_QH:
16539 case OPC_CMP_EQ_PW:
16540 case OPC_CMP_LT_PW:
16541 case OPC_CMP_LE_PW:
16542 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 16543 break;
099e5b4d
LA
16544 case OPC_CMPGDU_EQ_OB:
16545 case OPC_CMPGDU_LT_OB:
16546 case OPC_CMPGDU_LE_OB:
16547 case OPC_CMPGU_EQ_OB:
16548 case OPC_CMPGU_LT_OB:
16549 case OPC_CMPGU_LE_OB:
16550 case OPC_PACKRL_PW:
16551 case OPC_PICK_OB:
16552 case OPC_PICK_PW:
16553 case OPC_PICK_QH:
16554 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 16555 break;
099e5b4d
LA
16556 default: /* Invalid */
16557 MIPS_INVAL("MASK CMPU_EQ.OB");
16558 generate_exception(ctx, EXCP_RI);
161f85e6 16559 break;
099e5b4d
LA
16560 }
16561 break;
16562 case OPC_DAPPEND_DSP:
16563 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16564 break;
16565 case OPC_DEXTR_W_DSP:
16566 op2 = MASK_DEXTR_W(ctx->opcode);
16567 switch (op2) {
16568 case OPC_DEXTP:
16569 case OPC_DEXTPDP:
16570 case OPC_DEXTPDPV:
16571 case OPC_DEXTPV:
16572 case OPC_DEXTR_L:
16573 case OPC_DEXTR_R_L:
16574 case OPC_DEXTR_RS_L:
16575 case OPC_DEXTR_W:
16576 case OPC_DEXTR_R_W:
16577 case OPC_DEXTR_RS_W:
16578 case OPC_DEXTR_S_H:
16579 case OPC_DEXTRV_L:
16580 case OPC_DEXTRV_R_L:
16581 case OPC_DEXTRV_RS_L:
16582 case OPC_DEXTRV_S_H:
16583 case OPC_DEXTRV_W:
16584 case OPC_DEXTRV_R_W:
16585 case OPC_DEXTRV_RS_W:
16586 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 16587 break;
099e5b4d
LA
16588 case OPC_DMTHLIP:
16589 case OPC_DSHILO:
16590 case OPC_DSHILOV:
16591 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 16592 break;
099e5b4d
LA
16593 default: /* Invalid */
16594 MIPS_INVAL("MASK EXTR.W");
16595 generate_exception(ctx, EXCP_RI);
461c08df 16596 break;
099e5b4d
LA
16597 }
16598 break;
16599 case OPC_DPAQ_W_QH_DSP:
16600 op2 = MASK_DPAQ_W_QH(ctx->opcode);
16601 switch (op2) {
16602 case OPC_DPAU_H_OBL:
16603 case OPC_DPAU_H_OBR:
16604 case OPC_DPSU_H_OBL:
16605 case OPC_DPSU_H_OBR:
16606 case OPC_DPA_W_QH:
16607 case OPC_DPAQ_S_W_QH:
16608 case OPC_DPS_W_QH:
16609 case OPC_DPSQ_S_W_QH:
16610 case OPC_MULSAQ_S_W_QH:
16611 case OPC_DPAQ_SA_L_PW:
16612 case OPC_DPSQ_SA_L_PW:
16613 case OPC_MULSAQ_S_L_PW:
16614 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16615 break;
16616 case OPC_MAQ_S_W_QHLL:
16617 case OPC_MAQ_S_W_QHLR:
16618 case OPC_MAQ_S_W_QHRL:
16619 case OPC_MAQ_S_W_QHRR:
16620 case OPC_MAQ_SA_W_QHLL:
16621 case OPC_MAQ_SA_W_QHLR:
16622 case OPC_MAQ_SA_W_QHRL:
16623 case OPC_MAQ_SA_W_QHRR:
16624 case OPC_MAQ_S_L_PWL:
16625 case OPC_MAQ_S_L_PWR:
16626 case OPC_DMADD:
16627 case OPC_DMADDU:
16628 case OPC_DMSUB:
16629 case OPC_DMSUBU:
16630 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 16631 break;
099e5b4d
LA
16632 default: /* Invalid */
16633 MIPS_INVAL("MASK DPAQ.W.QH");
16634 generate_exception(ctx, EXCP_RI);
b53371ed 16635 break;
099e5b4d
LA
16636 }
16637 break;
16638 case OPC_DINSV_DSP:
16639 op2 = MASK_INSV(ctx->opcode);
16640 switch (op2) {
16641 case OPC_DINSV:
16642 {
16643 TCGv t0, t1;
16644
16645 if (rt == 0) {
16646 MIPS_DEBUG("NOP");
a22260ae
JL
16647 break;
16648 }
099e5b4d 16649 check_dsp(ctx);
1cb6686c 16650
099e5b4d
LA
16651 t0 = tcg_temp_new();
16652 t1 = tcg_temp_new();
1cb6686c 16653
099e5b4d
LA
16654 gen_load_gpr(t0, rt);
16655 gen_load_gpr(t1, rs);
1cb6686c 16656
099e5b4d 16657 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 16658
099e5b4d
LA
16659 tcg_temp_free(t0);
16660 tcg_temp_free(t1);
77c5fa8b 16661 break;
099e5b4d 16662 }
7a387fff 16663 default: /* Invalid */
099e5b4d 16664 MIPS_INVAL("MASK DINSV");
7a387fff
TS
16665 generate_exception(ctx, EXCP_RI);
16666 break;
16667 }
16668 break;
099e5b4d
LA
16669 case OPC_SHLL_OB_DSP:
16670 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16671 break;
16672#endif
fac5a073
LA
16673 default: /* Invalid */
16674 MIPS_INVAL("special3_legacy");
16675 generate_exception(ctx, EXCP_RI);
16676 break;
16677 }
16678}
16679
16680static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
16681{
16682 int rs, rt, rd, sa;
16683 uint32_t op1, op2;
16684
16685 rs = (ctx->opcode >> 21) & 0x1f;
16686 rt = (ctx->opcode >> 16) & 0x1f;
16687 rd = (ctx->opcode >> 11) & 0x1f;
16688 sa = (ctx->opcode >> 6) & 0x1f;
16689
16690 op1 = MASK_SPECIAL3(ctx->opcode);
16691 switch (op1) {
16692 case OPC_EXT:
16693 case OPC_INS:
16694 check_insn(ctx, ISA_MIPS32R2);
16695 gen_bitops(ctx, op1, rt, rs, sa, rd);
16696 break;
16697 case OPC_BSHFL:
fac5a073 16698 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
16699 switch (op2) {
16700 case OPC_ALIGN ... OPC_ALIGN_END:
16701 case OPC_BITSWAP:
16702 check_insn(ctx, ISA_MIPS32R6);
16703 decode_opc_special3_r6(env, ctx);
16704 break;
16705 default:
16706 check_insn(ctx, ISA_MIPS32R2);
16707 gen_bshfl(ctx, op2, rt, rd);
16708 break;
16709 }
fac5a073
LA
16710 break;
16711#if defined(TARGET_MIPS64)
16712 case OPC_DEXTM ... OPC_DEXT:
16713 case OPC_DINSM ... OPC_DINS:
16714 check_insn(ctx, ISA_MIPS64R2);
16715 check_mips_64(ctx);
16716 gen_bitops(ctx, op1, rt, rs, sa, rd);
16717 break;
16718 case OPC_DBSHFL:
fac5a073 16719 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
16720 switch (op2) {
16721 case OPC_DALIGN ... OPC_DALIGN_END:
16722 case OPC_DBITSWAP:
16723 check_insn(ctx, ISA_MIPS32R6);
16724 decode_opc_special3_r6(env, ctx);
16725 break;
16726 default:
16727 check_insn(ctx, ISA_MIPS64R2);
16728 check_mips_64(ctx);
16729 op2 = MASK_DBSHFL(ctx->opcode);
16730 gen_bshfl(ctx, op2, rt, rd);
16731 break;
16732 }
fac5a073
LA
16733 break;
16734#endif
16735 case OPC_RDHWR:
16736 gen_rdhwr(ctx, rt, rd);
16737 break;
16738 case OPC_FORK:
16739 check_insn(ctx, ASE_MT);
16740 {
16741 TCGv t0 = tcg_temp_new();
16742 TCGv t1 = tcg_temp_new();
16743
16744 gen_load_gpr(t0, rt);
16745 gen_load_gpr(t1, rs);
16746 gen_helper_fork(t0, t1);
16747 tcg_temp_free(t0);
16748 tcg_temp_free(t1);
16749 }
16750 break;
16751 case OPC_YIELD:
16752 check_insn(ctx, ASE_MT);
16753 {
16754 TCGv t0 = tcg_temp_new();
16755
16756 save_cpu_state(ctx, 1);
16757 gen_load_gpr(t0, rs);
16758 gen_helper_yield(t0, cpu_env, t0);
16759 gen_store_gpr(t0, rd);
16760 tcg_temp_free(t0);
16761 }
16762 break;
10dc65db
LA
16763 default:
16764 if (ctx->insn_flags & ISA_MIPS32R6) {
16765 decode_opc_special3_r6(env, ctx);
16766 } else {
16767 decode_opc_special3_legacy(env, ctx);
16768 }
099e5b4d
LA
16769 }
16770}
16771
16772static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
16773{
16774 int32_t offset;
16775 int rs, rt, rd, sa;
16776 uint32_t op, op1;
16777 int16_t imm;
16778
16779 /* make sure instructions are on a word boundary */
16780 if (ctx->pc & 0x3) {
16781 env->CP0_BadVAddr = ctx->pc;
16782 generate_exception(ctx, EXCP_AdEL);
16783 return;
16784 }
16785
16786 /* Handle blikely not taken case */
16787 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
16788 int l1 = gen_new_label();
16789
16790 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
16791 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
16792 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
16793 gen_goto_tb(ctx, 1, ctx->pc + 4);
16794 gen_set_label(l1);
16795 }
16796
16797 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
16798 tcg_gen_debug_insn_start(ctx->pc);
16799 }
16800
16801 op = MASK_OP_MAJOR(ctx->opcode);
16802 rs = (ctx->opcode >> 21) & 0x1f;
16803 rt = (ctx->opcode >> 16) & 0x1f;
16804 rd = (ctx->opcode >> 11) & 0x1f;
16805 sa = (ctx->opcode >> 6) & 0x1f;
16806 imm = (int16_t)ctx->opcode;
16807 switch (op) {
16808 case OPC_SPECIAL:
16809 decode_opc_special(env, ctx);
16810 break;
16811 case OPC_SPECIAL2:
4267d3e6 16812 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
16813 break;
16814 case OPC_SPECIAL3:
16815 decode_opc_special3(env, ctx);
16816 break;
7a387fff
TS
16817 case OPC_REGIMM:
16818 op1 = MASK_REGIMM(ctx->opcode);
16819 switch (op1) {
fecd2646
LA
16820 case OPC_BLTZL: /* REGIMM branches */
16821 case OPC_BGEZL:
16822 case OPC_BLTZALL:
16823 case OPC_BGEZALL:
16824 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16825 case OPC_BLTZ:
16826 case OPC_BGEZ:
b231c103 16827 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 16828 break;
fecd2646
LA
16829 case OPC_BLTZAL:
16830 case OPC_BGEZAL:
0aefa333
YK
16831 if (ctx->insn_flags & ISA_MIPS32R6) {
16832 if (rs == 0) {
16833 /* OPC_NAL, OPC_BAL */
b231c103 16834 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333
YK
16835 } else {
16836 generate_exception(ctx, EXCP_RI);
16837 }
16838 } else {
b231c103 16839 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 16840 }
c9602061 16841 break;
7a387fff
TS
16842 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
16843 case OPC_TNEI:
fecd2646 16844 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
16845 gen_trap(ctx, op1, rs, -1, imm);
16846 break;
16847 case OPC_SYNCI:
d75c135e 16848 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
16849 /* Break the TB to be able to sync copied instructions
16850 immediately */
16851 ctx->bstate = BS_STOP;
6af0bf9c 16852 break;
e45a93e2
JL
16853 case OPC_BPOSGE32: /* MIPS DSP branch */
16854#if defined(TARGET_MIPS64)
16855 case OPC_BPOSGE64:
16856#endif
16857 check_dsp(ctx);
b231c103 16858 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 16859 break;
d4ea6acd
LA
16860#if defined(TARGET_MIPS64)
16861 case OPC_DAHI:
16862 check_insn(ctx, ISA_MIPS32R6);
16863 check_mips_64(ctx);
16864 if (rs != 0) {
16865 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
16866 }
16867 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
16868 break;
16869 case OPC_DATI:
16870 check_insn(ctx, ISA_MIPS32R6);
16871 check_mips_64(ctx);
16872 if (rs != 0) {
16873 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
16874 }
16875 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
16876 break;
16877#endif
6af0bf9c 16878 default: /* Invalid */
923617a3 16879 MIPS_INVAL("regimm");
6af0bf9c
FB
16880 generate_exception(ctx, EXCP_RI);
16881 break;
16882 }
16883 break;
7a387fff 16884 case OPC_CP0:
387a8fe5 16885 check_cp0_enabled(ctx);
7a387fff 16886 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 16887 switch (op1) {
7a387fff
TS
16888 case OPC_MFC0:
16889 case OPC_MTC0:
ead9360e
TS
16890 case OPC_MFTR:
16891 case OPC_MTTR:
d26bc211 16892#if defined(TARGET_MIPS64)
7a387fff
TS
16893 case OPC_DMFC0:
16894 case OPC_DMTC0:
16895#endif
f1aa6320 16896#ifndef CONFIG_USER_ONLY
932e71cd 16897 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 16898#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
16899 break;
16900 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 16901#ifndef CONFIG_USER_ONLY
932e71cd 16902 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 16903#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
16904 break;
16905 case OPC_MFMC0:
8706c382 16906#ifndef CONFIG_USER_ONLY
932e71cd 16907 {
099e5b4d 16908 uint32_t op2;
35fbce2c 16909 TCGv t0 = tcg_temp_new();
6c5c1e20 16910
0eaef5aa 16911 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
16912 switch (op2) {
16913 case OPC_DMT:
d75c135e 16914 check_insn(ctx, ASE_MT);
9ed5726c 16915 gen_helper_dmt(t0);
35fbce2c 16916 gen_store_gpr(t0, rt);
6c5c1e20
TS
16917 break;
16918 case OPC_EMT:
d75c135e 16919 check_insn(ctx, ASE_MT);
9ed5726c 16920 gen_helper_emt(t0);
35fbce2c 16921 gen_store_gpr(t0, rt);
da80682b 16922 break;
6c5c1e20 16923 case OPC_DVPE:
d75c135e 16924 check_insn(ctx, ASE_MT);
895c2d04 16925 gen_helper_dvpe(t0, cpu_env);
35fbce2c 16926 gen_store_gpr(t0, rt);
6c5c1e20
TS
16927 break;
16928 case OPC_EVPE:
d75c135e 16929 check_insn(ctx, ASE_MT);
895c2d04 16930 gen_helper_evpe(t0, cpu_env);
35fbce2c 16931 gen_store_gpr(t0, rt);
6c5c1e20
TS
16932 break;
16933 case OPC_DI:
d75c135e 16934 check_insn(ctx, ISA_MIPS32R2);
867abc7e 16935 save_cpu_state(ctx, 1);
895c2d04 16936 gen_helper_di(t0, cpu_env);
35fbce2c 16937 gen_store_gpr(t0, rt);
6c5c1e20
TS
16938 /* Stop translation as we may have switched the execution mode */
16939 ctx->bstate = BS_STOP;
16940 break;
16941 case OPC_EI:
d75c135e 16942 check_insn(ctx, ISA_MIPS32R2);
867abc7e 16943 save_cpu_state(ctx, 1);
895c2d04 16944 gen_helper_ei(t0, cpu_env);
35fbce2c 16945 gen_store_gpr(t0, rt);
6c5c1e20
TS
16946 /* Stop translation as we may have switched the execution mode */
16947 ctx->bstate = BS_STOP;
16948 break;
16949 default: /* Invalid */
16950 MIPS_INVAL("mfmc0");
16951 generate_exception(ctx, EXCP_RI);
16952 break;
16953 }
6c5c1e20 16954 tcg_temp_free(t0);
7a387fff 16955 }
0eaef5aa 16956#endif /* !CONFIG_USER_ONLY */
6af0bf9c 16957 break;
7a387fff 16958 case OPC_RDPGPR:
d75c135e 16959 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 16960 gen_load_srsgpr(rt, rd);
ead9360e 16961 break;
7a387fff 16962 case OPC_WRPGPR:
d75c135e 16963 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 16964 gen_store_srsgpr(rt, rd);
38121543 16965 break;
6af0bf9c 16966 default:
923617a3 16967 MIPS_INVAL("cp0");
7a387fff 16968 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
16969 break;
16970 }
16971 break;
31837be3
YK
16972 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
16973 if (ctx->insn_flags & ISA_MIPS32R6) {
16974 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
16975 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
16976 } else {
16977 /* OPC_ADDI */
16978 /* Arithmetic with immediate opcode */
16979 gen_arith_imm(ctx, op, rt, rs, imm);
16980 }
16981 break;
324d9e32 16982 case OPC_ADDIU:
d75c135e 16983 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 16984 break;
324d9e32
AJ
16985 case OPC_SLTI: /* Set on less than with immediate opcode */
16986 case OPC_SLTIU:
d75c135e 16987 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
16988 break;
16989 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 16990 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
16991 case OPC_ORI:
16992 case OPC_XORI:
d75c135e 16993 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 16994 break;
7a387fff
TS
16995 case OPC_J ... OPC_JAL: /* Jump */
16996 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 16997 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 16998 break;
31837be3
YK
16999 /* Branch */
17000 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17001 if (ctx->insn_flags & ISA_MIPS32R6) {
17002 if (rt == 0) {
17003 generate_exception(ctx, EXCP_RI);
17004 break;
17005 }
17006 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17007 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17008 } else {
17009 /* OPC_BLEZL */
b231c103 17010 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17011 }
17012 break;
17013 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17014 if (ctx->insn_flags & ISA_MIPS32R6) {
17015 if (rt == 0) {
17016 generate_exception(ctx, EXCP_RI);
17017 break;
17018 }
17019 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17020 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17021 } else {
17022 /* OPC_BGTZL */
b231c103 17023 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17024 }
17025 break;
17026 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17027 if (rt == 0) {
17028 /* OPC_BLEZ */
b231c103 17029 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17030 } else {
17031 check_insn(ctx, ISA_MIPS32R6);
17032 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17033 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17034 }
17035 break;
17036 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17037 if (rt == 0) {
17038 /* OPC_BGTZ */
b231c103 17039 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
17040 } else {
17041 check_insn(ctx, ISA_MIPS32R6);
17042 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17043 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17044 }
17045 break;
17046 case OPC_BEQL:
17047 case OPC_BNEL:
fecd2646 17048 check_insn_opc_removed(ctx, ISA_MIPS32R6);
31837be3
YK
17049 case OPC_BEQ:
17050 case OPC_BNE:
b231c103 17051 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 17052 break;
fecd2646
LA
17053 case OPC_LWL: /* Load and stores */
17054 case OPC_LWR:
4368b29a 17055 case OPC_LL:
fecd2646
LA
17056 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17057 case OPC_LB ... OPC_LH:
17058 case OPC_LW ... OPC_LHU:
d75c135e 17059 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 17060 break;
fecd2646 17061 case OPC_SWL:
7a387fff 17062 case OPC_SWR:
fecd2646
LA
17063 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17064 case OPC_SB ... OPC_SH:
17065 case OPC_SW:
5c13fdfd 17066 gen_st(ctx, op, rt, rs, imm);
7a387fff 17067 break;
d66c7132 17068 case OPC_SC:
4368b29a 17069 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
17070 gen_st_cond(ctx, op, rt, rs, imm);
17071 break;
7a387fff 17072 case OPC_CACHE:
bf7910c6 17073 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 17074 check_cp0_enabled(ctx);
d75c135e 17075 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 17076 /* Treat as NOP. */
34ae7b51 17077 break;
7a387fff 17078 case OPC_PREF:
bf7910c6 17079 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17080 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 17081 /* Treat as NOP. */
6af0bf9c 17082 break;
4ad40f36 17083
923617a3 17084 /* Floating point (COP1). */
7a387fff
TS
17085 case OPC_LWC1:
17086 case OPC_LDC1:
17087 case OPC_SWC1:
17088 case OPC_SDC1:
5ab5c041 17089 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
17090 break;
17091
7a387fff 17092 case OPC_CP1:
5ab5c041 17093 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 17094 check_cp1_enabled(ctx);
36d23958
TS
17095 op1 = MASK_CP1(ctx->opcode);
17096 switch (op1) {
3a95e3a7
TS
17097 case OPC_MFHC1:
17098 case OPC_MTHC1:
d75c135e 17099 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
17100 case OPC_MFC1:
17101 case OPC_CFC1:
17102 case OPC_MTC1:
17103 case OPC_CTC1:
e189e748
TS
17104 gen_cp1(ctx, op1, rt, rd);
17105 break;
d26bc211 17106#if defined(TARGET_MIPS64)
36d23958
TS
17107 case OPC_DMFC1:
17108 case OPC_DMTC1:
d75c135e 17109 check_insn(ctx, ISA_MIPS3);
36d23958
TS
17110 gen_cp1(ctx, op1, rt, rd);
17111 break;
e189e748 17112#endif
31837be3
YK
17113 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
17114 if (ctx->insn_flags & ISA_MIPS32R6) {
17115 /* OPC_BC1EQZ */
17116 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17117 rt, imm << 2);
17118 } else {
17119 /* OPC_BC1ANY2 */
17120 check_cop1x(ctx);
17121 check_insn(ctx, ASE_MIPS3D);
17122 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
17123 (rt >> 2) & 0x7, imm << 2);
17124 }
17125 break;
17126 case OPC_BC1NEZ:
17127 check_insn(ctx, ISA_MIPS32R6);
17128 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17129 rt, imm << 2);
17130 break;
fbcc6828 17131 case OPC_BC1ANY4:
fecd2646 17132 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b8aa4598 17133 check_cop1x(ctx);
d75c135e 17134 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
17135 /* fall through */
17136 case OPC_BC1:
fecd2646 17137 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17138 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 17139 (rt >> 2) & 0x7, imm << 2);
c9602061 17140 break;
fecd2646
LA
17141 case OPC_PS_FMT:
17142 check_insn_opc_removed(ctx, ISA_MIPS32R6);
36d23958
TS
17143 case OPC_S_FMT:
17144 case OPC_D_FMT:
bf4120ad 17145 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 17146 (imm >> 8) & 0x7);
36d23958 17147 break;
3f493883
YK
17148 case OPC_W_FMT:
17149 case OPC_L_FMT:
17150 {
17151 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
17152 if (ctx->insn_flags & ISA_MIPS32R6) {
17153 switch (r6_op) {
17154 case R6_OPC_CMP_AF_S:
17155 case R6_OPC_CMP_UN_S:
17156 case R6_OPC_CMP_EQ_S:
17157 case R6_OPC_CMP_UEQ_S:
17158 case R6_OPC_CMP_LT_S:
17159 case R6_OPC_CMP_ULT_S:
17160 case R6_OPC_CMP_LE_S:
17161 case R6_OPC_CMP_ULE_S:
17162 case R6_OPC_CMP_SAF_S:
17163 case R6_OPC_CMP_SUN_S:
17164 case R6_OPC_CMP_SEQ_S:
17165 case R6_OPC_CMP_SEUQ_S:
17166 case R6_OPC_CMP_SLT_S:
17167 case R6_OPC_CMP_SULT_S:
17168 case R6_OPC_CMP_SLE_S:
17169 case R6_OPC_CMP_SULE_S:
17170 case R6_OPC_CMP_OR_S:
17171 case R6_OPC_CMP_UNE_S:
17172 case R6_OPC_CMP_NE_S:
17173 case R6_OPC_CMP_SOR_S:
17174 case R6_OPC_CMP_SUNE_S:
17175 case R6_OPC_CMP_SNE_S:
17176 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17177 break;
17178 case R6_OPC_CMP_AF_D:
17179 case R6_OPC_CMP_UN_D:
17180 case R6_OPC_CMP_EQ_D:
17181 case R6_OPC_CMP_UEQ_D:
17182 case R6_OPC_CMP_LT_D:
17183 case R6_OPC_CMP_ULT_D:
17184 case R6_OPC_CMP_LE_D:
17185 case R6_OPC_CMP_ULE_D:
17186 case R6_OPC_CMP_SAF_D:
17187 case R6_OPC_CMP_SUN_D:
17188 case R6_OPC_CMP_SEQ_D:
17189 case R6_OPC_CMP_SEUQ_D:
17190 case R6_OPC_CMP_SLT_D:
17191 case R6_OPC_CMP_SULT_D:
17192 case R6_OPC_CMP_SLE_D:
17193 case R6_OPC_CMP_SULE_D:
17194 case R6_OPC_CMP_OR_D:
17195 case R6_OPC_CMP_UNE_D:
17196 case R6_OPC_CMP_NE_D:
17197 case R6_OPC_CMP_SOR_D:
17198 case R6_OPC_CMP_SUNE_D:
17199 case R6_OPC_CMP_SNE_D:
17200 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17201 break;
17202 default:
17203 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17204 (imm >> 8) & 0x7);
17205 break;
17206 }
17207 } else {
17208 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17209 (imm >> 8) & 0x7);
17210 }
17211 break;
17212 }
36d23958 17213 default:
923617a3 17214 MIPS_INVAL("cp1");
e397ee33 17215 generate_exception (ctx, EXCP_RI);
36d23958
TS
17216 break;
17217 }
17218 } else {
17219 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 17220 }
4ad40f36
FB
17221 break;
17222
31837be3
YK
17223 /* Compact branches [R6] and COP2 [non-R6] */
17224 case OPC_BC: /* OPC_LWC2 */
17225 case OPC_BALC: /* OPC_SWC2 */
17226 if (ctx->insn_flags & ISA_MIPS32R6) {
17227 /* OPC_BC, OPC_BALC */
17228 gen_compute_compact_branch(ctx, op, 0, 0,
17229 sextract32(ctx->opcode << 2, 0, 28));
17230 } else {
17231 /* OPC_LWC2, OPC_SWC2 */
17232 /* COP2: Not implemented. */
17233 generate_exception_err(ctx, EXCP_CpU, 2);
17234 }
17235 break;
17236 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
17237 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
17238 if (ctx->insn_flags & ISA_MIPS32R6) {
17239 if (rs != 0) {
17240 /* OPC_BEQZC, OPC_BNEZC */
17241 gen_compute_compact_branch(ctx, op, rs, 0,
17242 sextract32(ctx->opcode << 2, 0, 23));
17243 } else {
17244 /* OPC_JIC, OPC_JIALC */
17245 gen_compute_compact_branch(ctx, op, 0, rt, imm);
17246 }
17247 } else {
17248 /* OPC_LWC2, OPC_SWC2 */
17249 /* COP2: Not implemented. */
17250 generate_exception_err(ctx, EXCP_CpU, 2);
17251 }
4ad40f36 17252 break;
bd277fa1 17253 case OPC_CP2:
d75c135e 17254 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
17255 /* Note that these instructions use different fields. */
17256 gen_loongson_multimedia(ctx, sa, rd, rt);
17257 break;
4ad40f36 17258
7a387fff 17259 case OPC_CP3:
fecd2646 17260 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 17261 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 17262 check_cp1_enabled(ctx);
36d23958
TS
17263 op1 = MASK_CP3(ctx->opcode);
17264 switch (op1) {
5a5012ec
TS
17265 case OPC_LWXC1:
17266 case OPC_LDXC1:
17267 case OPC_LUXC1:
17268 case OPC_SWXC1:
17269 case OPC_SDXC1:
17270 case OPC_SUXC1:
93b12ccc 17271 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 17272 break;
e0c84da7 17273 case OPC_PREFX:
ead9360e 17274 /* Treat as NOP. */
e0c84da7 17275 break;
5a5012ec
TS
17276 case OPC_ALNV_PS:
17277 case OPC_MADD_S:
17278 case OPC_MADD_D:
17279 case OPC_MADD_PS:
17280 case OPC_MSUB_S:
17281 case OPC_MSUB_D:
17282 case OPC_MSUB_PS:
17283 case OPC_NMADD_S:
17284 case OPC_NMADD_D:
17285 case OPC_NMADD_PS:
17286 case OPC_NMSUB_S:
17287 case OPC_NMSUB_D:
17288 case OPC_NMSUB_PS:
17289 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
17290 break;
36d23958 17291 default:
923617a3 17292 MIPS_INVAL("cp3");
e397ee33 17293 generate_exception (ctx, EXCP_RI);
36d23958
TS
17294 break;
17295 }
17296 } else {
e397ee33 17297 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 17298 }
4ad40f36
FB
17299 break;
17300
d26bc211 17301#if defined(TARGET_MIPS64)
7a387fff 17302 /* MIPS64 opcodes */
7a387fff 17303 case OPC_LDL ... OPC_LDR:
bf7910c6 17304 case OPC_LLD:
fecd2646
LA
17305 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17306 case OPC_LWU:
7a387fff 17307 case OPC_LD:
d75c135e 17308 check_insn(ctx, ISA_MIPS3);
5c13fdfd 17309 check_mips_64(ctx);
d75c135e 17310 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
17311 break;
17312 case OPC_SDL ... OPC_SDR:
fecd2646 17313 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 17314 case OPC_SD:
d75c135e 17315 check_insn(ctx, ISA_MIPS3);
e189e748 17316 check_mips_64(ctx);
5c13fdfd 17317 gen_st(ctx, op, rt, rs, imm);
7a387fff 17318 break;
d66c7132 17319 case OPC_SCD:
bf7910c6 17320 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17321 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
17322 check_mips_64(ctx);
17323 gen_st_cond(ctx, op, rt, rs, imm);
17324 break;
31837be3
YK
17325 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17326 if (ctx->insn_flags & ISA_MIPS32R6) {
17327 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17328 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17329 } else {
17330 /* OPC_DADDI */
17331 check_insn(ctx, ISA_MIPS3);
17332 check_mips_64(ctx);
17333 gen_arith_imm(ctx, op, rt, rs, imm);
17334 }
17335 break;
324d9e32 17336 case OPC_DADDIU:
d75c135e 17337 check_insn(ctx, ISA_MIPS3);
e189e748 17338 check_mips_64(ctx);
d75c135e 17339 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 17340 break;
31837be3
YK
17341#else
17342 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
17343 if (ctx->insn_flags & ISA_MIPS32R6) {
17344 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17345 } else {
17346 MIPS_INVAL("major opcode");
17347 generate_exception(ctx, EXCP_RI);
17348 }
17349 break;
6af0bf9c 17350#endif
d4ea6acd
LA
17351 case OPC_DAUI: /* OPC_JALX */
17352 if (ctx->insn_flags & ISA_MIPS32R6) {
17353#if defined(TARGET_MIPS64)
17354 /* OPC_DAUI */
17355 check_mips_64(ctx);
17356 if (rt != 0) {
17357 TCGv t0 = tcg_temp_new();
17358 gen_load_gpr(t0, rs);
17359 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
17360 tcg_temp_free(t0);
17361 }
17362 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
17363#else
17364 generate_exception(ctx, EXCP_RI);
17365 MIPS_INVAL("major opcode");
17366#endif
17367 } else {
17368 /* OPC_JALX */
17369 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
17370 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 17371 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 17372 }
364d4831 17373 break;
7a387fff 17374 case OPC_MDMX:
d75c135e 17375 check_insn(ctx, ASE_MDMX);
7a387fff 17376 /* MDMX: Not implemented. */
d4ea6acd
LA
17377 break;
17378 case OPC_PCREL:
17379 check_insn(ctx, ISA_MIPS32R6);
17380 gen_pcrel(ctx, rs, imm);
17381 break;
6af0bf9c 17382 default: /* Invalid */
923617a3 17383 MIPS_INVAL("major opcode");
6af0bf9c
FB
17384 generate_exception(ctx, EXCP_RI);
17385 break;
17386 }
6af0bf9c
FB
17387}
17388
2cfc5f17 17389static inline void
6429db34
AF
17390gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
17391 bool search_pc)
6af0bf9c 17392{
ed2803da 17393 CPUState *cs = CPU(cpu);
6429db34 17394 CPUMIPSState *env = &cpu->env;
278d0702 17395 DisasContext ctx;
6af0bf9c
FB
17396 target_ulong pc_start;
17397 uint16_t *gen_opc_end;
a1d1bb31 17398 CPUBreakpoint *bp;
6af0bf9c 17399 int j, lj = -1;
2e70f6ef
PB
17400 int num_insns;
17401 int max_insns;
c9602061 17402 int insn_bytes;
240ce26a 17403 int is_delay;
6af0bf9c 17404
93fcfe39
AL
17405 if (search_pc)
17406 qemu_log("search pc %d\n", search_pc);
4ad40f36 17407
6af0bf9c 17408 pc_start = tb->pc;
92414b31 17409 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 17410 ctx.pc = pc_start;
4ad40f36 17411 ctx.saved_pc = -1;
ed2803da 17412 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 17413 ctx.insn_flags = env->insn_flags;
5ab5c041 17414 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
17415 ctx.tb = tb;
17416 ctx.bstate = BS_NONE;
4ad40f36 17417 /* Restore delay slot state from the tb context. */
c068688b 17418 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 17419 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 17420 restore_cpu_state(env, &ctx);
932e71cd 17421#ifdef CONFIG_USER_ONLY
0eaef5aa 17422 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 17423#else
0eaef5aa 17424 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 17425#endif
2e70f6ef
PB
17426 num_insns = 0;
17427 max_insns = tb->cflags & CF_COUNT_MASK;
17428 if (max_insns == 0)
17429 max_insns = CF_COUNT_MASK;
d12d51d5 17430 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 17431 gen_tb_start();
faf7aaa9 17432 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
17433 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
17434 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 17435 if (bp->pc == ctx.pc) {
278d0702 17436 save_cpu_state(&ctx, 1);
4ad40f36 17437 ctx.bstate = BS_BRANCH;
895c2d04 17438 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
17439 /* Include the breakpoint location or the tb won't
17440 * be flushed when it must be. */
17441 ctx.pc += 4;
4ad40f36
FB
17442 goto done_generating;
17443 }
17444 }
17445 }
17446
6af0bf9c 17447 if (search_pc) {
92414b31 17448 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
17449 if (lj < j) {
17450 lj++;
17451 while (lj < j)
ab1103de 17452 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 17453 }
25983cad 17454 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 17455 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 17456 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 17457 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 17458 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 17459 }
2e70f6ef
PB
17460 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
17461 gen_io_start();
c9602061 17462
240ce26a 17463 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 17464 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 17465 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 17466 insn_bytes = 4;
240ce26a 17467 decode_opc(env, &ctx);
d75c135e 17468 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 17469 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 17470 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 17471 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 17472 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 17473 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
17474 } else {
17475 generate_exception(&ctx, EXCP_RI);
3c824109 17476 ctx.bstate = BS_STOP;
c9602061
NF
17477 break;
17478 }
31837be3 17479
b231c103
YK
17480 if (ctx.hflags & MIPS_HFLAG_BMASK) {
17481 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32))) {
17482 is_delay = 1;
17483 /* force to generate branch as no delay slot is required */
17484 }
17485 }
240ce26a 17486 if (is_delay) {
31837be3 17487 gen_branch(&ctx, insn_bytes);
c9602061
NF
17488 }
17489 ctx.pc += insn_bytes;
17490
2e70f6ef 17491 num_insns++;
4ad40f36 17492
7b270ef2
NF
17493 /* Execute a branch and its delay slot as a single instruction.
17494 This is what GDB expects and is consistent with what the
17495 hardware does (e.g. if a delay slot instruction faults, the
17496 reported PC is the PC of the branch). */
ed2803da 17497 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 17498 break;
ed2803da 17499 }
4ad40f36 17500
6af0bf9c
FB
17501 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
17502 break;
4ad40f36 17503
efd7f486 17504 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 17505 break;
efd7f486 17506 }
faf7aaa9 17507
2e70f6ef
PB
17508 if (num_insns >= max_insns)
17509 break;
1b530a6d
AJ
17510
17511 if (singlestep)
17512 break;
6af0bf9c 17513 }
ed2803da 17514 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 17515 gen_io_end();
ed2803da
AF
17516 }
17517 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 17518 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 17519 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 17520 } else {
6958549d 17521 switch (ctx.bstate) {
16c00cb2 17522 case BS_STOP:
df1561e2
TS
17523 gen_goto_tb(&ctx, 0, ctx.pc);
17524 break;
16c00cb2 17525 case BS_NONE:
278d0702 17526 save_cpu_state(&ctx, 0);
16c00cb2
TS
17527 gen_goto_tb(&ctx, 0, ctx.pc);
17528 break;
5a5012ec 17529 case BS_EXCP:
57fec1fe 17530 tcg_gen_exit_tb(0);
16c00cb2 17531 break;
5a5012ec
TS
17532 case BS_BRANCH:
17533 default:
17534 break;
6958549d 17535 }
6af0bf9c 17536 }
4ad40f36 17537done_generating:
806f352d 17538 gen_tb_end(tb, num_insns);
efd7f486 17539 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 17540 if (search_pc) {
92414b31 17541 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
17542 lj++;
17543 while (lj <= j)
ab1103de 17544 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
17545 } else {
17546 tb->size = ctx.pc - pc_start;
2e70f6ef 17547 tb->icount = num_insns;
6af0bf9c
FB
17548 }
17549#ifdef DEBUG_DISAS
d12d51d5 17550 LOG_DISAS("\n");
8fec2b8c 17551 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 17552 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 17553 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 17554 qemu_log("\n");
6af0bf9c
FB
17555 }
17556#endif
6af0bf9c
FB
17557}
17558
7db13fae 17559void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 17560{
6429db34 17561 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
17562}
17563
7db13fae 17564void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 17565{
6429db34 17566 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
17567}
17568
7db13fae 17569static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 17570 int flags)
6ea83fed
FB
17571{
17572 int i;
5e755519 17573 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 17574
2a5612e6
SW
17575#define printfpr(fp) \
17576 do { \
17577 if (is_fpu64) \
17578 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17579 " fd:%13g fs:%13g psu: %13g\n", \
17580 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
17581 (double)(fp)->fd, \
17582 (double)(fp)->fs[FP_ENDIAN_IDX], \
17583 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
17584 else { \
17585 fpr_t tmp; \
17586 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
17587 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
17588 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17589 " fd:%13g fs:%13g psu:%13g\n", \
17590 tmp.w[FP_ENDIAN_IDX], tmp.d, \
17591 (double)tmp.fd, \
17592 (double)tmp.fs[FP_ENDIAN_IDX], \
17593 (double)tmp.fs[!FP_ENDIAN_IDX]); \
17594 } \
6ea83fed
FB
17595 } while(0)
17596
5a5012ec 17597
9a78eead
SW
17598 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
17599 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 17600 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
17601 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
17602 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 17603 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
17604 }
17605
17606#undef printfpr
17607}
17608
d26bc211 17609#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 17610/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 17611 sign-extended values on 64bit machines. */
c570fd16
TS
17612
17613#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
17614
8706c382 17615static void
7db13fae 17616cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 17617 fprintf_function cpu_fprintf,
8706c382 17618 int flags)
c570fd16
TS
17619{
17620 int i;
17621
b5dc7732
TS
17622 if (!SIGN_EXT_P(env->active_tc.PC))
17623 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
17624 if (!SIGN_EXT_P(env->active_tc.HI[0]))
17625 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
17626 if (!SIGN_EXT_P(env->active_tc.LO[0]))
17627 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 17628 if (!SIGN_EXT_P(env->btarget))
3594c774 17629 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
17630
17631 for (i = 0; i < 32; i++) {
b5dc7732
TS
17632 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
17633 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
17634 }
17635
17636 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 17637 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
17638 if (!SIGN_EXT_P(env->lladdr))
17639 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
17640}
17641#endif
17642
878096ee
AF
17643void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
17644 int flags)
6af0bf9c 17645{
878096ee
AF
17646 MIPSCPU *cpu = MIPS_CPU(cs);
17647 CPUMIPSState *env = &cpu->env;
6af0bf9c 17648 int i;
3b46e624 17649
a7200c9f
SW
17650 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
17651 " LO=0x" TARGET_FMT_lx " ds %04x "
17652 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
17653 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
17654 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
17655 for (i = 0; i < 32; i++) {
17656 if ((i & 3) == 0)
17657 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 17658 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
17659 if ((i & 3) == 3)
17660 cpu_fprintf(f, "\n");
17661 }
568b600d 17662
3594c774 17663 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 17664 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 17665 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 17666 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 17667 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 17668 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 17669#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
17670 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
17671#endif
6af0bf9c
FB
17672}
17673
78ce64f4 17674void mips_tcg_init(void)
39454628 17675{
f01be154 17676 int i;
39454628
TS
17677 static int inited;
17678
17679 /* Initialize various static tables. */
17680 if (inited)
6958549d 17681 return;
39454628 17682
a7812ae4 17683 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 17684 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 17685 for (i = 1; i < 32; i++)
a7812ae4 17686 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17687 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 17688 regnames[i]);
d73ee8a2
RH
17689
17690 for (i = 0; i < 32; i++) {
17691 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
17692 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
17693 }
17694
a7812ae4 17695 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 17696 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 17697 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 17698 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17699 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 17700 regnames_HI[i]);
a7812ae4 17701 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17702 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 17703 regnames_LO[i]);
4b2eb8d2 17704 }
a7812ae4 17705 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 17706 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 17707 "DSPControl");
1ba74fb8 17708 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 17709 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 17710 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 17711 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 17712 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 17713 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 17714
a7812ae4 17715 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 17716 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
17717 "fcr0");
17718 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 17719 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 17720 "fcr31");
39454628
TS
17721
17722 inited = 1;
17723}
17724
aaed909a
FB
17725#include "translate_init.c"
17726
30bf942d 17727MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 17728{
0f71a709 17729 MIPSCPU *cpu;
6af0bf9c 17730 CPUMIPSState *env;
c227f099 17731 const mips_def_t *def;
6af0bf9c 17732
aaed909a
FB
17733 def = cpu_mips_find_by_name(cpu_model);
17734 if (!def)
17735 return NULL;
0f71a709
AF
17736 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
17737 env = &cpu->env;
aaed909a
FB
17738 env->cpu_model = def;
17739
51cc2e78
BS
17740#ifndef CONFIG_USER_ONLY
17741 mmu_init(env, def);
17742#endif
17743 fpu_init(env, def);
17744 mvp_init(env, def);
c1caf1d9
AF
17745
17746 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
17747
30bf942d 17748 return cpu;
6ae81775
TS
17749}
17750
1bba0dc9 17751void cpu_state_reset(CPUMIPSState *env)
6ae81775 17752{
55e5c285
AF
17753 MIPSCPU *cpu = mips_env_get_cpu(env);
17754 CPUState *cs = CPU(cpu);
6ae81775 17755
51cc2e78
BS
17756 /* Reset registers to their default values */
17757 env->CP0_PRid = env->cpu_model->CP0_PRid;
17758 env->CP0_Config0 = env->cpu_model->CP0_Config0;
17759#ifdef TARGET_WORDS_BIGENDIAN
17760 env->CP0_Config0 |= (1 << CP0C0_BE);
17761#endif
17762 env->CP0_Config1 = env->cpu_model->CP0_Config1;
17763 env->CP0_Config2 = env->cpu_model->CP0_Config2;
17764 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
17765 env->CP0_Config4 = env->cpu_model->CP0_Config4;
17766 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
17767 env->CP0_Config5 = env->cpu_model->CP0_Config5;
17768 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
17769 env->CP0_Config6 = env->cpu_model->CP0_Config6;
17770 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
17771 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
17772 << env->cpu_model->CP0_LLAddr_shift;
17773 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
17774 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
17775 env->CCRes = env->cpu_model->CCRes;
17776 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
17777 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
17778 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
17779 env->current_tc = 0;
17780 env->SEGBITS = env->cpu_model->SEGBITS;
17781 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
17782#if defined(TARGET_MIPS64)
17783 if (env->cpu_model->insn_flags & ISA_MIPS3) {
17784 env->SEGMask |= 3ULL << 62;
17785 }
17786#endif
17787 env->PABITS = env->cpu_model->PABITS;
17788 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
17789 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
17790 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
17791 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
17792 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
17793 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
17794 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
17795 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
17796 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
17797 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
17798 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 17799 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
17800 env->insn_flags = env->cpu_model->insn_flags;
17801
0eaef5aa 17802#if defined(CONFIG_USER_ONLY)
03e6e501 17803 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
17804# ifdef TARGET_MIPS64
17805 /* Enable 64-bit register mode. */
17806 env->CP0_Status |= (1 << CP0St_PX);
17807# endif
17808# ifdef TARGET_ABI_MIPSN64
17809 /* Enable 64-bit address mode. */
17810 env->CP0_Status |= (1 << CP0St_UX);
17811# endif
94159135
MI
17812 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
17813 hardware registers. */
17814 env->CP0_HWREna |= 0x0000000F;
91a75935 17815 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 17816 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 17817 }
6f0af304
PJ
17818 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
17819 env->CP0_Status |= (1 << CP0St_MX);
853c3240 17820 }
4d66261f
PJ
17821# if defined(TARGET_MIPS64)
17822 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
17823 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
17824 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
17825 env->CP0_Status |= (1 << CP0St_FR);
17826 }
4d66261f 17827# endif
932e71cd
AJ
17828#else
17829 if (env->hflags & MIPS_HFLAG_BMASK) {
17830 /* If the exception was raised from a delay slot,
17831 come back to the jump. */
17832 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 17833 } else {
932e71cd
AJ
17834 env->CP0_ErrorEPC = env->active_tc.PC;
17835 }
17836 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
17837 env->CP0_Random = env->tlb->nb_tlb - 1;
17838 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 17839 env->CP0_Wired = 0;
0a2672b7
JH
17840 env->CP0_EBase = (cs->cpu_index & 0x3FF);
17841 if (kvm_enabled()) {
17842 env->CP0_EBase |= 0x40000000;
17843 } else {
17844 env->CP0_EBase |= 0x80000000;
17845 }
932e71cd
AJ
17846 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
17847 /* vectored interrupts not implemented, timer on int 7,
17848 no performance counters. */
17849 env->CP0_IntCtl = 0xe0000000;
17850 {
17851 int i;
17852
17853 for (i = 0; i < 7; i++) {
17854 env->CP0_WatchLo[i] = 0;
17855 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 17856 }
932e71cd
AJ
17857 env->CP0_WatchLo[7] = 0;
17858 env->CP0_WatchHi[7] = 0;
fd88b6ab 17859 }
932e71cd
AJ
17860 /* Count register increments in debug mode, EJTAG version 1 */
17861 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 17862
4b69c7e2
JH
17863 cpu_mips_store_count(env, 1);
17864
9e56e756
EI
17865 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
17866 int i;
17867
17868 /* Only TC0 on VPE 0 starts as active. */
17869 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 17870 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
17871 env->tcs[i].CP0_TCHalt = 1;
17872 }
17873 env->active_tc.CP0_TCHalt = 1;
259186a7 17874 cs->halted = 1;
9e56e756 17875
55e5c285 17876 if (cs->cpu_index == 0) {
9e56e756
EI
17877 /* VPE0 starts up enabled. */
17878 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
17879 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
17880
17881 /* TC0 starts up unhalted. */
259186a7 17882 cs->halted = 0;
9e56e756
EI
17883 env->active_tc.CP0_TCHalt = 0;
17884 env->tcs[0].CP0_TCHalt = 0;
17885 /* With thread 0 active. */
17886 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
17887 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
17888 }
17889 }
51cc2e78 17890#endif
ddc584bd
LA
17891 if ((env->insn_flags & ISA_MIPS32R6) &&
17892 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
17893 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
17894 env->CP0_Status |= (1 << CP0St_FR);
17895 }
17896
03e6e501 17897 compute_hflags(env);
27103424 17898 cs->exception_index = EXCP_NONE;
6af0bf9c 17899}
d2856f1a 17900
7db13fae 17901void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 17902{
25983cad 17903 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
17904 env->hflags &= ~MIPS_HFLAG_BMASK;
17905 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
17906 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
17907 case MIPS_HFLAG_BR:
17908 break;
17909 case MIPS_HFLAG_BC:
17910 case MIPS_HFLAG_BL:
17911 case MIPS_HFLAG_B:
17912 env->btarget = gen_opc_btarget[pc_pos];
17913 break;
17914 }
d2856f1a 17915}
This page took 3.77408 seconds and 4 git commands to generate.