]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/tcg/translate.c
target/mips: Remove gen_helper_1e2i()
[mirror_qemu.git] / target / mips / tcg / translate.c
CommitLineData
6af0bf9c 1/*
ab99e0e4 2 * MIPS 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)
96e5b4c7 9 * Copyright (c) 2020 Philippe Mathieu-Daudé
6af0bf9c
FB
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
89975214 14 * version 2.1 of the License, or (at your option) any later version.
6af0bf9c
FB
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
8167ee88 22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
23 */
24
c684822a 25#include "qemu/osdep.h"
6af0bf9c 26#include "cpu.h"
26aa3d9a 27#include "internal.h"
dcb32f1d 28#include "tcg/tcg-op.h"
0ab8e33a 29#include "exec/translator.h"
2ef6175a
RH
30#include "exec/helper-proto.h"
31#include "exec/helper-gen.h"
6b5fe137 32#include "semihosting/semihost.h"
a7812ae4 33
34b8ff25 34#include "trace.h"
b28425ba 35#include "exec/translator.h"
508127e2 36#include "exec/log.h"
0442428a 37#include "qemu/qemu-print.h"
81ddae7c 38#include "fpu_helper.h"
e3130936 39#include "translate.h"
a7e30d84 40
ecdbcb0a
PMD
41/*
42 * Many sysemu-only helpers are not reachable for user-only.
43 * Define stub generators here, so that we need not either sprinkle
44 * ifdefs through the translator, nor provide the helper function.
45 */
46#define STUB_HELPER(NAME, ...) \
47 static inline void gen_helper_##NAME(__VA_ARGS__) \
48 { g_assert_not_reached(); }
49
50#ifdef CONFIG_USER_ONLY
51STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
52#endif
53
e37e863f
FB
54enum {
55 /* indirect opcode tables */
7a387fff
TS
56 OPC_SPECIAL = (0x00 << 26),
57 OPC_REGIMM = (0x01 << 26),
58 OPC_CP0 = (0x10 << 26),
7a387fff
TS
59 OPC_CP2 = (0x12 << 26),
60 OPC_CP3 = (0x13 << 26),
61 OPC_SPECIAL2 = (0x1C << 26),
62 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 63 /* arithmetic with immediate */
7a387fff
TS
64 OPC_ADDI = (0x08 << 26),
65 OPC_ADDIU = (0x09 << 26),
66 OPC_SLTI = (0x0A << 26),
67 OPC_SLTIU = (0x0B << 26),
324d9e32 68 /* logic with immediate */
7a387fff
TS
69 OPC_ANDI = (0x0C << 26),
70 OPC_ORI = (0x0D << 26),
71 OPC_XORI = (0x0E << 26),
72 OPC_LUI = (0x0F << 26),
324d9e32 73 /* arithmetic with immediate */
7a387fff
TS
74 OPC_DADDI = (0x18 << 26),
75 OPC_DADDIU = (0x19 << 26),
e37e863f 76 /* Jump and branches */
7a387fff
TS
77 OPC_J = (0x02 << 26),
78 OPC_JAL = (0x03 << 26),
79 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
80 OPC_BEQL = (0x14 << 26),
81 OPC_BNE = (0x05 << 26),
82 OPC_BNEL = (0x15 << 26),
83 OPC_BLEZ = (0x06 << 26),
84 OPC_BLEZL = (0x16 << 26),
85 OPC_BGTZ = (0x07 << 26),
86 OPC_BGTZL = (0x17 << 26),
b231c103 87 OPC_JALX = (0x1D << 26),
d4ea6acd 88 OPC_DAUI = (0x1D << 26),
e37e863f 89 /* Load and stores */
7a387fff
TS
90 OPC_LDL = (0x1A << 26),
91 OPC_LDR = (0x1B << 26),
92 OPC_LB = (0x20 << 26),
93 OPC_LH = (0x21 << 26),
94 OPC_LWL = (0x22 << 26),
95 OPC_LW = (0x23 << 26),
364d4831 96 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
97 OPC_LBU = (0x24 << 26),
98 OPC_LHU = (0x25 << 26),
99 OPC_LWR = (0x26 << 26),
100 OPC_LWU = (0x27 << 26),
101 OPC_SB = (0x28 << 26),
102 OPC_SH = (0x29 << 26),
103 OPC_SWL = (0x2A << 26),
104 OPC_SW = (0x2B << 26),
105 OPC_SDL = (0x2C << 26),
106 OPC_SDR = (0x2D << 26),
107 OPC_SWR = (0x2E << 26),
108 OPC_LL = (0x30 << 26),
109 OPC_LLD = (0x34 << 26),
110 OPC_LD = (0x37 << 26),
364d4831 111 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
112 OPC_SC = (0x38 << 26),
113 OPC_SCD = (0x3C << 26),
114 OPC_SD = (0x3F << 26),
e37e863f 115 /* Floating point load/store */
7a387fff
TS
116 OPC_LWC1 = (0x31 << 26),
117 OPC_LWC2 = (0x32 << 26),
118 OPC_LDC1 = (0x35 << 26),
119 OPC_LDC2 = (0x36 << 26),
120 OPC_SWC1 = (0x39 << 26),
121 OPC_SWC2 = (0x3A << 26),
122 OPC_SDC1 = (0x3D << 26),
123 OPC_SDC2 = (0x3E << 26),
31837be3
YK
124 /* Compact Branches */
125 OPC_BLEZALC = (0x06 << 26),
126 OPC_BGEZALC = (0x06 << 26),
127 OPC_BGEUC = (0x06 << 26),
128 OPC_BGTZALC = (0x07 << 26),
129 OPC_BLTZALC = (0x07 << 26),
130 OPC_BLTUC = (0x07 << 26),
131 OPC_BOVC = (0x08 << 26),
132 OPC_BEQZALC = (0x08 << 26),
133 OPC_BEQC = (0x08 << 26),
134 OPC_BLEZC = (0x16 << 26),
135 OPC_BGEZC = (0x16 << 26),
136 OPC_BGEC = (0x16 << 26),
137 OPC_BGTZC = (0x17 << 26),
138 OPC_BLTZC = (0x17 << 26),
139 OPC_BLTC = (0x17 << 26),
140 OPC_BNVC = (0x18 << 26),
141 OPC_BNEZALC = (0x18 << 26),
142 OPC_BNEC = (0x18 << 26),
143 OPC_BC = (0x32 << 26),
144 OPC_BEQZC = (0x36 << 26),
145 OPC_JIC = (0x36 << 26),
146 OPC_BALC = (0x3A << 26),
147 OPC_BNEZC = (0x3E << 26),
148 OPC_JIALC = (0x3E << 26),
7a387fff
TS
149 /* MDMX ASE specific */
150 OPC_MDMX = (0x1E << 26),
e37e863f 151 /* Cache and prefetch */
7a387fff
TS
152 OPC_CACHE = (0x2F << 26),
153 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
154 /* PC-relative address computation / loads */
155 OPC_PCREL = (0x3B << 26),
156};
157
158/* PC-relative address computation / loads */
71375b59
AM
159#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
160#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
d4ea6acd
LA
161enum {
162 /* Instructions determined by bits 19 and 20 */
163 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
164 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
165 OPC_LWUPC = OPC_PCREL | (2 << 19),
166
167 /* Instructions determined by bits 16 ... 20 */
168 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
169 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
170
171 /* Other */
172 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
173};
174
175/* MIPS special opcodes */
71375b59 176#define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
7a387fff 177
e37e863f
FB
178enum {
179 /* Shifts */
7a387fff 180 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
181 /* NOP is SLL r0, r0, 0 */
182 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
183 /* EHB is SLL r0, r0, 3 */
184 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 185 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
186 OPC_SRA = 0x03 | OPC_SPECIAL,
187 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 188 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 189 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
190 OPC_SRAV = 0x07 | OPC_SPECIAL,
191 OPC_DSLLV = 0x14 | OPC_SPECIAL,
192 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 193 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
194 OPC_DSRAV = 0x17 | OPC_SPECIAL,
195 OPC_DSLL = 0x38 | OPC_SPECIAL,
196 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 197 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
198 OPC_DSRA = 0x3B | OPC_SPECIAL,
199 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
200 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 201 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 202 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 203 /* Multiplication / division */
7a387fff
TS
204 OPC_MULT = 0x18 | OPC_SPECIAL,
205 OPC_MULTU = 0x19 | OPC_SPECIAL,
206 OPC_DIV = 0x1A | OPC_SPECIAL,
207 OPC_DIVU = 0x1B | OPC_SPECIAL,
208 OPC_DMULT = 0x1C | OPC_SPECIAL,
209 OPC_DMULTU = 0x1D | OPC_SPECIAL,
210 OPC_DDIV = 0x1E | OPC_SPECIAL,
211 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 212
e37e863f 213 /* 2 registers arithmetic / logic */
7a387fff
TS
214 OPC_ADD = 0x20 | OPC_SPECIAL,
215 OPC_ADDU = 0x21 | OPC_SPECIAL,
216 OPC_SUB = 0x22 | OPC_SPECIAL,
217 OPC_SUBU = 0x23 | OPC_SPECIAL,
218 OPC_AND = 0x24 | OPC_SPECIAL,
219 OPC_OR = 0x25 | OPC_SPECIAL,
220 OPC_XOR = 0x26 | OPC_SPECIAL,
221 OPC_NOR = 0x27 | OPC_SPECIAL,
222 OPC_SLT = 0x2A | OPC_SPECIAL,
223 OPC_SLTU = 0x2B | OPC_SPECIAL,
224 OPC_DADD = 0x2C | OPC_SPECIAL,
225 OPC_DADDU = 0x2D | OPC_SPECIAL,
226 OPC_DSUB = 0x2E | OPC_SPECIAL,
227 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 228 /* Jumps */
7a387fff
TS
229 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
230 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 231 /* Traps */
7a387fff
TS
232 OPC_TGE = 0x30 | OPC_SPECIAL,
233 OPC_TGEU = 0x31 | OPC_SPECIAL,
234 OPC_TLT = 0x32 | OPC_SPECIAL,
235 OPC_TLTU = 0x33 | OPC_SPECIAL,
236 OPC_TEQ = 0x34 | OPC_SPECIAL,
237 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 238 /* HI / LO registers load & stores */
7a387fff
TS
239 OPC_MFHI = 0x10 | OPC_SPECIAL,
240 OPC_MTHI = 0x11 | OPC_SPECIAL,
241 OPC_MFLO = 0x12 | OPC_SPECIAL,
242 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 243 /* Conditional moves */
7a387fff
TS
244 OPC_MOVZ = 0x0A | OPC_SPECIAL,
245 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 246
b691d9d2
LA
247 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
248 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
249
7a387fff 250 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
251
252 /* Special */
a0d700e4 253 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
254 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
255 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 256 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
257 OPC_SYNC = 0x0F | OPC_SPECIAL,
258
7a387fff
TS
259 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
260 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
261 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
262 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
263};
264
7480515f
AM
265/*
266 * R6 Multiply and Divide instructions have the same opcode
267 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
268 */
71375b59 269#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
b42ee5e1
LA
270
271enum {
272 R6_OPC_MUL = OPC_MULT | (2 << 6),
273 R6_OPC_MUH = OPC_MULT | (3 << 6),
274 R6_OPC_MULU = OPC_MULTU | (2 << 6),
275 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
276 R6_OPC_DIV = OPC_DIV | (2 << 6),
277 R6_OPC_MOD = OPC_DIV | (3 << 6),
278 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
279 R6_OPC_MODU = OPC_DIVU | (3 << 6),
280
281 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
282 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
283 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
284 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
285 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
286 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
287 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
288 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
289
290 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
291 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
292 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
293 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
b42ee5e1
LA
295};
296
7a387fff 297/* REGIMM (rt field) opcodes */
71375b59 298#define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
7a387fff
TS
299
300enum {
301 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
302 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
303 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
304 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
305 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
306 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
307 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
308 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
309 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
310 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
311 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
312 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
313 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
314 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 315 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 316 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
317
318 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
319 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
320};
321
7a387fff 322/* Special2 opcodes */
71375b59 323#define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
7a387fff 324
e37e863f 325enum {
7a387fff
TS
326 /* Multiply & xxx operations */
327 OPC_MADD = 0x00 | OPC_SPECIAL2,
328 OPC_MADDU = 0x01 | OPC_SPECIAL2,
329 OPC_MUL = 0x02 | OPC_SPECIAL2,
330 OPC_MSUB = 0x04 | OPC_SPECIAL2,
331 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
332 /* Loongson 2F */
333 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
334 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
335 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
336 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
337 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
338 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
339 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
340 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
341 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
342 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
343 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
344 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 345 /* Misc */
7a387fff
TS
346 OPC_CLZ = 0x20 | OPC_SPECIAL2,
347 OPC_CLO = 0x21 | OPC_SPECIAL2,
348 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
349 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 350 /* Special */
7a387fff
TS
351 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
352};
353
354/* Special3 opcodes */
71375b59 355#define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
7a387fff
TS
356
357enum {
358 OPC_EXT = 0x00 | OPC_SPECIAL3,
359 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
360 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
361 OPC_DEXT = 0x03 | OPC_SPECIAL3,
362 OPC_INS = 0x04 | OPC_SPECIAL3,
363 OPC_DINSM = 0x05 | OPC_SPECIAL3,
364 OPC_DINSU = 0x06 | OPC_SPECIAL3,
365 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
366 OPC_FORK = 0x08 | OPC_SPECIAL3,
367 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
368 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
369 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
370 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
99029be1 371 OPC_GINV = 0x3D | OPC_SPECIAL3,
161f85e6
AJ
372
373 /* Loongson 2E */
374 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
375 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
376 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
377 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
378 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
379 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
380 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
381 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
382 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
383 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
384 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
385 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
386
387 /* MIPS DSP Load */
388 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
389 /* MIPS DSP Arithmetic */
390 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 391 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 392 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 393 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
394 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
395 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
396 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 397 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
398 /* MIPS DSP GPR-Based Shift Sub-class */
399 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 400 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
401 /* MIPS DSP Multiply Sub-class insns */
402 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
403 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 405 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
406 /* DSP Bit/Manipulation Sub-class */
407 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 408 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 409 /* MIPS DSP Append Sub-class */
26690560 410 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 411 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
412 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
413 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 414 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 415
76964147
JH
416 /* EVA */
417 OPC_LWLE = 0x19 | OPC_SPECIAL3,
418 OPC_LWRE = 0x1A | OPC_SPECIAL3,
419 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
420 OPC_SBE = 0x1C | OPC_SPECIAL3,
421 OPC_SHE = 0x1D | OPC_SPECIAL3,
422 OPC_SCE = 0x1E | OPC_SPECIAL3,
423 OPC_SWE = 0x1F | OPC_SPECIAL3,
424 OPC_SWLE = 0x21 | OPC_SPECIAL3,
425 OPC_SWRE = 0x22 | OPC_SPECIAL3,
426 OPC_PREFE = 0x23 | OPC_SPECIAL3,
427 OPC_LBUE = 0x28 | OPC_SPECIAL3,
428 OPC_LHUE = 0x29 | OPC_SPECIAL3,
429 OPC_LBE = 0x2C | OPC_SPECIAL3,
430 OPC_LHE = 0x2D | OPC_SPECIAL3,
431 OPC_LLE = 0x2E | OPC_SPECIAL3,
432 OPC_LWE = 0x2F | OPC_SPECIAL3,
433
4368b29a 434 /* R6 */
bf7910c6
LA
435 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
436 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
437 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
438 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
439 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
440 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
441};
442
e10a0ca1
JY
443/* Loongson EXT load/store quad word opcodes */
444#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
445enum {
446 OPC_GSLQ = 0x0020 | OPC_LWC2,
447 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
448 OPC_GSSHFL = OPC_LWC2,
449 OPC_GSSQ = 0x0020 | OPC_SWC2,
450 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
451 OPC_GSSHFS = OPC_SWC2,
452};
453
fd723105
JY
454/* Loongson EXT shifted load/store opcodes */
455#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
456enum {
457 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
458 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
459 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
460 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
461 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
462 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
463 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
464 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
465};
466
90e22a57
JY
467/* Loongson EXT LDC2/SDC2 opcodes */
468#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
469
470enum {
471 OPC_GSLBX = 0x0 | OPC_LDC2,
472 OPC_GSLHX = 0x1 | OPC_LDC2,
473 OPC_GSLWX = 0x2 | OPC_LDC2,
474 OPC_GSLDX = 0x3 | OPC_LDC2,
475 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
476 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
477 OPC_GSSBX = 0x0 | OPC_SDC2,
478 OPC_GSSHX = 0x1 | OPC_SDC2,
479 OPC_GSSWX = 0x2 | OPC_SDC2,
480 OPC_GSSDX = 0x3 | OPC_SDC2,
481 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
482 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
483};
484
7a387fff 485/* BSHFL opcodes */
71375b59 486#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
7a387fff 487
e37e863f 488enum {
15eacb9b
YK
489 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
490 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
491 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
373ecd38
AM
492 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
493 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
494 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
495 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
15eacb9b 496 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
497};
498
7a387fff 499/* DBSHFL opcodes */
71375b59 500#define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
7a387fff 501
e37e863f 502enum {
15eacb9b
YK
503 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
504 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
373ecd38
AM
505 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
506 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
507 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
508 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
509 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
510 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
511 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
512 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
15eacb9b 513 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
514};
515
e45a93e2
JL
516/* MIPS DSP REGIMM opcodes */
517enum {
518 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 519 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
520};
521
71375b59 522#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
9b1a1d68
JL
523/* MIPS DSP Load */
524enum {
525 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
526 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
527 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 528 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
529};
530
71375b59 531#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
532enum {
533 /* MIPS DSP Arithmetic Sub-class */
534 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
535 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
536 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
537 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
538 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
539 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
540 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
541 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
542 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
543 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
544 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
545 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
546 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
547 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
549 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
550 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
551 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
552 /* MIPS DSP Multiply Sub-class insns */
553 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
554 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
555 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
556 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
557 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
558 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
559};
560
561#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
71375b59 562#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
563enum {
564 /* MIPS DSP Arithmetic Sub-class */
565 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
566 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
567 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
568 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
569 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
570 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
571 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
572 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
573 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
574 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
575 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
576 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
577 /* MIPS DSP Multiply Sub-class insns */
578 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
579 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
580 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
581 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
582};
583
71375b59 584#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
585enum {
586 /* MIPS DSP Arithmetic Sub-class */
587 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
588 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
589 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
590 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
591 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
592 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
593 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
594 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
595 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
596 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
597 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
598 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
599 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
600 /* DSP Bit/Manipulation Sub-class */
601 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
605 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
606};
607
71375b59 608#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
609enum {
610 /* MIPS DSP Arithmetic Sub-class */
611 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
612 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
613 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
614 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
615 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
616 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
617 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
618 /* DSP Compare-Pick Sub-class */
619 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
620 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
621 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
622 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
626 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
627 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
629 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
630 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 634};
a22260ae 635
71375b59 636#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
77c5fa8b
JL
637enum {
638 /* MIPS DSP GPR-Based Shift Sub-class */
639 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
640 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
641 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
642 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
643 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
644 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
645 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
646 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
647 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
648 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
649 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
650 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
661};
461c08df 662
71375b59 663#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
a22260ae
JL
664enum {
665 /* MIPS DSP Multiply Sub-class insns */
666 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
667 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
668 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
669 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
670 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
671 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
672 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
673 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
674 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
675 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
676 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
677 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
679 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
680 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
682 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
683 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
686 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
688};
689
71375b59 690#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
1cb6686c
JL
691enum {
692 /* DSP Bit/Manipulation Sub-class */
693 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
694};
695
71375b59 696#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
26690560 697enum {
df6126a7 698 /* MIPS DSP Append Sub-class */
26690560
JL
699 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
700 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
701 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
702};
703
71375b59 704#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
b53371ed
JL
705enum {
706 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
707 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
708 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
709 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
710 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
711 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
712 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
713 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
714 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
715 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
716 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
717 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
718 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
719 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
720 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
721 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
722 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
723 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
724};
725
71375b59 726#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df
JL
727enum {
728 /* MIPS DSP Arithmetic Sub-class */
729 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
730 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
731 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
732 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
733 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
734 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
735 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
736 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
737 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
738 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
739 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
740 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
745 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
746 /* DSP Bit/Manipulation Sub-class */
747 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 753};
461c08df 754
71375b59 755#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df 756enum {
a22260ae
JL
757 /* MIPS DSP Multiply Sub-class insns */
758 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
759 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
760 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
761 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
762 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
763 /* MIPS DSP Arithmetic Sub-class */
764 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
765 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
766 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
767 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
768 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
769 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
770 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
771 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
772 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
773 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
774 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
775 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
776 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
777 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
778 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
779 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
780 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
781 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
782 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
783 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
784 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
785};
461c08df 786
71375b59 787#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
461c08df 788enum {
26690560
JL
789 /* DSP Compare-Pick Sub-class */
790 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
795 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
796 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
797 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
798 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
799 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
800 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
801 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
808 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
809 /* MIPS DSP Arithmetic Sub-class */
810 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
817 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
818};
461c08df 819
71375b59 820#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
26690560 821enum {
df6126a7 822 /* DSP Append Sub-class */
26690560
JL
823 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
824 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
825 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
826 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
827};
26690560 828
71375b59 829#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
b53371ed
JL
830enum {
831 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
832 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
833 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
834 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
835 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
836 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
837 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
838 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
839 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
840 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
841 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
842 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
843 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
844 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
852 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
853};
854
71375b59 855#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
1cb6686c
JL
856enum {
857 /* DSP Bit/Manipulation Sub-class */
858 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
859};
1cb6686c 860
71375b59 861#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
a22260ae
JL
862enum {
863 /* MIPS DSP Multiply Sub-class insns */
864 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
867 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
868 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
869 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
870 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
871 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
872 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
873 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
874 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
875 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
890};
a22260ae 891
71375b59 892#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
77c5fa8b
JL
893enum {
894 /* MIPS DSP GPR-Based Shift Sub-class */
895 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
898 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
899 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
900 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
901 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
902 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
903 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
904 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
905 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
906 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
921};
77c5fa8b 922
7a387fff 923/* Coprocessor 0 (rs field) */
71375b59 924#define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
7a387fff 925
6ea83fed 926enum {
7a387fff
TS
927 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
928 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 929 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
930 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
931 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 932 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 933 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
934 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
935 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 936 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
937 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
938 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
939 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
940 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
941 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
942 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
943 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
944 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
945 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
946 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
947 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
948 OPC_C0_A = (0x1A << 21) | OPC_CP0,
949 OPC_C0_B = (0x1B << 21) | OPC_CP0,
950 OPC_C0_C = (0x1C << 21) | OPC_CP0,
951 OPC_C0_D = (0x1D << 21) | OPC_CP0,
952 OPC_C0_E = (0x1E << 21) | OPC_CP0,
953 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 954};
7a387fff
TS
955
956/* MFMC0 opcodes */
71375b59 957#define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
7a387fff
TS
958
959enum {
ead9360e
TS
960 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
961 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
962 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
963 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
964 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
965 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
966 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
967 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
968};
969
970/* Coprocessor 0 (with rs == C0) */
71375b59 971#define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
7a387fff
TS
972
973enum {
974 OPC_TLBR = 0x01 | OPC_C0,
975 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
976 OPC_TLBINV = 0x03 | OPC_C0,
977 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
978 OPC_TLBWR = 0x06 | OPC_C0,
979 OPC_TLBP = 0x08 | OPC_C0,
980 OPC_RFE = 0x10 | OPC_C0,
981 OPC_ERET = 0x18 | OPC_C0,
982 OPC_DERET = 0x1F | OPC_C0,
983 OPC_WAIT = 0x20 | OPC_C0,
984};
985
71375b59 986#define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
e0c84da7
TS
987
988enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1000};
1001
8e2d5831 1002#define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
bd277fa1
RH
1003
1004enum {
71375b59
AM
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
bd277fa1
RH
1096};
1097
1098
71375b59 1099#define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
e0c84da7
TS
1100
1101enum {
71375b59
AM
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS = 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS = 0x3E | OPC_CP3,
e0c84da7
TS
1122};
1123
497f072b 1124/*
baa609db
AM
1125 * MMI (MultiMedia Instruction) encodings
1126 * ======================================
f99c0d6d 1127 *
baa609db 1128 * MMI instructions encoding table keys:
f99c0d6d
FN
1129 *
1130 * * This code is reserved for future use. An attempt to execute it
1131 * causes a Reserved Instruction exception.
1132 * % This code indicates an instruction class. The instruction word
1133 * must be further decoded by examining additional tables that show
1134 * the values for other instruction fields.
1135 * # This code is reserved for the unsupported instructions DMULT,
1136 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1137 * to execute it causes a Reserved Instruction exception.
1138 *
baa609db 1139 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
f99c0d6d
FN
1140 *
1141 * 31 26 0
1142 * +--------+----------------------------------------+
1143 * | opcode | |
1144 * +--------+----------------------------------------+
1145 *
1146 * opcode bits 28..26
1147 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1148 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1149 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1150 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1151 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1152 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1153 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1154 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1155 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1156 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1157 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
497f072b 1158 */
b158d449 1159
f99c0d6d 1160enum {
baa609db 1161 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
baa609db 1162 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
f99c0d6d
FN
1163};
1164
d3297211 1165/*
baa609db 1166 * MMI instructions with opcode field = MMI:
d3297211
FN
1167 *
1168 * 31 26 5 0
1169 * +--------+-------------------------------+--------+
1170 * | MMI | |function|
1171 * +--------+-------------------------------+--------+
1172 *
1173 * function bits 2..0
1174 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1175 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1176 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1177 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1178 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1179 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1180 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1181 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1182 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1183 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1184 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1185 */
1186
c8341e00 1187#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
d3297211 1188enum {
baa609db
AM
1189 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1190 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
baa609db
AM
1191 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1192 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1193 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
1194 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1195 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1196 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
dd581bf9
FN
1197};
1198
39454628 1199/* global register indices */
46c9e2b3 1200TCGv cpu_gpr[32], cpu_PC;
cefd68f6
PMD
1201/*
1202 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1203 * and the upper halves in cpu_gpr_hi[].
1204 */
1205TCGv_i64 cpu_gpr_hi[32];
9f5f7691 1206TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
46c9e2b3
PMD
1207static TCGv cpu_dspctrl, btarget;
1208TCGv bcond;
33a07fa2 1209static TCGv cpu_lladdr, cpu_llval;
41db4607 1210static TCGv_i32 hflags;
8758d1b8
PMD
1211TCGv_i32 fpu_fcr0, fpu_fcr31;
1212TCGv_i64 fpu_f64[32];
aa0bf00b 1213
022c62cb 1214#include "exec/gen-icount.h"
2e70f6ef 1215
895c2d04 1216#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1217 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1218 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4 1219 tcg_temp_free_i32(helper_tmp); \
71375b59 1220 } while (0)
be24bb4f 1221
895c2d04 1222#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1223 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1224 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4 1225 tcg_temp_free_i32(helper_tmp); \
71375b59 1226 } while (0)
be24bb4f 1227
895c2d04
BS
1228#define gen_helper_1e0i(name, ret, arg1) do { \
1229 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1230 gen_helper_##name(ret, cpu_env, helper_tmp); \
1231 tcg_temp_free_i32(helper_tmp); \
71375b59 1232 } while (0)
895c2d04
BS
1233
1234#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1235 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1236 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1237 tcg_temp_free_i32(helper_tmp); \
71375b59 1238 } while (0)
895c2d04
BS
1239
1240#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1241 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1242 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1243 tcg_temp_free_i32(helper_tmp); \
71375b59 1244 } while (0)
895c2d04 1245
b28425ba
EC
1246#define DISAS_STOP DISAS_TARGET_0
1247#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 1248
06106772 1249static const char regnames_HI[][4] = {
d73ee8a2
RH
1250 "HI0", "HI1", "HI2", "HI3",
1251};
4b2eb8d2 1252
06106772 1253static const char regnames_LO[][4] = {
d73ee8a2
RH
1254 "LO0", "LO1", "LO2", "LO3",
1255};
4b2eb8d2 1256
8e9ade68 1257/* General purpose registers moves. */
46c9e2b3 1258void gen_load_gpr(TCGv t, int reg)
aaa9128a 1259{
1f8929d2 1260 if (reg == 0) {
8e9ade68 1261 tcg_gen_movi_tl(t, 0);
1f8929d2 1262 } else {
4b2eb8d2 1263 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1f8929d2 1264 }
aaa9128a
TS
1265}
1266
46c9e2b3 1267void gen_store_gpr(TCGv t, int reg)
aaa9128a 1268{
1f8929d2 1269 if (reg != 0) {
4b2eb8d2 1270 tcg_gen_mov_tl(cpu_gpr[reg], t);
1f8929d2 1271 }
aaa9128a
TS
1272}
1273
61f4e0ec
PMD
1274#if defined(TARGET_MIPS64)
1275void gen_load_gpr_hi(TCGv_i64 t, int reg)
1276{
1277 if (reg == 0) {
1278 tcg_gen_movi_i64(t, 0);
1279 } else {
1280 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1281 }
1282}
1283
1284void gen_store_gpr_hi(TCGv_i64 t, int reg)
1285{
1286 if (reg != 0) {
1287 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1288 }
1289}
1290#endif /* TARGET_MIPS64 */
1291
8e9ade68 1292/* Moves to/from shadow registers. */
235785e8 1293static inline void gen_load_srsgpr(int from, int to)
aaa9128a 1294{
d9bea114 1295 TCGv t0 = tcg_temp_new();
be24bb4f 1296
1f8929d2 1297 if (from == 0) {
d9bea114 1298 tcg_gen_movi_tl(t0, 0);
1f8929d2 1299 } else {
d9bea114 1300 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1301 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1302
7db13fae 1303 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1304 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1305 tcg_gen_andi_i32(t2, t2, 0xf);
1306 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1307 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1308 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1309
d9bea114 1310 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1311 tcg_temp_free_ptr(addr);
d9bea114 1312 tcg_temp_free_i32(t2);
8e9ade68 1313 }
d9bea114
AJ
1314 gen_store_gpr(t0, to);
1315 tcg_temp_free(t0);
aaa9128a
TS
1316}
1317
71375b59 1318static inline void gen_store_srsgpr(int from, int to)
aaa9128a 1319{
be24bb4f 1320 if (to != 0) {
d9bea114
AJ
1321 TCGv t0 = tcg_temp_new();
1322 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1323 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1324
d9bea114 1325 gen_load_gpr(t0, from);
7db13fae 1326 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1327 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1328 tcg_gen_andi_i32(t2, t2, 0xf);
1329 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1330 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1331 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1332
d9bea114 1333 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1334 tcg_temp_free_ptr(addr);
d9bea114
AJ
1335 tcg_temp_free_i32(t2);
1336 tcg_temp_free(t0);
8e9ade68 1337 }
aaa9128a
TS
1338}
1339
eab9944c
LA
1340/* Tests */
1341static inline void gen_save_pc(target_ulong pc)
1342{
1343 tcg_gen_movi_tl(cpu_PC, pc);
1344}
1345
1346static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1347{
1348 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
1349 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1350 gen_save_pc(ctx->base.pc_next);
1351 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
1352 }
1353 if (ctx->hflags != ctx->saved_hflags) {
1354 tcg_gen_movi_i32(hflags, ctx->hflags);
1355 ctx->saved_hflags = ctx->hflags;
1356 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1357 case MIPS_HFLAG_BR:
1358 break;
1359 case MIPS_HFLAG_BC:
1360 case MIPS_HFLAG_BL:
1361 case MIPS_HFLAG_B:
1362 tcg_gen_movi_tl(btarget, ctx->btarget);
1363 break;
1364 }
1365 }
1366}
1367
1368static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1369{
1370 ctx->saved_hflags = ctx->hflags;
1371 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1372 case MIPS_HFLAG_BR:
1373 break;
1374 case MIPS_HFLAG_BC:
1375 case MIPS_HFLAG_BL:
1376 case MIPS_HFLAG_B:
1377 ctx->btarget = env->btarget;
1378 break;
1379 }
1380}
1381
46c9e2b3 1382void generate_exception_err(DisasContext *ctx, int excp, int err)
eab9944c
LA
1383{
1384 TCGv_i32 texcp = tcg_const_i32(excp);
1385 TCGv_i32 terr = tcg_const_i32(err);
1386 save_cpu_state(ctx, 1);
1387 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1388 tcg_temp_free_i32(terr);
1389 tcg_temp_free_i32(texcp);
eeb3bba8 1390 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
1391}
1392
46c9e2b3 1393void generate_exception(DisasContext *ctx, int excp)
eab9944c 1394{
eab9944c
LA
1395 gen_helper_0e0i(raise_exception, excp);
1396}
1397
46c9e2b3 1398void generate_exception_end(DisasContext *ctx, int excp)
9c708c7f
PD
1399{
1400 generate_exception_err(ctx, excp, 0);
1401}
1402
3a4ef3b7
PMD
1403void gen_reserved_instruction(DisasContext *ctx)
1404{
1405 generate_exception_end(ctx, EXCP_RI);
1406}
1407
aaa9128a 1408/* Floating point register moves. */
8758d1b8 1409void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1410{
7c979afd
LA
1411 if (ctx->hflags & MIPS_HFLAG_FRE) {
1412 generate_exception(ctx, EXCP_RI);
1413 }
ecc7b3aa 1414 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1415}
1416
8758d1b8 1417void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1418{
7c979afd
LA
1419 TCGv_i64 t64;
1420 if (ctx->hflags & MIPS_HFLAG_FRE) {
1421 generate_exception(ctx, EXCP_RI);
1422 }
1423 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1424 tcg_gen_extu_i32_i64(t64, t);
1425 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1426 tcg_temp_free_i64(t64);
6d066274
AJ
1427}
1428
7f6613ce 1429static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1430{
7f6613ce 1431 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1432 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1433 } else {
7c979afd 1434 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1435 }
6d066274
AJ
1436}
1437
7f6613ce 1438static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1439{
7f6613ce
PJ
1440 if (ctx->hflags & MIPS_HFLAG_F64) {
1441 TCGv_i64 t64 = tcg_temp_new_i64();
1442 tcg_gen_extu_i32_i64(t64, t);
1443 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1444 tcg_temp_free_i64(t64);
1445 } else {
7c979afd 1446 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1447 }
aa0bf00b 1448}
6ea83fed 1449
8758d1b8 1450void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1451{
f364515c 1452 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1453 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1454 } else {
d73ee8a2 1455 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1456 }
1457}
6ea83fed 1458
8758d1b8 1459void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1460{
f364515c 1461 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1462 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1463 } else {
d73ee8a2
RH
1464 TCGv_i64 t0;
1465 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1466 t0 = tcg_temp_new_i64();
6d066274 1467 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1468 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1469 tcg_temp_free_i64(t0);
aa0bf00b
TS
1470 }
1471}
6ea83fed 1472
8758d1b8 1473int get_fp_bit(int cc)
a16336e4 1474{
1f8929d2 1475 if (cc) {
d94536f4 1476 return 24 + cc;
1f8929d2 1477 } else {
d94536f4 1478 return 23;
1f8929d2 1479 }
a16336e4
TS
1480}
1481
48d38ca5 1482/* Addresses computation */
46c9e2b3 1483void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1484{
941694d0 1485 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1486
1487#if defined(TARGET_MIPS64)
01f72885 1488 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1489 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1490 }
1491#endif
4ad40f36
FB
1492}
1493
bf0718c5
SM
1494static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1495 target_long ofs)
1496{
1497 tcg_gen_addi_tl(ret, base, ofs);
1498
1499#if defined(TARGET_MIPS64)
1500 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1501 tcg_gen_ext32s_i64(ret, ret);
1502 }
1503#endif
1504}
1505
31837be3
YK
1506/* Addresses computation (translation time) */
1507static target_long addr_add(DisasContext *ctx, target_long base,
1508 target_long offset)
1509{
1510 target_long sum = base + offset;
1511
1512#if defined(TARGET_MIPS64)
1513 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1514 sum = (int32_t)sum;
1515 }
1516#endif
1517 return sum;
1518}
1519
71f303cd 1520/* Sign-extract the low 32-bits to a target_long. */
46c9e2b3 1521void gen_move_low32(TCGv ret, TCGv_i64 arg)
1f1b4c00
YK
1522{
1523#if defined(TARGET_MIPS64)
71f303cd
RH
1524 tcg_gen_ext32s_i64(ret, arg);
1525#else
1526 tcg_gen_extrl_i64_i32(ret, arg);
1527#endif
1528}
1529
1530/* Sign-extract the high 32-bits to a target_long. */
46c9e2b3 1531void gen_move_high32(TCGv ret, TCGv_i64 arg)
71f303cd
RH
1532{
1533#if defined(TARGET_MIPS64)
1534 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1535#else
71f303cd 1536 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1537#endif
1538}
1539
905bdf72 1540bool check_cp0_enabled(DisasContext *ctx)
387a8fe5 1541{
1f8929d2 1542 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
11a75118 1543 generate_exception_end(ctx, EXCP_CpU);
905bdf72 1544 return false;
1f8929d2 1545 }
905bdf72 1546 return true;
387a8fe5
TS
1547}
1548
8758d1b8 1549void check_cp1_enabled(DisasContext *ctx)
5e755519 1550{
1f8929d2 1551 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
5e755519 1552 generate_exception_err(ctx, EXCP_CpU, 1);
1f8929d2 1553 }
5e755519
TS
1554}
1555
7480515f
AM
1556/*
1557 * Verify that the processor is running with COP1X instructions enabled.
1558 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1559 * opcode tables.
1560 */
8758d1b8 1561void check_cop1x(DisasContext *ctx)
b8aa4598 1562{
1f8929d2 1563 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
3a4ef3b7 1564 gen_reserved_instruction(ctx);
1f8929d2 1565 }
b8aa4598
TS
1566}
1567
7480515f
AM
1568/*
1569 * Verify that the processor is running with 64-bit floating-point
1570 * operations enabled.
1571 */
8758d1b8 1572void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1573{
1f8929d2 1574 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
3a4ef3b7 1575 gen_reserved_instruction(ctx);
1f8929d2 1576 }
5e755519
TS
1577}
1578
1579/*
1580 * Verify if floating point register is valid; an operation is not defined
1581 * if bit 0 of any register specification is set and the FR bit in the
1582 * Status register equals zero, since the register numbers specify an
1583 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1584 * in the Status register equals one, both even and odd register numbers
1585 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1586 *
1587 * Multiple 64 bit wide registers can be checked by calling
1588 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1589 */
8758d1b8 1590void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1591{
1f8929d2 1592 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
3a4ef3b7 1593 gen_reserved_instruction(ctx);
1f8929d2 1594 }
5e755519
TS
1595}
1596
7480515f
AM
1597/*
1598 * Verify that the processor is running with DSP instructions enabled.
1599 * This is enabled by CP0 Status register MX(24) bit.
853c3240 1600 */
853c3240
JL
1601static inline void check_dsp(DisasContext *ctx)
1602{
1603 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1604 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1605 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1606 } else {
3a4ef3b7 1607 gen_reserved_instruction(ctx);
ad153f15 1608 }
853c3240
JL
1609 }
1610}
1611
908f6be1 1612static inline void check_dsp_r2(DisasContext *ctx)
853c3240 1613{
908f6be1 1614 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 1615 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1616 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1617 } else {
3a4ef3b7 1618 gen_reserved_instruction(ctx);
ad153f15 1619 }
853c3240
JL
1620 }
1621}
1622
908f6be1 1623static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 1624{
908f6be1 1625 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
1626 if (ctx->insn_flags & ASE_DSP) {
1627 generate_exception_end(ctx, EXCP_DSPDIS);
1628 } else {
3a4ef3b7 1629 gen_reserved_instruction(ctx);
59e781fb
SM
1630 }
1631 }
1632}
1633
7480515f
AM
1634/*
1635 * This code generates a "reserved instruction" exception if the
1636 * CPU does not support the instruction set corresponding to flags.
1637 */
46c9e2b3 1638void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 1639{
d75c135e 1640 if (unlikely(!(ctx->insn_flags & flags))) {
3a4ef3b7 1641 gen_reserved_instruction(ctx);
d75c135e 1642 }
3a95e3a7
TS
1643}
1644
7480515f
AM
1645/*
1646 * This code generates a "reserved instruction" exception if the
1647 * CPU has corresponding flag set which indicates that the instruction
1648 * has been removed.
1649 */
f9c9cd63 1650static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
1651{
1652 if (unlikely(ctx->insn_flags & flags)) {
3a4ef3b7 1653 gen_reserved_instruction(ctx);
fecd2646
LA
1654 }
1655}
1656
96631327
FN
1657/*
1658 * The Linux kernel traps certain reserved instruction exceptions to
1659 * emulate the corresponding instructions. QEMU is the kernel in user
1660 * mode, so those traps are emulated by accepting the instructions.
1661 *
1662 * A reserved instruction exception is generated for flagged CPUs if
1663 * QEMU runs in system mode.
1664 */
1665static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1666{
1667#ifndef CONFIG_USER_ONLY
1668 check_insn_opc_removed(ctx, flags);
1669#endif
1670}
1671
7480515f
AM
1672/*
1673 * This code generates a "reserved instruction" exception if the
1674 * CPU does not support 64-bit paired-single (PS) floating point data type.
1675 */
e29c9628
YK
1676static inline void check_ps(DisasContext *ctx)
1677{
1678 if (unlikely(!ctx->ps)) {
1679 generate_exception(ctx, EXCP_RI);
1680 }
1681 check_cp1_64bitmode(ctx);
1682}
1683
7480515f 1684/*
d7efb693
PMD
1685 * This code generates a "reserved instruction" exception if cpu is not
1686 * 64-bit or 64-bit instructions are not enabled.
7480515f 1687 */
46c9e2b3 1688void check_mips_64(DisasContext *ctx)
e189e748 1689{
d7efb693 1690 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
3a4ef3b7 1691 gen_reserved_instruction(ctx);
1f8929d2 1692 }
e189e748
TS
1693}
1694
5204ea79
LA
1695#ifndef CONFIG_USER_ONLY
1696static inline void check_mvh(DisasContext *ctx)
1697{
1698 if (unlikely(!ctx->mvh)) {
1699 generate_exception(ctx, EXCP_RI);
1700 }
1701}
1702#endif
1703
0b16dcd1
AR
1704/*
1705 * This code generates a "reserved instruction" exception if the
1706 * Config5 XNP bit is set.
1707 */
1708static inline void check_xnp(DisasContext *ctx)
1709{
1710 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3a4ef3b7 1711 gen_reserved_instruction(ctx);
0b16dcd1
AR
1712 }
1713}
1714
5e31fdd5
YK
1715#ifndef CONFIG_USER_ONLY
1716/*
1717 * This code generates a "reserved instruction" exception if the
1718 * Config3 PW bit is NOT set.
1719 */
1720static inline void check_pw(DisasContext *ctx)
1721{
1722 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3a4ef3b7 1723 gen_reserved_instruction(ctx);
5e31fdd5
YK
1724 }
1725}
1726#endif
1727
9affc1c5
AR
1728/*
1729 * This code generates a "reserved instruction" exception if the
1730 * Config3 MT bit is NOT set.
1731 */
1732static inline void check_mt(DisasContext *ctx)
1733{
1734 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3a4ef3b7 1735 gen_reserved_instruction(ctx);
9affc1c5
AR
1736 }
1737}
1738
1739#ifndef CONFIG_USER_ONLY
1740/*
1741 * This code generates a "coprocessor unusable" exception if CP0 is not
1742 * available, and, if that is not the case, generates a "reserved instruction"
1743 * exception if the Config5 MT bit is NOT set. This is needed for availability
1744 * control of some of MT ASE instructions.
1745 */
1746static inline void check_cp0_mt(DisasContext *ctx)
1747{
1748 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
11a75118 1749 generate_exception_end(ctx, EXCP_CpU);
9affc1c5
AR
1750 } else {
1751 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3a4ef3b7 1752 gen_reserved_instruction(ctx);
9affc1c5
AR
1753 }
1754 }
1755}
1756#endif
1757
fb32f8c8
DN
1758/*
1759 * This code generates a "reserved instruction" exception if the
1760 * Config5 NMS bit is set.
1761 */
1762static inline void check_nms(DisasContext *ctx)
1763{
1764 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3a4ef3b7 1765 gen_reserved_instruction(ctx);
fb32f8c8
DN
1766 }
1767}
1768
d046a9ea
DN
1769/*
1770 * This code generates a "reserved instruction" exception if the
1771 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1772 * Config2 TL, and Config5 L2C are unset.
1773 */
1774static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1775{
1f8929d2
AM
1776 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1777 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1778 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1779 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1780 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1781 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3a4ef3b7 1782 gen_reserved_instruction(ctx);
d046a9ea
DN
1783 }
1784}
1785
1786/*
1787 * This code generates a "reserved instruction" exception if the
1788 * Config5 EVA bit is NOT set.
1789 */
1790static inline void check_eva(DisasContext *ctx)
1791{
1792 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3a4ef3b7 1793 gen_reserved_instruction(ctx);
d046a9ea
DN
1794 }
1795}
1796
0b16dcd1 1797
7480515f
AM
1798/*
1799 * Define small wrappers for gen_load_fpr* so that we have a uniform
1800 * calling interface for 32 and 64-bit FPRs. No sense in changing
1801 * all callers for gen_load_fpr32 when we need the CTX parameter for
1802 * this one use.
1803 */
7c979afd 1804#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1805#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1806#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1807static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1808 int ft, int fs, int cc) \
1809{ \
71375b59
AM
1810 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1811 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
8153667c
NF
1812 switch (ifmt) { \
1813 case FMT_PS: \
e29c9628 1814 check_ps(ctx); \
8153667c
NF
1815 break; \
1816 case FMT_D: \
1817 if (abs) { \
1818 check_cop1x(ctx); \
1819 } \
1820 check_cp1_registers(ctx, fs | ft); \
1821 break; \
1822 case FMT_S: \
1823 if (abs) { \
1824 check_cop1x(ctx); \
1825 } \
1826 break; \
1827 } \
71375b59
AM
1828 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1829 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
8153667c 1830 switch (n) { \
1f8929d2
AM
1831 case 0: \
1832 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1833 break; \
1834 case 1: \
1835 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1836 break; \
1837 case 2: \
1838 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1839 break; \
1840 case 3: \
1841 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1842 break; \
1843 case 4: \
1844 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1845 break; \
1846 case 5: \
1847 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1848 break; \
1849 case 6: \
1850 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1851 break; \
1852 case 7: \
1853 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1854 break; \
1855 case 8: \
1856 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1857 break; \
1858 case 9: \
1859 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1860 break; \
1861 case 10: \
1862 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1863 break; \
1864 case 11: \
1865 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1866 break; \
1867 case 12: \
1868 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1869 break; \
1870 case 13: \
1871 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1872 break; \
1873 case 14: \
1874 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1875 break; \
1876 case 15: \
1877 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1878 break; \
1879 default: \
1880 abort(); \
8153667c 1881 } \
71375b59
AM
1882 tcg_temp_free_i##bits(fp0); \
1883 tcg_temp_free_i##bits(fp1); \
8153667c
NF
1884}
1885
1886FOP_CONDS(, 0, d, FMT_D, 64)
1887FOP_CONDS(abs, 1, d, FMT_D, 64)
1888FOP_CONDS(, 0, s, FMT_S, 32)
1889FOP_CONDS(abs, 1, s, FMT_S, 32)
1890FOP_CONDS(, 0, ps, FMT_PS, 64)
1891FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1892#undef FOP_CONDS
3f493883
YK
1893
1894#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
71375b59 1895static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3f493883
YK
1896 int ft, int fs, int fd) \
1897{ \
1898 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1899 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1900 if (ifmt == FMT_D) { \
3f493883 1901 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1902 } \
1903 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1904 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1905 switch (n) { \
1906 case 0: \
1907 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 1: \
1910 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 2: \
1913 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 3: \
1916 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 4: \
1919 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 5: \
1922 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 6: \
1925 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 7: \
1928 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 8: \
1931 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 9: \
1934 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 10: \
1937 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 case 11: \
1940 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1941 break; \
1942 case 12: \
1943 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1944 break; \
1945 case 13: \
1946 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1947 break; \
1948 case 14: \
1949 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 15: \
1952 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 17: \
1955 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 case 18: \
1958 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1959 break; \
1960 case 19: \
1961 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1962 break; \
1963 case 25: \
1964 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1965 break; \
1966 case 26: \
1967 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1968 break; \
1969 case 27: \
1970 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1971 break; \
1972 default: \
1973 abort(); \
1974 } \
1975 STORE; \
71375b59
AM
1976 tcg_temp_free_i ## bits(fp0); \
1977 tcg_temp_free_i ## bits(fp1); \
3f493883
YK
1978}
1979
1980FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 1981FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 1982#undef FOP_CONDNS
8153667c
NF
1983#undef gen_ldcmp_fpr32
1984#undef gen_ldcmp_fpr64
1985
958fb4a9 1986/* load/store instructions. */
e7139c44 1987#ifdef CONFIG_USER_ONLY
71375b59 1988#define OP_LD_ATOMIC(insn, fname) \
dd4096cd
JH
1989static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1990 DisasContext *ctx) \
d9bea114
AJ
1991{ \
1992 TCGv t0 = tcg_temp_new(); \
1993 tcg_gen_mov_tl(t0, arg1); \
1994 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
71375b59
AM
1995 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1996 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1997 tcg_temp_free(t0); \
aaa9128a 1998}
e7139c44 1999#else
71375b59 2000#define OP_LD_ATOMIC(insn, fname) \
dd4096cd
JH
2001static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2002 DisasContext *ctx) \
e7139c44 2003{ \
dd4096cd 2004 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2005}
2006#endif
71375b59 2007OP_LD_ATOMIC(ll, ld32s);
aaa9128a 2008#if defined(TARGET_MIPS64)
71375b59 2009OP_LD_ATOMIC(lld, ld64);
aaa9128a
TS
2010#endif
2011#undef OP_LD_ATOMIC
2012
46c9e2b3 2013void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
662d7485
NF
2014{
2015 if (base == 0) {
2016 tcg_gen_movi_tl(addr, offset);
2017 } else if (offset == 0) {
2018 gen_load_gpr(addr, base);
2019 } else {
2020 tcg_gen_movi_tl(addr, offset);
2021 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2022 }
2023}
2024
235785e8 2025static target_ulong pc_relative_pc(DisasContext *ctx)
364d4831 2026{
eeb3bba8 2027 target_ulong pc = ctx->base.pc_next;
364d4831
NF
2028
2029 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2030 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2031
2032 pc -= branch_bytes;
2033 }
2034
2035 pc &= ~(target_ulong)3;
2036 return pc;
2037}
2038
5c13fdfd 2039/* Load */
d75c135e 2040static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 2041 int rt, int base, int offset)
6af0bf9c 2042{
fc40787a 2043 TCGv t0, t1, t2;
dd4096cd 2044 int mem_idx = ctx->mem_idx;
afa88c3a 2045
8e2d5831
JY
2046 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2047 INSN_LOONGSON3A)) {
7480515f
AM
2048 /*
2049 * Loongson CPU uses a load to zero register for prefetch.
2050 * We emulate it as a NOP. On other CPU we must perform the
2051 * actual memory access.
2052 */
afa88c3a
AJ
2053 return;
2054 }
6af0bf9c 2055
afa88c3a 2056 t0 = tcg_temp_new();
662d7485 2057 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2058
6af0bf9c 2059 switch (opc) {
d26bc211 2060#if defined(TARGET_MIPS64)
6e473128 2061 case OPC_LWU:
dd4096cd 2062 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2063 ctx->default_tcg_memop_mask);
78723684 2064 gen_store_gpr(t0, rt);
6e473128 2065 break;
6af0bf9c 2066 case OPC_LD:
dd4096cd 2067 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2068 ctx->default_tcg_memop_mask);
78723684 2069 gen_store_gpr(t0, rt);
6af0bf9c 2070 break;
7a387fff 2071 case OPC_LLD:
bf7910c6 2072 case R6_OPC_LLD:
dd4096cd 2073 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2074 gen_store_gpr(t0, rt);
7a387fff 2075 break;
6af0bf9c 2076 case OPC_LDL:
3cee3050 2077 t1 = tcg_temp_new();
7480515f
AM
2078 /*
2079 * Do a byte access to possibly trigger a page
2080 * fault with the unaligned address.
2081 */
dd4096cd 2082 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2083 tcg_gen_andi_tl(t1, t0, 7);
2084#ifndef TARGET_WORDS_BIGENDIAN
2085 tcg_gen_xori_tl(t1, t1, 7);
2086#endif
2087 tcg_gen_shli_tl(t1, t1, 3);
2088 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2089 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2090 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2091 t2 = tcg_const_tl(-1);
2092 tcg_gen_shl_tl(t2, t2, t1);
78723684 2093 gen_load_gpr(t1, rt);
eb02cc3f 2094 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2095 tcg_temp_free(t2);
2096 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2097 tcg_temp_free(t1);
fc40787a 2098 gen_store_gpr(t0, rt);
6af0bf9c 2099 break;
6af0bf9c 2100 case OPC_LDR:
3cee3050 2101 t1 = tcg_temp_new();
7480515f
AM
2102 /*
2103 * Do a byte access to possibly trigger a page
2104 * fault with the unaligned address.
2105 */
dd4096cd 2106 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2107 tcg_gen_andi_tl(t1, t0, 7);
2108#ifdef TARGET_WORDS_BIGENDIAN
2109 tcg_gen_xori_tl(t1, t1, 7);
2110#endif
2111 tcg_gen_shli_tl(t1, t1, 3);
2112 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2113 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2114 tcg_gen_shr_tl(t0, t0, t1);
2115 tcg_gen_xori_tl(t1, t1, 63);
2116 t2 = tcg_const_tl(0xfffffffffffffffeull);
2117 tcg_gen_shl_tl(t2, t2, t1);
78723684 2118 gen_load_gpr(t1, rt);
fc40787a
AJ
2119 tcg_gen_and_tl(t1, t1, t2);
2120 tcg_temp_free(t2);
2121 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2122 tcg_temp_free(t1);
fc40787a 2123 gen_store_gpr(t0, rt);
6af0bf9c 2124 break;
364d4831 2125 case OPC_LDPC:
3cee3050 2126 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2127 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2128 tcg_temp_free(t1);
dd4096cd 2129 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2130 gen_store_gpr(t0, rt);
2131 break;
6af0bf9c 2132#endif
364d4831 2133 case OPC_LWPC:
3cee3050 2134 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2135 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2136 tcg_temp_free(t1);
dd4096cd 2137 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2138 gen_store_gpr(t0, rt);
2139 break;
76964147
JH
2140 case OPC_LWE:
2141 mem_idx = MIPS_HFLAG_UM;
2142 /* fall through */
6af0bf9c 2143 case OPC_LW:
dd4096cd 2144 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2145 ctx->default_tcg_memop_mask);
78723684 2146 gen_store_gpr(t0, rt);
6af0bf9c 2147 break;
76964147
JH
2148 case OPC_LHE:
2149 mem_idx = MIPS_HFLAG_UM;
2150 /* fall through */
6af0bf9c 2151 case OPC_LH:
dd4096cd 2152 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2153 ctx->default_tcg_memop_mask);
78723684 2154 gen_store_gpr(t0, rt);
6af0bf9c 2155 break;
76964147
JH
2156 case OPC_LHUE:
2157 mem_idx = MIPS_HFLAG_UM;
2158 /* fall through */
6af0bf9c 2159 case OPC_LHU:
dd4096cd 2160 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2161 ctx->default_tcg_memop_mask);
78723684 2162 gen_store_gpr(t0, rt);
6af0bf9c 2163 break;
76964147
JH
2164 case OPC_LBE:
2165 mem_idx = MIPS_HFLAG_UM;
2166 /* fall through */
6af0bf9c 2167 case OPC_LB:
dd4096cd 2168 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2169 gen_store_gpr(t0, rt);
6af0bf9c 2170 break;
76964147
JH
2171 case OPC_LBUE:
2172 mem_idx = MIPS_HFLAG_UM;
2173 /* fall through */
6af0bf9c 2174 case OPC_LBU:
dd4096cd 2175 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2176 gen_store_gpr(t0, rt);
6af0bf9c 2177 break;
76964147
JH
2178 case OPC_LWLE:
2179 mem_idx = MIPS_HFLAG_UM;
2180 /* fall through */
6af0bf9c 2181 case OPC_LWL:
3cee3050 2182 t1 = tcg_temp_new();
7480515f
AM
2183 /*
2184 * Do a byte access to possibly trigger a page
2185 * fault with the unaligned address.
2186 */
dd4096cd 2187 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2188 tcg_gen_andi_tl(t1, t0, 3);
2189#ifndef TARGET_WORDS_BIGENDIAN
2190 tcg_gen_xori_tl(t1, t1, 3);
2191#endif
2192 tcg_gen_shli_tl(t1, t1, 3);
2193 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2194 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2195 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2196 t2 = tcg_const_tl(-1);
2197 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2198 gen_load_gpr(t1, rt);
eb02cc3f 2199 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2200 tcg_temp_free(t2);
2201 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2202 tcg_temp_free(t1);
fc40787a
AJ
2203 tcg_gen_ext32s_tl(t0, t0);
2204 gen_store_gpr(t0, rt);
6af0bf9c 2205 break;
76964147
JH
2206 case OPC_LWRE:
2207 mem_idx = MIPS_HFLAG_UM;
2208 /* fall through */
6af0bf9c 2209 case OPC_LWR:
3cee3050 2210 t1 = tcg_temp_new();
7480515f
AM
2211 /*
2212 * Do a byte access to possibly trigger a page
2213 * fault with the unaligned address.
2214 */
dd4096cd 2215 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2216 tcg_gen_andi_tl(t1, t0, 3);
2217#ifdef TARGET_WORDS_BIGENDIAN
2218 tcg_gen_xori_tl(t1, t1, 3);
2219#endif
2220 tcg_gen_shli_tl(t1, t1, 3);
2221 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2222 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2223 tcg_gen_shr_tl(t0, t0, t1);
2224 tcg_gen_xori_tl(t1, t1, 31);
2225 t2 = tcg_const_tl(0xfffffffeull);
2226 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2227 gen_load_gpr(t1, rt);
fc40787a
AJ
2228 tcg_gen_and_tl(t1, t1, t2);
2229 tcg_temp_free(t2);
2230 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2231 tcg_temp_free(t1);
c728154b 2232 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2233 gen_store_gpr(t0, rt);
6af0bf9c 2234 break;
76964147
JH
2235 case OPC_LLE:
2236 mem_idx = MIPS_HFLAG_UM;
2237 /* fall through */
6af0bf9c 2238 case OPC_LL:
4368b29a 2239 case R6_OPC_LL:
dd4096cd 2240 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2241 gen_store_gpr(t0, rt);
6af0bf9c 2242 break;
d66c7132 2243 }
d66c7132 2244 tcg_temp_free(t0);
d66c7132
AJ
2245}
2246
5c13fdfd 2247/* Store */
235785e8
AM
2248static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2249 int base, int offset)
5c13fdfd 2250{
5c13fdfd
AJ
2251 TCGv t0 = tcg_temp_new();
2252 TCGv t1 = tcg_temp_new();
dd4096cd 2253 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2254
2255 gen_base_offset_addr(ctx, t0, base, offset);
2256 gen_load_gpr(t1, rt);
2257 switch (opc) {
2258#if defined(TARGET_MIPS64)
2259 case OPC_SD:
dd4096cd 2260 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2261 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2262 break;
2263 case OPC_SDL:
dd4096cd 2264 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2265 break;
2266 case OPC_SDR:
dd4096cd 2267 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2268 break;
2269#endif
76964147
JH
2270 case OPC_SWE:
2271 mem_idx = MIPS_HFLAG_UM;
2272 /* fall through */
5c13fdfd 2273 case OPC_SW:
dd4096cd 2274 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2275 ctx->default_tcg_memop_mask);
5c13fdfd 2276 break;
76964147
JH
2277 case OPC_SHE:
2278 mem_idx = MIPS_HFLAG_UM;
2279 /* fall through */
5c13fdfd 2280 case OPC_SH:
dd4096cd 2281 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2282 ctx->default_tcg_memop_mask);
5c13fdfd 2283 break;
76964147
JH
2284 case OPC_SBE:
2285 mem_idx = MIPS_HFLAG_UM;
2286 /* fall through */
5c13fdfd 2287 case OPC_SB:
dd4096cd 2288 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2289 break;
76964147
JH
2290 case OPC_SWLE:
2291 mem_idx = MIPS_HFLAG_UM;
2292 /* fall through */
5c13fdfd 2293 case OPC_SWL:
dd4096cd 2294 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2295 break;
76964147
JH
2296 case OPC_SWRE:
2297 mem_idx = MIPS_HFLAG_UM;
2298 /* fall through */
5c13fdfd 2299 case OPC_SWR:
dd4096cd 2300 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2301 break;
2302 }
5c13fdfd
AJ
2303 tcg_temp_free(t0);
2304 tcg_temp_free(t1);
2305}
2306
2307
d66c7132 2308/* Store conditional */
33a07fa2 2309static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
14776ab5 2310 MemOp tcg_mo, bool eva)
d66c7132 2311{
33a07fa2
LA
2312 TCGv addr, t0, val;
2313 TCGLabel *l1 = gen_new_label();
2314 TCGLabel *done = gen_new_label();
d66c7132 2315
2d2826b9 2316 t0 = tcg_temp_new();
33a07fa2 2317 addr = tcg_temp_new();
8cdf8869 2318 /* compare the address against that of the preceding LL */
33a07fa2
LA
2319 gen_base_offset_addr(ctx, addr, base, offset);
2320 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2321 tcg_temp_free(addr);
2322 tcg_gen_movi_tl(t0, 0);
2323 gen_store_gpr(t0, rt);
2324 tcg_gen_br(done);
2325
2326 gen_set_label(l1);
2327 /* generate cmpxchg */
2328 val = tcg_temp_new();
2329 gen_load_gpr(val, rt);
2330 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2331 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2332 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2333 gen_store_gpr(t0, rt);
2334 tcg_temp_free(val);
2335
2336 gen_set_label(done);
d66c7132 2337 tcg_temp_free(t0);
6af0bf9c
FB
2338}
2339
6ea83fed 2340/* Load and store */
235785e8
AM
2341static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2342 TCGv t0)
6ea83fed 2343{
7480515f
AM
2344 /*
2345 * Don't do NOP if destination is zero: we must perform the actual
2346 * memory access.
2347 */
6ea83fed
FB
2348 switch (opc) {
2349 case OPC_LWC1:
b6d96bed 2350 {
a7812ae4 2351 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2352 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2353 ctx->default_tcg_memop_mask);
7c979afd 2354 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2355 tcg_temp_free_i32(fp0);
b6d96bed 2356 }
6ea83fed
FB
2357 break;
2358 case OPC_SWC1:
b6d96bed 2359 {
a7812ae4 2360 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2361 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2362 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2363 ctx->default_tcg_memop_mask);
a7812ae4 2364 tcg_temp_free_i32(fp0);
b6d96bed 2365 }
6ea83fed
FB
2366 break;
2367 case OPC_LDC1:
b6d96bed 2368 {
a7812ae4 2369 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2370 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2371 ctx->default_tcg_memop_mask);
b6d96bed 2372 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2373 tcg_temp_free_i64(fp0);
b6d96bed 2374 }
6ea83fed
FB
2375 break;
2376 case OPC_SDC1:
b6d96bed 2377 {
a7812ae4 2378 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2379 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2380 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2381 ctx->default_tcg_memop_mask);
a7812ae4 2382 tcg_temp_free_i64(fp0);
b6d96bed 2383 }
6ea83fed
FB
2384 break;
2385 default:
9d68ac14 2386 MIPS_INVAL("flt_ldst");
3a4ef3b7 2387 gen_reserved_instruction(ctx);
b52d3bfa 2388 break;
6ea83fed 2389 }
6ea83fed 2390}
6ea83fed 2391
5ab5c041
AJ
2392static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2393 int rs, int16_t imm)
26ebe468 2394{
b52d3bfa
YK
2395 TCGv t0 = tcg_temp_new();
2396
5ab5c041 2397 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2398 check_cp1_enabled(ctx);
d9224450
MR
2399 switch (op) {
2400 case OPC_LDC1:
2401 case OPC_SDC1:
2402 check_insn(ctx, ISA_MIPS2);
2403 /* Fallthrough */
2404 default:
b52d3bfa
YK
2405 gen_base_offset_addr(ctx, t0, rs, imm);
2406 gen_flt_ldst(ctx, op, rt, t0);
d9224450 2407 }
26ebe468
NF
2408 } else {
2409 generate_exception_err(ctx, EXCP_CpU, 1);
2410 }
b52d3bfa 2411 tcg_temp_free(t0);
26ebe468
NF
2412}
2413
6af0bf9c 2414/* Arithmetic with immediate operand */
d75c135e 2415static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 2416 int rt, int rs, int imm)
6af0bf9c 2417{
324d9e32 2418 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2419
7a387fff 2420 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
7480515f
AM
2421 /*
2422 * If no destination, treat it as a NOP.
2423 * For addi, we must generate the overflow exception when needed.
2424 */
324d9e32 2425 return;
6af0bf9c
FB
2426 }
2427 switch (opc) {
2428 case OPC_ADDI:
48d38ca5 2429 {
324d9e32
AJ
2430 TCGv t0 = tcg_temp_local_new();
2431 TCGv t1 = tcg_temp_new();
2432 TCGv t2 = tcg_temp_new();
42a268c2 2433 TCGLabel *l1 = gen_new_label();
48d38ca5 2434
324d9e32
AJ
2435 gen_load_gpr(t1, rs);
2436 tcg_gen_addi_tl(t0, t1, uimm);
2437 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2438
324d9e32
AJ
2439 tcg_gen_xori_tl(t1, t1, ~uimm);
2440 tcg_gen_xori_tl(t2, t0, uimm);
2441 tcg_gen_and_tl(t1, t1, t2);
2442 tcg_temp_free(t2);
2443 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2444 tcg_temp_free(t1);
48d38ca5
TS
2445 /* operands of same sign, result different sign */
2446 generate_exception(ctx, EXCP_OVERFLOW);
2447 gen_set_label(l1);
78723684 2448 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2449 gen_store_gpr(t0, rt);
2450 tcg_temp_free(t0);
48d38ca5 2451 }
6af0bf9c
FB
2452 break;
2453 case OPC_ADDIU:
324d9e32
AJ
2454 if (rs != 0) {
2455 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2456 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2457 } else {
2458 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2459 }
6af0bf9c 2460 break;
d26bc211 2461#if defined(TARGET_MIPS64)
7a387fff 2462 case OPC_DADDI:
48d38ca5 2463 {
324d9e32
AJ
2464 TCGv t0 = tcg_temp_local_new();
2465 TCGv t1 = tcg_temp_new();
2466 TCGv t2 = tcg_temp_new();
42a268c2 2467 TCGLabel *l1 = gen_new_label();
48d38ca5 2468
324d9e32
AJ
2469 gen_load_gpr(t1, rs);
2470 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2471
324d9e32
AJ
2472 tcg_gen_xori_tl(t1, t1, ~uimm);
2473 tcg_gen_xori_tl(t2, t0, uimm);
2474 tcg_gen_and_tl(t1, t1, t2);
2475 tcg_temp_free(t2);
2476 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2477 tcg_temp_free(t1);
48d38ca5
TS
2478 /* operands of same sign, result different sign */
2479 generate_exception(ctx, EXCP_OVERFLOW);
2480 gen_set_label(l1);
324d9e32
AJ
2481 gen_store_gpr(t0, rt);
2482 tcg_temp_free(t0);
48d38ca5 2483 }
7a387fff
TS
2484 break;
2485 case OPC_DADDIU:
324d9e32
AJ
2486 if (rs != 0) {
2487 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2488 } else {
2489 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2490 }
7a387fff
TS
2491 break;
2492#endif
324d9e32 2493 }
324d9e32
AJ
2494}
2495
2496/* Logic with immediate operand */
d75c135e 2497static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2498 int rt, int rs, int16_t imm)
324d9e32
AJ
2499{
2500 target_ulong uimm;
324d9e32
AJ
2501
2502 if (rt == 0) {
2503 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2504 return;
2505 }
2506 uimm = (uint16_t)imm;
2507 switch (opc) {
6af0bf9c 2508 case OPC_ANDI:
1f8929d2 2509 if (likely(rs != 0)) {
324d9e32 2510 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 2511 } else {
324d9e32 2512 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1f8929d2 2513 }
6af0bf9c
FB
2514 break;
2515 case OPC_ORI:
1f8929d2 2516 if (rs != 0) {
324d9e32 2517 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 2518 } else {
324d9e32 2519 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1f8929d2 2520 }
6af0bf9c
FB
2521 break;
2522 case OPC_XORI:
1f8929d2 2523 if (likely(rs != 0)) {
324d9e32 2524 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 2525 } else {
324d9e32 2526 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1f8929d2 2527 }
6af0bf9c
FB
2528 break;
2529 case OPC_LUI:
2e211e0a 2530 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
d4ea6acd
LA
2531 /* OPC_AUI */
2532 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2533 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2534 } else {
2535 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2536 }
7c2c3ea3
EJ
2537 break;
2538
2539 default:
6af0bf9c 2540 break;
324d9e32 2541 }
324d9e32
AJ
2542}
2543
2544/* Set on less than with immediate operand */
d75c135e 2545static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2546 int rt, int rs, int16_t imm)
324d9e32
AJ
2547{
2548 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2549 TCGv t0;
2550
2551 if (rt == 0) {
2552 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2553 return;
2554 }
2555 t0 = tcg_temp_new();
2556 gen_load_gpr(t0, rs);
2557 switch (opc) {
2558 case OPC_SLTI:
e68dd28f 2559 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2560 break;
2561 case OPC_SLTIU:
e68dd28f 2562 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2563 break;
2564 }
324d9e32
AJ
2565 tcg_temp_free(t0);
2566}
2567
2568/* Shifts with immediate operand */
d75c135e 2569static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2570 int rt, int rs, int16_t imm)
2571{
2572 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2573 TCGv t0;
2574
2575 if (rt == 0) {
2576 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2577 return;
2578 }
2579
2580 t0 = tcg_temp_new();
2581 gen_load_gpr(t0, rs);
2582 switch (opc) {
6af0bf9c 2583 case OPC_SLL:
78723684 2584 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2585 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2586 break;
2587 case OPC_SRA:
324d9e32 2588 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2589 break;
2590 case OPC_SRL:
ea63e2c3
NF
2591 if (uimm != 0) {
2592 tcg_gen_ext32u_tl(t0, t0);
2593 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2594 } else {
2595 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2596 }
ea63e2c3
NF
2597 break;
2598 case OPC_ROTR:
2599 if (uimm != 0) {
2600 TCGv_i32 t1 = tcg_temp_new_i32();
2601
2602 tcg_gen_trunc_tl_i32(t1, t0);
2603 tcg_gen_rotri_i32(t1, t1, uimm);
2604 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2605 tcg_temp_free_i32(t1);
3399e30f
NF
2606 } else {
2607 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2608 }
7a387fff 2609 break;
d26bc211 2610#if defined(TARGET_MIPS64)
7a387fff 2611 case OPC_DSLL:
324d9e32 2612 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2613 break;
2614 case OPC_DSRA:
324d9e32 2615 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2616 break;
2617 case OPC_DSRL:
ea63e2c3 2618 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2619 break;
2620 case OPC_DROTR:
2621 if (uimm != 0) {
2622 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2623 } else {
2624 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2625 }
7a387fff
TS
2626 break;
2627 case OPC_DSLL32:
324d9e32 2628 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2629 break;
2630 case OPC_DSRA32:
324d9e32 2631 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2632 break;
2633 case OPC_DSRL32:
ea63e2c3 2634 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2635 break;
2636 case OPC_DROTR32:
2637 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2638 break;
7a387fff 2639#endif
6af0bf9c 2640 }
78723684 2641 tcg_temp_free(t0);
6af0bf9c
FB
2642}
2643
2644/* Arithmetic */
d75c135e
AJ
2645static void gen_arith(DisasContext *ctx, uint32_t opc,
2646 int rd, int rs, int rt)
6af0bf9c 2647{
7a387fff
TS
2648 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2649 && opc != OPC_DADD && opc != OPC_DSUB) {
7480515f
AM
2650 /*
2651 * If no destination, treat it as a NOP.
2652 * For add & sub, we must generate the overflow exception when needed.
2653 */
460f00c4 2654 return;
185f0762 2655 }
460f00c4 2656
6af0bf9c
FB
2657 switch (opc) {
2658 case OPC_ADD:
48d38ca5 2659 {
460f00c4
AJ
2660 TCGv t0 = tcg_temp_local_new();
2661 TCGv t1 = tcg_temp_new();
2662 TCGv t2 = tcg_temp_new();
42a268c2 2663 TCGLabel *l1 = gen_new_label();
48d38ca5 2664
460f00c4
AJ
2665 gen_load_gpr(t1, rs);
2666 gen_load_gpr(t2, rt);
2667 tcg_gen_add_tl(t0, t1, t2);
2668 tcg_gen_ext32s_tl(t0, t0);
2669 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2670 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2671 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2672 tcg_temp_free(t2);
2673 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2674 tcg_temp_free(t1);
48d38ca5
TS
2675 /* operands of same sign, result different sign */
2676 generate_exception(ctx, EXCP_OVERFLOW);
2677 gen_set_label(l1);
460f00c4
AJ
2678 gen_store_gpr(t0, rd);
2679 tcg_temp_free(t0);
48d38ca5 2680 }
6af0bf9c
FB
2681 break;
2682 case OPC_ADDU:
460f00c4
AJ
2683 if (rs != 0 && rt != 0) {
2684 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2685 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2686 } else if (rs == 0 && rt != 0) {
2687 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2688 } else if (rs != 0 && rt == 0) {
2689 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2690 } else {
2691 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2692 }
6af0bf9c
FB
2693 break;
2694 case OPC_SUB:
48d38ca5 2695 {
460f00c4
AJ
2696 TCGv t0 = tcg_temp_local_new();
2697 TCGv t1 = tcg_temp_new();
2698 TCGv t2 = tcg_temp_new();
42a268c2 2699 TCGLabel *l1 = gen_new_label();
48d38ca5 2700
460f00c4
AJ
2701 gen_load_gpr(t1, rs);
2702 gen_load_gpr(t2, rt);
2703 tcg_gen_sub_tl(t0, t1, t2);
2704 tcg_gen_ext32s_tl(t0, t0);
2705 tcg_gen_xor_tl(t2, t1, t2);
2706 tcg_gen_xor_tl(t1, t0, t1);
2707 tcg_gen_and_tl(t1, t1, t2);
2708 tcg_temp_free(t2);
2709 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2710 tcg_temp_free(t1);
7480515f
AM
2711 /*
2712 * operands of different sign, first operand and the result
2713 * of different sign
2714 */
48d38ca5
TS
2715 generate_exception(ctx, EXCP_OVERFLOW);
2716 gen_set_label(l1);
460f00c4
AJ
2717 gen_store_gpr(t0, rd);
2718 tcg_temp_free(t0);
48d38ca5 2719 }
6af0bf9c
FB
2720 break;
2721 case OPC_SUBU:
460f00c4
AJ
2722 if (rs != 0 && rt != 0) {
2723 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2724 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2725 } else if (rs == 0 && rt != 0) {
2726 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2727 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2728 } else if (rs != 0 && rt == 0) {
2729 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2730 } else {
2731 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2732 }
6af0bf9c 2733 break;
d26bc211 2734#if defined(TARGET_MIPS64)
7a387fff 2735 case OPC_DADD:
48d38ca5 2736 {
460f00c4
AJ
2737 TCGv t0 = tcg_temp_local_new();
2738 TCGv t1 = tcg_temp_new();
2739 TCGv t2 = tcg_temp_new();
42a268c2 2740 TCGLabel *l1 = gen_new_label();
48d38ca5 2741
460f00c4
AJ
2742 gen_load_gpr(t1, rs);
2743 gen_load_gpr(t2, rt);
2744 tcg_gen_add_tl(t0, t1, t2);
2745 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2746 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2747 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2748 tcg_temp_free(t2);
2749 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2750 tcg_temp_free(t1);
48d38ca5
TS
2751 /* operands of same sign, result different sign */
2752 generate_exception(ctx, EXCP_OVERFLOW);
2753 gen_set_label(l1);
460f00c4
AJ
2754 gen_store_gpr(t0, rd);
2755 tcg_temp_free(t0);
48d38ca5 2756 }
7a387fff
TS
2757 break;
2758 case OPC_DADDU:
460f00c4
AJ
2759 if (rs != 0 && rt != 0) {
2760 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2761 } else if (rs == 0 && rt != 0) {
2762 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2763 } else if (rs != 0 && rt == 0) {
2764 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2765 } else {
2766 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2767 }
7a387fff
TS
2768 break;
2769 case OPC_DSUB:
48d38ca5 2770 {
460f00c4
AJ
2771 TCGv t0 = tcg_temp_local_new();
2772 TCGv t1 = tcg_temp_new();
2773 TCGv t2 = tcg_temp_new();
42a268c2 2774 TCGLabel *l1 = gen_new_label();
48d38ca5 2775
460f00c4
AJ
2776 gen_load_gpr(t1, rs);
2777 gen_load_gpr(t2, rt);
2778 tcg_gen_sub_tl(t0, t1, t2);
2779 tcg_gen_xor_tl(t2, t1, t2);
2780 tcg_gen_xor_tl(t1, t0, t1);
2781 tcg_gen_and_tl(t1, t1, t2);
2782 tcg_temp_free(t2);
2783 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2784 tcg_temp_free(t1);
71375b59
AM
2785 /*
2786 * Operands of different sign, first operand and result different
2787 * sign.
2788 */
48d38ca5
TS
2789 generate_exception(ctx, EXCP_OVERFLOW);
2790 gen_set_label(l1);
460f00c4
AJ
2791 gen_store_gpr(t0, rd);
2792 tcg_temp_free(t0);
48d38ca5 2793 }
7a387fff
TS
2794 break;
2795 case OPC_DSUBU:
460f00c4
AJ
2796 if (rs != 0 && rt != 0) {
2797 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2798 } else if (rs == 0 && rt != 0) {
2799 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2800 } else if (rs != 0 && rt == 0) {
2801 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2802 } else {
2803 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2804 }
7a387fff
TS
2805 break;
2806#endif
460f00c4
AJ
2807 case OPC_MUL:
2808 if (likely(rs != 0 && rt != 0)) {
2809 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2810 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2811 } else {
2812 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2813 }
6af0bf9c 2814 break;
460f00c4 2815 }
460f00c4
AJ
2816}
2817
2818/* Conditional move */
d75c135e 2819static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2820 int rd, int rs, int rt)
460f00c4 2821{
acf12465 2822 TCGv t0, t1, t2;
460f00c4
AJ
2823
2824 if (rd == 0) {
acf12465 2825 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2826 return;
2827 }
2828
acf12465
AJ
2829 t0 = tcg_temp_new();
2830 gen_load_gpr(t0, rt);
2831 t1 = tcg_const_tl(0);
2832 t2 = tcg_temp_new();
2833 gen_load_gpr(t2, rs);
460f00c4
AJ
2834 switch (opc) {
2835 case OPC_MOVN:
acf12465 2836 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2837 break;
460f00c4 2838 case OPC_MOVZ:
acf12465 2839 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2840 break;
b691d9d2
LA
2841 case OPC_SELNEZ:
2842 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2843 break;
2844 case OPC_SELEQZ:
2845 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2846 break;
460f00c4 2847 }
acf12465
AJ
2848 tcg_temp_free(t2);
2849 tcg_temp_free(t1);
2850 tcg_temp_free(t0);
460f00c4
AJ
2851}
2852
2853/* Logic */
d75c135e 2854static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2855 int rd, int rs, int rt)
460f00c4 2856{
460f00c4
AJ
2857 if (rd == 0) {
2858 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2859 return;
2860 }
2861
2862 switch (opc) {
6af0bf9c 2863 case OPC_AND:
460f00c4
AJ
2864 if (likely(rs != 0 && rt != 0)) {
2865 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2866 } else {
2867 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2868 }
6af0bf9c
FB
2869 break;
2870 case OPC_NOR:
460f00c4
AJ
2871 if (rs != 0 && rt != 0) {
2872 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2873 } else if (rs == 0 && rt != 0) {
2874 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2875 } else if (rs != 0 && rt == 0) {
2876 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2877 } else {
2878 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2879 }
6af0bf9c
FB
2880 break;
2881 case OPC_OR:
460f00c4
AJ
2882 if (likely(rs != 0 && rt != 0)) {
2883 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2884 } else if (rs == 0 && rt != 0) {
2885 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2886 } else if (rs != 0 && rt == 0) {
2887 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2888 } else {
2889 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2890 }
6af0bf9c
FB
2891 break;
2892 case OPC_XOR:
460f00c4
AJ
2893 if (likely(rs != 0 && rt != 0)) {
2894 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2895 } else if (rs == 0 && rt != 0) {
2896 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2897 } else if (rs != 0 && rt == 0) {
2898 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2899 } else {
2900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2901 }
6af0bf9c 2902 break;
460f00c4 2903 }
460f00c4
AJ
2904}
2905
2906/* Set on lower than */
d75c135e 2907static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2908 int rd, int rs, int rt)
460f00c4 2909{
460f00c4
AJ
2910 TCGv t0, t1;
2911
2912 if (rd == 0) {
2913 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2914 return;
2915 }
2916
2917 t0 = tcg_temp_new();
2918 t1 = tcg_temp_new();
2919 gen_load_gpr(t0, rs);
2920 gen_load_gpr(t1, rt);
2921 switch (opc) {
2922 case OPC_SLT:
e68dd28f 2923 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2924 break;
460f00c4 2925 case OPC_SLTU:
e68dd28f 2926 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2927 break;
2928 }
460f00c4
AJ
2929 tcg_temp_free(t0);
2930 tcg_temp_free(t1);
2931}
20c4c97c 2932
460f00c4 2933/* Shifts */
d75c135e
AJ
2934static void gen_shift(DisasContext *ctx, uint32_t opc,
2935 int rd, int rs, int rt)
460f00c4 2936{
460f00c4 2937 TCGv t0, t1;
20c4c97c 2938
460f00c4 2939 if (rd == 0) {
7480515f
AM
2940 /*
2941 * If no destination, treat it as a NOP.
2942 * For add & sub, we must generate the overflow exception when needed.
2943 */
460f00c4
AJ
2944 return;
2945 }
2946
2947 t0 = tcg_temp_new();
2948 t1 = tcg_temp_new();
2949 gen_load_gpr(t0, rs);
2950 gen_load_gpr(t1, rt);
2951 switch (opc) {
6af0bf9c 2952 case OPC_SLLV:
78723684
TS
2953 tcg_gen_andi_tl(t0, t0, 0x1f);
2954 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2955 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2956 break;
2957 case OPC_SRAV:
78723684 2958 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2959 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2960 break;
2961 case OPC_SRLV:
ea63e2c3
NF
2962 tcg_gen_ext32u_tl(t1, t1);
2963 tcg_gen_andi_tl(t0, t0, 0x1f);
2964 tcg_gen_shr_tl(t0, t1, t0);
2965 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2966 break;
2967 case OPC_ROTRV:
2968 {
2969 TCGv_i32 t2 = tcg_temp_new_i32();
2970 TCGv_i32 t3 = tcg_temp_new_i32();
2971
2972 tcg_gen_trunc_tl_i32(t2, t0);
2973 tcg_gen_trunc_tl_i32(t3, t1);
2974 tcg_gen_andi_i32(t2, t2, 0x1f);
2975 tcg_gen_rotr_i32(t2, t3, t2);
2976 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2977 tcg_temp_free_i32(t2);
2978 tcg_temp_free_i32(t3);
5a63bcb2 2979 }
7a387fff 2980 break;
d26bc211 2981#if defined(TARGET_MIPS64)
7a387fff 2982 case OPC_DSLLV:
78723684 2983 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2984 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2985 break;
2986 case OPC_DSRAV:
78723684 2987 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2988 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2989 break;
2990 case OPC_DSRLV:
ea63e2c3
NF
2991 tcg_gen_andi_tl(t0, t0, 0x3f);
2992 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
2993 break;
2994 case OPC_DROTRV:
2995 tcg_gen_andi_tl(t0, t0, 0x3f);
2996 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 2997 break;
7a387fff 2998#endif
6af0bf9c 2999 }
78723684
TS
3000 tcg_temp_free(t0);
3001 tcg_temp_free(t1);
6af0bf9c
FB
3002}
3003
3004/* Arithmetic on HI/LO registers */
26135ead 3005static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3006{
86efbfb6 3007 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3008 /* Treat as NOP. */
a1f6684d 3009 return;
6af0bf9c 3010 }
4133498f 3011
4133498f 3012 if (acc != 0) {
86efbfb6 3013 check_dsp(ctx);
4133498f
JL
3014 }
3015
6af0bf9c
FB
3016 switch (opc) {
3017 case OPC_MFHI:
4133498f
JL
3018#if defined(TARGET_MIPS64)
3019 if (acc != 0) {
3020 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3021 } else
3022#endif
3023 {
3024 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3025 }
6af0bf9c
FB
3026 break;
3027 case OPC_MFLO:
4133498f
JL
3028#if defined(TARGET_MIPS64)
3029 if (acc != 0) {
3030 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3031 } else
3032#endif
3033 {
3034 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3035 }
6af0bf9c
FB
3036 break;
3037 case OPC_MTHI:
4133498f
JL
3038 if (reg != 0) {
3039#if defined(TARGET_MIPS64)
3040 if (acc != 0) {
3041 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3042 } else
3043#endif
3044 {
3045 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3046 }
3047 } else {
3048 tcg_gen_movi_tl(cpu_HI[acc], 0);
3049 }
6af0bf9c
FB
3050 break;
3051 case OPC_MTLO:
4133498f
JL
3052 if (reg != 0) {
3053#if defined(TARGET_MIPS64)
3054 if (acc != 0) {
3055 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3056 } else
3057#endif
3058 {
3059 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3060 }
3061 } else {
3062 tcg_gen_movi_tl(cpu_LO[acc], 0);
3063 }
6af0bf9c 3064 break;
6af0bf9c 3065 }
6af0bf9c
FB
3066}
3067
d4ea6acd 3068static inline void gen_r6_ld(target_long addr, int reg, int memidx,
14776ab5 3069 MemOp memop)
d4ea6acd
LA
3070{
3071 TCGv t0 = tcg_const_tl(addr);
3072 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3073 gen_store_gpr(t0, reg);
3074 tcg_temp_free(t0);
3075}
3076
ab39ee45
YK
3077static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3078 int rs)
d4ea6acd
LA
3079{
3080 target_long offset;
3081 target_long addr;
3082
ab39ee45 3083 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3084 case OPC_ADDIUPC:
3085 if (rs != 0) {
3086 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3087 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3088 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3089 }
3090 break;
3091 case R6_OPC_LWPC:
3092 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3093 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3094 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3095 break;
3096#if defined(TARGET_MIPS64)
3097 case OPC_LWUPC:
3098 check_mips_64(ctx);
3099 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3100 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3101 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3102 break;
3103#endif
3104 default:
ab39ee45 3105 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3106 case OPC_AUIPC:
3107 if (rs != 0) {
ab39ee45
YK
3108 offset = sextract32(ctx->opcode, 0, 16) << 16;
3109 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3110 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3111 }
3112 break;
3113 case OPC_ALUIPC:
3114 if (rs != 0) {
ab39ee45
YK
3115 offset = sextract32(ctx->opcode, 0, 16) << 16;
3116 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3117 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3118 }
3119 break;
3120#if defined(TARGET_MIPS64)
3121 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3122 case R6_OPC_LDPC + (1 << 16):
3123 case R6_OPC_LDPC + (2 << 16):
3124 case R6_OPC_LDPC + (3 << 16):
3125 check_mips_64(ctx);
3126 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3127 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3128 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3129 break;
3130#endif
3131 default:
3132 MIPS_INVAL("OPC_PCREL");
3a4ef3b7 3133 gen_reserved_instruction(ctx);
d4ea6acd
LA
3134 break;
3135 }
3136 break;
3137 }
3138}
3139
b42ee5e1
LA
3140static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3141{
b42ee5e1
LA
3142 TCGv t0, t1;
3143
3144 if (rd == 0) {
3145 /* Treat as NOP. */
b42ee5e1
LA
3146 return;
3147 }
3148
3149 t0 = tcg_temp_new();
3150 t1 = tcg_temp_new();
3151
3152 gen_load_gpr(t0, rs);
3153 gen_load_gpr(t1, rt);
3154
3155 switch (opc) {
3156 case R6_OPC_DIV:
3157 {
3158 TCGv t2 = tcg_temp_new();
3159 TCGv t3 = tcg_temp_new();
3160 tcg_gen_ext32s_tl(t0, t0);
3161 tcg_gen_ext32s_tl(t1, t1);
3162 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3163 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3164 tcg_gen_and_tl(t2, t2, t3);
3165 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3166 tcg_gen_or_tl(t2, t2, t3);
3167 tcg_gen_movi_tl(t3, 0);
3168 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3169 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3170 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3171 tcg_temp_free(t3);
3172 tcg_temp_free(t2);
3173 }
b42ee5e1
LA
3174 break;
3175 case R6_OPC_MOD:
3176 {
3177 TCGv t2 = tcg_temp_new();
3178 TCGv t3 = tcg_temp_new();
3179 tcg_gen_ext32s_tl(t0, t0);
3180 tcg_gen_ext32s_tl(t1, t1);
3181 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3182 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3183 tcg_gen_and_tl(t2, t2, t3);
3184 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3185 tcg_gen_or_tl(t2, t2, t3);
3186 tcg_gen_movi_tl(t3, 0);
3187 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3188 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3189 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3190 tcg_temp_free(t3);
3191 tcg_temp_free(t2);
3192 }
b42ee5e1
LA
3193 break;
3194 case R6_OPC_DIVU:
3195 {
3196 TCGv t2 = tcg_const_tl(0);
3197 TCGv t3 = tcg_const_tl(1);
3198 tcg_gen_ext32u_tl(t0, t0);
3199 tcg_gen_ext32u_tl(t1, t1);
3200 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3201 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3202 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3203 tcg_temp_free(t3);
3204 tcg_temp_free(t2);
3205 }
b42ee5e1
LA
3206 break;
3207 case R6_OPC_MODU:
3208 {
3209 TCGv t2 = tcg_const_tl(0);
3210 TCGv t3 = tcg_const_tl(1);
3211 tcg_gen_ext32u_tl(t0, t0);
3212 tcg_gen_ext32u_tl(t1, t1);
3213 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3214 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3215 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3216 tcg_temp_free(t3);
3217 tcg_temp_free(t2);
3218 }
b42ee5e1
LA
3219 break;
3220 case R6_OPC_MUL:
3221 {
3222 TCGv_i32 t2 = tcg_temp_new_i32();
3223 TCGv_i32 t3 = tcg_temp_new_i32();
3224 tcg_gen_trunc_tl_i32(t2, t0);
3225 tcg_gen_trunc_tl_i32(t3, t1);
3226 tcg_gen_mul_i32(t2, t2, t3);
3227 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3228 tcg_temp_free_i32(t2);
3229 tcg_temp_free_i32(t3);
3230 }
b42ee5e1
LA
3231 break;
3232 case R6_OPC_MUH:
3233 {
3234 TCGv_i32 t2 = tcg_temp_new_i32();
3235 TCGv_i32 t3 = tcg_temp_new_i32();
3236 tcg_gen_trunc_tl_i32(t2, t0);
3237 tcg_gen_trunc_tl_i32(t3, t1);
3238 tcg_gen_muls2_i32(t2, t3, t2, t3);
3239 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3240 tcg_temp_free_i32(t2);
3241 tcg_temp_free_i32(t3);
3242 }
b42ee5e1
LA
3243 break;
3244 case R6_OPC_MULU:
3245 {
3246 TCGv_i32 t2 = tcg_temp_new_i32();
3247 TCGv_i32 t3 = tcg_temp_new_i32();
3248 tcg_gen_trunc_tl_i32(t2, t0);
3249 tcg_gen_trunc_tl_i32(t3, t1);
3250 tcg_gen_mul_i32(t2, t2, t3);
3251 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3252 tcg_temp_free_i32(t2);
3253 tcg_temp_free_i32(t3);
3254 }
b42ee5e1
LA
3255 break;
3256 case R6_OPC_MUHU:
3257 {
3258 TCGv_i32 t2 = tcg_temp_new_i32();
3259 TCGv_i32 t3 = tcg_temp_new_i32();
3260 tcg_gen_trunc_tl_i32(t2, t0);
3261 tcg_gen_trunc_tl_i32(t3, t1);
3262 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3263 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3264 tcg_temp_free_i32(t2);
3265 tcg_temp_free_i32(t3);
3266 }
b42ee5e1
LA
3267 break;
3268#if defined(TARGET_MIPS64)
3269 case R6_OPC_DDIV:
3270 {
3271 TCGv t2 = tcg_temp_new();
3272 TCGv t3 = tcg_temp_new();
3273 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3274 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3275 tcg_gen_and_tl(t2, t2, t3);
3276 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3277 tcg_gen_or_tl(t2, t2, t3);
3278 tcg_gen_movi_tl(t3, 0);
3279 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3280 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3281 tcg_temp_free(t3);
3282 tcg_temp_free(t2);
3283 }
b42ee5e1
LA
3284 break;
3285 case R6_OPC_DMOD:
3286 {
3287 TCGv t2 = tcg_temp_new();
3288 TCGv t3 = tcg_temp_new();
3289 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3290 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3291 tcg_gen_and_tl(t2, t2, t3);
3292 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3293 tcg_gen_or_tl(t2, t2, t3);
3294 tcg_gen_movi_tl(t3, 0);
3295 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3296 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3297 tcg_temp_free(t3);
3298 tcg_temp_free(t2);
3299 }
b42ee5e1
LA
3300 break;
3301 case R6_OPC_DDIVU:
3302 {
3303 TCGv t2 = tcg_const_tl(0);
3304 TCGv t3 = tcg_const_tl(1);
3305 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3306 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3307 tcg_temp_free(t3);
3308 tcg_temp_free(t2);
3309 }
b42ee5e1
LA
3310 break;
3311 case R6_OPC_DMODU:
3312 {
3313 TCGv t2 = tcg_const_tl(0);
3314 TCGv t3 = tcg_const_tl(1);
3315 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3316 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3317 tcg_temp_free(t3);
3318 tcg_temp_free(t2);
3319 }
b42ee5e1
LA
3320 break;
3321 case R6_OPC_DMUL:
3322 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3323 break;
3324 case R6_OPC_DMUH:
3325 {
3326 TCGv t2 = tcg_temp_new();
3327 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3328 tcg_temp_free(t2);
3329 }
b42ee5e1
LA
3330 break;
3331 case R6_OPC_DMULU:
3332 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3333 break;
3334 case R6_OPC_DMUHU:
3335 {
3336 TCGv t2 = tcg_temp_new();
3337 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3338 tcg_temp_free(t2);
3339 }
b42ee5e1
LA
3340 break;
3341#endif
3342 default:
9d68ac14 3343 MIPS_INVAL("r6 mul/div");
3a4ef3b7 3344 gen_reserved_instruction(ctx);
b42ee5e1
LA
3345 goto out;
3346 }
b42ee5e1
LA
3347 out:
3348 tcg_temp_free(t0);
3349 tcg_temp_free(t1);
3350}
3351
37b9aae2 3352#if defined(TARGET_MIPS64)
c42171c3
FN
3353static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3354{
3355 TCGv t0, t1;
3356
3357 t0 = tcg_temp_new();
3358 t1 = tcg_temp_new();
3359
3360 gen_load_gpr(t0, rs);
3361 gen_load_gpr(t1, rt);
3362
3363 switch (opc) {
baa609db 3364 case MMI_OPC_DIV1:
c42171c3
FN
3365 {
3366 TCGv t2 = tcg_temp_new();
3367 TCGv t3 = tcg_temp_new();
3368 tcg_gen_ext32s_tl(t0, t0);
3369 tcg_gen_ext32s_tl(t1, t1);
3370 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3371 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3372 tcg_gen_and_tl(t2, t2, t3);
3373 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3374 tcg_gen_or_tl(t2, t2, t3);
3375 tcg_gen_movi_tl(t3, 0);
3376 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3377 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3378 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3379 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3380 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3381 tcg_temp_free(t3);
3382 tcg_temp_free(t2);
3383 }
3384 break;
baa609db 3385 case MMI_OPC_DIVU1:
c42171c3
FN
3386 {
3387 TCGv t2 = tcg_const_tl(0);
3388 TCGv t3 = tcg_const_tl(1);
3389 tcg_gen_ext32u_tl(t0, t0);
3390 tcg_gen_ext32u_tl(t1, t1);
3391 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3392 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3393 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3394 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3395 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3396 tcg_temp_free(t3);
3397 tcg_temp_free(t2);
3398 }
3399 break;
3400 default:
3401 MIPS_INVAL("div1 TX79");
3a4ef3b7 3402 gen_reserved_instruction(ctx);
c42171c3
FN
3403 goto out;
3404 }
3405 out:
3406 tcg_temp_free(t0);
3407 tcg_temp_free(t1);
3408}
37b9aae2 3409#endif
c42171c3 3410
26135ead
RS
3411static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3412 int acc, int rs, int rt)
6af0bf9c 3413{
d45f89f4
AJ
3414 TCGv t0, t1;
3415
51127181
AJ
3416 t0 = tcg_temp_new();
3417 t1 = tcg_temp_new();
6af0bf9c 3418
78723684
TS
3419 gen_load_gpr(t0, rs);
3420 gen_load_gpr(t1, rt);
51127181 3421
26135ead 3422 if (acc != 0) {
c42171c3 3423 check_dsp(ctx);
26135ead
RS
3424 }
3425
6af0bf9c
FB
3426 switch (opc) {
3427 case OPC_DIV:
48d38ca5 3428 {
51127181
AJ
3429 TCGv t2 = tcg_temp_new();
3430 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3431 tcg_gen_ext32s_tl(t0, t0);
3432 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3433 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3434 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3435 tcg_gen_and_tl(t2, t2, t3);
3436 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3437 tcg_gen_or_tl(t2, t2, t3);
3438 tcg_gen_movi_tl(t3, 0);
3439 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3440 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3441 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3442 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3443 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3444 tcg_temp_free(t3);
3445 tcg_temp_free(t2);
48d38ca5 3446 }
6af0bf9c
FB
3447 break;
3448 case OPC_DIVU:
48d38ca5 3449 {
51127181
AJ
3450 TCGv t2 = tcg_const_tl(0);
3451 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3452 tcg_gen_ext32u_tl(t0, t0);
3453 tcg_gen_ext32u_tl(t1, t1);
51127181 3454 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3455 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3456 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3457 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3458 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3459 tcg_temp_free(t3);
3460 tcg_temp_free(t2);
48d38ca5 3461 }
6af0bf9c
FB
3462 break;
3463 case OPC_MULT:
214c465f 3464 {
ce1dd5d1
RH
3465 TCGv_i32 t2 = tcg_temp_new_i32();
3466 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3467 tcg_gen_trunc_tl_i32(t2, t0);
3468 tcg_gen_trunc_tl_i32(t3, t1);
3469 tcg_gen_muls2_i32(t2, t3, t2, t3);
3470 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3471 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3472 tcg_temp_free_i32(t2);
3473 tcg_temp_free_i32(t3);
214c465f 3474 }
6af0bf9c
FB
3475 break;
3476 case OPC_MULTU:
214c465f 3477 {
ce1dd5d1
RH
3478 TCGv_i32 t2 = tcg_temp_new_i32();
3479 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3480 tcg_gen_trunc_tl_i32(t2, t0);
3481 tcg_gen_trunc_tl_i32(t3, t1);
3482 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3483 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3484 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3485 tcg_temp_free_i32(t2);
3486 tcg_temp_free_i32(t3);
214c465f 3487 }
6af0bf9c 3488 break;
d26bc211 3489#if defined(TARGET_MIPS64)
7a387fff 3490 case OPC_DDIV:
48d38ca5 3491 {
51127181
AJ
3492 TCGv t2 = tcg_temp_new();
3493 TCGv t3 = tcg_temp_new();
3494 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3495 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3496 tcg_gen_and_tl(t2, t2, t3);
3497 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3498 tcg_gen_or_tl(t2, t2, t3);
3499 tcg_gen_movi_tl(t3, 0);
3500 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3501 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3502 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3503 tcg_temp_free(t3);
3504 tcg_temp_free(t2);
48d38ca5 3505 }
7a387fff
TS
3506 break;
3507 case OPC_DDIVU:
48d38ca5 3508 {
51127181
AJ
3509 TCGv t2 = tcg_const_tl(0);
3510 TCGv t3 = tcg_const_tl(1);
3511 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3512 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3513 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3514 tcg_temp_free(t3);
3515 tcg_temp_free(t2);
48d38ca5 3516 }
7a387fff
TS
3517 break;
3518 case OPC_DMULT:
26135ead 3519 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3520 break;
3521 case OPC_DMULTU:
26135ead 3522 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3523 break;
3524#endif
6af0bf9c 3525 case OPC_MADD:
214c465f 3526 {
d45f89f4
AJ
3527 TCGv_i64 t2 = tcg_temp_new_i64();
3528 TCGv_i64 t3 = tcg_temp_new_i64();
3529
3530 tcg_gen_ext_tl_i64(t2, t0);
3531 tcg_gen_ext_tl_i64(t3, t1);
3532 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3533 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3534 tcg_gen_add_i64(t2, t2, t3);
3535 tcg_temp_free_i64(t3);
71f303cd
RH
3536 gen_move_low32(cpu_LO[acc], t2);
3537 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3538 tcg_temp_free_i64(t2);
214c465f 3539 }
6af0bf9c
FB
3540 break;
3541 case OPC_MADDU:
4133498f 3542 {
d45f89f4
AJ
3543 TCGv_i64 t2 = tcg_temp_new_i64();
3544 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3545
78723684
TS
3546 tcg_gen_ext32u_tl(t0, t0);
3547 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3548 tcg_gen_extu_tl_i64(t2, t0);
3549 tcg_gen_extu_tl_i64(t3, t1);
3550 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3551 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3552 tcg_gen_add_i64(t2, t2, t3);
3553 tcg_temp_free_i64(t3);
71f303cd
RH
3554 gen_move_low32(cpu_LO[acc], t2);
3555 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3556 tcg_temp_free_i64(t2);
214c465f 3557 }
6af0bf9c
FB
3558 break;
3559 case OPC_MSUB:
214c465f 3560 {
d45f89f4
AJ
3561 TCGv_i64 t2 = tcg_temp_new_i64();
3562 TCGv_i64 t3 = tcg_temp_new_i64();
3563
3564 tcg_gen_ext_tl_i64(t2, t0);
3565 tcg_gen_ext_tl_i64(t3, t1);
3566 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3567 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3568 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3569 tcg_temp_free_i64(t3);
71f303cd
RH
3570 gen_move_low32(cpu_LO[acc], t2);
3571 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3572 tcg_temp_free_i64(t2);
214c465f 3573 }
6af0bf9c
FB
3574 break;
3575 case OPC_MSUBU:
214c465f 3576 {
d45f89f4
AJ
3577 TCGv_i64 t2 = tcg_temp_new_i64();
3578 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3579
78723684
TS
3580 tcg_gen_ext32u_tl(t0, t0);
3581 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3582 tcg_gen_extu_tl_i64(t2, t0);
3583 tcg_gen_extu_tl_i64(t3, t1);
3584 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3585 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3586 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3587 tcg_temp_free_i64(t3);
71f303cd
RH
3588 gen_move_low32(cpu_LO[acc], t2);
3589 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3590 tcg_temp_free_i64(t2);
214c465f 3591 }
6af0bf9c
FB
3592 break;
3593 default:
9d68ac14 3594 MIPS_INVAL("mul/div");
3a4ef3b7 3595 gen_reserved_instruction(ctx);
78723684 3596 goto out;
6af0bf9c 3597 }
78723684
TS
3598 out:
3599 tcg_temp_free(t0);
3600 tcg_temp_free(t1);
6af0bf9c
FB
3601}
3602
21e8e8b2 3603/*
3b948f05
PMD
3604 * These MULT[U] and MADD[U] instructions implemented in for example
3605 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
21e8e8b2
FN
3606 * architectures are special three-operand variants with the syntax
3607 *
06de726b 3608 * MULT[U][1] rd, rs, rt
21e8e8b2
FN
3609 *
3610 * such that
3611 *
3612 * (rd, LO, HI) <- rs * rt
3613 *
3b948f05
PMD
3614 * and
3615 *
a95c4c26 3616 * MADD[U][1] rd, rs, rt
3b948f05
PMD
3617 *
3618 * such that
3619 *
3620 * (rd, LO, HI) <- (LO, HI) + rs * rt
3621 *
21e8e8b2
FN
3622 * where the low-order 32-bits of the result is placed into both the
3623 * GPR rd and the special register LO. The high-order 32-bits of the
3624 * result is placed into the special register HI.
3625 *
3626 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3627 * which is the zero register that always reads as 0.
3628 */
3629static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3630 int rd, int rs, int rt)
3631{
3632 TCGv t0 = tcg_temp_new();
3633 TCGv t1 = tcg_temp_new();
3634 int acc = 0;
3635
3636 gen_load_gpr(t0, rs);
3637 gen_load_gpr(t1, rt);
3638
3639 switch (opc) {
baa609db 3640 case MMI_OPC_MULT1:
06de726b
FN
3641 acc = 1;
3642 /* Fall through */
21e8e8b2
FN
3643 case OPC_MULT:
3644 {
3645 TCGv_i32 t2 = tcg_temp_new_i32();
3646 TCGv_i32 t3 = tcg_temp_new_i32();
3647 tcg_gen_trunc_tl_i32(t2, t0);
3648 tcg_gen_trunc_tl_i32(t3, t1);
3649 tcg_gen_muls2_i32(t2, t3, t2, t3);
3650 if (rd) {
3651 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3652 }
3653 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3654 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3655 tcg_temp_free_i32(t2);
3656 tcg_temp_free_i32(t3);
3657 }
3658 break;
baa609db 3659 case MMI_OPC_MULTU1:
06de726b
FN
3660 acc = 1;
3661 /* Fall through */
21e8e8b2
FN
3662 case OPC_MULTU:
3663 {
3664 TCGv_i32 t2 = tcg_temp_new_i32();
3665 TCGv_i32 t3 = tcg_temp_new_i32();
3666 tcg_gen_trunc_tl_i32(t2, t0);
3667 tcg_gen_trunc_tl_i32(t3, t1);
3668 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3669 if (rd) {
3670 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3671 }
3672 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3673 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3674 tcg_temp_free_i32(t2);
3675 tcg_temp_free_i32(t3);
3676 }
3677 break;
a95c4c26
FN
3678 case MMI_OPC_MADD1:
3679 acc = 1;
3680 /* Fall through */
3b948f05
PMD
3681 case MMI_OPC_MADD:
3682 {
3683 TCGv_i64 t2 = tcg_temp_new_i64();
3684 TCGv_i64 t3 = tcg_temp_new_i64();
3685
3686 tcg_gen_ext_tl_i64(t2, t0);
3687 tcg_gen_ext_tl_i64(t3, t1);
3688 tcg_gen_mul_i64(t2, t2, t3);
3689 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3690 tcg_gen_add_i64(t2, t2, t3);
3691 tcg_temp_free_i64(t3);
3692 gen_move_low32(cpu_LO[acc], t2);
3693 gen_move_high32(cpu_HI[acc], t2);
3694 if (rd) {
3695 gen_move_low32(cpu_gpr[rd], t2);
3696 }
3697 tcg_temp_free_i64(t2);
3698 }
3699 break;
a95c4c26
FN
3700 case MMI_OPC_MADDU1:
3701 acc = 1;
3702 /* Fall through */
3b948f05
PMD
3703 case MMI_OPC_MADDU:
3704 {
3705 TCGv_i64 t2 = tcg_temp_new_i64();
3706 TCGv_i64 t3 = tcg_temp_new_i64();
3707
3708 tcg_gen_ext32u_tl(t0, t0);
3709 tcg_gen_ext32u_tl(t1, t1);
3710 tcg_gen_extu_tl_i64(t2, t0);
3711 tcg_gen_extu_tl_i64(t3, t1);
3712 tcg_gen_mul_i64(t2, t2, t3);
3713 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3714 tcg_gen_add_i64(t2, t2, t3);
3715 tcg_temp_free_i64(t3);
3716 gen_move_low32(cpu_LO[acc], t2);
3717 gen_move_high32(cpu_HI[acc], t2);
3718 if (rd) {
3719 gen_move_low32(cpu_gpr[rd], t2);
3720 }
3721 tcg_temp_free_i64(t2);
3722 }
3723 break;
21e8e8b2 3724 default:
3b948f05 3725 MIPS_INVAL("mul/madd TXx9");
3a4ef3b7 3726 gen_reserved_instruction(ctx);
21e8e8b2
FN
3727 goto out;
3728 }
3729
3730 out:
3731 tcg_temp_free(t0);
3732 tcg_temp_free(t1);
3733}
3734
235785e8
AM
3735static void gen_cl(DisasContext *ctx, uint32_t opc,
3736 int rd, int rs)
6af0bf9c 3737{
20e1fb52 3738 TCGv t0;
6c5c1e20 3739
6af0bf9c 3740 if (rd == 0) {
ead9360e 3741 /* Treat as NOP. */
20e1fb52 3742 return;
6af0bf9c 3743 }
1a0196c5 3744 t0 = cpu_gpr[rd];
6c5c1e20 3745 gen_load_gpr(t0, rs);
1a0196c5 3746
6af0bf9c
FB
3747 switch (opc) {
3748 case OPC_CLO:
4267d3e6 3749 case R6_OPC_CLO:
1a0196c5
RH
3750#if defined(TARGET_MIPS64)
3751 case OPC_DCLO:
3752 case R6_OPC_DCLO:
3753#endif
3754 tcg_gen_not_tl(t0, t0);
6af0bf9c 3755 break;
1a0196c5
RH
3756 }
3757
3758 switch (opc) {
3759 case OPC_CLO:
3760 case R6_OPC_CLO:
6af0bf9c 3761 case OPC_CLZ:
4267d3e6 3762 case R6_OPC_CLZ:
1a0196c5
RH
3763 tcg_gen_ext32u_tl(t0, t0);
3764 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3765 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3766 break;
d26bc211 3767#if defined(TARGET_MIPS64)
7a387fff 3768 case OPC_DCLO:
4267d3e6 3769 case R6_OPC_DCLO:
7a387fff 3770 case OPC_DCLZ:
4267d3e6 3771 case R6_OPC_DCLZ:
1a0196c5 3772 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3773 break;
3774#endif
6af0bf9c 3775 }
6af0bf9c
FB
3776}
3777
161f85e6 3778/* Godson integer instructions */
bd277fa1
RH
3779static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3780 int rd, int rs, int rt)
161f85e6 3781{
161f85e6
AJ
3782 TCGv t0, t1;
3783
3784 if (rd == 0) {
3785 /* Treat as NOP. */
161f85e6
AJ
3786 return;
3787 }
3788
3789 switch (opc) {
3790 case OPC_MULT_G_2E:
3791 case OPC_MULT_G_2F:
3792 case OPC_MULTU_G_2E:
3793 case OPC_MULTU_G_2F:
3794#if defined(TARGET_MIPS64)
3795 case OPC_DMULT_G_2E:
3796 case OPC_DMULT_G_2F:
3797 case OPC_DMULTU_G_2E:
3798 case OPC_DMULTU_G_2F:
3799#endif
3800 t0 = tcg_temp_new();
3801 t1 = tcg_temp_new();
3802 break;
3803 default:
3804 t0 = tcg_temp_local_new();
3805 t1 = tcg_temp_local_new();
3806 break;
3807 }
3808
3809 gen_load_gpr(t0, rs);
3810 gen_load_gpr(t1, rt);
3811
3812 switch (opc) {
3813 case OPC_MULT_G_2E:
3814 case OPC_MULT_G_2F:
3815 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3816 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3817 break;
3818 case OPC_MULTU_G_2E:
3819 case OPC_MULTU_G_2F:
3820 tcg_gen_ext32u_tl(t0, t0);
3821 tcg_gen_ext32u_tl(t1, t1);
3822 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3823 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3824 break;
3825 case OPC_DIV_G_2E:
3826 case OPC_DIV_G_2F:
3827 {
42a268c2
RH
3828 TCGLabel *l1 = gen_new_label();
3829 TCGLabel *l2 = gen_new_label();
3830 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3831 tcg_gen_ext32s_tl(t0, t0);
3832 tcg_gen_ext32s_tl(t1, t1);
3833 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3834 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3835 tcg_gen_br(l3);
3836 gen_set_label(l1);
3837 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3838 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3839 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3840 tcg_gen_br(l3);
3841 gen_set_label(l2);
3842 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3843 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3844 gen_set_label(l3);
3845 }
161f85e6
AJ
3846 break;
3847 case OPC_DIVU_G_2E:
3848 case OPC_DIVU_G_2F:
3849 {
42a268c2
RH
3850 TCGLabel *l1 = gen_new_label();
3851 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3852 tcg_gen_ext32u_tl(t0, t0);
3853 tcg_gen_ext32u_tl(t1, t1);
3854 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3855 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3856 tcg_gen_br(l2);
3857 gen_set_label(l1);
3858 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3859 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3860 gen_set_label(l2);
3861 }
161f85e6
AJ
3862 break;
3863 case OPC_MOD_G_2E:
3864 case OPC_MOD_G_2F:
3865 {
42a268c2
RH
3866 TCGLabel *l1 = gen_new_label();
3867 TCGLabel *l2 = gen_new_label();
3868 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3869 tcg_gen_ext32u_tl(t0, t0);
3870 tcg_gen_ext32u_tl(t1, t1);
3871 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3872 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3873 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3874 gen_set_label(l1);
3875 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3876 tcg_gen_br(l3);
3877 gen_set_label(l2);
3878 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3879 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3880 gen_set_label(l3);
3881 }
161f85e6
AJ
3882 break;
3883 case OPC_MODU_G_2E:
3884 case OPC_MODU_G_2F:
3885 {
42a268c2
RH
3886 TCGLabel *l1 = gen_new_label();
3887 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3888 tcg_gen_ext32u_tl(t0, t0);
3889 tcg_gen_ext32u_tl(t1, t1);
3890 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3891 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3892 tcg_gen_br(l2);
3893 gen_set_label(l1);
3894 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3895 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3896 gen_set_label(l2);
3897 }
161f85e6
AJ
3898 break;
3899#if defined(TARGET_MIPS64)
3900 case OPC_DMULT_G_2E:
3901 case OPC_DMULT_G_2F:
3902 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3903 break;
3904 case OPC_DMULTU_G_2E:
3905 case OPC_DMULTU_G_2F:
3906 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3907 break;
3908 case OPC_DDIV_G_2E:
3909 case OPC_DDIV_G_2F:
3910 {
42a268c2
RH
3911 TCGLabel *l1 = gen_new_label();
3912 TCGLabel *l2 = gen_new_label();
3913 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3915 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3916 tcg_gen_br(l3);
3917 gen_set_label(l1);
3918 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3919 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3920 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3921 tcg_gen_br(l3);
3922 gen_set_label(l2);
3923 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3924 gen_set_label(l3);
3925 }
161f85e6
AJ
3926 break;
3927 case OPC_DDIVU_G_2E:
3928 case OPC_DDIVU_G_2F:
3929 {
42a268c2
RH
3930 TCGLabel *l1 = gen_new_label();
3931 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3932 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3933 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3934 tcg_gen_br(l2);
3935 gen_set_label(l1);
3936 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3937 gen_set_label(l2);
3938 }
161f85e6
AJ
3939 break;
3940 case OPC_DMOD_G_2E:
3941 case OPC_DMOD_G_2F:
3942 {
42a268c2
RH
3943 TCGLabel *l1 = gen_new_label();
3944 TCGLabel *l2 = gen_new_label();
3945 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3946 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3947 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3948 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3949 gen_set_label(l1);
3950 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3951 tcg_gen_br(l3);
3952 gen_set_label(l2);
3953 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3954 gen_set_label(l3);
3955 }
161f85e6
AJ
3956 break;
3957 case OPC_DMODU_G_2E:
3958 case OPC_DMODU_G_2F:
3959 {
42a268c2
RH
3960 TCGLabel *l1 = gen_new_label();
3961 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3962 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3963 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3964 tcg_gen_br(l2);
3965 gen_set_label(l1);
3966 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3967 gen_set_label(l2);
3968 }
161f85e6
AJ
3969 break;
3970#endif
3971 }
3972
161f85e6
AJ
3973 tcg_temp_free(t0);
3974 tcg_temp_free(t1);
3975}
3976
bd277fa1
RH
3977/* Loongson multimedia instructions */
3978static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3979{
bd277fa1
RH
3980 uint32_t opc, shift_max;
3981 TCGv_i64 t0, t1;
84878f4c 3982 TCGCond cond;
bd277fa1 3983
8e2d5831 3984 opc = MASK_LMMI(ctx->opcode);
bd277fa1
RH
3985 switch (opc) {
3986 case OPC_ADD_CP2:
3987 case OPC_SUB_CP2:
3988 case OPC_DADD_CP2:
3989 case OPC_DSUB_CP2:
3990 t0 = tcg_temp_local_new_i64();
3991 t1 = tcg_temp_local_new_i64();
3992 break;
3993 default:
3994 t0 = tcg_temp_new_i64();
3995 t1 = tcg_temp_new_i64();
3996 break;
3997 }
3998
b5a587b6 3999 check_cp1_enabled(ctx);
bd277fa1
RH
4000 gen_load_fpr64(ctx, t0, rs);
4001 gen_load_fpr64(ctx, t1, rt);
4002
bd277fa1 4003 switch (opc) {
b1cf82f0
AM
4004 case OPC_PADDSH:
4005 gen_helper_paddsh(t0, t0, t1);
4006 break;
4007 case OPC_PADDUSH:
4008 gen_helper_paddush(t0, t0, t1);
4009 break;
4010 case OPC_PADDH:
4011 gen_helper_paddh(t0, t0, t1);
4012 break;
4013 case OPC_PADDW:
4014 gen_helper_paddw(t0, t0, t1);
4015 break;
4016 case OPC_PADDSB:
4017 gen_helper_paddsb(t0, t0, t1);
4018 break;
4019 case OPC_PADDUSB:
4020 gen_helper_paddusb(t0, t0, t1);
4021 break;
4022 case OPC_PADDB:
4023 gen_helper_paddb(t0, t0, t1);
4024 break;
4025
4026 case OPC_PSUBSH:
4027 gen_helper_psubsh(t0, t0, t1);
4028 break;
4029 case OPC_PSUBUSH:
4030 gen_helper_psubush(t0, t0, t1);
4031 break;
4032 case OPC_PSUBH:
4033 gen_helper_psubh(t0, t0, t1);
4034 break;
4035 case OPC_PSUBW:
4036 gen_helper_psubw(t0, t0, t1);
4037 break;
4038 case OPC_PSUBSB:
4039 gen_helper_psubsb(t0, t0, t1);
4040 break;
4041 case OPC_PSUBUSB:
4042 gen_helper_psubusb(t0, t0, t1);
4043 break;
4044 case OPC_PSUBB:
4045 gen_helper_psubb(t0, t0, t1);
4046 break;
4047
4048 case OPC_PSHUFH:
4049 gen_helper_pshufh(t0, t0, t1);
4050 break;
4051 case OPC_PACKSSWH:
4052 gen_helper_packsswh(t0, t0, t1);
4053 break;
4054 case OPC_PACKSSHB:
4055 gen_helper_packsshb(t0, t0, t1);
4056 break;
4057 case OPC_PACKUSHB:
4058 gen_helper_packushb(t0, t0, t1);
4059 break;
4060
4061 case OPC_PUNPCKLHW:
4062 gen_helper_punpcklhw(t0, t0, t1);
4063 break;
4064 case OPC_PUNPCKHHW:
4065 gen_helper_punpckhhw(t0, t0, t1);
4066 break;
4067 case OPC_PUNPCKLBH:
4068 gen_helper_punpcklbh(t0, t0, t1);
4069 break;
4070 case OPC_PUNPCKHBH:
4071 gen_helper_punpckhbh(t0, t0, t1);
4072 break;
4073 case OPC_PUNPCKLWD:
4074 gen_helper_punpcklwd(t0, t0, t1);
4075 break;
4076 case OPC_PUNPCKHWD:
4077 gen_helper_punpckhwd(t0, t0, t1);
4078 break;
4079
4080 case OPC_PAVGH:
4081 gen_helper_pavgh(t0, t0, t1);
4082 break;
4083 case OPC_PAVGB:
4084 gen_helper_pavgb(t0, t0, t1);
4085 break;
4086 case OPC_PMAXSH:
4087 gen_helper_pmaxsh(t0, t0, t1);
4088 break;
4089 case OPC_PMINSH:
4090 gen_helper_pminsh(t0, t0, t1);
4091 break;
4092 case OPC_PMAXUB:
4093 gen_helper_pmaxub(t0, t0, t1);
4094 break;
4095 case OPC_PMINUB:
4096 gen_helper_pminub(t0, t0, t1);
4097 break;
4098
4099 case OPC_PCMPEQW:
4100 gen_helper_pcmpeqw(t0, t0, t1);
4101 break;
4102 case OPC_PCMPGTW:
4103 gen_helper_pcmpgtw(t0, t0, t1);
4104 break;
4105 case OPC_PCMPEQH:
4106 gen_helper_pcmpeqh(t0, t0, t1);
4107 break;
4108 case OPC_PCMPGTH:
4109 gen_helper_pcmpgth(t0, t0, t1);
4110 break;
4111 case OPC_PCMPEQB:
4112 gen_helper_pcmpeqb(t0, t0, t1);
4113 break;
4114 case OPC_PCMPGTB:
4115 gen_helper_pcmpgtb(t0, t0, t1);
4116 break;
4117
4118 case OPC_PSLLW:
4119 gen_helper_psllw(t0, t0, t1);
4120 break;
4121 case OPC_PSLLH:
4122 gen_helper_psllh(t0, t0, t1);
4123 break;
4124 case OPC_PSRLW:
4125 gen_helper_psrlw(t0, t0, t1);
4126 break;
4127 case OPC_PSRLH:
4128 gen_helper_psrlh(t0, t0, t1);
4129 break;
4130 case OPC_PSRAW:
4131 gen_helper_psraw(t0, t0, t1);
4132 break;
4133 case OPC_PSRAH:
4134 gen_helper_psrah(t0, t0, t1);
4135 break;
4136
4137 case OPC_PMULLH:
4138 gen_helper_pmullh(t0, t0, t1);
4139 break;
4140 case OPC_PMULHH:
4141 gen_helper_pmulhh(t0, t0, t1);
4142 break;
4143 case OPC_PMULHUH:
4144 gen_helper_pmulhuh(t0, t0, t1);
4145 break;
4146 case OPC_PMADDHW:
4147 gen_helper_pmaddhw(t0, t0, t1);
4148 break;
4149
4150 case OPC_PASUBUB:
4151 gen_helper_pasubub(t0, t0, t1);
4152 break;
4153 case OPC_BIADD:
4154 gen_helper_biadd(t0, t0);
4155 break;
4156 case OPC_PMOVMSKB:
4157 gen_helper_pmovmskb(t0, t0);
4158 break;
4159
4160 case OPC_PADDD:
4161 tcg_gen_add_i64(t0, t0, t1);
4162 break;
4163 case OPC_PSUBD:
4164 tcg_gen_sub_i64(t0, t0, t1);
4165 break;
4166 case OPC_XOR_CP2:
4167 tcg_gen_xor_i64(t0, t0, t1);
4168 break;
4169 case OPC_NOR_CP2:
4170 tcg_gen_nor_i64(t0, t0, t1);
4171 break;
4172 case OPC_AND_CP2:
4173 tcg_gen_and_i64(t0, t0, t1);
4174 break;
4175 case OPC_OR_CP2:
4176 tcg_gen_or_i64(t0, t0, t1);
4177 break;
bd277fa1 4178
9099a36b
H
4179 case OPC_PANDN:
4180 tcg_gen_andc_i64(t0, t1, t0);
4181 break;
4182
bd277fa1
RH
4183 case OPC_PINSRH_0:
4184 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4185 break;
4186 case OPC_PINSRH_1:
4187 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4188 break;
4189 case OPC_PINSRH_2:
4190 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4191 break;
4192 case OPC_PINSRH_3:
4193 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4194 break;
4195
4196 case OPC_PEXTRH:
4197 tcg_gen_andi_i64(t1, t1, 3);
4198 tcg_gen_shli_i64(t1, t1, 4);
4199 tcg_gen_shr_i64(t0, t0, t1);
4200 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4201 break;
4202
4203 case OPC_ADDU_CP2:
4204 tcg_gen_add_i64(t0, t0, t1);
4205 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4206 break;
4207 case OPC_SUBU_CP2:
4208 tcg_gen_sub_i64(t0, t0, t1);
4209 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4210 break;
4211
4212 case OPC_SLL_CP2:
bd277fa1
RH
4213 shift_max = 32;
4214 goto do_shift;
4215 case OPC_SRL_CP2:
bd277fa1
RH
4216 shift_max = 32;
4217 goto do_shift;
4218 case OPC_SRA_CP2:
bd277fa1
RH
4219 shift_max = 32;
4220 goto do_shift;
4221 case OPC_DSLL_CP2:
bd277fa1
RH
4222 shift_max = 64;
4223 goto do_shift;
4224 case OPC_DSRL_CP2:
bd277fa1
RH
4225 shift_max = 64;
4226 goto do_shift;
4227 case OPC_DSRA_CP2:
bd277fa1
RH
4228 shift_max = 64;
4229 goto do_shift;
4230 do_shift:
4231 /* Make sure shift count isn't TCG undefined behaviour. */
4232 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4233
4234 switch (opc) {
4235 case OPC_SLL_CP2:
4236 case OPC_DSLL_CP2:
4237 tcg_gen_shl_i64(t0, t0, t1);
4238 break;
4239 case OPC_SRA_CP2:
4240 case OPC_DSRA_CP2:
7480515f
AM
4241 /*
4242 * Since SRA is UndefinedResult without sign-extended inputs,
4243 * we can treat SRA and DSRA the same.
4244 */
bd277fa1
RH
4245 tcg_gen_sar_i64(t0, t0, t1);
4246 break;
4247 case OPC_SRL_CP2:
4248 /* We want to shift in zeros for SRL; zero-extend first. */
4249 tcg_gen_ext32u_i64(t0, t0);
4250 /* FALLTHRU */
4251 case OPC_DSRL_CP2:
4252 tcg_gen_shr_i64(t0, t0, t1);
4253 break;
4254 }
4255
4256 if (shift_max == 32) {
4257 tcg_gen_ext32s_i64(t0, t0);
4258 }
4259
4260 /* Shifts larger than MAX produce zero. */
4261 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4262 tcg_gen_neg_i64(t1, t1);
4263 tcg_gen_and_i64(t0, t0, t1);
4264 break;
4265
4266 case OPC_ADD_CP2:
4267 case OPC_DADD_CP2:
4268 {
4269 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4270 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4271
4272 tcg_gen_mov_i64(t2, t0);
4273 tcg_gen_add_i64(t0, t1, t2);
4274 if (opc == OPC_ADD_CP2) {
4275 tcg_gen_ext32s_i64(t0, t0);
4276 }
4277 tcg_gen_xor_i64(t1, t1, t2);
4278 tcg_gen_xor_i64(t2, t2, t0);
4279 tcg_gen_andc_i64(t1, t2, t1);
4280 tcg_temp_free_i64(t2);
4281 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4282 generate_exception(ctx, EXCP_OVERFLOW);
4283 gen_set_label(lab);
bd277fa1
RH
4284 break;
4285 }
4286
4287 case OPC_SUB_CP2:
4288 case OPC_DSUB_CP2:
4289 {
4290 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4291 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4292
4293 tcg_gen_mov_i64(t2, t0);
4294 tcg_gen_sub_i64(t0, t1, t2);
4295 if (opc == OPC_SUB_CP2) {
4296 tcg_gen_ext32s_i64(t0, t0);
4297 }
4298 tcg_gen_xor_i64(t1, t1, t2);
4299 tcg_gen_xor_i64(t2, t2, t0);
4300 tcg_gen_and_i64(t1, t1, t2);
4301 tcg_temp_free_i64(t2);
4302 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4303 generate_exception(ctx, EXCP_OVERFLOW);
4304 gen_set_label(lab);
bd277fa1
RH
4305 break;
4306 }
4307
4308 case OPC_PMULUW:
4309 tcg_gen_ext32u_i64(t0, t0);
4310 tcg_gen_ext32u_i64(t1, t1);
4311 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4312 break;
4313
4314 case OPC_SEQU_CP2:
4315 case OPC_SEQ_CP2:
84878f4c
JY
4316 cond = TCG_COND_EQ;
4317 goto do_cc_cond;
4318 break;
bd277fa1 4319 case OPC_SLTU_CP2:
84878f4c
JY
4320 cond = TCG_COND_LTU;
4321 goto do_cc_cond;
4322 break;
bd277fa1 4323 case OPC_SLT_CP2:
84878f4c
JY
4324 cond = TCG_COND_LT;
4325 goto do_cc_cond;
4326 break;
bd277fa1 4327 case OPC_SLEU_CP2:
84878f4c
JY
4328 cond = TCG_COND_LEU;
4329 goto do_cc_cond;
4330 break;
bd277fa1 4331 case OPC_SLE_CP2:
84878f4c
JY
4332 cond = TCG_COND_LE;
4333 do_cc_cond:
4334 {
4335 int cc = (ctx->opcode >> 8) & 0x7;
4336 TCGv_i64 t64 = tcg_temp_new_i64();
4337 TCGv_i32 t32 = tcg_temp_new_i32();
4338
4339 tcg_gen_setcond_i64(cond, t64, t0, t1);
4340 tcg_gen_extrl_i64_i32(t32, t64);
4341 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4342 get_fp_bit(cc), 1);
4343
4344 tcg_temp_free_i32(t32);
4345 tcg_temp_free_i64(t64);
4346 }
4347 goto no_rd;
4348 break;
bd277fa1 4349 default:
9d68ac14 4350 MIPS_INVAL("loongson_cp2");
3a4ef3b7 4351 gen_reserved_instruction(ctx);
bd277fa1
RH
4352 return;
4353 }
4354
bd277fa1
RH
4355 gen_store_fpr64(ctx, t0, rd);
4356
84878f4c 4357no_rd:
bd277fa1
RH
4358 tcg_temp_free_i64(t0);
4359 tcg_temp_free_i64(t1);
4360}
4361
e10a0ca1
JY
4362static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4363 int rs, int rd)
4364{
fd723105
JY
4365 TCGv t0, t1, t2;
4366 TCGv_i32 fp0;
e10a0ca1 4367#if defined(TARGET_MIPS64)
e10a0ca1
JY
4368 int lsq_rt1 = ctx->opcode & 0x1f;
4369 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4370#endif
fd723105 4371 int shf_offset = sextract32(ctx->opcode, 6, 8);
e10a0ca1
JY
4372
4373 t0 = tcg_temp_new();
4374
4375 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4376#if defined(TARGET_MIPS64)
4377 case OPC_GSLQ:
4378 t1 = tcg_temp_new();
4379 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4380 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4381 ctx->default_tcg_memop_mask);
4382 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4383 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4384 ctx->default_tcg_memop_mask);
4385 gen_store_gpr(t1, rt);
4386 gen_store_gpr(t0, lsq_rt1);
4387 tcg_temp_free(t1);
4388 break;
4389 case OPC_GSLQC1:
4390 check_cp1_enabled(ctx);
4391 t1 = tcg_temp_new();
4392 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4393 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4394 ctx->default_tcg_memop_mask);
4395 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4396 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4397 ctx->default_tcg_memop_mask);
4398 gen_store_fpr64(ctx, t1, rt);
4399 gen_store_fpr64(ctx, t0, lsq_rt1);
4400 tcg_temp_free(t1);
4401 break;
4402 case OPC_GSSQ:
4403 t1 = tcg_temp_new();
4404 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4405 gen_load_gpr(t1, rt);
4406 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4407 ctx->default_tcg_memop_mask);
4408 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4409 gen_load_gpr(t1, lsq_rt1);
4410 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4411 ctx->default_tcg_memop_mask);
4412 tcg_temp_free(t1);
4413 break;
4414 case OPC_GSSQC1:
4415 check_cp1_enabled(ctx);
4416 t1 = tcg_temp_new();
4417 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4418 gen_load_fpr64(ctx, t1, rt);
4419 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4420 ctx->default_tcg_memop_mask);
4421 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4422 gen_load_fpr64(ctx, t1, lsq_rt1);
4423 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4424 ctx->default_tcg_memop_mask);
4425 tcg_temp_free(t1);
4426 break;
4427#endif
fd723105
JY
4428 case OPC_GSSHFL:
4429 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4430 case OPC_GSLWLC1:
4431 check_cp1_enabled(ctx);
4432 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4433 t1 = tcg_temp_new();
4434 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4435 tcg_gen_andi_tl(t1, t0, 3);
4436#ifndef TARGET_WORDS_BIGENDIAN
4437 tcg_gen_xori_tl(t1, t1, 3);
4438#endif
4439 tcg_gen_shli_tl(t1, t1, 3);
4440 tcg_gen_andi_tl(t0, t0, ~3);
4441 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4442 tcg_gen_shl_tl(t0, t0, t1);
4443 t2 = tcg_const_tl(-1);
4444 tcg_gen_shl_tl(t2, t2, t1);
4445 fp0 = tcg_temp_new_i32();
4446 gen_load_fpr32(ctx, fp0, rt);
4447 tcg_gen_ext_i32_tl(t1, fp0);
4448 tcg_gen_andc_tl(t1, t1, t2);
4449 tcg_temp_free(t2);
4450 tcg_gen_or_tl(t0, t0, t1);
4451 tcg_temp_free(t1);
4452#if defined(TARGET_MIPS64)
4453 tcg_gen_extrl_i64_i32(fp0, t0);
4454#else
4455 tcg_gen_ext32s_tl(fp0, t0);
4456#endif
4457 gen_store_fpr32(ctx, fp0, rt);
4458 tcg_temp_free_i32(fp0);
4459 break;
4460 case OPC_GSLWRC1:
4461 check_cp1_enabled(ctx);
4462 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4463 t1 = tcg_temp_new();
4464 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4465 tcg_gen_andi_tl(t1, t0, 3);
4466#ifdef TARGET_WORDS_BIGENDIAN
4467 tcg_gen_xori_tl(t1, t1, 3);
4468#endif
4469 tcg_gen_shli_tl(t1, t1, 3);
4470 tcg_gen_andi_tl(t0, t0, ~3);
4471 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4472 tcg_gen_shr_tl(t0, t0, t1);
4473 tcg_gen_xori_tl(t1, t1, 31);
4474 t2 = tcg_const_tl(0xfffffffeull);
4475 tcg_gen_shl_tl(t2, t2, t1);
4476 fp0 = tcg_temp_new_i32();
4477 gen_load_fpr32(ctx, fp0, rt);
4478 tcg_gen_ext_i32_tl(t1, fp0);
4479 tcg_gen_and_tl(t1, t1, t2);
4480 tcg_temp_free(t2);
4481 tcg_gen_or_tl(t0, t0, t1);
4482 tcg_temp_free(t1);
4483#if defined(TARGET_MIPS64)
4484 tcg_gen_extrl_i64_i32(fp0, t0);
4485#else
4486 tcg_gen_ext32s_tl(fp0, t0);
4487#endif
4488 gen_store_fpr32(ctx, fp0, rt);
4489 tcg_temp_free_i32(fp0);
4490 break;
4491#if defined(TARGET_MIPS64)
4492 case OPC_GSLDLC1:
4493 check_cp1_enabled(ctx);
4494 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4495 t1 = tcg_temp_new();
4496 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4497 tcg_gen_andi_tl(t1, t0, 7);
4498#ifndef TARGET_WORDS_BIGENDIAN
4499 tcg_gen_xori_tl(t1, t1, 7);
4500#endif
4501 tcg_gen_shli_tl(t1, t1, 3);
4502 tcg_gen_andi_tl(t0, t0, ~7);
4503 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4504 tcg_gen_shl_tl(t0, t0, t1);
4505 t2 = tcg_const_tl(-1);
4506 tcg_gen_shl_tl(t2, t2, t1);
4507 gen_load_fpr64(ctx, t1, rt);
4508 tcg_gen_andc_tl(t1, t1, t2);
4509 tcg_temp_free(t2);
4510 tcg_gen_or_tl(t0, t0, t1);
4511 tcg_temp_free(t1);
4512 gen_store_fpr64(ctx, t0, rt);
4513 break;
4514 case OPC_GSLDRC1:
4515 check_cp1_enabled(ctx);
4516 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4517 t1 = tcg_temp_new();
4518 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4519 tcg_gen_andi_tl(t1, t0, 7);
4520#ifdef TARGET_WORDS_BIGENDIAN
4521 tcg_gen_xori_tl(t1, t1, 7);
4522#endif
4523 tcg_gen_shli_tl(t1, t1, 3);
4524 tcg_gen_andi_tl(t0, t0, ~7);
4525 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4526 tcg_gen_shr_tl(t0, t0, t1);
4527 tcg_gen_xori_tl(t1, t1, 63);
4528 t2 = tcg_const_tl(0xfffffffffffffffeull);
4529 tcg_gen_shl_tl(t2, t2, t1);
4530 gen_load_fpr64(ctx, t1, rt);
4531 tcg_gen_and_tl(t1, t1, t2);
4532 tcg_temp_free(t2);
4533 tcg_gen_or_tl(t0, t0, t1);
4534 tcg_temp_free(t1);
4535 gen_store_fpr64(ctx, t0, rt);
4536 break;
4537#endif
4538 default:
4539 MIPS_INVAL("loongson_gsshfl");
3a4ef3b7 4540 gen_reserved_instruction(ctx);
fd723105
JY
4541 break;
4542 }
4543 break;
4544 case OPC_GSSHFS:
4545 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4546 case OPC_GSSWLC1:
4547 check_cp1_enabled(ctx);
4548 t1 = tcg_temp_new();
4549 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4550 fp0 = tcg_temp_new_i32();
4551 gen_load_fpr32(ctx, fp0, rt);
4552 tcg_gen_ext_i32_tl(t1, fp0);
4553 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4554 tcg_temp_free_i32(fp0);
4555 tcg_temp_free(t1);
4556 break;
4557 case OPC_GSSWRC1:
4558 check_cp1_enabled(ctx);
4559 t1 = tcg_temp_new();
4560 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4561 fp0 = tcg_temp_new_i32();
4562 gen_load_fpr32(ctx, fp0, rt);
4563 tcg_gen_ext_i32_tl(t1, fp0);
4564 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4565 tcg_temp_free_i32(fp0);
4566 tcg_temp_free(t1);
4567 break;
4568#if defined(TARGET_MIPS64)
4569 case OPC_GSSDLC1:
4570 check_cp1_enabled(ctx);
4571 t1 = tcg_temp_new();
4572 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4573 gen_load_fpr64(ctx, t1, rt);
4574 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4575 tcg_temp_free(t1);
4576 break;
4577 case OPC_GSSDRC1:
4578 check_cp1_enabled(ctx);
4579 t1 = tcg_temp_new();
4580 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4581 gen_load_fpr64(ctx, t1, rt);
4582 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4583 tcg_temp_free(t1);
4584 break;
4585#endif
4586 default:
4587 MIPS_INVAL("loongson_gsshfs");
3a4ef3b7 4588 gen_reserved_instruction(ctx);
fd723105
JY
4589 break;
4590 }
4591 break;
e10a0ca1
JY
4592 default:
4593 MIPS_INVAL("loongson_gslsq");
3a4ef3b7 4594 gen_reserved_instruction(ctx);
e10a0ca1
JY
4595 break;
4596 }
4597 tcg_temp_free(t0);
4598}
4599
90e22a57
JY
4600/* Loongson EXT LDC2/SDC2 */
4601static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4602 int rs, int rd)
4603{
4604 int offset = sextract32(ctx->opcode, 3, 8);
4605 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4606 TCGv t0, t1;
4607 TCGv_i32 fp0;
4608
4609 /* Pre-conditions */
4610 switch (opc) {
4611 case OPC_GSLBX:
4612 case OPC_GSLHX:
4613 case OPC_GSLWX:
4614 case OPC_GSLDX:
4615 /* prefetch, implement as NOP */
4616 if (rt == 0) {
4617 return;
4618 }
4619 break;
4620 case OPC_GSSBX:
4621 case OPC_GSSHX:
4622 case OPC_GSSWX:
4623 case OPC_GSSDX:
4624 break;
4625 case OPC_GSLWXC1:
4626#if defined(TARGET_MIPS64)
4627 case OPC_GSLDXC1:
4628#endif
4629 check_cp1_enabled(ctx);
4630 /* prefetch, implement as NOP */
4631 if (rt == 0) {
4632 return;
4633 }
4634 break;
4635 case OPC_GSSWXC1:
4636#if defined(TARGET_MIPS64)
4637 case OPC_GSSDXC1:
4638#endif
4639 check_cp1_enabled(ctx);
4640 break;
4641 default:
4642 MIPS_INVAL("loongson_lsdc2");
3a4ef3b7 4643 gen_reserved_instruction(ctx);
90e22a57
JY
4644 return;
4645 break;
4646 }
4647
4648 t0 = tcg_temp_new();
4649
4650 gen_base_offset_addr(ctx, t0, rs, offset);
4651 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4652
4653 switch (opc) {
4654 case OPC_GSLBX:
4655 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4656 gen_store_gpr(t0, rt);
4657 break;
4658 case OPC_GSLHX:
4659 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4660 ctx->default_tcg_memop_mask);
4661 gen_store_gpr(t0, rt);
4662 break;
4663 case OPC_GSLWX:
4664 gen_base_offset_addr(ctx, t0, rs, offset);
4665 if (rd) {
4666 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4667 }
4668 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4669 ctx->default_tcg_memop_mask);
4670 gen_store_gpr(t0, rt);
4671 break;
4672#if defined(TARGET_MIPS64)
4673 case OPC_GSLDX:
4674 gen_base_offset_addr(ctx, t0, rs, offset);
4675 if (rd) {
4676 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4677 }
4678 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4679 ctx->default_tcg_memop_mask);
4680 gen_store_gpr(t0, rt);
4681 break;
4682#endif
4683 case OPC_GSLWXC1:
90e22a57
JY
4684 gen_base_offset_addr(ctx, t0, rs, offset);
4685 if (rd) {
4686 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4687 }
4688 fp0 = tcg_temp_new_i32();
4689 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4690 ctx->default_tcg_memop_mask);
4691 gen_store_fpr32(ctx, fp0, rt);
4692 tcg_temp_free_i32(fp0);
4693 break;
4694#if defined(TARGET_MIPS64)
4695 case OPC_GSLDXC1:
90e22a57
JY
4696 gen_base_offset_addr(ctx, t0, rs, offset);
4697 if (rd) {
4698 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4699 }
4700 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4701 ctx->default_tcg_memop_mask);
4702 gen_store_fpr64(ctx, t0, rt);
4703 break;
4704#endif
4705 case OPC_GSSBX:
4706 t1 = tcg_temp_new();
4707 gen_load_gpr(t1, rt);
4708 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4709 tcg_temp_free(t1);
4710 break;
4711 case OPC_GSSHX:
4712 t1 = tcg_temp_new();
4713 gen_load_gpr(t1, rt);
4714 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4715 ctx->default_tcg_memop_mask);
4716 tcg_temp_free(t1);
4717 break;
4718 case OPC_GSSWX:
4719 t1 = tcg_temp_new();
4720 gen_load_gpr(t1, rt);
4721 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4722 ctx->default_tcg_memop_mask);
4723 tcg_temp_free(t1);
4724 break;
4725#if defined(TARGET_MIPS64)
4726 case OPC_GSSDX:
4727 t1 = tcg_temp_new();
4728 gen_load_gpr(t1, rt);
4729 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4730 ctx->default_tcg_memop_mask);
4731 tcg_temp_free(t1);
4732 break;
4733#endif
4734 case OPC_GSSWXC1:
4735 fp0 = tcg_temp_new_i32();
4736 gen_load_fpr32(ctx, fp0, rt);
4737 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4738 ctx->default_tcg_memop_mask);
4739 tcg_temp_free_i32(fp0);
4740 break;
4741#if defined(TARGET_MIPS64)
4742 case OPC_GSSDXC1:
4743 t1 = tcg_temp_new();
4744 gen_load_fpr64(ctx, t1, rt);
4745 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
4746 ctx->default_tcg_memop_mask);
4747 tcg_temp_free(t1);
4748 break;
4749#endif
4750 default:
4751 break;
4752 }
4753
4754 tcg_temp_free(t0);
4755}
4756
6af0bf9c 4757/* Traps */
71375b59
AM
4758static void gen_trap(DisasContext *ctx, uint32_t opc,
4759 int rs, int rt, int16_t imm)
6af0bf9c
FB
4760{
4761 int cond;
cdc0faa6 4762 TCGv t0 = tcg_temp_new();
1ba74fb8 4763 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4764
4765 cond = 0;
4766 /* Load needed operands */
4767 switch (opc) {
4768 case OPC_TEQ:
4769 case OPC_TGE:
4770 case OPC_TGEU:
4771 case OPC_TLT:
4772 case OPC_TLTU:
4773 case OPC_TNE:
4774 /* Compare two registers */
4775 if (rs != rt) {
be24bb4f
TS
4776 gen_load_gpr(t0, rs);
4777 gen_load_gpr(t1, rt);
6af0bf9c
FB
4778 cond = 1;
4779 }
179e32bb 4780 break;
6af0bf9c
FB
4781 case OPC_TEQI:
4782 case OPC_TGEI:
4783 case OPC_TGEIU:
4784 case OPC_TLTI:
4785 case OPC_TLTIU:
4786 case OPC_TNEI:
4787 /* Compare register to immediate */
4788 if (rs != 0 || imm != 0) {
be24bb4f
TS
4789 gen_load_gpr(t0, rs);
4790 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4791 cond = 1;
4792 }
4793 break;
4794 }
4795 if (cond == 0) {
4796 switch (opc) {
4797 case OPC_TEQ: /* rs == rs */
4798 case OPC_TEQI: /* r0 == 0 */
4799 case OPC_TGE: /* rs >= rs */
4800 case OPC_TGEI: /* r0 >= 0 */
4801 case OPC_TGEU: /* rs >= rs unsigned */
4802 case OPC_TGEIU: /* r0 >= 0 unsigned */
4803 /* Always trap */
9c708c7f 4804 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4805 break;
4806 case OPC_TLT: /* rs < rs */
4807 case OPC_TLTI: /* r0 < 0 */
4808 case OPC_TLTU: /* rs < rs unsigned */
4809 case OPC_TLTIU: /* r0 < 0 unsigned */
4810 case OPC_TNE: /* rs != rs */
4811 case OPC_TNEI: /* r0 != 0 */
ead9360e 4812 /* Never trap: treat as NOP. */
cdc0faa6 4813 break;
6af0bf9c
FB
4814 }
4815 } else {
42a268c2 4816 TCGLabel *l1 = gen_new_label();
cdc0faa6 4817
6af0bf9c
FB
4818 switch (opc) {
4819 case OPC_TEQ:
4820 case OPC_TEQI:
cdc0faa6 4821 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4822 break;
4823 case OPC_TGE:
4824 case OPC_TGEI:
cdc0faa6 4825 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4826 break;
4827 case OPC_TGEU:
4828 case OPC_TGEIU:
cdc0faa6 4829 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4830 break;
4831 case OPC_TLT:
4832 case OPC_TLTI:
cdc0faa6 4833 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4834 break;
4835 case OPC_TLTU:
4836 case OPC_TLTIU:
cdc0faa6 4837 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4838 break;
4839 case OPC_TNE:
4840 case OPC_TNEI:
cdc0faa6 4841 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4842 break;
6af0bf9c 4843 }
cdc0faa6 4844 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4845 gen_set_label(l1);
4846 }
be24bb4f
TS
4847 tcg_temp_free(t0);
4848 tcg_temp_free(t1);
6af0bf9c
FB
4849}
4850
97eea3c1 4851static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
90aa39a1 4852{
97eea3c1 4853 if (translator_use_goto_tb(&ctx->base, dest)) {
57fec1fe 4854 tcg_gen_goto_tb(n);
9b9e4393 4855 gen_save_pc(dest);
07ea28b4 4856 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 4857 } else {
9b9e4393 4858 gen_save_pc(dest);
eeb3bba8 4859 if (ctx->base.singlestep_enabled) {
7b270ef2 4860 save_cpu_state(ctx, 0);
9c708c7f 4861 gen_helper_raise_exception_debug(cpu_env);
34f5e75a
RH
4862 } else {
4863 tcg_gen_lookup_and_goto_ptr();
7b270ef2 4864 }
6e256c93 4865 }
c53be334
FB
4866}
4867
6af0bf9c 4868/* Branches (before delay slot) */
71375b59
AM
4869static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4870 int insn_bytes,
4871 int rs, int rt, int32_t offset,
4872 int delayslot_size)
6af0bf9c 4873{
d077b6f7 4874 target_ulong btgt = -1;
3ad4bb2d 4875 int blink = 0;
2fdbad25 4876 int bcond_compute = 0;
1ba74fb8
AJ
4877 TCGv t0 = tcg_temp_new();
4878 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4879
4880 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4881#ifdef MIPS_DEBUG_DISAS
339cd2a8 4882 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 4883 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 4884#endif
3a4ef3b7 4885 gen_reserved_instruction(ctx);
6c5c1e20 4886 goto out;
3ad4bb2d 4887 }
6af0bf9c 4888
6af0bf9c
FB
4889 /* Load needed operands */
4890 switch (opc) {
4891 case OPC_BEQ:
4892 case OPC_BEQL:
4893 case OPC_BNE:
4894 case OPC_BNEL:
4895 /* Compare two registers */
4896 if (rs != rt) {
6c5c1e20
TS
4897 gen_load_gpr(t0, rs);
4898 gen_load_gpr(t1, rt);
2fdbad25 4899 bcond_compute = 1;
6af0bf9c 4900 }
eeb3bba8 4901 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
4902 break;
4903 case OPC_BGEZ:
4904 case OPC_BGEZAL:
4905 case OPC_BGEZALL:
4906 case OPC_BGEZL:
4907 case OPC_BGTZ:
4908 case OPC_BGTZL:
4909 case OPC_BLEZ:
4910 case OPC_BLEZL:
4911 case OPC_BLTZ:
4912 case OPC_BLTZAL:
4913 case OPC_BLTZALL:
4914 case OPC_BLTZL:
4915 /* Compare to zero */
4916 if (rs != 0) {
6c5c1e20 4917 gen_load_gpr(t0, rs);
2fdbad25 4918 bcond_compute = 1;
6af0bf9c 4919 }
eeb3bba8 4920 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 4921 break;
e45a93e2
JL
4922 case OPC_BPOSGE32:
4923#if defined(TARGET_MIPS64)
4924 case OPC_BPOSGE64:
4925 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4926#else
4927 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4928#endif
4929 bcond_compute = 1;
eeb3bba8 4930 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 4931 break;
6af0bf9c
FB
4932 case OPC_J:
4933 case OPC_JAL:
364d4831 4934 case OPC_JALX:
6af0bf9c 4935 /* Jump to immediate */
eeb3bba8
EC
4936 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4937 (uint32_t)offset;
6af0bf9c
FB
4938 break;
4939 case OPC_JR:
4940 case OPC_JALR:
4941 /* Jump to register */
7a387fff 4942 if (offset != 0 && offset != 16) {
7480515f
AM
4943 /*
4944 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4945 * others are reserved.
4946 */
923617a3 4947 MIPS_INVAL("jump hint");
3a4ef3b7 4948 gen_reserved_instruction(ctx);
6c5c1e20 4949 goto out;
6af0bf9c 4950 }
d077b6f7 4951 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4952 break;
4953 default:
4954 MIPS_INVAL("branch/jump");
3a4ef3b7 4955 gen_reserved_instruction(ctx);
6c5c1e20 4956 goto out;
6af0bf9c 4957 }
2fdbad25 4958 if (bcond_compute == 0) {
6af0bf9c
FB
4959 /* No condition to be computed */
4960 switch (opc) {
4961 case OPC_BEQ: /* rx == rx */
4962 case OPC_BEQL: /* rx == rx likely */
4963 case OPC_BGEZ: /* 0 >= 0 */
4964 case OPC_BGEZL: /* 0 >= 0 likely */
4965 case OPC_BLEZ: /* 0 <= 0 */
4966 case OPC_BLEZL: /* 0 <= 0 likely */
4967 /* Always take */
4ad40f36 4968 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4969 break;
4970 case OPC_BGEZAL: /* 0 >= 0 */
4971 case OPC_BGEZALL: /* 0 >= 0 likely */
4972 /* Always take and link */
4973 blink = 31;
4ad40f36 4974 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4975 break;
4976 case OPC_BNE: /* rx != rx */
4977 case OPC_BGTZ: /* 0 > 0 */
4978 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4979 /* Treat as NOP. */
6c5c1e20 4980 goto out;
eeef26cd 4981 case OPC_BLTZAL: /* 0 < 0 */
7480515f
AM
4982 /*
4983 * Handle as an unconditional branch to get correct delay
4984 * slot checking.
4985 */
3c824109 4986 blink = 31;
eeb3bba8 4987 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 4988 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4989 break;
eeef26cd 4990 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 4991 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 4992 /* Skip the instruction in the delay slot */
eeb3bba8 4993 ctx->base.pc_next += 4;
6c5c1e20 4994 goto out;
6af0bf9c
FB
4995 case OPC_BNEL: /* rx != rx likely */
4996 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4997 case OPC_BLTZL: /* 0 < 0 likely */
4998 /* Skip the instruction in the delay slot */
eeb3bba8 4999 ctx->base.pc_next += 4;
6c5c1e20 5000 goto out;
6af0bf9c 5001 case OPC_J:
4ad40f36 5002 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 5003 break;
364d4831
NF
5004 case OPC_JALX:
5005 ctx->hflags |= MIPS_HFLAG_BX;
5006 /* Fallthrough */
6af0bf9c
FB
5007 case OPC_JAL:
5008 blink = 31;
4ad40f36 5009 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5010 break;
5011 case OPC_JR:
4ad40f36 5012 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5013 break;
5014 case OPC_JALR:
5015 blink = rt;
4ad40f36 5016 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5017 break;
5018 default:
5019 MIPS_INVAL("branch/jump");
3a4ef3b7 5020 gen_reserved_instruction(ctx);
6c5c1e20 5021 goto out;
6af0bf9c
FB
5022 }
5023 } else {
5024 switch (opc) {
5025 case OPC_BEQ:
e68dd28f 5026 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5027 goto not_likely;
5028 case OPC_BEQL:
e68dd28f 5029 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5030 goto likely;
5031 case OPC_BNE:
e68dd28f 5032 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5033 goto not_likely;
5034 case OPC_BNEL:
e68dd28f 5035 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5036 goto likely;
5037 case OPC_BGEZ:
e68dd28f 5038 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5039 goto not_likely;
5040 case OPC_BGEZL:
e68dd28f 5041 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5042 goto likely;
5043 case OPC_BGEZAL:
e68dd28f 5044 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5045 blink = 31;
5046 goto not_likely;
5047 case OPC_BGEZALL:
e68dd28f 5048 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 5049 blink = 31;
6af0bf9c
FB
5050 goto likely;
5051 case OPC_BGTZ:
e68dd28f 5052 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5053 goto not_likely;
5054 case OPC_BGTZL:
e68dd28f 5055 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5056 goto likely;
5057 case OPC_BLEZ:
e68dd28f 5058 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5059 goto not_likely;
5060 case OPC_BLEZL:
e68dd28f 5061 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5062 goto likely;
5063 case OPC_BLTZ:
e68dd28f 5064 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
5065 goto not_likely;
5066 case OPC_BLTZL:
e68dd28f 5067 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5068 goto likely;
e45a93e2
JL
5069 case OPC_BPOSGE32:
5070 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
5071 goto not_likely;
5072#if defined(TARGET_MIPS64)
5073 case OPC_BPOSGE64:
5074 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
5075 goto not_likely;
5076#endif
6af0bf9c 5077 case OPC_BLTZAL:
e68dd28f 5078 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5079 blink = 31;
6af0bf9c 5080 not_likely:
4ad40f36 5081 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
5082 break;
5083 case OPC_BLTZALL:
e68dd28f 5084 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5085 blink = 31;
6af0bf9c 5086 likely:
4ad40f36 5087 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 5088 break;
c53f4a62
TS
5089 default:
5090 MIPS_INVAL("conditional branch/jump");
3a4ef3b7 5091 gen_reserved_instruction(ctx);
6c5c1e20 5092 goto out;
6af0bf9c 5093 }
6af0bf9c 5094 }
9b9e4393 5095
d077b6f7 5096 ctx->btarget = btgt;
b231c103
YK
5097
5098 switch (delayslot_size) {
5099 case 2:
5100 ctx->hflags |= MIPS_HFLAG_BDS16;
5101 break;
5102 case 4:
5103 ctx->hflags |= MIPS_HFLAG_BDS32;
5104 break;
5105 }
5106
6af0bf9c 5107 if (blink > 0) {
b231c103 5108 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
5109 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5110
eeb3bba8
EC
5111 tcg_gen_movi_tl(cpu_gpr[blink],
5112 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 5113 }
6c5c1e20
TS
5114
5115 out:
1f8929d2 5116 if (insn_bytes == 2) {
364d4831 5117 ctx->hflags |= MIPS_HFLAG_B16;
1f8929d2 5118 }
6c5c1e20
TS
5119 tcg_temp_free(t0);
5120 tcg_temp_free(t1);
6af0bf9c
FB
5121}
5122
764371d2 5123
7a387fff 5124/* special3 bitfield operations */
235785e8
AM
5125static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5126 int rs, int lsb, int msb)
7a387fff 5127{
a7812ae4
PB
5128 TCGv t0 = tcg_temp_new();
5129 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
5130
5131 gen_load_gpr(t1, rs);
7a387fff
TS
5132 switch (opc) {
5133 case OPC_EXT:
b7f26e52 5134 if (lsb + msb > 31) {
7a387fff 5135 goto fail;
b7f26e52 5136 }
505ad7c2 5137 if (msb != 31) {
6eebb7a4 5138 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 5139 } else {
7480515f
AM
5140 /*
5141 * The two checks together imply that lsb == 0,
5142 * so this is a simple sign-extension.
5143 */
6eebb7a4 5144 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 5145 }
7a387fff 5146 break;
c6d6dd7c 5147#if defined(TARGET_MIPS64)
7a387fff 5148 case OPC_DEXTU:
b7f26e52
RH
5149 lsb += 32;
5150 goto do_dext;
5151 case OPC_DEXTM:
5152 msb += 32;
5153 goto do_dext;
7a387fff 5154 case OPC_DEXT:
b7f26e52
RH
5155 do_dext:
5156 if (lsb + msb > 63) {
5157 goto fail;
5158 }
6eebb7a4 5159 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 5160 break;
c6d6dd7c 5161#endif
7a387fff 5162 case OPC_INS:
b7f26e52 5163 if (lsb > msb) {
7a387fff 5164 goto fail;
b7f26e52 5165 }
6c5c1e20 5166 gen_load_gpr(t0, rt);
e0d002f1 5167 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 5168 tcg_gen_ext32s_tl(t0, t0);
7a387fff 5169 break;
c6d6dd7c 5170#if defined(TARGET_MIPS64)
7a387fff 5171 case OPC_DINSU:
b7f26e52
RH
5172 lsb += 32;
5173 /* FALLTHRU */
5174 case OPC_DINSM:
5175 msb += 32;
5176 /* FALLTHRU */
7a387fff 5177 case OPC_DINS:
b7f26e52
RH
5178 if (lsb > msb) {
5179 goto fail;
5180 }
6c5c1e20 5181 gen_load_gpr(t0, rt);
e0d002f1 5182 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 5183 break;
c6d6dd7c 5184#endif
7a387fff
TS
5185 default:
5186fail:
5187 MIPS_INVAL("bitops");
3a4ef3b7 5188 gen_reserved_instruction(ctx);
6c5c1e20
TS
5189 tcg_temp_free(t0);
5190 tcg_temp_free(t1);
7a387fff
TS
5191 return;
5192 }
6c5c1e20
TS
5193 gen_store_gpr(t0, rt);
5194 tcg_temp_free(t0);
5195 tcg_temp_free(t1);
7a387fff
TS
5196}
5197
235785e8 5198static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
49bcf33c 5199{
3a55fa47 5200 TCGv t0;
49bcf33c 5201
3a55fa47
AJ
5202 if (rd == 0) {
5203 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
5204 return;
5205 }
5206
5207 t0 = tcg_temp_new();
5208 gen_load_gpr(t0, rt);
49bcf33c
AJ
5209 switch (op2) {
5210 case OPC_WSBH:
3a55fa47
AJ
5211 {
5212 TCGv t1 = tcg_temp_new();
06a57e5c 5213 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
5214
5215 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5216 tcg_gen_and_tl(t1, t1, t2);
5217 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5218 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5219 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 5220 tcg_temp_free(t2);
3a55fa47
AJ
5221 tcg_temp_free(t1);
5222 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5223 }
49bcf33c
AJ
5224 break;
5225 case OPC_SEB:
3a55fa47 5226 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5227 break;
5228 case OPC_SEH:
3a55fa47 5229 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5230 break;
5231#if defined(TARGET_MIPS64)
5232 case OPC_DSBH:
3a55fa47
AJ
5233 {
5234 TCGv t1 = tcg_temp_new();
06a57e5c 5235 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
5236
5237 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5238 tcg_gen_and_tl(t1, t1, t2);
5239 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5240 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5241 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5242 tcg_temp_free(t2);
3a55fa47
AJ
5243 tcg_temp_free(t1);
5244 }
49bcf33c
AJ
5245 break;
5246 case OPC_DSHD:
3a55fa47
AJ
5247 {
5248 TCGv t1 = tcg_temp_new();
06a57e5c 5249 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
5250
5251 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
5252 tcg_gen_and_tl(t1, t1, t2);
5253 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5254 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
5255 tcg_gen_or_tl(t0, t0, t1);
5256 tcg_gen_shri_tl(t1, t0, 32);
5257 tcg_gen_shli_tl(t0, t0, 32);
5258 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5259 tcg_temp_free(t2);
3a55fa47
AJ
5260 tcg_temp_free(t1);
5261 }
49bcf33c
AJ
5262 break;
5263#endif
5264 default:
5265 MIPS_INVAL("bsfhl");
3a4ef3b7 5266 gen_reserved_instruction(ctx);
49bcf33c 5267 tcg_temp_free(t0);
49bcf33c
AJ
5268 return;
5269 }
49bcf33c 5270 tcg_temp_free(t0);
49bcf33c
AJ
5271}
5272
821f2008
JH
5273static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5274 int rt, int bits)
284b731a 5275{
1f1b4c00
YK
5276 TCGv t0;
5277 if (rd == 0) {
5278 /* Treat as NOP. */
5279 return;
5280 }
5281 t0 = tcg_temp_new();
821f2008
JH
5282 if (bits == 0 || bits == wordsz) {
5283 if (bits == 0) {
5284 gen_load_gpr(t0, rt);
5285 } else {
5286 gen_load_gpr(t0, rs);
5287 }
5288 switch (wordsz) {
5289 case 32:
51243852
MD
5290 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5291 break;
5292#if defined(TARGET_MIPS64)
821f2008 5293 case 64:
51243852
MD
5294 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5295 break;
5296#endif
5297 }
1f1b4c00
YK
5298 } else {
5299 TCGv t1 = tcg_temp_new();
821f2008 5300 gen_load_gpr(t0, rt);
1f1b4c00 5301 gen_load_gpr(t1, rs);
821f2008
JH
5302 switch (wordsz) {
5303 case 32:
1f1b4c00
YK
5304 {
5305 TCGv_i64 t2 = tcg_temp_new_i64();
5306 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 5307 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
5308 gen_move_low32(cpu_gpr[rd], t2);
5309 tcg_temp_free_i64(t2);
5310 }
5311 break;
284b731a 5312#if defined(TARGET_MIPS64)
821f2008
JH
5313 case 64:
5314 tcg_gen_shli_tl(t0, t0, bits);
5315 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
5316 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5317 break;
284b731a 5318#endif
1f1b4c00
YK
5319 }
5320 tcg_temp_free(t1);
5321 }
5322
5323 tcg_temp_free(t0);
5324}
5325
d5076631 5326void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
821f2008
JH
5327{
5328 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5329}
5330
1f1b4c00
YK
5331static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5332{
5333 TCGv t0;
5334 if (rd == 0) {
5335 /* Treat as NOP. */
5336 return;
5337 }
5338 t0 = tcg_temp_new();
5339 gen_load_gpr(t0, rt);
5340 switch (opc) {
5341 case OPC_BITSWAP:
5342 gen_helper_bitswap(cpu_gpr[rd], t0);
5343 break;
5344#if defined(TARGET_MIPS64)
5345 case OPC_DBITSWAP:
5346 gen_helper_dbitswap(cpu_gpr[rd], t0);
5347 break;
5348#endif
5349 }
5350 tcg_temp_free(t0);
284b731a
LA
5351}
5352
1f1b4c00
YK
5353#ifndef CONFIG_USER_ONLY
5354/* CP0 (MMU and control) */
5204ea79
LA
5355static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5356{
5357 TCGv_i64 t0 = tcg_temp_new_i64();
5358 TCGv_i64 t1 = tcg_temp_new_i64();
5359
5360 tcg_gen_ext_tl_i64(t0, arg);
5361 tcg_gen_ld_i64(t1, cpu_env, off);
5362#if defined(TARGET_MIPS64)
5363 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5364#else
5365 tcg_gen_concat32_i64(t1, t1, t0);
5366#endif
5367 tcg_gen_st_i64(t1, cpu_env, off);
5368 tcg_temp_free_i64(t1);
5369 tcg_temp_free_i64(t0);
5370}
5371
5372static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5373{
5374 TCGv_i64 t0 = tcg_temp_new_i64();
5375 TCGv_i64 t1 = tcg_temp_new_i64();
5376
5377 tcg_gen_ext_tl_i64(t0, arg);
5378 tcg_gen_ld_i64(t1, cpu_env, off);
5379 tcg_gen_concat32_i64(t1, t1, t0);
5380 tcg_gen_st_i64(t1, cpu_env, off);
5381 tcg_temp_free_i64(t1);
5382 tcg_temp_free_i64(t0);
5383}
5384
5385static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5386{
5387 TCGv_i64 t0 = tcg_temp_new_i64();
5388
5389 tcg_gen_ld_i64(t0, cpu_env, off);
5390#if defined(TARGET_MIPS64)
5391 tcg_gen_shri_i64(t0, t0, 30);
5392#else
5393 tcg_gen_shri_i64(t0, t0, 32);
5394#endif
5395 gen_move_low32(arg, t0);
5396 tcg_temp_free_i64(t0);
5397}
5398
5399static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5400{
5401 TCGv_i64 t0 = tcg_temp_new_i64();
5402
5403 tcg_gen_ld_i64(t0, cpu_env, off);
5404 tcg_gen_shri_i64(t0, t0, 32 + shift);
5405 gen_move_low32(arg, t0);
5406 tcg_temp_free_i64(t0);
5407}
5408
235785e8 5409static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4f57689a 5410{
d9bea114 5411 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 5412
d9bea114
AJ
5413 tcg_gen_ld_i32(t0, cpu_env, off);
5414 tcg_gen_ext_i32_tl(arg, t0);
5415 tcg_temp_free_i32(t0);
4f57689a
TS
5416}
5417
235785e8 5418static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4f57689a 5419{
d9bea114
AJ
5420 tcg_gen_ld_tl(arg, cpu_env, off);
5421 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
5422}
5423
235785e8 5424static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
f1aa6320 5425{
d9bea114 5426 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 5427
d9bea114
AJ
5428 tcg_gen_trunc_tl_i32(t0, arg);
5429 tcg_gen_st_i32(t0, cpu_env, off);
5430 tcg_temp_free_i32(t0);
f1aa6320
TS
5431}
5432
c98d3d79
YK
5433#define CP0_CHECK(c) \
5434 do { \
5435 if (!(c)) { \
5436 goto cp0_unimplemented; \
5437 } \
5438 } while (0)
5439
5204ea79
LA
5440static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5441{
294fc2ea 5442 const char *register_name = "invalid";
5204ea79 5443
5204ea79 5444 switch (reg) {
04992c8c 5445 case CP0_REGISTER_02:
5204ea79
LA
5446 switch (sel) {
5447 case 0:
59488dda 5448 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79 5449 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 5450 register_name = "EntryLo0";
5204ea79
LA
5451 break;
5452 default:
c98d3d79 5453 goto cp0_unimplemented;
5204ea79
LA
5454 }
5455 break;
04992c8c 5456 case CP0_REGISTER_03:
5204ea79 5457 switch (sel) {
acd37316 5458 case CP0_REG03__ENTRYLO1:
59488dda 5459 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79 5460 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 5461 register_name = "EntryLo1";
5204ea79
LA
5462 break;
5463 default:
c98d3d79 5464 goto cp0_unimplemented;
5204ea79
LA
5465 }
5466 break;
04992c8c 5467 case CP0_REGISTER_09:
5fb2dcd1 5468 switch (sel) {
e5a98a72 5469 case CP0_REG09__SAAR:
5fb2dcd1
YK
5470 CP0_CHECK(ctx->saar);
5471 gen_helper_mfhc0_saar(arg, cpu_env);
294fc2ea 5472 register_name = "SAAR";
5fb2dcd1
YK
5473 break;
5474 default:
5475 goto cp0_unimplemented;
5476 }
5477 break;
04992c8c 5478 case CP0_REGISTER_17:
5204ea79 5479 switch (sel) {
706ce142 5480 case CP0_REG17__LLADDR:
c7c7e1e9 5481 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5204ea79 5482 ctx->CP0_LLAddr_shift);
294fc2ea 5483 register_name = "LLAddr";
5204ea79 5484 break;
706ce142 5485 case CP0_REG17__MAAR:
f6d4dd81
YK
5486 CP0_CHECK(ctx->mrp);
5487 gen_helper_mfhc0_maar(arg, cpu_env);
294fc2ea 5488 register_name = "MAAR";
f6d4dd81 5489 break;
5204ea79 5490 default:
c98d3d79 5491 goto cp0_unimplemented;
5204ea79
LA
5492 }
5493 break;
feafe82c
YK
5494 case CP0_REGISTER_19:
5495 switch (sel) {
5496 case CP0_REG19__WATCHHI0:
5497 case CP0_REG19__WATCHHI1:
5498 case CP0_REG19__WATCHHI2:
5499 case CP0_REG19__WATCHHI3:
5500 case CP0_REG19__WATCHHI4:
5501 case CP0_REG19__WATCHHI5:
5502 case CP0_REG19__WATCHHI6:
5503 case CP0_REG19__WATCHHI7:
5504 /* upper 32 bits are only available when Config5MI != 0 */
5505 CP0_CHECK(ctx->mi);
5506 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5507 register_name = "WatchHi";
5508 break;
5509 default:
5510 goto cp0_unimplemented;
5511 }
5512 break;
04992c8c 5513 case CP0_REGISTER_28:
5204ea79
LA
5514 switch (sel) {
5515 case 0:
5516 case 2:
5517 case 4:
5518 case 6:
5519 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
294fc2ea 5520 register_name = "TagLo";
5204ea79
LA
5521 break;
5522 default:
c98d3d79 5523 goto cp0_unimplemented;
5204ea79
LA
5524 }
5525 break;
5526 default:
c98d3d79 5527 goto cp0_unimplemented;
5204ea79 5528 }
294fc2ea 5529 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5204ea79
LA
5530 return;
5531
c98d3d79 5532cp0_unimplemented:
294fc2ea
AM
5533 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5534 register_name, reg, sel);
5204ea79
LA
5535 tcg_gen_movi_tl(arg, 0);
5536}
5537
5538static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5539{
294fc2ea 5540 const char *register_name = "invalid";
5204ea79
LA
5541 uint64_t mask = ctx->PAMask >> 36;
5542
5204ea79 5543 switch (reg) {
04992c8c 5544 case CP0_REGISTER_02:
5204ea79
LA
5545 switch (sel) {
5546 case 0:
59488dda 5547 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5548 tcg_gen_andi_tl(arg, arg, mask);
5549 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 5550 register_name = "EntryLo0";
5204ea79
LA
5551 break;
5552 default:
c98d3d79 5553 goto cp0_unimplemented;
5204ea79
LA
5554 }
5555 break;
04992c8c 5556 case CP0_REGISTER_03:
5204ea79 5557 switch (sel) {
acd37316 5558 case CP0_REG03__ENTRYLO1:
59488dda 5559 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5560 tcg_gen_andi_tl(arg, arg, mask);
5561 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 5562 register_name = "EntryLo1";
5204ea79
LA
5563 break;
5564 default:
c98d3d79 5565 goto cp0_unimplemented;
5204ea79
LA
5566 }
5567 break;
04992c8c 5568 case CP0_REGISTER_09:
5fb2dcd1 5569 switch (sel) {
e5a98a72 5570 case CP0_REG09__SAAR:
5fb2dcd1
YK
5571 CP0_CHECK(ctx->saar);
5572 gen_helper_mthc0_saar(cpu_env, arg);
294fc2ea 5573 register_name = "SAAR";
5fb2dcd1
YK
5574 break;
5575 default:
5576 goto cp0_unimplemented;
5577 }
ab8c3410 5578 break;
04992c8c 5579 case CP0_REGISTER_17:
5204ea79 5580 switch (sel) {
706ce142 5581 case CP0_REG17__LLADDR:
7480515f
AM
5582 /*
5583 * LLAddr is read-only (the only exception is bit 0 if LLB is
5584 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5585 * relevant for modern MIPS cores supporting MTHC0, therefore
5586 * treating MTHC0 to LLAddr as NOP.
5587 */
294fc2ea 5588 register_name = "LLAddr";
5204ea79 5589 break;
706ce142 5590 case CP0_REG17__MAAR:
f6d4dd81
YK
5591 CP0_CHECK(ctx->mrp);
5592 gen_helper_mthc0_maar(cpu_env, arg);
294fc2ea 5593 register_name = "MAAR";
f6d4dd81 5594 break;
5204ea79 5595 default:
c98d3d79 5596 goto cp0_unimplemented;
5204ea79
LA
5597 }
5598 break;
feafe82c
YK
5599 case CP0_REGISTER_19:
5600 switch (sel) {
5601 case CP0_REG19__WATCHHI0:
5602 case CP0_REG19__WATCHHI1:
5603 case CP0_REG19__WATCHHI2:
5604 case CP0_REG19__WATCHHI3:
5605 case CP0_REG19__WATCHHI4:
5606 case CP0_REG19__WATCHHI5:
5607 case CP0_REG19__WATCHHI6:
5608 case CP0_REG19__WATCHHI7:
5609 /* upper 32 bits are only available when Config5MI != 0 */
5610 CP0_CHECK(ctx->mi);
5611 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5612 register_name = "WatchHi";
5613 break;
5614 default:
5615 goto cp0_unimplemented;
5616 }
5617 break;
04992c8c 5618 case CP0_REGISTER_28:
5204ea79
LA
5619 switch (sel) {
5620 case 0:
5621 case 2:
5622 case 4:
5623 case 6:
5624 tcg_gen_andi_tl(arg, arg, mask);
5625 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
294fc2ea 5626 register_name = "TagLo";
5204ea79
LA
5627 break;
5628 default:
c98d3d79 5629 goto cp0_unimplemented;
5204ea79
LA
5630 }
5631 break;
5632 default:
c98d3d79 5633 goto cp0_unimplemented;
5204ea79 5634 }
294fc2ea 5635 trace_mips_translate_c0("mthc0", register_name, reg, sel);
bc2eb5ea 5636 return;
5204ea79 5637
c98d3d79 5638cp0_unimplemented:
294fc2ea
AM
5639 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5640 register_name, reg, sel);
5204ea79
LA
5641}
5642
e98c0d17
LA
5643static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5644{
2e211e0a 5645 if (ctx->insn_flags & ISA_MIPS_R6) {
e98c0d17
LA
5646 tcg_gen_movi_tl(arg, 0);
5647 } else {
5648 tcg_gen_movi_tl(arg, ~0);
5649 }
5650}
5651
d75c135e 5652static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5653{
294fc2ea 5654 const char *register_name = "invalid";
873eb012 5655
1f8929d2 5656 if (sel != 0) {
bbd5e4a2 5657 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 5658 }
e189e748 5659
873eb012 5660 switch (reg) {
04992c8c 5661 case CP0_REGISTER_00:
7a387fff 5662 switch (sel) {
1b142da5 5663 case CP0_REG00__INDEX:
7db13fae 5664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
294fc2ea 5665 register_name = "Index";
7a387fff 5666 break;
1b142da5 5667 case CP0_REG00__MVPCONTROL:
f31b035a 5668 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5669 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
294fc2ea 5670 register_name = "MVPControl";
ead9360e 5671 break;
1b142da5 5672 case CP0_REG00__MVPCONF0:
f31b035a 5673 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5674 gen_helper_mfc0_mvpconf0(arg, cpu_env);
294fc2ea 5675 register_name = "MVPConf0";
ead9360e 5676 break;
1b142da5 5677 case CP0_REG00__MVPCONF1:
f31b035a 5678 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5679 gen_helper_mfc0_mvpconf1(arg, cpu_env);
294fc2ea 5680 register_name = "MVPConf1";
ead9360e 5681 break;
1b142da5 5682 case CP0_REG00__VPCONTROL:
01bc435b
YK
5683 CP0_CHECK(ctx->vp);
5684 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
294fc2ea 5685 register_name = "VPControl";
01bc435b 5686 break;
7a387fff 5687 default:
f31b035a 5688 goto cp0_unimplemented;
7a387fff 5689 }
873eb012 5690 break;
04992c8c 5691 case CP0_REGISTER_01:
7a387fff 5692 switch (sel) {
30deb460 5693 case CP0_REG01__RANDOM:
2e211e0a 5694 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
895c2d04 5695 gen_helper_mfc0_random(arg, cpu_env);
294fc2ea 5696 register_name = "Random";
2423f660 5697 break;
30deb460 5698 case CP0_REG01__VPECONTROL:
f31b035a 5699 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5700 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
294fc2ea 5701 register_name = "VPEControl";
ead9360e 5702 break;
30deb460 5703 case CP0_REG01__VPECONF0:
f31b035a 5704 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5705 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
294fc2ea 5706 register_name = "VPEConf0";
ead9360e 5707 break;
30deb460 5708 case CP0_REG01__VPECONF1:
f31b035a 5709 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
294fc2ea 5711 register_name = "VPEConf1";
ead9360e 5712 break;
30deb460 5713 case CP0_REG01__YQMASK:
f31b035a 5714 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5715 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
294fc2ea 5716 register_name = "YQMask";
ead9360e 5717 break;
30deb460 5718 case CP0_REG01__VPESCHEDULE:
f31b035a 5719 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5720 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 5721 register_name = "VPESchedule";
ead9360e 5722 break;
30deb460 5723 case CP0_REG01__VPESCHEFBACK:
f31b035a 5724 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5725 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 5726 register_name = "VPEScheFBack";
ead9360e 5727 break;
30deb460 5728 case CP0_REG01__VPEOPT:
f31b035a 5729 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5730 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
294fc2ea 5731 register_name = "VPEOpt";
ead9360e 5732 break;
7a387fff 5733 default:
f31b035a 5734 goto cp0_unimplemented;
7a387fff 5735 }
873eb012 5736 break;
04992c8c 5737 case CP0_REGISTER_02:
7a387fff 5738 switch (sel) {
6d27d5bd 5739 case CP0_REG02__ENTRYLO0:
284b731a
LA
5740 {
5741 TCGv_i64 tmp = tcg_temp_new_i64();
5742 tcg_gen_ld_i64(tmp, cpu_env,
5743 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5744#if defined(TARGET_MIPS64)
284b731a
LA
5745 if (ctx->rxi) {
5746 /* Move RI/XI fields to bits 31:30 */
5747 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5748 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5749 }
7207c7f9 5750#endif
284b731a
LA
5751 gen_move_low32(arg, tmp);
5752 tcg_temp_free_i64(tmp);
5753 }
294fc2ea 5754 register_name = "EntryLo0";
2423f660 5755 break;
6d27d5bd 5756 case CP0_REG02__TCSTATUS:
f31b035a 5757 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5758 gen_helper_mfc0_tcstatus(arg, cpu_env);
294fc2ea 5759 register_name = "TCStatus";
ead9360e 5760 break;
6d27d5bd 5761 case CP0_REG02__TCBIND:
f31b035a 5762 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5763 gen_helper_mfc0_tcbind(arg, cpu_env);
294fc2ea 5764 register_name = "TCBind";
ead9360e 5765 break;
6d27d5bd 5766 case CP0_REG02__TCRESTART:
f31b035a 5767 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5768 gen_helper_mfc0_tcrestart(arg, cpu_env);
294fc2ea 5769 register_name = "TCRestart";
ead9360e 5770 break;
6d27d5bd 5771 case CP0_REG02__TCHALT:
f31b035a 5772 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5773 gen_helper_mfc0_tchalt(arg, cpu_env);
294fc2ea 5774 register_name = "TCHalt";
ead9360e 5775 break;
6d27d5bd 5776 case CP0_REG02__TCCONTEXT:
f31b035a 5777 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5778 gen_helper_mfc0_tccontext(arg, cpu_env);
294fc2ea 5779 register_name = "TCContext";
ead9360e 5780 break;
6d27d5bd 5781 case CP0_REG02__TCSCHEDULE:
f31b035a 5782 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5783 gen_helper_mfc0_tcschedule(arg, cpu_env);
294fc2ea 5784 register_name = "TCSchedule";
ead9360e 5785 break;
6d27d5bd 5786 case CP0_REG02__TCSCHEFBACK:
f31b035a 5787 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5788 gen_helper_mfc0_tcschefback(arg, cpu_env);
294fc2ea 5789 register_name = "TCScheFBack";
ead9360e 5790 break;
7a387fff 5791 default:
f31b035a 5792 goto cp0_unimplemented;
7a387fff 5793 }
873eb012 5794 break;
04992c8c 5795 case CP0_REGISTER_03:
7a387fff 5796 switch (sel) {
acd37316 5797 case CP0_REG03__ENTRYLO1:
284b731a
LA
5798 {
5799 TCGv_i64 tmp = tcg_temp_new_i64();
5800 tcg_gen_ld_i64(tmp, cpu_env,
5801 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5802#if defined(TARGET_MIPS64)
284b731a
LA
5803 if (ctx->rxi) {
5804 /* Move RI/XI fields to bits 31:30 */
5805 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5806 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5807 }
7207c7f9 5808#endif
284b731a
LA
5809 gen_move_low32(arg, tmp);
5810 tcg_temp_free_i64(tmp);
5811 }
294fc2ea 5812 register_name = "EntryLo1";
2423f660 5813 break;
acd37316 5814 case CP0_REG03__GLOBALNUM:
01bc435b
YK
5815 CP0_CHECK(ctx->vp);
5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
294fc2ea 5817 register_name = "GlobalNumber";
01bc435b 5818 break;
7a387fff 5819 default:
f31b035a 5820 goto cp0_unimplemented;
1579a72e 5821 }
873eb012 5822 break;
04992c8c 5823 case CP0_REGISTER_04:
7a387fff 5824 switch (sel) {
020fe379 5825 case CP0_REG04__CONTEXT:
7db13fae 5826 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5827 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5828 register_name = "Context";
2423f660 5829 break;
020fe379
AM
5830 case CP0_REG04__CONTEXTCONFIG:
5831 /* SmartMIPS ASE */
5832 /* gen_helper_mfc0_contextconfig(arg); */
294fc2ea 5833 register_name = "ContextConfig";
f31b035a 5834 goto cp0_unimplemented;
020fe379 5835 case CP0_REG04__USERLOCAL:
f31b035a 5836 CP0_CHECK(ctx->ulri);
e40df9a8
JH
5837 tcg_gen_ld_tl(arg, cpu_env,
5838 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5839 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5840 register_name = "UserLocal";
d279279e 5841 break;
99029be1
YK
5842 case CP0_REG04__MMID:
5843 CP0_CHECK(ctx->mi);
5844 gen_helper_mtc0_memorymapid(cpu_env, arg);
5845 register_name = "MMID";
5846 break;
7a387fff 5847 default:
f31b035a 5848 goto cp0_unimplemented;
1579a72e 5849 }
873eb012 5850 break;
04992c8c 5851 case CP0_REGISTER_05:
7a387fff 5852 switch (sel) {
a1e76353 5853 case CP0_REG05__PAGEMASK:
7db13fae 5854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
294fc2ea 5855 register_name = "PageMask";
2423f660 5856 break;
a1e76353 5857 case CP0_REG05__PAGEGRAIN:
7a47bae5 5858 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
294fc2ea 5860 register_name = "PageGrain";
2423f660 5861 break;
a1e76353 5862 case CP0_REG05__SEGCTL0:
cec56a73
JH
5863 CP0_CHECK(ctx->sc);
5864 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5865 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5866 register_name = "SegCtl0";
cec56a73 5867 break;
a1e76353 5868 case CP0_REG05__SEGCTL1:
cec56a73
JH
5869 CP0_CHECK(ctx->sc);
5870 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5871 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5872 register_name = "SegCtl1";
cec56a73 5873 break;
a1e76353 5874 case CP0_REG05__SEGCTL2:
cec56a73
JH
5875 CP0_CHECK(ctx->sc);
5876 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5877 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5878 register_name = "SegCtl2";
cec56a73 5879 break;
a1e76353 5880 case CP0_REG05__PWBASE:
5e31fdd5
YK
5881 check_pw(ctx);
5882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 5883 register_name = "PWBase";
5e31fdd5 5884 break;
a1e76353 5885 case CP0_REG05__PWFIELD:
fa75ad14
YK
5886 check_pw(ctx);
5887 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
294fc2ea 5888 register_name = "PWField";
fa75ad14 5889 break;
a1e76353 5890 case CP0_REG05__PWSIZE:
20b28ebc
YK
5891 check_pw(ctx);
5892 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
294fc2ea 5893 register_name = "PWSize";
20b28ebc 5894 break;
7a387fff 5895 default:
f31b035a 5896 goto cp0_unimplemented;
1579a72e 5897 }
873eb012 5898 break;
04992c8c 5899 case CP0_REGISTER_06:
7a387fff 5900 switch (sel) {
9023594b 5901 case CP0_REG06__WIRED:
7db13fae 5902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
294fc2ea 5903 register_name = "Wired";
2423f660 5904 break;
9023594b 5905 case CP0_REG06__SRSCONF0:
7a47bae5 5906 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
294fc2ea 5908 register_name = "SRSConf0";
ead9360e 5909 break;
9023594b 5910 case CP0_REG06__SRSCONF1:
7a47bae5 5911 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5912 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
294fc2ea 5913 register_name = "SRSConf1";
ead9360e 5914 break;
9023594b 5915 case CP0_REG06__SRSCONF2:
7a47bae5 5916 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
294fc2ea 5918 register_name = "SRSConf2";
ead9360e 5919 break;
9023594b 5920 case CP0_REG06__SRSCONF3:
7a47bae5 5921 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5922 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
294fc2ea 5923 register_name = "SRSConf3";
ead9360e 5924 break;
9023594b 5925 case CP0_REG06__SRSCONF4:
7a47bae5 5926 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5927 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
294fc2ea 5928 register_name = "SRSConf4";
ead9360e 5929 break;
9023594b 5930 case CP0_REG06__PWCTL:
103be64c
YK
5931 check_pw(ctx);
5932 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
294fc2ea 5933 register_name = "PWCtl";
103be64c 5934 break;
7a387fff 5935 default:
f31b035a 5936 goto cp0_unimplemented;
1579a72e 5937 }
873eb012 5938 break;
04992c8c 5939 case CP0_REGISTER_07:
7a387fff 5940 switch (sel) {
143a9875 5941 case CP0_REG07__HWRENA:
7a47bae5 5942 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5943 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
294fc2ea 5944 register_name = "HWREna";
2423f660 5945 break;
7a387fff 5946 default:
f31b035a 5947 goto cp0_unimplemented;
1579a72e 5948 }
8c0fdd85 5949 break;
04992c8c 5950 case CP0_REGISTER_08:
7a387fff 5951 switch (sel) {
67d167d2 5952 case CP0_REG08__BADVADDR:
7db13fae 5953 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5954 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5955 register_name = "BadVAddr";
2423f660 5956 break;
67d167d2 5957 case CP0_REG08__BADINSTR:
f31b035a
LA
5958 CP0_CHECK(ctx->bi);
5959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
294fc2ea 5960 register_name = "BadInstr";
aea14095 5961 break;
67d167d2 5962 case CP0_REG08__BADINSTRP:
f31b035a
LA
5963 CP0_CHECK(ctx->bp);
5964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
294fc2ea 5965 register_name = "BadInstrP";
aea14095 5966 break;
67d167d2 5967 case CP0_REG08__BADINSTRX:
25beba9b
SM
5968 CP0_CHECK(ctx->bi);
5969 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5970 tcg_gen_andi_tl(arg, arg, ~0xffff);
294fc2ea 5971 register_name = "BadInstrX";
25beba9b 5972 break;
05aa7e93 5973 default:
f31b035a 5974 goto cp0_unimplemented;
aea14095 5975 }
873eb012 5976 break;
04992c8c 5977 case CP0_REGISTER_09:
7a387fff 5978 switch (sel) {
e5a98a72 5979 case CP0_REG09__COUNT:
2e70f6ef 5980 /* Mark as an IO operation because we read the time. */
eeb3bba8 5981 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5982 gen_io_start();
7d37435b 5983 }
895c2d04 5984 gen_helper_mfc0_count(arg, cpu_env);
7480515f
AM
5985 /*
5986 * Break the TB to be able to take timer interrupts immediately
5987 * after reading count. DISAS_STOP isn't sufficient, we need to
5988 * ensure we break completely out of translated code.
5989 */
eeb3bba8
EC
5990 gen_save_pc(ctx->base.pc_next + 4);
5991 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 5992 register_name = "Count";
2423f660 5993 break;
e5a98a72 5994 case CP0_REG09__SAARI:
5fb2dcd1
YK
5995 CP0_CHECK(ctx->saar);
5996 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
294fc2ea 5997 register_name = "SAARI";
5fb2dcd1 5998 break;
e5a98a72 5999 case CP0_REG09__SAAR:
5fb2dcd1
YK
6000 CP0_CHECK(ctx->saar);
6001 gen_helper_mfc0_saar(arg, cpu_env);
294fc2ea 6002 register_name = "SAAR";
5fb2dcd1 6003 break;
7a387fff 6004 default:
f31b035a 6005 goto cp0_unimplemented;
2423f660 6006 }
873eb012 6007 break;
04992c8c 6008 case CP0_REGISTER_10:
7a387fff 6009 switch (sel) {
860ffef0 6010 case CP0_REG10__ENTRYHI:
7db13fae 6011 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 6012 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6013 register_name = "EntryHi";
2423f660 6014 break;
7a387fff 6015 default:
f31b035a 6016 goto cp0_unimplemented;
1579a72e 6017 }
873eb012 6018 break;
04992c8c 6019 case CP0_REGISTER_11:
7a387fff 6020 switch (sel) {
f5f3834f 6021 case CP0_REG11__COMPARE:
7db13fae 6022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
294fc2ea 6023 register_name = "Compare";
2423f660
TS
6024 break;
6025 /* 6,7 are implementation dependent */
7a387fff 6026 default:
f31b035a 6027 goto cp0_unimplemented;
2423f660 6028 }
873eb012 6029 break;
04992c8c 6030 case CP0_REGISTER_12:
7a387fff 6031 switch (sel) {
2b084867 6032 case CP0_REG12__STATUS:
7db13fae 6033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
294fc2ea 6034 register_name = "Status";
2423f660 6035 break;
2b084867 6036 case CP0_REG12__INTCTL:
7a47bae5 6037 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
294fc2ea 6039 register_name = "IntCtl";
2423f660 6040 break;
2b084867 6041 case CP0_REG12__SRSCTL:
7a47bae5 6042 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
294fc2ea 6044 register_name = "SRSCtl";
2423f660 6045 break;
2b084867 6046 case CP0_REG12__SRSMAP:
7a47bae5 6047 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6048 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
294fc2ea 6049 register_name = "SRSMap";
fd88b6ab 6050 break;
7a387fff 6051 default:
f31b035a 6052 goto cp0_unimplemented;
7a387fff 6053 }
873eb012 6054 break;
04992c8c 6055 case CP0_REGISTER_13:
7a387fff 6056 switch (sel) {
e3c7559d 6057 case CP0_REG13__CAUSE:
7db13fae 6058 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
294fc2ea 6059 register_name = "Cause";
2423f660 6060 break;
7a387fff 6061 default:
f31b035a 6062 goto cp0_unimplemented;
7a387fff 6063 }
873eb012 6064 break;
04992c8c 6065 case CP0_REGISTER_14:
7a387fff 6066 switch (sel) {
35e4b54d 6067 case CP0_REG14__EPC:
7db13fae 6068 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 6069 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6070 register_name = "EPC";
2423f660 6071 break;
7a387fff 6072 default:
f31b035a 6073 goto cp0_unimplemented;
1579a72e 6074 }
873eb012 6075 break;
04992c8c 6076 case CP0_REGISTER_15:
7a387fff 6077 switch (sel) {
4466cd49 6078 case CP0_REG15__PRID:
7db13fae 6079 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
294fc2ea 6080 register_name = "PRid";
2423f660 6081 break;
4466cd49 6082 case CP0_REG15__EBASE:
7a47bae5 6083 check_insn(ctx, ISA_MIPS_R2);
74dbf824
JH
6084 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6085 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6086 register_name = "EBase";
2423f660 6087 break;
4466cd49 6088 case CP0_REG15__CMGCRBASE:
7a47bae5 6089 check_insn(ctx, ISA_MIPS_R2);
c870e3f5
YK
6090 CP0_CHECK(ctx->cmgcr);
6091 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6092 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6093 register_name = "CMGCRBase";
c870e3f5 6094 break;
7a387fff 6095 default:
f31b035a 6096 goto cp0_unimplemented;
7a387fff 6097 }
873eb012 6098 break;
04992c8c 6099 case CP0_REGISTER_16:
873eb012 6100 switch (sel) {
433efb4c 6101 case CP0_REG16__CONFIG:
7db13fae 6102 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
294fc2ea 6103 register_name = "Config";
873eb012 6104 break;
433efb4c 6105 case CP0_REG16__CONFIG1:
7db13fae 6106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
294fc2ea 6107 register_name = "Config1";
873eb012 6108 break;
433efb4c 6109 case CP0_REG16__CONFIG2:
7db13fae 6110 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
294fc2ea 6111 register_name = "Config2";
7a387fff 6112 break;
433efb4c 6113 case CP0_REG16__CONFIG3:
7db13fae 6114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
294fc2ea 6115 register_name = "Config3";
7a387fff 6116 break;
433efb4c 6117 case CP0_REG16__CONFIG4:
b4160af1 6118 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
294fc2ea 6119 register_name = "Config4";
b4160af1 6120 break;
433efb4c 6121 case CP0_REG16__CONFIG5:
b4dd99a3 6122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
294fc2ea 6123 register_name = "Config5";
b4dd99a3 6124 break;
e397ee33 6125 /* 6,7 are implementation dependent */
433efb4c 6126 case CP0_REG16__CONFIG6:
7db13fae 6127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
294fc2ea 6128 register_name = "Config6";
e397ee33 6129 break;
433efb4c 6130 case CP0_REG16__CONFIG7:
7db13fae 6131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
294fc2ea 6132 register_name = "Config7";
e397ee33 6133 break;
873eb012 6134 default:
f31b035a 6135 goto cp0_unimplemented;
873eb012
TS
6136 }
6137 break;
04992c8c 6138 case CP0_REGISTER_17:
7a387fff 6139 switch (sel) {
706ce142 6140 case CP0_REG17__LLADDR:
895c2d04 6141 gen_helper_mfc0_lladdr(arg, cpu_env);
294fc2ea 6142 register_name = "LLAddr";
2423f660 6143 break;
706ce142 6144 case CP0_REG17__MAAR:
f6d4dd81
YK
6145 CP0_CHECK(ctx->mrp);
6146 gen_helper_mfc0_maar(arg, cpu_env);
294fc2ea 6147 register_name = "MAAR";
f6d4dd81 6148 break;
706ce142 6149 case CP0_REG17__MAARI:
f6d4dd81
YK
6150 CP0_CHECK(ctx->mrp);
6151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
294fc2ea 6152 register_name = "MAARI";
f6d4dd81 6153 break;
7a387fff 6154 default:
f31b035a 6155 goto cp0_unimplemented;
7a387fff 6156 }
873eb012 6157 break;
04992c8c 6158 case CP0_REGISTER_18:
7a387fff 6159 switch (sel) {
e8dcfe82
AM
6160 case CP0_REG18__WATCHLO0:
6161 case CP0_REG18__WATCHLO1:
6162 case CP0_REG18__WATCHLO2:
6163 case CP0_REG18__WATCHLO3:
6164 case CP0_REG18__WATCHLO4:
6165 case CP0_REG18__WATCHLO5:
6166 case CP0_REG18__WATCHLO6:
6167 case CP0_REG18__WATCHLO7:
fa192d49 6168 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6169 gen_helper_1e0i(mfc0_watchlo, arg, sel);
294fc2ea 6170 register_name = "WatchLo";
2423f660 6171 break;
7a387fff 6172 default:
f31b035a 6173 goto cp0_unimplemented;
7a387fff 6174 }
873eb012 6175 break;
04992c8c 6176 case CP0_REGISTER_19:
7a387fff 6177 switch (sel) {
be274dc1
AM
6178 case CP0_REG19__WATCHHI0:
6179 case CP0_REG19__WATCHHI1:
6180 case CP0_REG19__WATCHHI2:
6181 case CP0_REG19__WATCHHI3:
6182 case CP0_REG19__WATCHHI4:
6183 case CP0_REG19__WATCHHI5:
6184 case CP0_REG19__WATCHHI6:
6185 case CP0_REG19__WATCHHI7:
fa192d49 6186 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6187 gen_helper_1e0i(mfc0_watchhi, arg, sel);
294fc2ea 6188 register_name = "WatchHi";
2423f660 6189 break;
7a387fff 6190 default:
f31b035a 6191 goto cp0_unimplemented;
7a387fff 6192 }
873eb012 6193 break;
04992c8c 6194 case CP0_REGISTER_20:
7a387fff 6195 switch (sel) {
14f92b0b 6196 case CP0_REG20__XCONTEXT:
d26bc211 6197#if defined(TARGET_MIPS64)
d75c135e 6198 check_insn(ctx, ISA_MIPS3);
7db13fae 6199 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 6200 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6201 register_name = "XContext";
2423f660 6202 break;
703eaf37 6203#endif
7a387fff 6204 default:
f31b035a 6205 goto cp0_unimplemented;
7a387fff 6206 }
8c0fdd85 6207 break;
04992c8c 6208 case CP0_REGISTER_21:
7a387fff 6209 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 6210 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7a387fff
TS
6211 switch (sel) {
6212 case 0:
7db13fae 6213 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
294fc2ea 6214 register_name = "Framemask";
2423f660 6215 break;
7a387fff 6216 default:
f31b035a 6217 goto cp0_unimplemented;
7a387fff 6218 }
8c0fdd85 6219 break;
04992c8c 6220 case CP0_REGISTER_22:
d9bea114 6221 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 6222 register_name = "'Diagnostic"; /* implementation dependent */
2423f660 6223 break;
04992c8c 6224 case CP0_REGISTER_23:
7a387fff 6225 switch (sel) {
4cbf4b6d 6226 case CP0_REG23__DEBUG:
895c2d04 6227 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
294fc2ea 6228 register_name = "Debug";
2423f660 6229 break;
4cbf4b6d
AM
6230 case CP0_REG23__TRACECONTROL:
6231 /* PDtrace support */
6232 /* gen_helper_mfc0_tracecontrol(arg); */
294fc2ea 6233 register_name = "TraceControl";
3570d7f6 6234 goto cp0_unimplemented;
4cbf4b6d
AM
6235 case CP0_REG23__TRACECONTROL2:
6236 /* PDtrace support */
6237 /* gen_helper_mfc0_tracecontrol2(arg); */
294fc2ea 6238 register_name = "TraceControl2";
3570d7f6 6239 goto cp0_unimplemented;
4cbf4b6d
AM
6240 case CP0_REG23__USERTRACEDATA1:
6241 /* PDtrace support */
6242 /* gen_helper_mfc0_usertracedata1(arg);*/
6243 register_name = "UserTraceData1";
3570d7f6 6244 goto cp0_unimplemented;
4cbf4b6d
AM
6245 case CP0_REG23__TRACEIBPC:
6246 /* PDtrace support */
6247 /* gen_helper_mfc0_traceibpc(arg); */
6248 register_name = "TraceIBPC";
6249 goto cp0_unimplemented;
6250 case CP0_REG23__TRACEDBPC:
6251 /* PDtrace support */
6252 /* gen_helper_mfc0_tracedbpc(arg); */
6253 register_name = "TraceDBPC";
3570d7f6 6254 goto cp0_unimplemented;
7a387fff 6255 default:
f31b035a 6256 goto cp0_unimplemented;
7a387fff 6257 }
873eb012 6258 break;
04992c8c 6259 case CP0_REGISTER_24:
7a387fff 6260 switch (sel) {
8d7b4b6e 6261 case CP0_REG24__DEPC:
f0b3f3ae 6262 /* EJTAG support */
7db13fae 6263 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 6264 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6265 register_name = "DEPC";
2423f660 6266 break;
7a387fff 6267 default:
f31b035a 6268 goto cp0_unimplemented;
7a387fff 6269 }
873eb012 6270 break;
04992c8c 6271 case CP0_REGISTER_25:
7a387fff 6272 switch (sel) {
1176b328 6273 case CP0_REG25__PERFCTL0:
7db13fae 6274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
294fc2ea 6275 register_name = "Performance0";
7a387fff 6276 break;
1176b328 6277 case CP0_REG25__PERFCNT0:
7480515f 6278 /* gen_helper_mfc0_performance1(arg); */
294fc2ea 6279 register_name = "Performance1";
3570d7f6 6280 goto cp0_unimplemented;
1176b328 6281 case CP0_REG25__PERFCTL1:
7480515f 6282 /* gen_helper_mfc0_performance2(arg); */
294fc2ea 6283 register_name = "Performance2";
3570d7f6 6284 goto cp0_unimplemented;
1176b328 6285 case CP0_REG25__PERFCNT1:
7480515f 6286 /* gen_helper_mfc0_performance3(arg); */
294fc2ea 6287 register_name = "Performance3";
3570d7f6 6288 goto cp0_unimplemented;
1176b328 6289 case CP0_REG25__PERFCTL2:
7480515f 6290 /* gen_helper_mfc0_performance4(arg); */
294fc2ea 6291 register_name = "Performance4";
3570d7f6 6292 goto cp0_unimplemented;
1176b328 6293 case CP0_REG25__PERFCNT2:
7480515f 6294 /* gen_helper_mfc0_performance5(arg); */
294fc2ea 6295 register_name = "Performance5";
3570d7f6 6296 goto cp0_unimplemented;
1176b328 6297 case CP0_REG25__PERFCTL3:
7480515f 6298 /* gen_helper_mfc0_performance6(arg); */
294fc2ea 6299 register_name = "Performance6";
3570d7f6 6300 goto cp0_unimplemented;
1176b328 6301 case CP0_REG25__PERFCNT3:
7480515f 6302 /* gen_helper_mfc0_performance7(arg); */
294fc2ea 6303 register_name = "Performance7";
3570d7f6 6304 goto cp0_unimplemented;
7a387fff 6305 default:
f31b035a 6306 goto cp0_unimplemented;
7a387fff 6307 }
8c0fdd85 6308 break;
04992c8c 6309 case CP0_REGISTER_26:
0d74a222 6310 switch (sel) {
dbbf08b2 6311 case CP0_REG26__ERRCTL:
0d74a222 6312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
294fc2ea 6313 register_name = "ErrCtl";
0d74a222
LA
6314 break;
6315 default:
6316 goto cp0_unimplemented;
6317 }
da80682b 6318 break;
04992c8c 6319 case CP0_REGISTER_27:
7a387fff 6320 switch (sel) {
5a10873d 6321 case CP0_REG27__CACHERR:
d9bea114 6322 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 6323 register_name = "CacheErr";
2423f660 6324 break;
7a387fff 6325 default:
f31b035a 6326 goto cp0_unimplemented;
7a387fff 6327 }
8c0fdd85 6328 break;
04992c8c 6329 case CP0_REGISTER_28:
873eb012 6330 switch (sel) {
a30e2f21
AM
6331 case CP0_REG28__TAGLO:
6332 case CP0_REG28__TAGLO1:
6333 case CP0_REG28__TAGLO2:
6334 case CP0_REG28__TAGLO3:
284b731a
LA
6335 {
6336 TCGv_i64 tmp = tcg_temp_new_i64();
6337 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6338 gen_move_low32(arg, tmp);
6339 tcg_temp_free_i64(tmp);
6340 }
294fc2ea 6341 register_name = "TagLo";
873eb012 6342 break;
a30e2f21
AM
6343 case CP0_REG28__DATALO:
6344 case CP0_REG28__DATALO1:
6345 case CP0_REG28__DATALO2:
6346 case CP0_REG28__DATALO3:
7db13fae 6347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
294fc2ea 6348 register_name = "DataLo";
873eb012
TS
6349 break;
6350 default:
f31b035a 6351 goto cp0_unimplemented;
873eb012
TS
6352 }
6353 break;
04992c8c 6354 case CP0_REGISTER_29:
7a387fff 6355 switch (sel) {
af4bb6da
AM
6356 case CP0_REG29__TAGHI:
6357 case CP0_REG29__TAGHI1:
6358 case CP0_REG29__TAGHI2:
6359 case CP0_REG29__TAGHI3:
7db13fae 6360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
294fc2ea 6361 register_name = "TagHi";
7a387fff 6362 break;
af4bb6da
AM
6363 case CP0_REG29__DATAHI:
6364 case CP0_REG29__DATAHI1:
6365 case CP0_REG29__DATAHI2:
6366 case CP0_REG29__DATAHI3:
7db13fae 6367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
294fc2ea 6368 register_name = "DataHi";
7a387fff
TS
6369 break;
6370 default:
f31b035a 6371 goto cp0_unimplemented;
7a387fff 6372 }
8c0fdd85 6373 break;
04992c8c 6374 case CP0_REGISTER_30:
7a387fff 6375 switch (sel) {
4bcf121e 6376 case CP0_REG30__ERROREPC:
7db13fae 6377 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 6378 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6379 register_name = "ErrorEPC";
2423f660 6380 break;
7a387fff 6381 default:
f31b035a 6382 goto cp0_unimplemented;
7a387fff 6383 }
873eb012 6384 break;
04992c8c 6385 case CP0_REGISTER_31:
7a387fff 6386 switch (sel) {
14d92efd 6387 case CP0_REG31__DESAVE:
f0b3f3ae 6388 /* EJTAG support */
7db13fae 6389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 6390 register_name = "DESAVE";
2423f660 6391 break;
14d92efd
AM
6392 case CP0_REG31__KSCRATCH1:
6393 case CP0_REG31__KSCRATCH2:
6394 case CP0_REG31__KSCRATCH3:
6395 case CP0_REG31__KSCRATCH4:
6396 case CP0_REG31__KSCRATCH5:
6397 case CP0_REG31__KSCRATCH6:
f31b035a
LA
6398 CP0_CHECK(ctx->kscrexist & (1 << sel));
6399 tcg_gen_ld_tl(arg, cpu_env,
05aa7e93 6400 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
f31b035a 6401 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6402 register_name = "KScratch";
e98c0d17 6403 break;
7a387fff 6404 default:
f31b035a 6405 goto cp0_unimplemented;
7a387fff 6406 }
873eb012
TS
6407 break;
6408 default:
f31b035a 6409 goto cp0_unimplemented;
873eb012 6410 }
294fc2ea 6411 trace_mips_translate_c0("mfc0", register_name, reg, sel);
873eb012
TS
6412 return;
6413
f31b035a 6414cp0_unimplemented:
294fc2ea
AM
6415 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6416 register_name, reg, sel);
f31b035a 6417 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
6418}
6419
d75c135e 6420static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 6421{
294fc2ea 6422 const char *register_name = "invalid";
7a387fff 6423
1f8929d2 6424 if (sel != 0) {
bbd5e4a2 6425 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 6426 }
e189e748 6427
eeb3bba8 6428 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6429 gen_io_start();
bd79255d 6430 }
2e70f6ef 6431
8c0fdd85 6432 switch (reg) {
04992c8c 6433 case CP0_REGISTER_00:
7a387fff 6434 switch (sel) {
1b142da5 6435 case CP0_REG00__INDEX:
895c2d04 6436 gen_helper_mtc0_index(cpu_env, arg);
294fc2ea 6437 register_name = "Index";
7a387fff 6438 break;
1b142da5 6439 case CP0_REG00__MVPCONTROL:
f31b035a 6440 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6441 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
294fc2ea 6442 register_name = "MVPControl";
ead9360e 6443 break;
1b142da5 6444 case CP0_REG00__MVPCONF0:
f31b035a 6445 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6446 /* ignored */
294fc2ea 6447 register_name = "MVPConf0";
ead9360e 6448 break;
1b142da5 6449 case CP0_REG00__MVPCONF1:
f31b035a 6450 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6451 /* ignored */
294fc2ea 6452 register_name = "MVPConf1";
ead9360e 6453 break;
1b142da5 6454 case CP0_REG00__VPCONTROL:
01bc435b
YK
6455 CP0_CHECK(ctx->vp);
6456 /* ignored */
294fc2ea 6457 register_name = "VPControl";
01bc435b 6458 break;
7a387fff 6459 default:
f31b035a 6460 goto cp0_unimplemented;
7a387fff 6461 }
8c0fdd85 6462 break;
04992c8c 6463 case CP0_REGISTER_01:
7a387fff 6464 switch (sel) {
30deb460 6465 case CP0_REG01__RANDOM:
2423f660 6466 /* ignored */
294fc2ea 6467 register_name = "Random";
2423f660 6468 break;
30deb460 6469 case CP0_REG01__VPECONTROL:
f31b035a 6470 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6471 gen_helper_mtc0_vpecontrol(cpu_env, arg);
294fc2ea 6472 register_name = "VPEControl";
ead9360e 6473 break;
30deb460 6474 case CP0_REG01__VPECONF0:
f31b035a 6475 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6476 gen_helper_mtc0_vpeconf0(cpu_env, arg);
294fc2ea 6477 register_name = "VPEConf0";
ead9360e 6478 break;
30deb460 6479 case CP0_REG01__VPECONF1:
f31b035a 6480 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6481 gen_helper_mtc0_vpeconf1(cpu_env, arg);
294fc2ea 6482 register_name = "VPEConf1";
ead9360e 6483 break;
30deb460 6484 case CP0_REG01__YQMASK:
f31b035a 6485 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6486 gen_helper_mtc0_yqmask(cpu_env, arg);
294fc2ea 6487 register_name = "YQMask";
ead9360e 6488 break;
30deb460 6489 case CP0_REG01__VPESCHEDULE:
f31b035a 6490 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
6491 tcg_gen_st_tl(arg, cpu_env,
6492 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 6493 register_name = "VPESchedule";
ead9360e 6494 break;
30deb460 6495 case CP0_REG01__VPESCHEFBACK:
f31b035a 6496 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
6497 tcg_gen_st_tl(arg, cpu_env,
6498 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 6499 register_name = "VPEScheFBack";
ead9360e 6500 break;
30deb460 6501 case CP0_REG01__VPEOPT:
f31b035a 6502 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6503 gen_helper_mtc0_vpeopt(cpu_env, arg);
294fc2ea 6504 register_name = "VPEOpt";
ead9360e 6505 break;
7a387fff 6506 default:
f31b035a 6507 goto cp0_unimplemented;
7a387fff 6508 }
8c0fdd85 6509 break;
04992c8c 6510 case CP0_REGISTER_02:
7a387fff 6511 switch (sel) {
6d27d5bd 6512 case CP0_REG02__ENTRYLO0:
895c2d04 6513 gen_helper_mtc0_entrylo0(cpu_env, arg);
294fc2ea 6514 register_name = "EntryLo0";
2423f660 6515 break;
6d27d5bd 6516 case CP0_REG02__TCSTATUS:
f31b035a 6517 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6518 gen_helper_mtc0_tcstatus(cpu_env, arg);
294fc2ea 6519 register_name = "TCStatus";
ead9360e 6520 break;
6d27d5bd 6521 case CP0_REG02__TCBIND:
f31b035a 6522 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6523 gen_helper_mtc0_tcbind(cpu_env, arg);
294fc2ea 6524 register_name = "TCBind";
ead9360e 6525 break;
6d27d5bd 6526 case CP0_REG02__TCRESTART:
f31b035a 6527 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6528 gen_helper_mtc0_tcrestart(cpu_env, arg);
294fc2ea 6529 register_name = "TCRestart";
ead9360e 6530 break;
6d27d5bd 6531 case CP0_REG02__TCHALT:
f31b035a 6532 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6533 gen_helper_mtc0_tchalt(cpu_env, arg);
294fc2ea 6534 register_name = "TCHalt";
ead9360e 6535 break;
6d27d5bd 6536 case CP0_REG02__TCCONTEXT:
f31b035a 6537 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6538 gen_helper_mtc0_tccontext(cpu_env, arg);
294fc2ea 6539 register_name = "TCContext";
ead9360e 6540 break;
6d27d5bd 6541 case CP0_REG02__TCSCHEDULE:
f31b035a 6542 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6543 gen_helper_mtc0_tcschedule(cpu_env, arg);
294fc2ea 6544 register_name = "TCSchedule";
ead9360e 6545 break;
6d27d5bd 6546 case CP0_REG02__TCSCHEFBACK:
f31b035a 6547 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6548 gen_helper_mtc0_tcschefback(cpu_env, arg);
294fc2ea 6549 register_name = "TCScheFBack";
ead9360e 6550 break;
7a387fff 6551 default:
f31b035a 6552 goto cp0_unimplemented;
7a387fff 6553 }
8c0fdd85 6554 break;
04992c8c 6555 case CP0_REGISTER_03:
7a387fff 6556 switch (sel) {
acd37316 6557 case CP0_REG03__ENTRYLO1:
895c2d04 6558 gen_helper_mtc0_entrylo1(cpu_env, arg);
294fc2ea 6559 register_name = "EntryLo1";
2423f660 6560 break;
acd37316 6561 case CP0_REG03__GLOBALNUM:
01bc435b
YK
6562 CP0_CHECK(ctx->vp);
6563 /* ignored */
294fc2ea 6564 register_name = "GlobalNumber";
01bc435b 6565 break;
7a387fff 6566 default:
f31b035a 6567 goto cp0_unimplemented;
876d4b07 6568 }
8c0fdd85 6569 break;
04992c8c 6570 case CP0_REGISTER_04:
7a387fff 6571 switch (sel) {
020fe379 6572 case CP0_REG04__CONTEXT:
895c2d04 6573 gen_helper_mtc0_context(cpu_env, arg);
294fc2ea 6574 register_name = "Context";
2423f660 6575 break;
020fe379
AM
6576 case CP0_REG04__CONTEXTCONFIG:
6577 /* SmartMIPS ASE */
6578 /* gen_helper_mtc0_contextconfig(arg); */
294fc2ea 6579 register_name = "ContextConfig";
f31b035a 6580 goto cp0_unimplemented;
020fe379 6581 case CP0_REG04__USERLOCAL:
f31b035a
LA
6582 CP0_CHECK(ctx->ulri);
6583 tcg_gen_st_tl(arg, cpu_env,
6584 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 6585 register_name = "UserLocal";
d279279e 6586 break;
99029be1
YK
6587 case CP0_REG04__MMID:
6588 CP0_CHECK(ctx->mi);
6589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6590 register_name = "MMID";
6591 break;
7a387fff 6592 default:
f31b035a 6593 goto cp0_unimplemented;
876d4b07 6594 }
8c0fdd85 6595 break;
04992c8c 6596 case CP0_REGISTER_05:
7a387fff 6597 switch (sel) {
a1e76353 6598 case CP0_REG05__PAGEMASK:
895c2d04 6599 gen_helper_mtc0_pagemask(cpu_env, arg);
294fc2ea 6600 register_name = "PageMask";
2423f660 6601 break;
a1e76353 6602 case CP0_REG05__PAGEGRAIN:
7a47bae5 6603 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6604 gen_helper_mtc0_pagegrain(cpu_env, arg);
294fc2ea 6605 register_name = "PageGrain";
eeb3bba8 6606 ctx->base.is_jmp = DISAS_STOP;
2423f660 6607 break;
a1e76353 6608 case CP0_REG05__SEGCTL0:
cec56a73
JH
6609 CP0_CHECK(ctx->sc);
6610 gen_helper_mtc0_segctl0(cpu_env, arg);
294fc2ea 6611 register_name = "SegCtl0";
cec56a73 6612 break;
a1e76353 6613 case CP0_REG05__SEGCTL1:
cec56a73
JH
6614 CP0_CHECK(ctx->sc);
6615 gen_helper_mtc0_segctl1(cpu_env, arg);
294fc2ea 6616 register_name = "SegCtl1";
cec56a73 6617 break;
a1e76353 6618 case CP0_REG05__SEGCTL2:
cec56a73
JH
6619 CP0_CHECK(ctx->sc);
6620 gen_helper_mtc0_segctl2(cpu_env, arg);
294fc2ea 6621 register_name = "SegCtl2";
cec56a73 6622 break;
a1e76353 6623 case CP0_REG05__PWBASE:
5e31fdd5
YK
6624 check_pw(ctx);
6625 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 6626 register_name = "PWBase";
5e31fdd5 6627 break;
a1e76353 6628 case CP0_REG05__PWFIELD:
fa75ad14
YK
6629 check_pw(ctx);
6630 gen_helper_mtc0_pwfield(cpu_env, arg);
294fc2ea 6631 register_name = "PWField";
fa75ad14 6632 break;
a1e76353 6633 case CP0_REG05__PWSIZE:
20b28ebc
YK
6634 check_pw(ctx);
6635 gen_helper_mtc0_pwsize(cpu_env, arg);
294fc2ea 6636 register_name = "PWSize";
20b28ebc 6637 break;
7a387fff 6638 default:
f31b035a 6639 goto cp0_unimplemented;
876d4b07 6640 }
8c0fdd85 6641 break;
04992c8c 6642 case CP0_REGISTER_06:
7a387fff 6643 switch (sel) {
9023594b 6644 case CP0_REG06__WIRED:
895c2d04 6645 gen_helper_mtc0_wired(cpu_env, arg);
294fc2ea 6646 register_name = "Wired";
2423f660 6647 break;
9023594b 6648 case CP0_REG06__SRSCONF0:
7a47bae5 6649 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6650 gen_helper_mtc0_srsconf0(cpu_env, arg);
294fc2ea 6651 register_name = "SRSConf0";
ead9360e 6652 break;
9023594b 6653 case CP0_REG06__SRSCONF1:
7a47bae5 6654 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6655 gen_helper_mtc0_srsconf1(cpu_env, arg);
294fc2ea 6656 register_name = "SRSConf1";
ead9360e 6657 break;
9023594b 6658 case CP0_REG06__SRSCONF2:
7a47bae5 6659 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6660 gen_helper_mtc0_srsconf2(cpu_env, arg);
294fc2ea 6661 register_name = "SRSConf2";
ead9360e 6662 break;
9023594b 6663 case CP0_REG06__SRSCONF3:
7a47bae5 6664 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6665 gen_helper_mtc0_srsconf3(cpu_env, arg);
294fc2ea 6666 register_name = "SRSConf3";
ead9360e 6667 break;
9023594b 6668 case CP0_REG06__SRSCONF4:
7a47bae5 6669 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6670 gen_helper_mtc0_srsconf4(cpu_env, arg);
294fc2ea 6671 register_name = "SRSConf4";
ead9360e 6672 break;
9023594b 6673 case CP0_REG06__PWCTL:
103be64c
YK
6674 check_pw(ctx);
6675 gen_helper_mtc0_pwctl(cpu_env, arg);
294fc2ea 6676 register_name = "PWCtl";
103be64c 6677 break;
7a387fff 6678 default:
f31b035a 6679 goto cp0_unimplemented;
876d4b07 6680 }
8c0fdd85 6681 break;
04992c8c 6682 case CP0_REGISTER_07:
7a387fff 6683 switch (sel) {
143a9875 6684 case CP0_REG07__HWRENA:
7a47bae5 6685 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6686 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 6687 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6688 register_name = "HWREna";
2423f660 6689 break;
7a387fff 6690 default:
f31b035a 6691 goto cp0_unimplemented;
876d4b07 6692 }
8c0fdd85 6693 break;
04992c8c 6694 case CP0_REGISTER_08:
aea14095 6695 switch (sel) {
67d167d2 6696 case CP0_REG08__BADVADDR:
aea14095 6697 /* ignored */
294fc2ea 6698 register_name = "BadVAddr";
aea14095 6699 break;
67d167d2 6700 case CP0_REG08__BADINSTR:
aea14095 6701 /* ignored */
294fc2ea 6702 register_name = "BadInstr";
aea14095 6703 break;
67d167d2 6704 case CP0_REG08__BADINSTRP:
aea14095 6705 /* ignored */
294fc2ea 6706 register_name = "BadInstrP";
aea14095 6707 break;
67d167d2 6708 case CP0_REG08__BADINSTRX:
25beba9b 6709 /* ignored */
294fc2ea 6710 register_name = "BadInstrX";
25beba9b 6711 break;
aea14095 6712 default:
f31b035a 6713 goto cp0_unimplemented;
aea14095 6714 }
8c0fdd85 6715 break;
04992c8c 6716 case CP0_REGISTER_09:
7a387fff 6717 switch (sel) {
e5a98a72 6718 case CP0_REG09__COUNT:
895c2d04 6719 gen_helper_mtc0_count(cpu_env, arg);
294fc2ea 6720 register_name = "Count";
2423f660 6721 break;
e5a98a72 6722 case CP0_REG09__SAARI:
5fb2dcd1
YK
6723 CP0_CHECK(ctx->saar);
6724 gen_helper_mtc0_saari(cpu_env, arg);
294fc2ea 6725 register_name = "SAARI";
5fb2dcd1 6726 break;
e5a98a72 6727 case CP0_REG09__SAAR:
5fb2dcd1
YK
6728 CP0_CHECK(ctx->saar);
6729 gen_helper_mtc0_saar(cpu_env, arg);
294fc2ea 6730 register_name = "SAAR";
5fb2dcd1 6731 break;
7a387fff 6732 default:
f31b035a 6733 goto cp0_unimplemented;
876d4b07 6734 }
8c0fdd85 6735 break;
04992c8c 6736 case CP0_REGISTER_10:
7a387fff 6737 switch (sel) {
860ffef0 6738 case CP0_REG10__ENTRYHI:
895c2d04 6739 gen_helper_mtc0_entryhi(cpu_env, arg);
294fc2ea 6740 register_name = "EntryHi";
2423f660 6741 break;
7a387fff 6742 default:
f31b035a 6743 goto cp0_unimplemented;
876d4b07 6744 }
8c0fdd85 6745 break;
04992c8c 6746 case CP0_REGISTER_11:
7a387fff 6747 switch (sel) {
f5f3834f 6748 case CP0_REG11__COMPARE:
895c2d04 6749 gen_helper_mtc0_compare(cpu_env, arg);
294fc2ea 6750 register_name = "Compare";
2423f660
TS
6751 break;
6752 /* 6,7 are implementation dependent */
7a387fff 6753 default:
f31b035a 6754 goto cp0_unimplemented;
876d4b07 6755 }
8c0fdd85 6756 break;
04992c8c 6757 case CP0_REGISTER_12:
7a387fff 6758 switch (sel) {
2b084867 6759 case CP0_REG12__STATUS:
867abc7e 6760 save_cpu_state(ctx, 1);
895c2d04 6761 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6762 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6763 gen_save_pc(ctx->base.pc_next + 4);
6764 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 6765 register_name = "Status";
2423f660 6766 break;
2b084867 6767 case CP0_REG12__INTCTL:
7a47bae5 6768 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6769 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6770 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6771 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6772 register_name = "IntCtl";
2423f660 6773 break;
2b084867 6774 case CP0_REG12__SRSCTL:
7a47bae5 6775 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6776 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6777 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6778 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6779 register_name = "SRSCtl";
2423f660 6780 break;
2b084867 6781 case CP0_REG12__SRSMAP:
7a47bae5 6782 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6783 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6784 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6785 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6786 register_name = "SRSMap";
fd88b6ab 6787 break;
7a387fff 6788 default:
f31b035a 6789 goto cp0_unimplemented;
876d4b07 6790 }
8c0fdd85 6791 break;
04992c8c 6792 case CP0_REGISTER_13:
7a387fff 6793 switch (sel) {
e3c7559d 6794 case CP0_REG13__CAUSE:
867abc7e 6795 save_cpu_state(ctx, 1);
895c2d04 6796 gen_helper_mtc0_cause(cpu_env, arg);
7480515f
AM
6797 /*
6798 * Stop translation as we may have triggered an interrupt.
b28425ba 6799 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7480515f
AM
6800 * translated code to check for pending interrupts.
6801 */
eeb3bba8
EC
6802 gen_save_pc(ctx->base.pc_next + 4);
6803 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 6804 register_name = "Cause";
2423f660 6805 break;
7a387fff 6806 default:
f31b035a 6807 goto cp0_unimplemented;
876d4b07 6808 }
8c0fdd85 6809 break;
04992c8c 6810 case CP0_REGISTER_14:
7a387fff 6811 switch (sel) {
35e4b54d 6812 case CP0_REG14__EPC:
d54a299b 6813 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 6814 register_name = "EPC";
2423f660 6815 break;
7a387fff 6816 default:
f31b035a 6817 goto cp0_unimplemented;
876d4b07 6818 }
8c0fdd85 6819 break;
04992c8c 6820 case CP0_REGISTER_15:
7a387fff 6821 switch (sel) {
4466cd49 6822 case CP0_REG15__PRID:
2423f660 6823 /* ignored */
294fc2ea 6824 register_name = "PRid";
2423f660 6825 break;
4466cd49 6826 case CP0_REG15__EBASE:
7a47bae5 6827 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6828 gen_helper_mtc0_ebase(cpu_env, arg);
294fc2ea 6829 register_name = "EBase";
2423f660 6830 break;
7a387fff 6831 default:
f31b035a 6832 goto cp0_unimplemented;
1579a72e 6833 }
8c0fdd85 6834 break;
04992c8c 6835 case CP0_REGISTER_16:
8c0fdd85 6836 switch (sel) {
433efb4c 6837 case CP0_REG16__CONFIG:
895c2d04 6838 gen_helper_mtc0_config0(cpu_env, arg);
294fc2ea 6839 register_name = "Config";
2423f660 6840 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6841 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6842 break;
433efb4c 6843 case CP0_REG16__CONFIG1:
e397ee33 6844 /* ignored, read only */
294fc2ea 6845 register_name = "Config1";
7a387fff 6846 break;
433efb4c 6847 case CP0_REG16__CONFIG2:
895c2d04 6848 gen_helper_mtc0_config2(cpu_env, arg);
294fc2ea 6849 register_name = "Config2";
2423f660 6850 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6851 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6852 break;
433efb4c 6853 case CP0_REG16__CONFIG3:
90f12d73 6854 gen_helper_mtc0_config3(cpu_env, arg);
294fc2ea 6855 register_name = "Config3";
90f12d73 6856 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6857 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6858 break;
433efb4c 6859 case CP0_REG16__CONFIG4:
b4160af1 6860 gen_helper_mtc0_config4(cpu_env, arg);
294fc2ea 6861 register_name = "Config4";
eeb3bba8 6862 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6863 break;
433efb4c 6864 case CP0_REG16__CONFIG5:
b4dd99a3 6865 gen_helper_mtc0_config5(cpu_env, arg);
294fc2ea 6866 register_name = "Config5";
b4dd99a3 6867 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6868 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6869 break;
e397ee33 6870 /* 6,7 are implementation dependent */
433efb4c 6871 case CP0_REG16__CONFIG6:
e397ee33 6872 /* ignored */
294fc2ea 6873 register_name = "Config6";
e397ee33 6874 break;
433efb4c 6875 case CP0_REG16__CONFIG7:
e397ee33 6876 /* ignored */
294fc2ea 6877 register_name = "Config7";
e397ee33 6878 break;
8c0fdd85 6879 default:
294fc2ea 6880 register_name = "Invalid config selector";
f31b035a 6881 goto cp0_unimplemented;
8c0fdd85
TS
6882 }
6883 break;
04992c8c 6884 case CP0_REGISTER_17:
7a387fff 6885 switch (sel) {
706ce142 6886 case CP0_REG17__LLADDR:
895c2d04 6887 gen_helper_mtc0_lladdr(cpu_env, arg);
294fc2ea 6888 register_name = "LLAddr";
2423f660 6889 break;
706ce142 6890 case CP0_REG17__MAAR:
f6d4dd81
YK
6891 CP0_CHECK(ctx->mrp);
6892 gen_helper_mtc0_maar(cpu_env, arg);
294fc2ea 6893 register_name = "MAAR";
f6d4dd81 6894 break;
706ce142 6895 case CP0_REG17__MAARI:
f6d4dd81
YK
6896 CP0_CHECK(ctx->mrp);
6897 gen_helper_mtc0_maari(cpu_env, arg);
294fc2ea 6898 register_name = "MAARI";
f6d4dd81 6899 break;
7a387fff 6900 default:
f31b035a 6901 goto cp0_unimplemented;
7a387fff 6902 }
8c0fdd85 6903 break;
04992c8c 6904 case CP0_REGISTER_18:
7a387fff 6905 switch (sel) {
e8dcfe82
AM
6906 case CP0_REG18__WATCHLO0:
6907 case CP0_REG18__WATCHLO1:
6908 case CP0_REG18__WATCHLO2:
6909 case CP0_REG18__WATCHLO3:
6910 case CP0_REG18__WATCHLO4:
6911 case CP0_REG18__WATCHLO5:
6912 case CP0_REG18__WATCHLO6:
6913 case CP0_REG18__WATCHLO7:
fa192d49 6914 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6915 gen_helper_0e1i(mtc0_watchlo, arg, sel);
294fc2ea 6916 register_name = "WatchLo";
2423f660 6917 break;
7a387fff 6918 default:
f31b035a 6919 goto cp0_unimplemented;
7a387fff 6920 }
8c0fdd85 6921 break;
04992c8c 6922 case CP0_REGISTER_19:
7a387fff 6923 switch (sel) {
be274dc1
AM
6924 case CP0_REG19__WATCHHI0:
6925 case CP0_REG19__WATCHHI1:
6926 case CP0_REG19__WATCHHI2:
6927 case CP0_REG19__WATCHHI3:
6928 case CP0_REG19__WATCHHI4:
6929 case CP0_REG19__WATCHHI5:
6930 case CP0_REG19__WATCHHI6:
6931 case CP0_REG19__WATCHHI7:
fa192d49 6932 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6933 gen_helper_0e1i(mtc0_watchhi, arg, sel);
294fc2ea 6934 register_name = "WatchHi";
2423f660 6935 break;
7a387fff 6936 default:
f31b035a 6937 goto cp0_unimplemented;
7a387fff 6938 }
8c0fdd85 6939 break;
04992c8c 6940 case CP0_REGISTER_20:
7a387fff 6941 switch (sel) {
14f92b0b 6942 case CP0_REG20__XCONTEXT:
d26bc211 6943#if defined(TARGET_MIPS64)
d75c135e 6944 check_insn(ctx, ISA_MIPS3);
895c2d04 6945 gen_helper_mtc0_xcontext(cpu_env, arg);
294fc2ea 6946 register_name = "XContext";
2423f660 6947 break;
703eaf37 6948#endif
7a387fff 6949 default:
f31b035a 6950 goto cp0_unimplemented;
7a387fff 6951 }
8c0fdd85 6952 break;
04992c8c 6953 case CP0_REGISTER_21:
7a387fff 6954 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 6955 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7a387fff
TS
6956 switch (sel) {
6957 case 0:
895c2d04 6958 gen_helper_mtc0_framemask(cpu_env, arg);
294fc2ea 6959 register_name = "Framemask";
2423f660 6960 break;
7a387fff 6961 default:
f31b035a 6962 goto cp0_unimplemented;
7a387fff
TS
6963 }
6964 break;
04992c8c 6965 case CP0_REGISTER_22:
7a387fff 6966 /* ignored */
294fc2ea 6967 register_name = "Diagnostic"; /* implementation dependent */
2423f660 6968 break;
04992c8c 6969 case CP0_REGISTER_23:
7a387fff 6970 switch (sel) {
4cbf4b6d 6971 case CP0_REG23__DEBUG:
895c2d04 6972 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6973 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6974 gen_save_pc(ctx->base.pc_next + 4);
6975 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 6976 register_name = "Debug";
2423f660 6977 break;
4cbf4b6d
AM
6978 case CP0_REG23__TRACECONTROL:
6979 /* PDtrace support */
6980 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
294fc2ea 6981 register_name = "TraceControl";
8487327a 6982 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6983 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6984 goto cp0_unimplemented;
4cbf4b6d
AM
6985 case CP0_REG23__TRACECONTROL2:
6986 /* PDtrace support */
6987 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
294fc2ea 6988 register_name = "TraceControl2";
8487327a 6989 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6990 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6991 goto cp0_unimplemented;
4cbf4b6d 6992 case CP0_REG23__USERTRACEDATA1:
8487327a 6993 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6994 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d
AM
6995 /* PDtrace support */
6996 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
294fc2ea 6997 register_name = "UserTraceData";
8487327a 6998 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6999 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7000 goto cp0_unimplemented;
4cbf4b6d
AM
7001 case CP0_REG23__TRACEIBPC:
7002 /* PDtrace support */
7003 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8487327a 7004 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7005 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d
AM
7006 register_name = "TraceIBPC";
7007 goto cp0_unimplemented;
7008 case CP0_REG23__TRACEDBPC:
7009 /* PDtrace support */
7010 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
7011 /* Stop translation as we may have switched the execution mode */
7012 ctx->base.is_jmp = DISAS_STOP;
7013 register_name = "TraceDBPC";
3570d7f6 7014 goto cp0_unimplemented;
7a387fff 7015 default:
f31b035a 7016 goto cp0_unimplemented;
7a387fff 7017 }
8c0fdd85 7018 break;
04992c8c 7019 case CP0_REGISTER_24:
7a387fff 7020 switch (sel) {
8d7b4b6e 7021 case CP0_REG24__DEPC:
f1aa6320 7022 /* EJTAG support */
d54a299b 7023 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 7024 register_name = "DEPC";
2423f660 7025 break;
7a387fff 7026 default:
f31b035a 7027 goto cp0_unimplemented;
7a387fff 7028 }
8c0fdd85 7029 break;
04992c8c 7030 case CP0_REGISTER_25:
7a387fff 7031 switch (sel) {
1176b328 7032 case CP0_REG25__PERFCTL0:
895c2d04 7033 gen_helper_mtc0_performance0(cpu_env, arg);
294fc2ea 7034 register_name = "Performance0";
2423f660 7035 break;
1176b328 7036 case CP0_REG25__PERFCNT0:
7480515f 7037 /* gen_helper_mtc0_performance1(arg); */
294fc2ea 7038 register_name = "Performance1";
3570d7f6 7039 goto cp0_unimplemented;
1176b328 7040 case CP0_REG25__PERFCTL1:
7480515f 7041 /* gen_helper_mtc0_performance2(arg); */
294fc2ea 7042 register_name = "Performance2";
3570d7f6 7043 goto cp0_unimplemented;
1176b328 7044 case CP0_REG25__PERFCNT1:
7480515f 7045 /* gen_helper_mtc0_performance3(arg); */
294fc2ea 7046 register_name = "Performance3";
3570d7f6 7047 goto cp0_unimplemented;
1176b328 7048 case CP0_REG25__PERFCTL2:
7480515f 7049 /* gen_helper_mtc0_performance4(arg); */
294fc2ea 7050 register_name = "Performance4";
3570d7f6 7051 goto cp0_unimplemented;
1176b328 7052 case CP0_REG25__PERFCNT2:
7480515f 7053 /* gen_helper_mtc0_performance5(arg); */
294fc2ea 7054 register_name = "Performance5";
3570d7f6 7055 goto cp0_unimplemented;
1176b328 7056 case CP0_REG25__PERFCTL3:
7480515f 7057 /* gen_helper_mtc0_performance6(arg); */
294fc2ea 7058 register_name = "Performance6";
3570d7f6 7059 goto cp0_unimplemented;
1176b328 7060 case CP0_REG25__PERFCNT3:
7480515f 7061 /* gen_helper_mtc0_performance7(arg); */
294fc2ea 7062 register_name = "Performance7";
3570d7f6 7063 goto cp0_unimplemented;
7a387fff 7064 default:
f31b035a 7065 goto cp0_unimplemented;
7a387fff 7066 }
8c0fdd85 7067 break;
04992c8c 7068 case CP0_REGISTER_26:
0d74a222 7069 switch (sel) {
dbbf08b2 7070 case CP0_REG26__ERRCTL:
0d74a222 7071 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7072 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 7073 register_name = "ErrCtl";
0d74a222
LA
7074 break;
7075 default:
7076 goto cp0_unimplemented;
7077 }
2423f660 7078 break;
04992c8c 7079 case CP0_REGISTER_27:
7a387fff 7080 switch (sel) {
5a10873d 7081 case CP0_REG27__CACHERR:
2423f660 7082 /* ignored */
294fc2ea 7083 register_name = "CacheErr";
2423f660 7084 break;
7a387fff 7085 default:
f31b035a 7086 goto cp0_unimplemented;
7a387fff 7087 }
8c0fdd85 7088 break;
04992c8c 7089 case CP0_REGISTER_28:
8c0fdd85 7090 switch (sel) {
a30e2f21
AM
7091 case CP0_REG28__TAGLO:
7092 case CP0_REG28__TAGLO1:
7093 case CP0_REG28__TAGLO2:
7094 case CP0_REG28__TAGLO3:
895c2d04 7095 gen_helper_mtc0_taglo(cpu_env, arg);
294fc2ea 7096 register_name = "TagLo";
8c0fdd85 7097 break;
a30e2f21
AM
7098 case CP0_REG28__DATALO:
7099 case CP0_REG28__DATALO1:
7100 case CP0_REG28__DATALO2:
7101 case CP0_REG28__DATALO3:
895c2d04 7102 gen_helper_mtc0_datalo(cpu_env, arg);
294fc2ea 7103 register_name = "DataLo";
7a387fff 7104 break;
8c0fdd85 7105 default:
f31b035a 7106 goto cp0_unimplemented;
8c0fdd85
TS
7107 }
7108 break;
04992c8c 7109 case CP0_REGISTER_29:
7a387fff 7110 switch (sel) {
af4bb6da
AM
7111 case CP0_REG29__TAGHI:
7112 case CP0_REG29__TAGHI1:
7113 case CP0_REG29__TAGHI2:
7114 case CP0_REG29__TAGHI3:
895c2d04 7115 gen_helper_mtc0_taghi(cpu_env, arg);
294fc2ea 7116 register_name = "TagHi";
7a387fff 7117 break;
af4bb6da
AM
7118 case CP0_REG29__DATAHI:
7119 case CP0_REG29__DATAHI1:
7120 case CP0_REG29__DATAHI2:
7121 case CP0_REG29__DATAHI3:
895c2d04 7122 gen_helper_mtc0_datahi(cpu_env, arg);
294fc2ea 7123 register_name = "DataHi";
7a387fff
TS
7124 break;
7125 default:
294fc2ea 7126 register_name = "invalid sel";
f31b035a 7127 goto cp0_unimplemented;
7a387fff 7128 }
8c0fdd85 7129 break;
04992c8c 7130 case CP0_REGISTER_30:
7a387fff 7131 switch (sel) {
4bcf121e 7132 case CP0_REG30__ERROREPC:
d54a299b 7133 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 7134 register_name = "ErrorEPC";
2423f660 7135 break;
7a387fff 7136 default:
f31b035a 7137 goto cp0_unimplemented;
7a387fff 7138 }
8c0fdd85 7139 break;
04992c8c 7140 case CP0_REGISTER_31:
7a387fff 7141 switch (sel) {
14d92efd 7142 case CP0_REG31__DESAVE:
f1aa6320 7143 /* EJTAG support */
7db13fae 7144 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 7145 register_name = "DESAVE";
2423f660 7146 break;
14d92efd
AM
7147 case CP0_REG31__KSCRATCH1:
7148 case CP0_REG31__KSCRATCH2:
7149 case CP0_REG31__KSCRATCH3:
7150 case CP0_REG31__KSCRATCH4:
7151 case CP0_REG31__KSCRATCH5:
7152 case CP0_REG31__KSCRATCH6:
f31b035a
LA
7153 CP0_CHECK(ctx->kscrexist & (1 << sel));
7154 tcg_gen_st_tl(arg, cpu_env,
05aa7e93 7155 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 7156 register_name = "KScratch";
e98c0d17 7157 break;
7a387fff 7158 default:
f31b035a 7159 goto cp0_unimplemented;
7a387fff 7160 }
8c0fdd85
TS
7161 break;
7162 default:
f31b035a 7163 goto cp0_unimplemented;
8c0fdd85 7164 }
294fc2ea 7165 trace_mips_translate_c0("mtc0", register_name, reg, sel);
b44a7fb1 7166
bf20dc07 7167 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7168 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480515f
AM
7169 /*
7170 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7171 * translated code to check for pending interrupts.
7172 */
eeb3bba8
EC
7173 gen_save_pc(ctx->base.pc_next + 4);
7174 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7175 }
8c0fdd85
TS
7176 return;
7177
f31b035a 7178cp0_unimplemented:
294fc2ea
AM
7179 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7180 register_name, reg, sel);
8c0fdd85
TS
7181}
7182
d26bc211 7183#if defined(TARGET_MIPS64)
d75c135e 7184static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8 7185{
294fc2ea 7186 const char *register_name = "invalid";
9c2149c8 7187
1f8929d2 7188 if (sel != 0) {
bbd5e4a2 7189 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 7190 }
e189e748 7191
9c2149c8 7192 switch (reg) {
04992c8c 7193 case CP0_REGISTER_00:
9c2149c8 7194 switch (sel) {
1b142da5 7195 case CP0_REG00__INDEX:
7db13fae 7196 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
294fc2ea 7197 register_name = "Index";
9c2149c8 7198 break;
1b142da5 7199 case CP0_REG00__MVPCONTROL:
f31b035a 7200 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7201 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
294fc2ea 7202 register_name = "MVPControl";
ead9360e 7203 break;
1b142da5 7204 case CP0_REG00__MVPCONF0:
f31b035a 7205 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7206 gen_helper_mfc0_mvpconf0(arg, cpu_env);
294fc2ea 7207 register_name = "MVPConf0";
ead9360e 7208 break;
1b142da5 7209 case CP0_REG00__MVPCONF1:
f31b035a 7210 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7211 gen_helper_mfc0_mvpconf1(arg, cpu_env);
294fc2ea 7212 register_name = "MVPConf1";
ead9360e 7213 break;
1b142da5 7214 case CP0_REG00__VPCONTROL:
01bc435b
YK
7215 CP0_CHECK(ctx->vp);
7216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
294fc2ea 7217 register_name = "VPControl";
01bc435b 7218 break;
9c2149c8 7219 default:
f31b035a 7220 goto cp0_unimplemented;
9c2149c8
TS
7221 }
7222 break;
04992c8c 7223 case CP0_REGISTER_01:
9c2149c8 7224 switch (sel) {
30deb460 7225 case CP0_REG01__RANDOM:
2e211e0a 7226 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
895c2d04 7227 gen_helper_mfc0_random(arg, cpu_env);
294fc2ea 7228 register_name = "Random";
2423f660 7229 break;
30deb460 7230 case CP0_REG01__VPECONTROL:
f31b035a 7231 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
294fc2ea 7233 register_name = "VPEControl";
ead9360e 7234 break;
30deb460 7235 case CP0_REG01__VPECONF0:
f31b035a 7236 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
294fc2ea 7238 register_name = "VPEConf0";
ead9360e 7239 break;
30deb460 7240 case CP0_REG01__VPECONF1:
f31b035a 7241 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7242 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
294fc2ea 7243 register_name = "VPEConf1";
ead9360e 7244 break;
30deb460 7245 case CP0_REG01__YQMASK:
f31b035a 7246 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7247 tcg_gen_ld_tl(arg, cpu_env,
7248 offsetof(CPUMIPSState, CP0_YQMask));
294fc2ea 7249 register_name = "YQMask";
ead9360e 7250 break;
30deb460 7251 case CP0_REG01__VPESCHEDULE:
f31b035a 7252 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7253 tcg_gen_ld_tl(arg, cpu_env,
7254 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 7255 register_name = "VPESchedule";
ead9360e 7256 break;
30deb460 7257 case CP0_REG01__VPESCHEFBACK:
f31b035a 7258 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7259 tcg_gen_ld_tl(arg, cpu_env,
7260 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 7261 register_name = "VPEScheFBack";
ead9360e 7262 break;
30deb460 7263 case CP0_REG01__VPEOPT:
f31b035a 7264 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
294fc2ea 7266 register_name = "VPEOpt";
ead9360e 7267 break;
9c2149c8 7268 default:
f31b035a 7269 goto cp0_unimplemented;
9c2149c8
TS
7270 }
7271 break;
04992c8c 7272 case CP0_REGISTER_02:
9c2149c8 7273 switch (sel) {
6d27d5bd 7274 case CP0_REG02__ENTRYLO0:
05aa7e93
AM
7275 tcg_gen_ld_tl(arg, cpu_env,
7276 offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 7277 register_name = "EntryLo0";
2423f660 7278 break;
6d27d5bd 7279 case CP0_REG02__TCSTATUS:
f31b035a 7280 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7281 gen_helper_mfc0_tcstatus(arg, cpu_env);
294fc2ea 7282 register_name = "TCStatus";
ead9360e 7283 break;
6d27d5bd 7284 case CP0_REG02__TCBIND:
f31b035a 7285 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7286 gen_helper_mfc0_tcbind(arg, cpu_env);
294fc2ea 7287 register_name = "TCBind";
ead9360e 7288 break;
6d27d5bd 7289 case CP0_REG02__TCRESTART:
f31b035a 7290 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7291 gen_helper_dmfc0_tcrestart(arg, cpu_env);
294fc2ea 7292 register_name = "TCRestart";
ead9360e 7293 break;
6d27d5bd 7294 case CP0_REG02__TCHALT:
f31b035a 7295 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7296 gen_helper_dmfc0_tchalt(arg, cpu_env);
294fc2ea 7297 register_name = "TCHalt";
ead9360e 7298 break;
6d27d5bd 7299 case CP0_REG02__TCCONTEXT:
f31b035a 7300 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7301 gen_helper_dmfc0_tccontext(arg, cpu_env);
294fc2ea 7302 register_name = "TCContext";
ead9360e 7303 break;
6d27d5bd 7304 case CP0_REG02__TCSCHEDULE:
f31b035a 7305 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7306 gen_helper_dmfc0_tcschedule(arg, cpu_env);
294fc2ea 7307 register_name = "TCSchedule";
ead9360e 7308 break;
6d27d5bd 7309 case CP0_REG02__TCSCHEFBACK:
f31b035a 7310 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7311 gen_helper_dmfc0_tcschefback(arg, cpu_env);
294fc2ea 7312 register_name = "TCScheFBack";
ead9360e 7313 break;
9c2149c8 7314 default:
f31b035a 7315 goto cp0_unimplemented;
9c2149c8
TS
7316 }
7317 break;
04992c8c 7318 case CP0_REGISTER_03:
9c2149c8 7319 switch (sel) {
acd37316 7320 case CP0_REG03__ENTRYLO1:
7db13fae 7321 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 7322 register_name = "EntryLo1";
2423f660 7323 break;
acd37316 7324 case CP0_REG03__GLOBALNUM:
01bc435b
YK
7325 CP0_CHECK(ctx->vp);
7326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
294fc2ea 7327 register_name = "GlobalNumber";
01bc435b 7328 break;
9c2149c8 7329 default:
f31b035a 7330 goto cp0_unimplemented;
1579a72e 7331 }
9c2149c8 7332 break;
04992c8c 7333 case CP0_REGISTER_04:
9c2149c8 7334 switch (sel) {
020fe379 7335 case CP0_REG04__CONTEXT:
7db13fae 7336 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
294fc2ea 7337 register_name = "Context";
2423f660 7338 break;
020fe379
AM
7339 case CP0_REG04__CONTEXTCONFIG:
7340 /* SmartMIPS ASE */
7341 /* gen_helper_dmfc0_contextconfig(arg); */
294fc2ea 7342 register_name = "ContextConfig";
f31b035a 7343 goto cp0_unimplemented;
020fe379 7344 case CP0_REG04__USERLOCAL:
f31b035a
LA
7345 CP0_CHECK(ctx->ulri);
7346 tcg_gen_ld_tl(arg, cpu_env,
7347 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 7348 register_name = "UserLocal";
d279279e 7349 break;
99029be1
YK
7350 case CP0_REG04__MMID:
7351 CP0_CHECK(ctx->mi);
7352 gen_helper_mtc0_memorymapid(cpu_env, arg);
7353 register_name = "MMID";
7354 break;
9c2149c8 7355 default:
f31b035a 7356 goto cp0_unimplemented;
876d4b07 7357 }
9c2149c8 7358 break;
04992c8c 7359 case CP0_REGISTER_05:
9c2149c8 7360 switch (sel) {
a1e76353 7361 case CP0_REG05__PAGEMASK:
7db13fae 7362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
294fc2ea 7363 register_name = "PageMask";
2423f660 7364 break;
a1e76353 7365 case CP0_REG05__PAGEGRAIN:
7a47bae5 7366 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
294fc2ea 7368 register_name = "PageGrain";
2423f660 7369 break;
a1e76353 7370 case CP0_REG05__SEGCTL0:
cec56a73
JH
7371 CP0_CHECK(ctx->sc);
7372 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
294fc2ea 7373 register_name = "SegCtl0";
cec56a73 7374 break;
a1e76353 7375 case CP0_REG05__SEGCTL1:
cec56a73
JH
7376 CP0_CHECK(ctx->sc);
7377 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
294fc2ea 7378 register_name = "SegCtl1";
cec56a73 7379 break;
a1e76353 7380 case CP0_REG05__SEGCTL2:
cec56a73
JH
7381 CP0_CHECK(ctx->sc);
7382 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
294fc2ea 7383 register_name = "SegCtl2";
cec56a73 7384 break;
a1e76353 7385 case CP0_REG05__PWBASE:
5e31fdd5
YK
7386 check_pw(ctx);
7387 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 7388 register_name = "PWBase";
5e31fdd5 7389 break;
a1e76353 7390 case CP0_REG05__PWFIELD:
fa75ad14
YK
7391 check_pw(ctx);
7392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
294fc2ea 7393 register_name = "PWField";
fa75ad14 7394 break;
a1e76353 7395 case CP0_REG05__PWSIZE:
20b28ebc
YK
7396 check_pw(ctx);
7397 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
294fc2ea 7398 register_name = "PWSize";
20b28ebc 7399 break;
9c2149c8 7400 default:
f31b035a 7401 goto cp0_unimplemented;
876d4b07 7402 }
9c2149c8 7403 break;
04992c8c 7404 case CP0_REGISTER_06:
9c2149c8 7405 switch (sel) {
9023594b 7406 case CP0_REG06__WIRED:
7db13fae 7407 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
294fc2ea 7408 register_name = "Wired";
2423f660 7409 break;
9023594b 7410 case CP0_REG06__SRSCONF0:
7a47bae5 7411 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
294fc2ea 7413 register_name = "SRSConf0";
ead9360e 7414 break;
9023594b 7415 case CP0_REG06__SRSCONF1:
7a47bae5 7416 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
294fc2ea 7418 register_name = "SRSConf1";
ead9360e 7419 break;
9023594b 7420 case CP0_REG06__SRSCONF2:
7a47bae5 7421 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
294fc2ea 7423 register_name = "SRSConf2";
ead9360e 7424 break;
9023594b 7425 case CP0_REG06__SRSCONF3:
7a47bae5 7426 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
294fc2ea 7428 register_name = "SRSConf3";
ead9360e 7429 break;
9023594b 7430 case CP0_REG06__SRSCONF4:
7a47bae5 7431 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
294fc2ea 7433 register_name = "SRSConf4";
ead9360e 7434 break;
9023594b 7435 case CP0_REG06__PWCTL:
103be64c
YK
7436 check_pw(ctx);
7437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
294fc2ea 7438 register_name = "PWCtl";
103be64c 7439 break;
9c2149c8 7440 default:
f31b035a 7441 goto cp0_unimplemented;
876d4b07 7442 }
9c2149c8 7443 break;
04992c8c 7444 case CP0_REGISTER_07:
9c2149c8 7445 switch (sel) {
143a9875 7446 case CP0_REG07__HWRENA:
7a47bae5 7447 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
294fc2ea 7449 register_name = "HWREna";
2423f660 7450 break;
9c2149c8 7451 default:
f31b035a 7452 goto cp0_unimplemented;
876d4b07 7453 }
9c2149c8 7454 break;
04992c8c 7455 case CP0_REGISTER_08:
9c2149c8 7456 switch (sel) {
67d167d2 7457 case CP0_REG08__BADVADDR:
7db13fae 7458 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
294fc2ea 7459 register_name = "BadVAddr";
2423f660 7460 break;
67d167d2 7461 case CP0_REG08__BADINSTR:
f31b035a
LA
7462 CP0_CHECK(ctx->bi);
7463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
294fc2ea 7464 register_name = "BadInstr";
aea14095 7465 break;
67d167d2 7466 case CP0_REG08__BADINSTRP:
f31b035a
LA
7467 CP0_CHECK(ctx->bp);
7468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
294fc2ea 7469 register_name = "BadInstrP";
aea14095 7470 break;
67d167d2 7471 case CP0_REG08__BADINSTRX:
25beba9b
SM
7472 CP0_CHECK(ctx->bi);
7473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7474 tcg_gen_andi_tl(arg, arg, ~0xffff);
294fc2ea 7475 register_name = "BadInstrX";
25beba9b 7476 break;
9c2149c8 7477 default:
f31b035a 7478 goto cp0_unimplemented;
876d4b07 7479 }
9c2149c8 7480 break;
04992c8c 7481 case CP0_REGISTER_09:
9c2149c8 7482 switch (sel) {
e5a98a72 7483 case CP0_REG09__COUNT:
2e70f6ef 7484 /* Mark as an IO operation because we read the time. */
eeb3bba8 7485 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7486 gen_io_start();
bd79255d 7487 }
895c2d04 7488 gen_helper_mfc0_count(arg, cpu_env);
7480515f
AM
7489 /*
7490 * Break the TB to be able to take timer interrupts immediately
7491 * after reading count. DISAS_STOP isn't sufficient, we need to
7492 * ensure we break completely out of translated code.
7493 */
eeb3bba8
EC
7494 gen_save_pc(ctx->base.pc_next + 4);
7495 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 7496 register_name = "Count";
2423f660 7497 break;
e5a98a72 7498 case CP0_REG09__SAARI:
5fb2dcd1
YK
7499 CP0_CHECK(ctx->saar);
7500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
294fc2ea 7501 register_name = "SAARI";
5fb2dcd1 7502 break;
e5a98a72 7503 case CP0_REG09__SAAR:
5fb2dcd1
YK
7504 CP0_CHECK(ctx->saar);
7505 gen_helper_dmfc0_saar(arg, cpu_env);
294fc2ea 7506 register_name = "SAAR";
5fb2dcd1 7507 break;
9c2149c8 7508 default:
f31b035a 7509 goto cp0_unimplemented;
876d4b07 7510 }
9c2149c8 7511 break;
04992c8c 7512 case CP0_REGISTER_10:
9c2149c8 7513 switch (sel) {
860ffef0 7514 case CP0_REG10__ENTRYHI:
7db13fae 7515 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
294fc2ea 7516 register_name = "EntryHi";
2423f660 7517 break;
9c2149c8 7518 default:
f31b035a 7519 goto cp0_unimplemented;
876d4b07 7520 }
9c2149c8 7521 break;
04992c8c 7522 case CP0_REGISTER_11:
9c2149c8 7523 switch (sel) {
f5f3834f 7524 case CP0_REG11__COMPARE:
7db13fae 7525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
294fc2ea 7526 register_name = "Compare";
2423f660 7527 break;
876d4b07 7528 /* 6,7 are implementation dependent */
9c2149c8 7529 default:
f31b035a 7530 goto cp0_unimplemented;
876d4b07 7531 }
9c2149c8 7532 break;
04992c8c 7533 case CP0_REGISTER_12:
9c2149c8 7534 switch (sel) {
2b084867 7535 case CP0_REG12__STATUS:
7db13fae 7536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
294fc2ea 7537 register_name = "Status";
2423f660 7538 break;
2b084867 7539 case CP0_REG12__INTCTL:
7a47bae5 7540 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
294fc2ea 7542 register_name = "IntCtl";
2423f660 7543 break;
2b084867 7544 case CP0_REG12__SRSCTL:
7a47bae5 7545 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
294fc2ea 7547 register_name = "SRSCtl";
2423f660 7548 break;
2b084867 7549 case CP0_REG12__SRSMAP:
7a47bae5 7550 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
294fc2ea 7552 register_name = "SRSMap";
2423f660 7553 break;
9c2149c8 7554 default:
f31b035a 7555 goto cp0_unimplemented;
876d4b07 7556 }
9c2149c8 7557 break;
04992c8c 7558 case CP0_REGISTER_13:
9c2149c8 7559 switch (sel) {
e3c7559d 7560 case CP0_REG13__CAUSE:
7db13fae 7561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
294fc2ea 7562 register_name = "Cause";
2423f660 7563 break;
9c2149c8 7564 default:
f31b035a 7565 goto cp0_unimplemented;
876d4b07 7566 }
9c2149c8 7567 break;
04992c8c 7568 case CP0_REGISTER_14:
9c2149c8 7569 switch (sel) {
35e4b54d 7570 case CP0_REG14__EPC:
7db13fae 7571 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 7572 register_name = "EPC";
2423f660 7573 break;
9c2149c8 7574 default:
f31b035a 7575 goto cp0_unimplemented;
876d4b07 7576 }
9c2149c8 7577 break;
04992c8c 7578 case CP0_REGISTER_15:
9c2149c8 7579 switch (sel) {
4466cd49 7580 case CP0_REG15__PRID:
7db13fae 7581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
294fc2ea 7582 register_name = "PRid";
2423f660 7583 break;
4466cd49 7584 case CP0_REG15__EBASE:
7a47bae5 7585 check_insn(ctx, ISA_MIPS_R2);
74dbf824 7586 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
294fc2ea 7587 register_name = "EBase";
2423f660 7588 break;
4466cd49 7589 case CP0_REG15__CMGCRBASE:
7a47bae5 7590 check_insn(ctx, ISA_MIPS_R2);
c870e3f5
YK
7591 CP0_CHECK(ctx->cmgcr);
7592 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
294fc2ea 7593 register_name = "CMGCRBase";
c870e3f5 7594 break;
9c2149c8 7595 default:
f31b035a 7596 goto cp0_unimplemented;
876d4b07 7597 }
9c2149c8 7598 break;
04992c8c 7599 case CP0_REGISTER_16:
9c2149c8 7600 switch (sel) {
433efb4c 7601 case CP0_REG16__CONFIG:
7db13fae 7602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
294fc2ea 7603 register_name = "Config";
9c2149c8 7604 break;
433efb4c 7605 case CP0_REG16__CONFIG1:
7db13fae 7606 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
294fc2ea 7607 register_name = "Config1";
9c2149c8 7608 break;
433efb4c 7609 case CP0_REG16__CONFIG2:
7db13fae 7610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
294fc2ea 7611 register_name = "Config2";
9c2149c8 7612 break;
433efb4c 7613 case CP0_REG16__CONFIG3:
7db13fae 7614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
294fc2ea 7615 register_name = "Config3";
9c2149c8 7616 break;
433efb4c 7617 case CP0_REG16__CONFIG4:
faf1f68b 7618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
294fc2ea 7619 register_name = "Config4";
faf1f68b 7620 break;
433efb4c 7621 case CP0_REG16__CONFIG5:
faf1f68b 7622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
294fc2ea 7623 register_name = "Config5";
faf1f68b 7624 break;
05aa7e93 7625 /* 6,7 are implementation dependent */
433efb4c 7626 case CP0_REG16__CONFIG6:
7db13fae 7627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
294fc2ea 7628 register_name = "Config6";
f0b3f3ae 7629 break;
433efb4c 7630 case CP0_REG16__CONFIG7:
7db13fae 7631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
294fc2ea 7632 register_name = "Config7";
f0b3f3ae 7633 break;
9c2149c8 7634 default:
f31b035a 7635 goto cp0_unimplemented;
9c2149c8
TS
7636 }
7637 break;
04992c8c 7638 case CP0_REGISTER_17:
9c2149c8 7639 switch (sel) {
706ce142 7640 case CP0_REG17__LLADDR:
895c2d04 7641 gen_helper_dmfc0_lladdr(arg, cpu_env);
294fc2ea 7642 register_name = "LLAddr";
2423f660 7643 break;
706ce142 7644 case CP0_REG17__MAAR:
f6d4dd81
YK
7645 CP0_CHECK(ctx->mrp);
7646 gen_helper_dmfc0_maar(arg, cpu_env);
294fc2ea 7647 register_name = "MAAR";
f6d4dd81 7648 break;
706ce142 7649 case CP0_REG17__MAARI:
f6d4dd81
YK
7650 CP0_CHECK(ctx->mrp);
7651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
294fc2ea 7652 register_name = "MAARI";
f6d4dd81 7653 break;
9c2149c8 7654 default:
f31b035a 7655 goto cp0_unimplemented;
9c2149c8
TS
7656 }
7657 break;
04992c8c 7658 case CP0_REGISTER_18:
9c2149c8 7659 switch (sel) {
e8dcfe82
AM
7660 case CP0_REG18__WATCHLO0:
7661 case CP0_REG18__WATCHLO1:
7662 case CP0_REG18__WATCHLO2:
7663 case CP0_REG18__WATCHLO3:
7664 case CP0_REG18__WATCHLO4:
7665 case CP0_REG18__WATCHLO5:
7666 case CP0_REG18__WATCHLO6:
7667 case CP0_REG18__WATCHLO7:
fa192d49 7668 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7669 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
294fc2ea 7670 register_name = "WatchLo";
2423f660 7671 break;
9c2149c8 7672 default:
f31b035a 7673 goto cp0_unimplemented;
9c2149c8
TS
7674 }
7675 break;
04992c8c 7676 case CP0_REGISTER_19:
9c2149c8 7677 switch (sel) {
be274dc1
AM
7678 case CP0_REG19__WATCHHI0:
7679 case CP0_REG19__WATCHHI1:
7680 case CP0_REG19__WATCHHI2:
7681 case CP0_REG19__WATCHHI3:
7682 case CP0_REG19__WATCHHI4:
7683 case CP0_REG19__WATCHHI5:
7684 case CP0_REG19__WATCHHI6:
7685 case CP0_REG19__WATCHHI7:
fa192d49 7686 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
feafe82c 7687 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
294fc2ea 7688 register_name = "WatchHi";
2423f660 7689 break;
9c2149c8 7690 default:
f31b035a 7691 goto cp0_unimplemented;
9c2149c8
TS
7692 }
7693 break;
04992c8c 7694 case CP0_REGISTER_20:
9c2149c8 7695 switch (sel) {
14f92b0b 7696 case CP0_REG20__XCONTEXT:
d75c135e 7697 check_insn(ctx, ISA_MIPS3);
7db13fae 7698 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
294fc2ea 7699 register_name = "XContext";
2423f660 7700 break;
9c2149c8 7701 default:
f31b035a 7702 goto cp0_unimplemented;
9c2149c8
TS
7703 }
7704 break;
04992c8c 7705 case CP0_REGISTER_21:
05aa7e93 7706 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 7707 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
9c2149c8
TS
7708 switch (sel) {
7709 case 0:
7db13fae 7710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
294fc2ea 7711 register_name = "Framemask";
2423f660 7712 break;
9c2149c8 7713 default:
f31b035a 7714 goto cp0_unimplemented;
9c2149c8
TS
7715 }
7716 break;
04992c8c 7717 case CP0_REGISTER_22:
d9bea114 7718 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 7719 register_name = "'Diagnostic"; /* implementation dependent */
2423f660 7720 break;
04992c8c 7721 case CP0_REGISTER_23:
9c2149c8 7722 switch (sel) {
4cbf4b6d 7723 case CP0_REG23__DEBUG:
895c2d04 7724 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
294fc2ea 7725 register_name = "Debug";
2423f660 7726 break;
4cbf4b6d
AM
7727 case CP0_REG23__TRACECONTROL:
7728 /* PDtrace support */
7729 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
294fc2ea 7730 register_name = "TraceControl";
3570d7f6 7731 goto cp0_unimplemented;
4cbf4b6d
AM
7732 case CP0_REG23__TRACECONTROL2:
7733 /* PDtrace support */
7734 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
294fc2ea 7735 register_name = "TraceControl2";
3570d7f6 7736 goto cp0_unimplemented;
4cbf4b6d
AM
7737 case CP0_REG23__USERTRACEDATA1:
7738 /* PDtrace support */
7739 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7740 register_name = "UserTraceData1";
3570d7f6 7741 goto cp0_unimplemented;
4cbf4b6d
AM
7742 case CP0_REG23__TRACEIBPC:
7743 /* PDtrace support */
7744 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
7745 register_name = "TraceIBPC";
7746 goto cp0_unimplemented;
7747 case CP0_REG23__TRACEDBPC:
7748 /* PDtrace support */
7749 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
7750 register_name = "TraceDBPC";
3570d7f6 7751 goto cp0_unimplemented;
9c2149c8 7752 default:
f31b035a 7753 goto cp0_unimplemented;
9c2149c8
TS
7754 }
7755 break;
04992c8c 7756 case CP0_REGISTER_24:
9c2149c8 7757 switch (sel) {
8d7b4b6e 7758 case CP0_REG24__DEPC:
f0b3f3ae 7759 /* EJTAG support */
7db13fae 7760 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 7761 register_name = "DEPC";
2423f660 7762 break;
9c2149c8 7763 default:
f31b035a 7764 goto cp0_unimplemented;
9c2149c8
TS
7765 }
7766 break;
04992c8c 7767 case CP0_REGISTER_25:
9c2149c8 7768 switch (sel) {
1176b328 7769 case CP0_REG25__PERFCTL0:
7db13fae 7770 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
294fc2ea 7771 register_name = "Performance0";
9c2149c8 7772 break;
1176b328 7773 case CP0_REG25__PERFCNT0:
7480515f 7774 /* gen_helper_dmfc0_performance1(arg); */
294fc2ea 7775 register_name = "Performance1";
3570d7f6 7776 goto cp0_unimplemented;
1176b328 7777 case CP0_REG25__PERFCTL1:
7480515f 7778 /* gen_helper_dmfc0_performance2(arg); */
294fc2ea 7779 register_name = "Performance2";
3570d7f6 7780 goto cp0_unimplemented;
1176b328 7781 case CP0_REG25__PERFCNT1:
7480515f 7782 /* gen_helper_dmfc0_performance3(arg); */
294fc2ea 7783 register_name = "Performance3";
3570d7f6 7784 goto cp0_unimplemented;
1176b328 7785 case CP0_REG25__PERFCTL2:
7480515f 7786 /* gen_helper_dmfc0_performance4(arg); */
294fc2ea 7787 register_name = "Performance4";
3570d7f6 7788 goto cp0_unimplemented;
1176b328 7789 case CP0_REG25__PERFCNT2:
7480515f 7790 /* gen_helper_dmfc0_performance5(arg); */
294fc2ea 7791 register_name = "Performance5";
3570d7f6 7792 goto cp0_unimplemented;
1176b328 7793 case CP0_REG25__PERFCTL3:
7480515f 7794 /* gen_helper_dmfc0_performance6(arg); */
294fc2ea 7795 register_name = "Performance6";
3570d7f6 7796 goto cp0_unimplemented;
1176b328 7797 case CP0_REG25__PERFCNT3:
7480515f 7798 /* gen_helper_dmfc0_performance7(arg); */
294fc2ea 7799 register_name = "Performance7";
3570d7f6 7800 goto cp0_unimplemented;
9c2149c8 7801 default:
f31b035a 7802 goto cp0_unimplemented;
9c2149c8
TS
7803 }
7804 break;
04992c8c 7805 case CP0_REGISTER_26:
0d74a222 7806 switch (sel) {
dbbf08b2 7807 case CP0_REG26__ERRCTL:
0d74a222 7808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
294fc2ea 7809 register_name = "ErrCtl";
0d74a222
LA
7810 break;
7811 default:
7812 goto cp0_unimplemented;
7813 }
da80682b 7814 break;
04992c8c 7815 case CP0_REGISTER_27:
9c2149c8
TS
7816 switch (sel) {
7817 /* ignored */
5a10873d 7818 case CP0_REG27__CACHERR:
d9bea114 7819 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 7820 register_name = "CacheErr";
2423f660 7821 break;
9c2149c8 7822 default:
f31b035a 7823 goto cp0_unimplemented;
9c2149c8
TS
7824 }
7825 break;
04992c8c 7826 case CP0_REGISTER_28:
9c2149c8 7827 switch (sel) {
a30e2f21
AM
7828 case CP0_REG28__TAGLO:
7829 case CP0_REG28__TAGLO1:
7830 case CP0_REG28__TAGLO2:
7831 case CP0_REG28__TAGLO3:
7db13fae 7832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
294fc2ea 7833 register_name = "TagLo";
9c2149c8 7834 break;
a30e2f21
AM
7835 case CP0_REG28__DATALO:
7836 case CP0_REG28__DATALO1:
7837 case CP0_REG28__DATALO2:
7838 case CP0_REG28__DATALO3:
7db13fae 7839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
294fc2ea 7840 register_name = "DataLo";
9c2149c8
TS
7841 break;
7842 default:
f31b035a 7843 goto cp0_unimplemented;
9c2149c8
TS
7844 }
7845 break;
04992c8c 7846 case CP0_REGISTER_29:
9c2149c8 7847 switch (sel) {
af4bb6da
AM
7848 case CP0_REG29__TAGHI:
7849 case CP0_REG29__TAGHI1:
7850 case CP0_REG29__TAGHI2:
7851 case CP0_REG29__TAGHI3:
7db13fae 7852 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
294fc2ea 7853 register_name = "TagHi";
9c2149c8 7854 break;
af4bb6da
AM
7855 case CP0_REG29__DATAHI:
7856 case CP0_REG29__DATAHI1:
7857 case CP0_REG29__DATAHI2:
7858 case CP0_REG29__DATAHI3:
7db13fae 7859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
294fc2ea 7860 register_name = "DataHi";
9c2149c8
TS
7861 break;
7862 default:
f31b035a 7863 goto cp0_unimplemented;
9c2149c8
TS
7864 }
7865 break;
04992c8c 7866 case CP0_REGISTER_30:
9c2149c8 7867 switch (sel) {
4bcf121e 7868 case CP0_REG30__ERROREPC:
7db13fae 7869 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 7870 register_name = "ErrorEPC";
2423f660 7871 break;
9c2149c8 7872 default:
f31b035a 7873 goto cp0_unimplemented;
9c2149c8
TS
7874 }
7875 break;
04992c8c 7876 case CP0_REGISTER_31:
9c2149c8 7877 switch (sel) {
14d92efd 7878 case CP0_REG31__DESAVE:
f0b3f3ae 7879 /* EJTAG support */
7db13fae 7880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 7881 register_name = "DESAVE";
2423f660 7882 break;
14d92efd
AM
7883 case CP0_REG31__KSCRATCH1:
7884 case CP0_REG31__KSCRATCH2:
7885 case CP0_REG31__KSCRATCH3:
7886 case CP0_REG31__KSCRATCH4:
7887 case CP0_REG31__KSCRATCH5:
7888 case CP0_REG31__KSCRATCH6:
f31b035a
LA
7889 CP0_CHECK(ctx->kscrexist & (1 << sel));
7890 tcg_gen_ld_tl(arg, cpu_env,
05aa7e93 7891 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 7892 register_name = "KScratch";
e98c0d17 7893 break;
9c2149c8 7894 default:
f31b035a 7895 goto cp0_unimplemented;
9c2149c8
TS
7896 }
7897 break;
7898 default:
f31b035a 7899 goto cp0_unimplemented;
9c2149c8 7900 }
294fc2ea 7901 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9c2149c8
TS
7902 return;
7903
f31b035a 7904cp0_unimplemented:
294fc2ea
AM
7905 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7906 register_name, reg, sel);
f31b035a 7907 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7908}
7909
d75c135e 7910static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8 7911{
294fc2ea 7912 const char *register_name = "invalid";
9c2149c8 7913
1f8929d2 7914 if (sel != 0) {
bbd5e4a2 7915 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 7916 }
e189e748 7917
eeb3bba8 7918 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7919 gen_io_start();
bd79255d 7920 }
2e70f6ef 7921
9c2149c8 7922 switch (reg) {
04992c8c 7923 case CP0_REGISTER_00:
9c2149c8 7924 switch (sel) {
1b142da5 7925 case CP0_REG00__INDEX:
895c2d04 7926 gen_helper_mtc0_index(cpu_env, arg);
294fc2ea 7927 register_name = "Index";
9c2149c8 7928 break;
1b142da5 7929 case CP0_REG00__MVPCONTROL:
f31b035a 7930 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7931 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
294fc2ea 7932 register_name = "MVPControl";
ead9360e 7933 break;
1b142da5 7934 case CP0_REG00__MVPCONF0:
f31b035a 7935 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7936 /* ignored */
294fc2ea 7937 register_name = "MVPConf0";
ead9360e 7938 break;
1b142da5 7939 case CP0_REG00__MVPCONF1:
f31b035a 7940 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7941 /* ignored */
294fc2ea 7942 register_name = "MVPConf1";
ead9360e 7943 break;
1b142da5 7944 case CP0_REG00__VPCONTROL:
01bc435b
YK
7945 CP0_CHECK(ctx->vp);
7946 /* ignored */
294fc2ea 7947 register_name = "VPControl";
01bc435b 7948 break;
9c2149c8 7949 default:
f31b035a 7950 goto cp0_unimplemented;
9c2149c8
TS
7951 }
7952 break;
04992c8c 7953 case CP0_REGISTER_01:
9c2149c8 7954 switch (sel) {
30deb460 7955 case CP0_REG01__RANDOM:
2423f660 7956 /* ignored */
294fc2ea 7957 register_name = "Random";
2423f660 7958 break;
30deb460 7959 case CP0_REG01__VPECONTROL:
f31b035a 7960 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7961 gen_helper_mtc0_vpecontrol(cpu_env, arg);
294fc2ea 7962 register_name = "VPEControl";
ead9360e 7963 break;
30deb460 7964 case CP0_REG01__VPECONF0:
f31b035a 7965 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7966 gen_helper_mtc0_vpeconf0(cpu_env, arg);
294fc2ea 7967 register_name = "VPEConf0";
ead9360e 7968 break;
30deb460 7969 case CP0_REG01__VPECONF1:
f31b035a 7970 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7971 gen_helper_mtc0_vpeconf1(cpu_env, arg);
294fc2ea 7972 register_name = "VPEConf1";
ead9360e 7973 break;
30deb460 7974 case CP0_REG01__YQMASK:
f31b035a 7975 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7976 gen_helper_mtc0_yqmask(cpu_env, arg);
294fc2ea 7977 register_name = "YQMask";
ead9360e 7978 break;
30deb460 7979 case CP0_REG01__VPESCHEDULE:
f31b035a 7980 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7981 tcg_gen_st_tl(arg, cpu_env,
7982 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 7983 register_name = "VPESchedule";
ead9360e 7984 break;
30deb460 7985 case CP0_REG01__VPESCHEFBACK:
f31b035a 7986 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7987 tcg_gen_st_tl(arg, cpu_env,
7988 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 7989 register_name = "VPEScheFBack";
ead9360e 7990 break;
30deb460 7991 case CP0_REG01__VPEOPT:
f31b035a 7992 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7993 gen_helper_mtc0_vpeopt(cpu_env, arg);
294fc2ea 7994 register_name = "VPEOpt";
ead9360e 7995 break;
9c2149c8 7996 default:
f31b035a 7997 goto cp0_unimplemented;
9c2149c8
TS
7998 }
7999 break;
04992c8c 8000 case CP0_REGISTER_02:
9c2149c8 8001 switch (sel) {
6d27d5bd 8002 case CP0_REG02__ENTRYLO0:
7207c7f9 8003 gen_helper_dmtc0_entrylo0(cpu_env, arg);
294fc2ea 8004 register_name = "EntryLo0";
2423f660 8005 break;
6d27d5bd 8006 case CP0_REG02__TCSTATUS:
f31b035a 8007 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8008 gen_helper_mtc0_tcstatus(cpu_env, arg);
294fc2ea 8009 register_name = "TCStatus";
ead9360e 8010 break;
6d27d5bd 8011 case CP0_REG02__TCBIND:
f31b035a 8012 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8013 gen_helper_mtc0_tcbind(cpu_env, arg);
294fc2ea 8014 register_name = "TCBind";
ead9360e 8015 break;
6d27d5bd 8016 case CP0_REG02__TCRESTART:
f31b035a 8017 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8018 gen_helper_mtc0_tcrestart(cpu_env, arg);
294fc2ea 8019 register_name = "TCRestart";
ead9360e 8020 break;
6d27d5bd 8021 case CP0_REG02__TCHALT:
f31b035a 8022 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8023 gen_helper_mtc0_tchalt(cpu_env, arg);
294fc2ea 8024 register_name = "TCHalt";
ead9360e 8025 break;
6d27d5bd 8026 case CP0_REG02__TCCONTEXT:
f31b035a 8027 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8028 gen_helper_mtc0_tccontext(cpu_env, arg);
294fc2ea 8029 register_name = "TCContext";
ead9360e 8030 break;
6d27d5bd 8031 case CP0_REG02__TCSCHEDULE:
f31b035a 8032 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8033 gen_helper_mtc0_tcschedule(cpu_env, arg);
294fc2ea 8034 register_name = "TCSchedule";
ead9360e 8035 break;
6d27d5bd 8036 case CP0_REG02__TCSCHEFBACK:
f31b035a 8037 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8038 gen_helper_mtc0_tcschefback(cpu_env, arg);
294fc2ea 8039 register_name = "TCScheFBack";
ead9360e 8040 break;
9c2149c8 8041 default:
f31b035a 8042 goto cp0_unimplemented;
9c2149c8
TS
8043 }
8044 break;
04992c8c 8045 case CP0_REGISTER_03:
9c2149c8 8046 switch (sel) {
acd37316 8047 case CP0_REG03__ENTRYLO1:
7207c7f9 8048 gen_helper_dmtc0_entrylo1(cpu_env, arg);
294fc2ea 8049 register_name = "EntryLo1";
2423f660 8050 break;
acd37316 8051 case CP0_REG03__GLOBALNUM:
01bc435b
YK
8052 CP0_CHECK(ctx->vp);
8053 /* ignored */
294fc2ea 8054 register_name = "GlobalNumber";
01bc435b 8055 break;
9c2149c8 8056 default:
f31b035a 8057 goto cp0_unimplemented;
876d4b07 8058 }
9c2149c8 8059 break;
04992c8c 8060 case CP0_REGISTER_04:
9c2149c8 8061 switch (sel) {
020fe379 8062 case CP0_REG04__CONTEXT:
895c2d04 8063 gen_helper_mtc0_context(cpu_env, arg);
294fc2ea 8064 register_name = "Context";
2423f660 8065 break;
020fe379
AM
8066 case CP0_REG04__CONTEXTCONFIG:
8067 /* SmartMIPS ASE */
8068 /* gen_helper_dmtc0_contextconfig(arg); */
294fc2ea 8069 register_name = "ContextConfig";
f31b035a 8070 goto cp0_unimplemented;
020fe379 8071 case CP0_REG04__USERLOCAL:
f31b035a
LA
8072 CP0_CHECK(ctx->ulri);
8073 tcg_gen_st_tl(arg, cpu_env,
8074 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 8075 register_name = "UserLocal";
d279279e 8076 break;
99029be1
YK
8077 case CP0_REG04__MMID:
8078 CP0_CHECK(ctx->mi);
8079 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8080 register_name = "MMID";
8081 break;
9c2149c8 8082 default:
f31b035a 8083 goto cp0_unimplemented;
876d4b07 8084 }
9c2149c8 8085 break;
04992c8c 8086 case CP0_REGISTER_05:
9c2149c8 8087 switch (sel) {
a1e76353 8088 case CP0_REG05__PAGEMASK:
895c2d04 8089 gen_helper_mtc0_pagemask(cpu_env, arg);
294fc2ea 8090 register_name = "PageMask";
2423f660 8091 break;
a1e76353 8092 case CP0_REG05__PAGEGRAIN:
7a47bae5 8093 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8094 gen_helper_mtc0_pagegrain(cpu_env, arg);
294fc2ea 8095 register_name = "PageGrain";
2423f660 8096 break;
a1e76353 8097 case CP0_REG05__SEGCTL0:
cec56a73
JH
8098 CP0_CHECK(ctx->sc);
8099 gen_helper_mtc0_segctl0(cpu_env, arg);
294fc2ea 8100 register_name = "SegCtl0";
cec56a73 8101 break;
a1e76353 8102 case CP0_REG05__SEGCTL1:
cec56a73
JH
8103 CP0_CHECK(ctx->sc);
8104 gen_helper_mtc0_segctl1(cpu_env, arg);
294fc2ea 8105 register_name = "SegCtl1";
cec56a73 8106 break;
a1e76353 8107 case CP0_REG05__SEGCTL2:
cec56a73
JH
8108 CP0_CHECK(ctx->sc);
8109 gen_helper_mtc0_segctl2(cpu_env, arg);
294fc2ea 8110 register_name = "SegCtl2";
cec56a73 8111 break;
a1e76353 8112 case CP0_REG05__PWBASE:
5e31fdd5
YK
8113 check_pw(ctx);
8114 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 8115 register_name = "PWBase";
5e31fdd5 8116 break;
a1e76353 8117 case CP0_REG05__PWFIELD:
fa75ad14
YK
8118 check_pw(ctx);
8119 gen_helper_mtc0_pwfield(cpu_env, arg);
294fc2ea 8120 register_name = "PWField";
fa75ad14 8121 break;
a1e76353 8122 case CP0_REG05__PWSIZE:
20b28ebc
YK
8123 check_pw(ctx);
8124 gen_helper_mtc0_pwsize(cpu_env, arg);
294fc2ea 8125 register_name = "PWSize";
20b28ebc 8126 break;
9c2149c8 8127 default:
f31b035a 8128 goto cp0_unimplemented;
876d4b07 8129 }
9c2149c8 8130 break;
04992c8c 8131 case CP0_REGISTER_06:
9c2149c8 8132 switch (sel) {
9023594b 8133 case CP0_REG06__WIRED:
895c2d04 8134 gen_helper_mtc0_wired(cpu_env, arg);
294fc2ea 8135 register_name = "Wired";
2423f660 8136 break;
9023594b 8137 case CP0_REG06__SRSCONF0:
7a47bae5 8138 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8139 gen_helper_mtc0_srsconf0(cpu_env, arg);
294fc2ea 8140 register_name = "SRSConf0";
ead9360e 8141 break;
9023594b 8142 case CP0_REG06__SRSCONF1:
7a47bae5 8143 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8144 gen_helper_mtc0_srsconf1(cpu_env, arg);
294fc2ea 8145 register_name = "SRSConf1";
ead9360e 8146 break;
9023594b 8147 case CP0_REG06__SRSCONF2:
7a47bae5 8148 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8149 gen_helper_mtc0_srsconf2(cpu_env, arg);
294fc2ea 8150 register_name = "SRSConf2";
ead9360e 8151 break;
9023594b 8152 case CP0_REG06__SRSCONF3:
7a47bae5 8153 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8154 gen_helper_mtc0_srsconf3(cpu_env, arg);
294fc2ea 8155 register_name = "SRSConf3";
ead9360e 8156 break;
9023594b 8157 case CP0_REG06__SRSCONF4:
7a47bae5 8158 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8159 gen_helper_mtc0_srsconf4(cpu_env, arg);
294fc2ea 8160 register_name = "SRSConf4";
ead9360e 8161 break;
9023594b 8162 case CP0_REG06__PWCTL:
103be64c
YK
8163 check_pw(ctx);
8164 gen_helper_mtc0_pwctl(cpu_env, arg);
294fc2ea 8165 register_name = "PWCtl";
103be64c 8166 break;
9c2149c8 8167 default:
f31b035a 8168 goto cp0_unimplemented;
876d4b07 8169 }
9c2149c8 8170 break;
04992c8c 8171 case CP0_REGISTER_07:
9c2149c8 8172 switch (sel) {
143a9875 8173 case CP0_REG07__HWRENA:
7a47bae5 8174 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8175 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 8176 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8177 register_name = "HWREna";
2423f660 8178 break;
9c2149c8 8179 default:
f31b035a 8180 goto cp0_unimplemented;
876d4b07 8181 }
9c2149c8 8182 break;
04992c8c 8183 case CP0_REGISTER_08:
aea14095 8184 switch (sel) {
67d167d2 8185 case CP0_REG08__BADVADDR:
aea14095 8186 /* ignored */
294fc2ea 8187 register_name = "BadVAddr";
aea14095 8188 break;
67d167d2 8189 case CP0_REG08__BADINSTR:
aea14095 8190 /* ignored */
294fc2ea 8191 register_name = "BadInstr";
aea14095 8192 break;
67d167d2 8193 case CP0_REG08__BADINSTRP:
aea14095 8194 /* ignored */
294fc2ea 8195 register_name = "BadInstrP";
aea14095 8196 break;
67d167d2 8197 case CP0_REG08__BADINSTRX:
25beba9b 8198 /* ignored */
294fc2ea 8199 register_name = "BadInstrX";
25beba9b 8200 break;
aea14095 8201 default:
f31b035a 8202 goto cp0_unimplemented;
aea14095 8203 }
9c2149c8 8204 break;
04992c8c 8205 case CP0_REGISTER_09:
9c2149c8 8206 switch (sel) {
e5a98a72 8207 case CP0_REG09__COUNT:
895c2d04 8208 gen_helper_mtc0_count(cpu_env, arg);
294fc2ea 8209 register_name = "Count";
2423f660 8210 break;
e5a98a72 8211 case CP0_REG09__SAARI:
5fb2dcd1
YK
8212 CP0_CHECK(ctx->saar);
8213 gen_helper_mtc0_saari(cpu_env, arg);
294fc2ea 8214 register_name = "SAARI";
5fb2dcd1 8215 break;
e5a98a72 8216 case CP0_REG09__SAAR:
5fb2dcd1
YK
8217 CP0_CHECK(ctx->saar);
8218 gen_helper_mtc0_saar(cpu_env, arg);
294fc2ea 8219 register_name = "SAAR";
5fb2dcd1 8220 break;
9c2149c8 8221 default:
f31b035a 8222 goto cp0_unimplemented;
876d4b07
TS
8223 }
8224 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8225 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8226 break;
04992c8c 8227 case CP0_REGISTER_10:
9c2149c8 8228 switch (sel) {
860ffef0 8229 case CP0_REG10__ENTRYHI:
895c2d04 8230 gen_helper_mtc0_entryhi(cpu_env, arg);
294fc2ea 8231 register_name = "EntryHi";
2423f660 8232 break;
9c2149c8 8233 default:
f31b035a 8234 goto cp0_unimplemented;
876d4b07 8235 }
9c2149c8 8236 break;
04992c8c 8237 case CP0_REGISTER_11:
9c2149c8 8238 switch (sel) {
f5f3834f 8239 case CP0_REG11__COMPARE:
895c2d04 8240 gen_helper_mtc0_compare(cpu_env, arg);
294fc2ea 8241 register_name = "Compare";
2423f660 8242 break;
876d4b07 8243 /* 6,7 are implementation dependent */
9c2149c8 8244 default:
f31b035a 8245 goto cp0_unimplemented;
876d4b07 8246 }
de9a95f0 8247 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8248 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8249 break;
04992c8c 8250 case CP0_REGISTER_12:
9c2149c8 8251 switch (sel) {
2b084867 8252 case CP0_REG12__STATUS:
867abc7e 8253 save_cpu_state(ctx, 1);
895c2d04 8254 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 8255 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8256 gen_save_pc(ctx->base.pc_next + 4);
8257 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8258 register_name = "Status";
2423f660 8259 break;
2b084867 8260 case CP0_REG12__INTCTL:
7a47bae5 8261 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8262 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 8263 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8264 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8265 register_name = "IntCtl";
2423f660 8266 break;
2b084867 8267 case CP0_REG12__SRSCTL:
7a47bae5 8268 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8269 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 8270 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8271 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8272 register_name = "SRSCtl";
2423f660 8273 break;
2b084867 8274 case CP0_REG12__SRSMAP:
7a47bae5 8275 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8276 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 8277 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8278 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8279 register_name = "SRSMap";
2423f660
TS
8280 break;
8281 default:
f31b035a 8282 goto cp0_unimplemented;
876d4b07 8283 }
9c2149c8 8284 break;
04992c8c 8285 case CP0_REGISTER_13:
9c2149c8 8286 switch (sel) {
e3c7559d 8287 case CP0_REG13__CAUSE:
867abc7e 8288 save_cpu_state(ctx, 1);
895c2d04 8289 gen_helper_mtc0_cause(cpu_env, arg);
7480515f
AM
8290 /*
8291 * Stop translation as we may have triggered an interrupt.
b28425ba 8292 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7480515f
AM
8293 * translated code to check for pending interrupts.
8294 */
eeb3bba8
EC
8295 gen_save_pc(ctx->base.pc_next + 4);
8296 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8297 register_name = "Cause";
2423f660 8298 break;
9c2149c8 8299 default:
f31b035a 8300 goto cp0_unimplemented;
876d4b07 8301 }
9c2149c8 8302 break;
04992c8c 8303 case CP0_REGISTER_14:
9c2149c8 8304 switch (sel) {
35e4b54d 8305 case CP0_REG14__EPC:
7db13fae 8306 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 8307 register_name = "EPC";
2423f660 8308 break;
9c2149c8 8309 default:
f31b035a 8310 goto cp0_unimplemented;
876d4b07 8311 }
9c2149c8 8312 break;
04992c8c 8313 case CP0_REGISTER_15:
9c2149c8 8314 switch (sel) {
4466cd49 8315 case CP0_REG15__PRID:
2423f660 8316 /* ignored */
294fc2ea 8317 register_name = "PRid";
2423f660 8318 break;
4466cd49 8319 case CP0_REG15__EBASE:
7a47bae5 8320 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8321 gen_helper_mtc0_ebase(cpu_env, arg);
294fc2ea 8322 register_name = "EBase";
2423f660 8323 break;
9c2149c8 8324 default:
f31b035a 8325 goto cp0_unimplemented;
876d4b07 8326 }
9c2149c8 8327 break;
04992c8c 8328 case CP0_REGISTER_16:
9c2149c8 8329 switch (sel) {
433efb4c 8330 case CP0_REG16__CONFIG:
895c2d04 8331 gen_helper_mtc0_config0(cpu_env, arg);
294fc2ea 8332 register_name = "Config";
2423f660 8333 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8334 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8335 break;
433efb4c 8336 case CP0_REG16__CONFIG1:
1fc7bf6e 8337 /* ignored, read only */
294fc2ea 8338 register_name = "Config1";
9c2149c8 8339 break;
433efb4c 8340 case CP0_REG16__CONFIG2:
895c2d04 8341 gen_helper_mtc0_config2(cpu_env, arg);
294fc2ea 8342 register_name = "Config2";
2423f660 8343 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8344 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8345 break;
433efb4c 8346 case CP0_REG16__CONFIG3:
90f12d73 8347 gen_helper_mtc0_config3(cpu_env, arg);
294fc2ea 8348 register_name = "Config3";
90f12d73 8349 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8350 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8351 break;
433efb4c 8352 case CP0_REG16__CONFIG4:
faf1f68b 8353 /* currently ignored */
294fc2ea 8354 register_name = "Config4";
faf1f68b 8355 break;
433efb4c 8356 case CP0_REG16__CONFIG5:
faf1f68b 8357 gen_helper_mtc0_config5(cpu_env, arg);
294fc2ea 8358 register_name = "Config5";
faf1f68b 8359 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8360 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 8361 break;
9c2149c8
TS
8362 /* 6,7 are implementation dependent */
8363 default:
294fc2ea 8364 register_name = "Invalid config selector";
f31b035a 8365 goto cp0_unimplemented;
9c2149c8 8366 }
9c2149c8 8367 break;
04992c8c 8368 case CP0_REGISTER_17:
9c2149c8 8369 switch (sel) {
706ce142 8370 case CP0_REG17__LLADDR:
895c2d04 8371 gen_helper_mtc0_lladdr(cpu_env, arg);
294fc2ea 8372 register_name = "LLAddr";
2423f660 8373 break;
706ce142 8374 case CP0_REG17__MAAR:
f6d4dd81
YK
8375 CP0_CHECK(ctx->mrp);
8376 gen_helper_mtc0_maar(cpu_env, arg);
294fc2ea 8377 register_name = "MAAR";
f6d4dd81 8378 break;
706ce142 8379 case CP0_REG17__MAARI:
f6d4dd81
YK
8380 CP0_CHECK(ctx->mrp);
8381 gen_helper_mtc0_maari(cpu_env, arg);
294fc2ea 8382 register_name = "MAARI";
f6d4dd81 8383 break;
9c2149c8 8384 default:
f31b035a 8385 goto cp0_unimplemented;
9c2149c8
TS
8386 }
8387 break;
04992c8c 8388 case CP0_REGISTER_18:
9c2149c8 8389 switch (sel) {
e8dcfe82
AM
8390 case CP0_REG18__WATCHLO0:
8391 case CP0_REG18__WATCHLO1:
8392 case CP0_REG18__WATCHLO2:
8393 case CP0_REG18__WATCHLO3:
8394 case CP0_REG18__WATCHLO4:
8395 case CP0_REG18__WATCHLO5:
8396 case CP0_REG18__WATCHLO6:
8397 case CP0_REG18__WATCHLO7:
fa192d49 8398 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8399 gen_helper_0e1i(mtc0_watchlo, arg, sel);
294fc2ea 8400 register_name = "WatchLo";
2423f660 8401 break;
9c2149c8 8402 default:
f31b035a 8403 goto cp0_unimplemented;
9c2149c8
TS
8404 }
8405 break;
04992c8c 8406 case CP0_REGISTER_19:
9c2149c8 8407 switch (sel) {
be274dc1
AM
8408 case CP0_REG19__WATCHHI0:
8409 case CP0_REG19__WATCHHI1:
8410 case CP0_REG19__WATCHHI2:
8411 case CP0_REG19__WATCHHI3:
8412 case CP0_REG19__WATCHHI4:
8413 case CP0_REG19__WATCHHI5:
8414 case CP0_REG19__WATCHHI6:
8415 case CP0_REG19__WATCHHI7:
fa192d49 8416 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8417 gen_helper_0e1i(mtc0_watchhi, arg, sel);
294fc2ea 8418 register_name = "WatchHi";
2423f660 8419 break;
9c2149c8 8420 default:
f31b035a 8421 goto cp0_unimplemented;
9c2149c8
TS
8422 }
8423 break;
04992c8c 8424 case CP0_REGISTER_20:
9c2149c8 8425 switch (sel) {
14f92b0b 8426 case CP0_REG20__XCONTEXT:
d75c135e 8427 check_insn(ctx, ISA_MIPS3);
895c2d04 8428 gen_helper_mtc0_xcontext(cpu_env, arg);
294fc2ea 8429 register_name = "XContext";
2423f660 8430 break;
9c2149c8 8431 default:
f31b035a 8432 goto cp0_unimplemented;
9c2149c8
TS
8433 }
8434 break;
04992c8c 8435 case CP0_REGISTER_21:
9c2149c8 8436 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 8437 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
9c2149c8
TS
8438 switch (sel) {
8439 case 0:
895c2d04 8440 gen_helper_mtc0_framemask(cpu_env, arg);
294fc2ea 8441 register_name = "Framemask";
2423f660 8442 break;
9c2149c8 8443 default:
f31b035a 8444 goto cp0_unimplemented;
9c2149c8
TS
8445 }
8446 break;
04992c8c 8447 case CP0_REGISTER_22:
9c2149c8 8448 /* ignored */
294fc2ea 8449 register_name = "Diagnostic"; /* implementation dependent */
876d4b07 8450 break;
04992c8c 8451 case CP0_REGISTER_23:
9c2149c8 8452 switch (sel) {
4cbf4b6d 8453 case CP0_REG23__DEBUG:
895c2d04 8454 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 8455 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8456 gen_save_pc(ctx->base.pc_next + 4);
8457 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8458 register_name = "Debug";
2423f660 8459 break;
4cbf4b6d
AM
8460 case CP0_REG23__TRACECONTROL:
8461 /* PDtrace support */
8462 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8487327a 8463 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8464 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8465 register_name = "TraceControl";
3570d7f6 8466 goto cp0_unimplemented;
4cbf4b6d
AM
8467 case CP0_REG23__TRACECONTROL2:
8468 /* PDtrace support */
8469 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8487327a 8470 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8471 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8472 register_name = "TraceControl2";
3570d7f6 8473 goto cp0_unimplemented;
4cbf4b6d
AM
8474 case CP0_REG23__USERTRACEDATA1:
8475 /* PDtrace support */
8476 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8487327a 8477 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8478 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d 8479 register_name = "UserTraceData1";
3570d7f6 8480 goto cp0_unimplemented;
4cbf4b6d
AM
8481 case CP0_REG23__TRACEIBPC:
8482 /* PDtrace support */
8483 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8484 /* Stop translation as we may have switched the execution mode */
8485 ctx->base.is_jmp = DISAS_STOP;
8486 register_name = "TraceIBPC";
8487 goto cp0_unimplemented;
8488 case CP0_REG23__TRACEDBPC:
8489 /* PDtrace support */
8490 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8487327a 8491 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8492 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d 8493 register_name = "TraceDBPC";
3570d7f6 8494 goto cp0_unimplemented;
9c2149c8 8495 default:
f31b035a 8496 goto cp0_unimplemented;
9c2149c8 8497 }
9c2149c8 8498 break;
04992c8c 8499 case CP0_REGISTER_24:
9c2149c8 8500 switch (sel) {
8d7b4b6e 8501 case CP0_REG24__DEPC:
f1aa6320 8502 /* EJTAG support */
7db13fae 8503 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 8504 register_name = "DEPC";
2423f660 8505 break;
9c2149c8 8506 default:
f31b035a 8507 goto cp0_unimplemented;
9c2149c8
TS
8508 }
8509 break;
04992c8c 8510 case CP0_REGISTER_25:
9c2149c8 8511 switch (sel) {
1176b328 8512 case CP0_REG25__PERFCTL0:
895c2d04 8513 gen_helper_mtc0_performance0(cpu_env, arg);
294fc2ea 8514 register_name = "Performance0";
2423f660 8515 break;
1176b328 8516 case CP0_REG25__PERFCNT0:
7480515f 8517 /* gen_helper_mtc0_performance1(cpu_env, arg); */
294fc2ea 8518 register_name = "Performance1";
3570d7f6 8519 goto cp0_unimplemented;
1176b328 8520 case CP0_REG25__PERFCTL1:
7480515f 8521 /* gen_helper_mtc0_performance2(cpu_env, arg); */
294fc2ea 8522 register_name = "Performance2";
3570d7f6 8523 goto cp0_unimplemented;
1176b328 8524 case CP0_REG25__PERFCNT1:
7480515f 8525 /* gen_helper_mtc0_performance3(cpu_env, arg); */
294fc2ea 8526 register_name = "Performance3";
3570d7f6 8527 goto cp0_unimplemented;
1176b328 8528 case CP0_REG25__PERFCTL2:
7480515f 8529 /* gen_helper_mtc0_performance4(cpu_env, arg); */
294fc2ea 8530 register_name = "Performance4";
3570d7f6 8531 goto cp0_unimplemented;
1176b328 8532 case CP0_REG25__PERFCNT2:
7480515f 8533 /* gen_helper_mtc0_performance5(cpu_env, arg); */
294fc2ea 8534 register_name = "Performance5";
3570d7f6 8535 goto cp0_unimplemented;
1176b328 8536 case CP0_REG25__PERFCTL3:
7480515f 8537 /* gen_helper_mtc0_performance6(cpu_env, arg); */
294fc2ea 8538 register_name = "Performance6";
3570d7f6 8539 goto cp0_unimplemented;
1176b328 8540 case CP0_REG25__PERFCNT3:
7480515f 8541 /* gen_helper_mtc0_performance7(cpu_env, arg); */
294fc2ea 8542 register_name = "Performance7";
3570d7f6 8543 goto cp0_unimplemented;
9c2149c8 8544 default:
f31b035a 8545 goto cp0_unimplemented;
9c2149c8 8546 }
876d4b07 8547 break;
04992c8c 8548 case CP0_REGISTER_26:
0d74a222 8549 switch (sel) {
dbbf08b2 8550 case CP0_REG26__ERRCTL:
0d74a222 8551 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 8552 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8553 register_name = "ErrCtl";
0d74a222
LA
8554 break;
8555 default:
8556 goto cp0_unimplemented;
8557 }
876d4b07 8558 break;
04992c8c 8559 case CP0_REGISTER_27:
9c2149c8 8560 switch (sel) {
5a10873d 8561 case CP0_REG27__CACHERR:
2423f660 8562 /* ignored */
294fc2ea 8563 register_name = "CacheErr";
2423f660 8564 break;
9c2149c8 8565 default:
f31b035a 8566 goto cp0_unimplemented;
9c2149c8 8567 }
876d4b07 8568 break;
04992c8c 8569 case CP0_REGISTER_28:
9c2149c8 8570 switch (sel) {
a30e2f21
AM
8571 case CP0_REG28__TAGLO:
8572 case CP0_REG28__TAGLO1:
8573 case CP0_REG28__TAGLO2:
8574 case CP0_REG28__TAGLO3:
895c2d04 8575 gen_helper_mtc0_taglo(cpu_env, arg);
294fc2ea 8576 register_name = "TagLo";
9c2149c8 8577 break;
a30e2f21
AM
8578 case CP0_REG28__DATALO:
8579 case CP0_REG28__DATALO1:
8580 case CP0_REG28__DATALO2:
8581 case CP0_REG28__DATALO3:
895c2d04 8582 gen_helper_mtc0_datalo(cpu_env, arg);
294fc2ea 8583 register_name = "DataLo";
9c2149c8
TS
8584 break;
8585 default:
f31b035a 8586 goto cp0_unimplemented;
9c2149c8
TS
8587 }
8588 break;
04992c8c 8589 case CP0_REGISTER_29:
9c2149c8 8590 switch (sel) {
af4bb6da
AM
8591 case CP0_REG29__TAGHI:
8592 case CP0_REG29__TAGHI1:
8593 case CP0_REG29__TAGHI2:
8594 case CP0_REG29__TAGHI3:
895c2d04 8595 gen_helper_mtc0_taghi(cpu_env, arg);
294fc2ea 8596 register_name = "TagHi";
9c2149c8 8597 break;
af4bb6da
AM
8598 case CP0_REG29__DATAHI:
8599 case CP0_REG29__DATAHI1:
8600 case CP0_REG29__DATAHI2:
8601 case CP0_REG29__DATAHI3:
895c2d04 8602 gen_helper_mtc0_datahi(cpu_env, arg);
294fc2ea 8603 register_name = "DataHi";
9c2149c8
TS
8604 break;
8605 default:
294fc2ea 8606 register_name = "invalid sel";
f31b035a 8607 goto cp0_unimplemented;
9c2149c8 8608 }
876d4b07 8609 break;
04992c8c 8610 case CP0_REGISTER_30:
9c2149c8 8611 switch (sel) {
4bcf121e 8612 case CP0_REG30__ERROREPC:
7db13fae 8613 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 8614 register_name = "ErrorEPC";
2423f660 8615 break;
9c2149c8 8616 default:
f31b035a 8617 goto cp0_unimplemented;
9c2149c8
TS
8618 }
8619 break;
04992c8c 8620 case CP0_REGISTER_31:
9c2149c8 8621 switch (sel) {
14d92efd 8622 case CP0_REG31__DESAVE:
f1aa6320 8623 /* EJTAG support */
7db13fae 8624 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 8625 register_name = "DESAVE";
2423f660 8626 break;
14d92efd
AM
8627 case CP0_REG31__KSCRATCH1:
8628 case CP0_REG31__KSCRATCH2:
8629 case CP0_REG31__KSCRATCH3:
8630 case CP0_REG31__KSCRATCH4:
8631 case CP0_REG31__KSCRATCH5:
8632 case CP0_REG31__KSCRATCH6:
f31b035a
LA
8633 CP0_CHECK(ctx->kscrexist & (1 << sel));
8634 tcg_gen_st_tl(arg, cpu_env,
71375b59 8635 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 8636 register_name = "KScratch";
e98c0d17 8637 break;
9c2149c8 8638 default:
f31b035a 8639 goto cp0_unimplemented;
9c2149c8 8640 }
9c2149c8
TS
8641 break;
8642 default:
f31b035a 8643 goto cp0_unimplemented;
9c2149c8 8644 }
294fc2ea 8645 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
b44a7fb1 8646
bf20dc07 8647 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 8648 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480515f
AM
8649 /*
8650 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8651 * translated code to check for pending interrupts.
8652 */
eeb3bba8
EC
8653 gen_save_pc(ctx->base.pc_next + 4);
8654 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 8655 }
9c2149c8
TS
8656 return;
8657
f31b035a 8658cp0_unimplemented:
294fc2ea
AM
8659 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8660 register_name, reg, sel);
9c2149c8 8661}
d26bc211 8662#endif /* TARGET_MIPS64 */
9c2149c8 8663
7db13fae 8664static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
8665 int u, int sel, int h)
8666{
8667 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8668 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
8669
8670 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732 8671 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
1f8929d2 8672 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
1a3fd9c3 8673 tcg_gen_movi_tl(t0, -1);
1f8929d2
AM
8674 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8675 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
1a3fd9c3 8676 tcg_gen_movi_tl(t0, -1);
1f8929d2 8677 } else if (u == 0) {
ead9360e 8678 switch (rt) {
5a25ce94
EI
8679 case 1:
8680 switch (sel) {
8681 case 1:
895c2d04 8682 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
8683 break;
8684 case 2:
895c2d04 8685 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
8686 break;
8687 default:
8688 goto die;
8689 break;
8690 }
8691 break;
ead9360e
TS
8692 case 2:
8693 switch (sel) {
8694 case 1:
895c2d04 8695 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
8696 break;
8697 case 2:
895c2d04 8698 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
8699 break;
8700 case 3:
895c2d04 8701 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
8702 break;
8703 case 4:
895c2d04 8704 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
8705 break;
8706 case 5:
895c2d04 8707 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
8708 break;
8709 case 6:
895c2d04 8710 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
8711 break;
8712 case 7:
895c2d04 8713 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
8714 break;
8715 default:
d75c135e 8716 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8717 break;
8718 }
8719 break;
8720 case 10:
8721 switch (sel) {
8722 case 0:
895c2d04 8723 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
8724 break;
8725 default:
d75c135e 8726 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8727 break;
8728 }
f1fadbb2 8729 break;
ead9360e
TS
8730 case 12:
8731 switch (sel) {
8732 case 0:
895c2d04 8733 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
8734 break;
8735 default:
d75c135e 8736 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8737 break;
8738 }
f1fadbb2 8739 break;
5a25ce94
EI
8740 case 13:
8741 switch (sel) {
8742 case 0:
895c2d04 8743 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
8744 break;
8745 default:
8746 goto die;
8747 break;
8748 }
8749 break;
8750 case 14:
8751 switch (sel) {
8752 case 0:
895c2d04 8753 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
8754 break;
8755 default:
8756 goto die;
8757 break;
8758 }
8759 break;
8760 case 15:
8761 switch (sel) {
8762 case 1:
895c2d04 8763 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
8764 break;
8765 default:
8766 goto die;
8767 break;
8768 }
8769 break;
8770 case 16:
8771 switch (sel) {
c2e19f3c
AM
8772 case 0:
8773 case 1:
8774 case 2:
8775 case 3:
8776 case 4:
8777 case 5:
8778 case 6:
8779 case 7:
895c2d04 8780 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
8781 break;
8782 default:
8783 goto die;
8784 break;
8785 }
8786 break;
ead9360e
TS
8787 case 23:
8788 switch (sel) {
8789 case 0:
895c2d04 8790 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
8791 break;
8792 default:
d75c135e 8793 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8794 break;
8795 }
8796 break;
8797 default:
d75c135e 8798 gen_mfc0(ctx, t0, rt, sel);
ead9360e 8799 }
71375b59
AM
8800 } else {
8801 switch (sel) {
8802 /* GPR registers. */
ead9360e 8803 case 0:
71375b59 8804 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e 8805 break;
71375b59 8806 /* Auxiliary CPU registers */
ead9360e 8807 case 1:
71375b59
AM
8808 switch (rt) {
8809 case 0:
8810 gen_helper_1e0i(mftlo, t0, 0);
8811 break;
8812 case 1:
8813 gen_helper_1e0i(mfthi, t0, 0);
8814 break;
8815 case 2:
8816 gen_helper_1e0i(mftacx, t0, 0);
8817 break;
8818 case 4:
8819 gen_helper_1e0i(mftlo, t0, 1);
8820 break;
8821 case 5:
8822 gen_helper_1e0i(mfthi, t0, 1);
8823 break;
8824 case 6:
8825 gen_helper_1e0i(mftacx, t0, 1);
8826 break;
8827 case 8:
8828 gen_helper_1e0i(mftlo, t0, 2);
8829 break;
8830 case 9:
8831 gen_helper_1e0i(mfthi, t0, 2);
8832 break;
8833 case 10:
8834 gen_helper_1e0i(mftacx, t0, 2);
8835 break;
8836 case 12:
8837 gen_helper_1e0i(mftlo, t0, 3);
8838 break;
8839 case 13:
8840 gen_helper_1e0i(mfthi, t0, 3);
8841 break;
8842 case 14:
8843 gen_helper_1e0i(mftacx, t0, 3);
8844 break;
8845 case 16:
8846 gen_helper_mftdsp(t0, cpu_env);
8847 break;
8848 default:
8849 goto die;
8850 }
ead9360e 8851 break;
71375b59 8852 /* Floating point (COP1). */
ead9360e 8853 case 2:
71375b59
AM
8854 /* XXX: For now we support only a single FPU context. */
8855 if (h == 0) {
8856 TCGv_i32 fp0 = tcg_temp_new_i32();
8857
8858 gen_load_fpr32(ctx, fp0, rt);
8859 tcg_gen_ext_i32_tl(t0, fp0);
8860 tcg_temp_free_i32(fp0);
8861 } else {
8862 TCGv_i32 fp0 = tcg_temp_new_i32();
8863
8864 gen_load_fpr32h(ctx, fp0, rt);
8865 tcg_gen_ext_i32_tl(t0, fp0);
8866 tcg_temp_free_i32(fp0);
8867 }
ead9360e 8868 break;
71375b59
AM
8869 case 3:
8870 /* XXX: For now we support only a single FPU context. */
8871 gen_helper_1e0i(cfc1, t0, rt);
ead9360e 8872 break;
71375b59
AM
8873 /* COP2: Not implemented. */
8874 case 4:
ead9360e 8875 case 5:
71375b59 8876 /* fall through */
ead9360e
TS
8877 default:
8878 goto die;
8879 }
ead9360e 8880 }
b44a7fb1 8881 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8882 gen_store_gpr(t0, rd);
8883 tcg_temp_free(t0);
ead9360e
TS
8884 return;
8885
8886die:
1a3fd9c3 8887 tcg_temp_free(t0);
d12d51d5 8888 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
3a4ef3b7 8889 gen_reserved_instruction(ctx);
ead9360e
TS
8890}
8891
7db13fae 8892static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8893 int u, int sel, int h)
8894{
8895 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8896 TCGv t0 = tcg_temp_local_new();
ead9360e 8897
1a3fd9c3 8898 gen_load_gpr(t0, rt);
ead9360e 8899 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732 8900 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
1f8929d2 8901 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
7480515f
AM
8902 /* NOP */
8903 ;
1f8929d2
AM
8904 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8905 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
7480515f
AM
8906 /* NOP */
8907 ;
1f8929d2 8908 } else if (u == 0) {
ead9360e 8909 switch (rd) {
5a25ce94
EI
8910 case 1:
8911 switch (sel) {
8912 case 1:
895c2d04 8913 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8914 break;
8915 case 2:
895c2d04 8916 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8917 break;
8918 default:
8919 goto die;
8920 break;
8921 }
8922 break;
ead9360e
TS
8923 case 2:
8924 switch (sel) {
8925 case 1:
895c2d04 8926 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8927 break;
8928 case 2:
895c2d04 8929 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8930 break;
8931 case 3:
895c2d04 8932 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8933 break;
8934 case 4:
895c2d04 8935 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8936 break;
8937 case 5:
895c2d04 8938 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8939 break;
8940 case 6:
895c2d04 8941 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8942 break;
8943 case 7:
895c2d04 8944 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8945 break;
8946 default:
d75c135e 8947 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8948 break;
8949 }
8950 break;
8951 case 10:
8952 switch (sel) {
8953 case 0:
895c2d04 8954 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8955 break;
8956 default:
d75c135e 8957 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8958 break;
8959 }
0d0304f2 8960 break;
ead9360e
TS
8961 case 12:
8962 switch (sel) {
8963 case 0:
895c2d04 8964 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8965 break;
8966 default:
d75c135e 8967 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8968 break;
8969 }
0d0304f2 8970 break;
5a25ce94
EI
8971 case 13:
8972 switch (sel) {
8973 case 0:
895c2d04 8974 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8975 break;
8976 default:
8977 goto die;
8978 break;
8979 }
8980 break;
8981 case 15:
8982 switch (sel) {
8983 case 1:
895c2d04 8984 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8985 break;
8986 default:
8987 goto die;
8988 break;
8989 }
8990 break;
ead9360e
TS
8991 case 23:
8992 switch (sel) {
8993 case 0:
895c2d04 8994 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8995 break;
8996 default:
d75c135e 8997 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8998 break;
8999 }
9000 break;
9001 default:
d75c135e 9002 gen_mtc0(ctx, t0, rd, sel);
ead9360e 9003 }
71375b59
AM
9004 } else {
9005 switch (sel) {
9006 /* GPR registers. */
ead9360e 9007 case 0:
71375b59 9008 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e 9009 break;
71375b59 9010 /* Auxiliary CPU registers */
ead9360e 9011 case 1:
71375b59
AM
9012 switch (rd) {
9013 case 0:
9014 gen_helper_0e1i(mttlo, t0, 0);
9015 break;
9016 case 1:
9017 gen_helper_0e1i(mtthi, t0, 0);
9018 break;
9019 case 2:
9020 gen_helper_0e1i(mttacx, t0, 0);
9021 break;
9022 case 4:
9023 gen_helper_0e1i(mttlo, t0, 1);
9024 break;
9025 case 5:
9026 gen_helper_0e1i(mtthi, t0, 1);
9027 break;
9028 case 6:
9029 gen_helper_0e1i(mttacx, t0, 1);
9030 break;
9031 case 8:
9032 gen_helper_0e1i(mttlo, t0, 2);
9033 break;
9034 case 9:
9035 gen_helper_0e1i(mtthi, t0, 2);
9036 break;
9037 case 10:
9038 gen_helper_0e1i(mttacx, t0, 2);
9039 break;
9040 case 12:
9041 gen_helper_0e1i(mttlo, t0, 3);
9042 break;
9043 case 13:
9044 gen_helper_0e1i(mtthi, t0, 3);
9045 break;
9046 case 14:
9047 gen_helper_0e1i(mttacx, t0, 3);
9048 break;
9049 case 16:
9050 gen_helper_mttdsp(cpu_env, t0);
9051 break;
9052 default:
9053 goto die;
9054 }
ead9360e 9055 break;
71375b59 9056 /* Floating point (COP1). */
ead9360e 9057 case 2:
71375b59
AM
9058 /* XXX: For now we support only a single FPU context. */
9059 if (h == 0) {
9060 TCGv_i32 fp0 = tcg_temp_new_i32();
9061
9062 tcg_gen_trunc_tl_i32(fp0, t0);
9063 gen_store_fpr32(ctx, fp0, rd);
9064 tcg_temp_free_i32(fp0);
9065 } else {
9066 TCGv_i32 fp0 = tcg_temp_new_i32();
9067
9068 tcg_gen_trunc_tl_i32(fp0, t0);
9069 gen_store_fpr32h(ctx, fp0, rd);
9070 tcg_temp_free_i32(fp0);
9071 }
ead9360e 9072 break;
71375b59
AM
9073 case 3:
9074 /* XXX: For now we support only a single FPU context. */
9075 {
9076 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9077
9078 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9079 tcg_temp_free_i32(fs_tmp);
9080 }
9081 /* Stop translation as we may have changed hflags */
9082 ctx->base.is_jmp = DISAS_STOP;
ead9360e 9083 break;
71375b59
AM
9084 /* COP2: Not implemented. */
9085 case 4:
ead9360e 9086 case 5:
71375b59 9087 /* fall through */
ead9360e
TS
9088 default:
9089 goto die;
9090 }
ead9360e 9091 }
b44a7fb1 9092 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 9093 tcg_temp_free(t0);
ead9360e
TS
9094 return;
9095
9096die:
1a3fd9c3 9097 tcg_temp_free(t0);
d12d51d5 9098 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
3a4ef3b7 9099 gen_reserved_instruction(ctx);
ead9360e
TS
9100}
9101
235785e8
AM
9102static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9103 int rt, int rd)
6af0bf9c 9104{
287c4b84 9105 const char *opn = "ldst";
6af0bf9c 9106
2e15497c 9107 check_cp0_enabled(ctx);
6af0bf9c
FB
9108 switch (opc) {
9109 case OPC_MFC0:
9110 if (rt == 0) {
ead9360e 9111 /* Treat as NOP. */
6af0bf9c
FB
9112 return;
9113 }
d75c135e 9114 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
9115 opn = "mfc0";
9116 break;
9117 case OPC_MTC0:
1a3fd9c3 9118 {
1fc7bf6e 9119 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9120
9121 gen_load_gpr(t0, rt);
d75c135e 9122 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9123 tcg_temp_free(t0);
9124 }
6af0bf9c
FB
9125 opn = "mtc0";
9126 break;
d26bc211 9127#if defined(TARGET_MIPS64)
9c2149c8 9128 case OPC_DMFC0:
d75c135e 9129 check_insn(ctx, ISA_MIPS3);
9c2149c8 9130 if (rt == 0) {
ead9360e 9131 /* Treat as NOP. */
9c2149c8
TS
9132 return;
9133 }
d75c135e 9134 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
9135 opn = "dmfc0";
9136 break;
9137 case OPC_DMTC0:
d75c135e 9138 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 9139 {
1fc7bf6e 9140 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9141
9142 gen_load_gpr(t0, rt);
d75c135e 9143 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9144 tcg_temp_free(t0);
9145 }
9c2149c8
TS
9146 opn = "dmtc0";
9147 break;
534ce69f 9148#endif
5204ea79
LA
9149 case OPC_MFHC0:
9150 check_mvh(ctx);
9151 if (rt == 0) {
9152 /* Treat as NOP. */
9153 return;
9154 }
9155 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9156 opn = "mfhc0";
9157 break;
9158 case OPC_MTHC0:
9159 check_mvh(ctx);
9160 {
9161 TCGv t0 = tcg_temp_new();
9162 gen_load_gpr(t0, rt);
9163 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9164 tcg_temp_free(t0);
9165 }
9166 opn = "mthc0";
9167 break;
ead9360e 9168 case OPC_MFTR:
9affc1c5 9169 check_cp0_enabled(ctx);
ead9360e
TS
9170 if (rd == 0) {
9171 /* Treat as NOP. */
9172 return;
9173 }
6c5c1e20 9174 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 9175 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
9176 opn = "mftr";
9177 break;
9178 case OPC_MTTR:
9affc1c5 9179 check_cp0_enabled(ctx);
6c5c1e20 9180 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
9181 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9182 opn = "mttr";
9183 break;
6af0bf9c 9184 case OPC_TLBWI:
6af0bf9c 9185 opn = "tlbwi";
1f8929d2 9186 if (!env->tlb->helper_tlbwi) {
29929e34 9187 goto die;
1f8929d2 9188 }
895c2d04 9189 gen_helper_tlbwi(cpu_env);
6af0bf9c 9190 break;
9456c2fb
LA
9191 case OPC_TLBINV:
9192 opn = "tlbinv";
9193 if (ctx->ie >= 2) {
9194 if (!env->tlb->helper_tlbinv) {
9195 goto die;
9196 }
9197 gen_helper_tlbinv(cpu_env);
9198 } /* treat as nop if TLBINV not supported */
9199 break;
9200 case OPC_TLBINVF:
9201 opn = "tlbinvf";
9202 if (ctx->ie >= 2) {
9203 if (!env->tlb->helper_tlbinvf) {
9204 goto die;
9205 }
9206 gen_helper_tlbinvf(cpu_env);
9207 } /* treat as nop if TLBINV not supported */
9208 break;
6af0bf9c 9209 case OPC_TLBWR:
6af0bf9c 9210 opn = "tlbwr";
1f8929d2 9211 if (!env->tlb->helper_tlbwr) {
29929e34 9212 goto die;
1f8929d2 9213 }
895c2d04 9214 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
9215 break;
9216 case OPC_TLBP:
6af0bf9c 9217 opn = "tlbp";
1f8929d2 9218 if (!env->tlb->helper_tlbp) {
29929e34 9219 goto die;
1f8929d2 9220 }
895c2d04 9221 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
9222 break;
9223 case OPC_TLBR:
6af0bf9c 9224 opn = "tlbr";
1f8929d2 9225 if (!env->tlb->helper_tlbr) {
29929e34 9226 goto die;
1f8929d2 9227 }
895c2d04 9228 gen_helper_tlbr(cpu_env);
6af0bf9c 9229 break;
ce9782f4 9230 case OPC_ERET: /* OPC_ERETNC */
2e211e0a 9231 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 9232 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 9233 goto die;
ce9782f4
LA
9234 } else {
9235 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9236 if (ctx->opcode & (1 << bit_shift)) {
9237 /* OPC_ERETNC */
9238 opn = "eretnc";
5f89ce4f 9239 check_insn(ctx, ISA_MIPS_R5);
ce9782f4
LA
9240 gen_helper_eretnc(cpu_env);
9241 } else {
9242 /* OPC_ERET */
9243 opn = "eret";
9244 check_insn(ctx, ISA_MIPS2);
9245 gen_helper_eret(cpu_env);
9246 }
eeb3bba8 9247 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 9248 }
6af0bf9c
FB
9249 break;
9250 case OPC_DERET:
9251 opn = "deret";
bbd5e4a2 9252 check_insn(ctx, ISA_MIPS_R1);
2e211e0a 9253 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 9254 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9255 goto die;
9256 }
6af0bf9c 9257 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 9258 MIPS_INVAL(opn);
3a4ef3b7 9259 gen_reserved_instruction(ctx);
6af0bf9c 9260 } else {
895c2d04 9261 gen_helper_deret(cpu_env);
eeb3bba8 9262 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
9263 }
9264 break;
4ad40f36
FB
9265 case OPC_WAIT:
9266 opn = "wait";
bbd5e4a2 9267 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
2e211e0a 9268 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 9269 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9270 goto die;
9271 }
4ad40f36 9272 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 9273 ctx->base.pc_next += 4;
4ad40f36 9274 save_cpu_state(ctx, 1);
eeb3bba8 9275 ctx->base.pc_next -= 4;
895c2d04 9276 gen_helper_wait(cpu_env);
eeb3bba8 9277 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 9278 break;
6af0bf9c 9279 default:
29929e34 9280 die:
923617a3 9281 MIPS_INVAL(opn);
3a4ef3b7 9282 gen_reserved_instruction(ctx);
6af0bf9c
FB
9283 return;
9284 }
2abf314d 9285 (void)opn; /* avoid a compiler warning */
6af0bf9c 9286}
f1aa6320 9287#endif /* !CONFIG_USER_ONLY */
6af0bf9c 9288
6ea83fed 9289/* CP1 Branches (before delay slot) */
d75c135e
AJ
9290static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9291 int32_t cc, int32_t offset)
6ea83fed
FB
9292{
9293 target_ulong btarget;
a7812ae4 9294 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 9295
2e211e0a 9296 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 9297 gen_reserved_instruction(ctx);
339cd2a8
LA
9298 goto out;
9299 }
9300
1f8929d2 9301 if (cc != 0) {
bbd5e4a2 9302 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
1f8929d2 9303 }
e189e748 9304
eeb3bba8 9305 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 9306
7a387fff
TS
9307 switch (op) {
9308 case OPC_BC1F:
d94536f4
AJ
9309 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9310 tcg_gen_not_i32(t0, t0);
9311 tcg_gen_andi_i32(t0, t0, 1);
9312 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9313 goto not_likely;
7a387fff 9314 case OPC_BC1FL:
d94536f4
AJ
9315 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9316 tcg_gen_not_i32(t0, t0);
9317 tcg_gen_andi_i32(t0, t0, 1);
9318 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9319 goto likely;
7a387fff 9320 case OPC_BC1T:
d94536f4
AJ
9321 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9322 tcg_gen_andi_i32(t0, t0, 1);
9323 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 9324 goto not_likely;
7a387fff 9325 case OPC_BC1TL:
d94536f4
AJ
9326 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9327 tcg_gen_andi_i32(t0, t0, 1);
9328 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
9329 likely:
9330 ctx->hflags |= MIPS_HFLAG_BL;
9331 break;
5a5012ec 9332 case OPC_BC1FANY2:
a16336e4 9333 {
d94536f4
AJ
9334 TCGv_i32 t1 = tcg_temp_new_i32();
9335 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9336 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d7f66b52 9337 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9338 tcg_temp_free_i32(t1);
d94536f4
AJ
9339 tcg_gen_andi_i32(t0, t0, 1);
9340 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9341 }
5a5012ec
TS
9342 goto not_likely;
9343 case OPC_BC1TANY2:
a16336e4 9344 {
d94536f4
AJ
9345 TCGv_i32 t1 = tcg_temp_new_i32();
9346 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9347 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d94536f4
AJ
9348 tcg_gen_or_i32(t0, t0, t1);
9349 tcg_temp_free_i32(t1);
9350 tcg_gen_andi_i32(t0, t0, 1);
9351 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9352 }
5a5012ec
TS
9353 goto not_likely;
9354 case OPC_BC1FANY4:
a16336e4 9355 {
d94536f4
AJ
9356 TCGv_i32 t1 = tcg_temp_new_i32();
9357 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9358 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d7f66b52 9359 tcg_gen_and_i32(t0, t0, t1);
71375b59 9360 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
d7f66b52 9361 tcg_gen_and_i32(t0, t0, t1);
71375b59 9362 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
d7f66b52 9363 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9364 tcg_temp_free_i32(t1);
d94536f4
AJ
9365 tcg_gen_andi_i32(t0, t0, 1);
9366 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9367 }
5a5012ec
TS
9368 goto not_likely;
9369 case OPC_BC1TANY4:
a16336e4 9370 {
d94536f4
AJ
9371 TCGv_i32 t1 = tcg_temp_new_i32();
9372 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9373 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d94536f4 9374 tcg_gen_or_i32(t0, t0, t1);
71375b59 9375 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
d94536f4 9376 tcg_gen_or_i32(t0, t0, t1);
71375b59 9377 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
d94536f4
AJ
9378 tcg_gen_or_i32(t0, t0, t1);
9379 tcg_temp_free_i32(t1);
9380 tcg_gen_andi_i32(t0, t0, 1);
9381 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9382 }
5a5012ec
TS
9383 not_likely:
9384 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
9385 break;
9386 default:
9d68ac14 9387 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 9388 gen_reserved_instruction(ctx);
6c5c1e20 9389 goto out;
6ea83fed 9390 }
6ea83fed 9391 ctx->btarget = btarget;
b231c103 9392 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 9393 out:
a7812ae4 9394 tcg_temp_free_i32(t0);
6ea83fed
FB
9395}
9396
31837be3
YK
9397/* R6 CP1 Branches */
9398static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
9399 int32_t ft, int32_t offset,
9400 int delayslot_size)
31837be3
YK
9401{
9402 target_ulong btarget;
31837be3
YK
9403 TCGv_i64 t0 = tcg_temp_new_i64();
9404
9405 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9406#ifdef MIPS_DEBUG_DISAS
339cd2a8 9407 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 9408 "\n", ctx->base.pc_next);
31837be3 9409#endif
3a4ef3b7 9410 gen_reserved_instruction(ctx);
31837be3
YK
9411 goto out;
9412 }
9413
9414 gen_load_fpr64(ctx, t0, ft);
9415 tcg_gen_andi_i64(t0, t0, 1);
9416
eeb3bba8 9417 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
9418
9419 switch (op) {
9420 case OPC_BC1EQZ:
9421 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
9422 ctx->hflags |= MIPS_HFLAG_BC;
9423 break;
9424 case OPC_BC1NEZ:
9425 /* t0 already set */
31837be3
YK
9426 ctx->hflags |= MIPS_HFLAG_BC;
9427 break;
9428 default:
9d68ac14 9429 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 9430 gen_reserved_instruction(ctx);
31837be3
YK
9431 goto out;
9432 }
9433
9434 tcg_gen_trunc_i64_tl(bcond, t0);
9435
31837be3 9436 ctx->btarget = btarget;
65935f07
YK
9437
9438 switch (delayslot_size) {
9439 case 2:
9440 ctx->hflags |= MIPS_HFLAG_BDS16;
9441 break;
9442 case 4:
9443 ctx->hflags |= MIPS_HFLAG_BDS32;
9444 break;
9445 }
31837be3
YK
9446
9447out:
9448 tcg_temp_free_i64(t0);
9449}
9450
6af0bf9c 9451/* Coprocessor 1 (FPU) */
5a5012ec 9452
5a5012ec
TS
9453#define FOP(func, fmt) (((fmt) << 21) | (func))
9454
bf4120ad
NF
9455enum fopcode {
9456 OPC_ADD_S = FOP(0, FMT_S),
9457 OPC_SUB_S = FOP(1, FMT_S),
9458 OPC_MUL_S = FOP(2, FMT_S),
9459 OPC_DIV_S = FOP(3, FMT_S),
9460 OPC_SQRT_S = FOP(4, FMT_S),
9461 OPC_ABS_S = FOP(5, FMT_S),
9462 OPC_MOV_S = FOP(6, FMT_S),
9463 OPC_NEG_S = FOP(7, FMT_S),
9464 OPC_ROUND_L_S = FOP(8, FMT_S),
9465 OPC_TRUNC_L_S = FOP(9, FMT_S),
9466 OPC_CEIL_L_S = FOP(10, FMT_S),
9467 OPC_FLOOR_L_S = FOP(11, FMT_S),
9468 OPC_ROUND_W_S = FOP(12, FMT_S),
9469 OPC_TRUNC_W_S = FOP(13, FMT_S),
9470 OPC_CEIL_W_S = FOP(14, FMT_S),
9471 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 9472 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
9473 OPC_MOVCF_S = FOP(17, FMT_S),
9474 OPC_MOVZ_S = FOP(18, FMT_S),
9475 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 9476 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
9477 OPC_RECIP_S = FOP(21, FMT_S),
9478 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
9479 OPC_SELNEZ_S = FOP(23, FMT_S),
9480 OPC_MADDF_S = FOP(24, FMT_S),
9481 OPC_MSUBF_S = FOP(25, FMT_S),
9482 OPC_RINT_S = FOP(26, FMT_S),
9483 OPC_CLASS_S = FOP(27, FMT_S),
9484 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 9485 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 9486 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 9487 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 9488 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 9489 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 9490 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
9491 OPC_RSQRT2_S = FOP(31, FMT_S),
9492 OPC_CVT_D_S = FOP(33, FMT_S),
9493 OPC_CVT_W_S = FOP(36, FMT_S),
9494 OPC_CVT_L_S = FOP(37, FMT_S),
9495 OPC_CVT_PS_S = FOP(38, FMT_S),
235785e8
AM
9496 OPC_CMP_F_S = FOP(48, FMT_S),
9497 OPC_CMP_UN_S = FOP(49, FMT_S),
9498 OPC_CMP_EQ_S = FOP(50, FMT_S),
9499 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9500 OPC_CMP_OLT_S = FOP(52, FMT_S),
9501 OPC_CMP_ULT_S = FOP(53, FMT_S),
9502 OPC_CMP_OLE_S = FOP(54, FMT_S),
9503 OPC_CMP_ULE_S = FOP(55, FMT_S),
9504 OPC_CMP_SF_S = FOP(56, FMT_S),
9505 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9506 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9507 OPC_CMP_NGL_S = FOP(59, FMT_S),
9508 OPC_CMP_LT_S = FOP(60, FMT_S),
9509 OPC_CMP_NGE_S = FOP(61, FMT_S),
9510 OPC_CMP_LE_S = FOP(62, FMT_S),
9511 OPC_CMP_NGT_S = FOP(63, FMT_S),
bf4120ad
NF
9512
9513 OPC_ADD_D = FOP(0, FMT_D),
9514 OPC_SUB_D = FOP(1, FMT_D),
9515 OPC_MUL_D = FOP(2, FMT_D),
9516 OPC_DIV_D = FOP(3, FMT_D),
9517 OPC_SQRT_D = FOP(4, FMT_D),
9518 OPC_ABS_D = FOP(5, FMT_D),
9519 OPC_MOV_D = FOP(6, FMT_D),
9520 OPC_NEG_D = FOP(7, FMT_D),
9521 OPC_ROUND_L_D = FOP(8, FMT_D),
9522 OPC_TRUNC_L_D = FOP(9, FMT_D),
9523 OPC_CEIL_L_D = FOP(10, FMT_D),
9524 OPC_FLOOR_L_D = FOP(11, FMT_D),
9525 OPC_ROUND_W_D = FOP(12, FMT_D),
9526 OPC_TRUNC_W_D = FOP(13, FMT_D),
9527 OPC_CEIL_W_D = FOP(14, FMT_D),
9528 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 9529 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
9530 OPC_MOVCF_D = FOP(17, FMT_D),
9531 OPC_MOVZ_D = FOP(18, FMT_D),
9532 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 9533 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
9534 OPC_RECIP_D = FOP(21, FMT_D),
9535 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
9536 OPC_SELNEZ_D = FOP(23, FMT_D),
9537 OPC_MADDF_D = FOP(24, FMT_D),
9538 OPC_MSUBF_D = FOP(25, FMT_D),
9539 OPC_RINT_D = FOP(26, FMT_D),
9540 OPC_CLASS_D = FOP(27, FMT_D),
9541 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 9542 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 9543 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 9544 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 9545 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 9546 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 9547 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
9548 OPC_RSQRT2_D = FOP(31, FMT_D),
9549 OPC_CVT_S_D = FOP(32, FMT_D),
9550 OPC_CVT_W_D = FOP(36, FMT_D),
9551 OPC_CVT_L_D = FOP(37, FMT_D),
235785e8
AM
9552 OPC_CMP_F_D = FOP(48, FMT_D),
9553 OPC_CMP_UN_D = FOP(49, FMT_D),
9554 OPC_CMP_EQ_D = FOP(50, FMT_D),
9555 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9556 OPC_CMP_OLT_D = FOP(52, FMT_D),
9557 OPC_CMP_ULT_D = FOP(53, FMT_D),
9558 OPC_CMP_OLE_D = FOP(54, FMT_D),
9559 OPC_CMP_ULE_D = FOP(55, FMT_D),
9560 OPC_CMP_SF_D = FOP(56, FMT_D),
9561 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9562 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9563 OPC_CMP_NGL_D = FOP(59, FMT_D),
9564 OPC_CMP_LT_D = FOP(60, FMT_D),
9565 OPC_CMP_NGE_D = FOP(61, FMT_D),
9566 OPC_CMP_LE_D = FOP(62, FMT_D),
9567 OPC_CMP_NGT_D = FOP(63, FMT_D),
bf4120ad
NF
9568
9569 OPC_CVT_S_W = FOP(32, FMT_W),
9570 OPC_CVT_D_W = FOP(33, FMT_W),
9571 OPC_CVT_S_L = FOP(32, FMT_L),
9572 OPC_CVT_D_L = FOP(33, FMT_L),
9573 OPC_CVT_PS_PW = FOP(38, FMT_W),
9574
9575 OPC_ADD_PS = FOP(0, FMT_PS),
9576 OPC_SUB_PS = FOP(1, FMT_PS),
9577 OPC_MUL_PS = FOP(2, FMT_PS),
9578 OPC_DIV_PS = FOP(3, FMT_PS),
9579 OPC_ABS_PS = FOP(5, FMT_PS),
9580 OPC_MOV_PS = FOP(6, FMT_PS),
9581 OPC_NEG_PS = FOP(7, FMT_PS),
9582 OPC_MOVCF_PS = FOP(17, FMT_PS),
9583 OPC_MOVZ_PS = FOP(18, FMT_PS),
9584 OPC_MOVN_PS = FOP(19, FMT_PS),
9585 OPC_ADDR_PS = FOP(24, FMT_PS),
9586 OPC_MULR_PS = FOP(26, FMT_PS),
9587 OPC_RECIP2_PS = FOP(28, FMT_PS),
9588 OPC_RECIP1_PS = FOP(29, FMT_PS),
9589 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9590 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9591
9592 OPC_CVT_S_PU = FOP(32, FMT_PS),
9593 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9594 OPC_CVT_S_PL = FOP(40, FMT_PS),
9595 OPC_PLL_PS = FOP(44, FMT_PS),
9596 OPC_PLU_PS = FOP(45, FMT_PS),
9597 OPC_PUL_PS = FOP(46, FMT_PS),
9598 OPC_PUU_PS = FOP(47, FMT_PS),
235785e8
AM
9599 OPC_CMP_F_PS = FOP(48, FMT_PS),
9600 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9601 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9602 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9603 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9604 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9605 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9606 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9607 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9608 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9609 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9610 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9611 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9612 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9613 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9614 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
bf4120ad
NF
9615};
9616
3f493883
YK
9617enum r6_f_cmp_op {
9618 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9619 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9620 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9621 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9622 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9623 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9624 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9625 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9626 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9627 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9628 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9629 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9630 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9631 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9632 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9633 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9634 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9635 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9636 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9637 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9638 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9639 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9640
9641 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9642 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9643 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9644 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9645 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9646 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9647 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9648 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9649 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9650 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9651 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9652 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9653 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9654 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9655 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9656 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9657 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9658 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9659 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9660 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9661 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9662 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9663};
235785e8
AM
9664
9665static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 9666{
72c3a3ee 9667 TCGv t0 = tcg_temp_new();
6ea83fed
FB
9668
9669 switch (opc) {
9670 case OPC_MFC1:
b6d96bed 9671 {
a7812ae4 9672 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9673
7c979afd 9674 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 9675 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9676 tcg_temp_free_i32(fp0);
6958549d 9677 }
6c5c1e20 9678 gen_store_gpr(t0, rt);
6ea83fed
FB
9679 break;
9680 case OPC_MTC1:
6c5c1e20 9681 gen_load_gpr(t0, rt);
b6d96bed 9682 {
a7812ae4 9683 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9684
9685 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9686 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 9687 tcg_temp_free_i32(fp0);
6958549d 9688 }
6ea83fed
FB
9689 break;
9690 case OPC_CFC1:
895c2d04 9691 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 9692 gen_store_gpr(t0, rt);
6ea83fed
FB
9693 break;
9694 case OPC_CTC1:
6c5c1e20 9695 gen_load_gpr(t0, rt);
9c708c7f 9696 save_cpu_state(ctx, 0);
736d120a
PJ
9697 {
9698 TCGv_i32 fs_tmp = tcg_const_i32(fs);
9699
9700 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9701 tcg_temp_free_i32(fs_tmp);
9702 }
4cf8a45f 9703 /* Stop translation as we may have changed hflags */
eeb3bba8 9704 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 9705 break;
72c3a3ee 9706#if defined(TARGET_MIPS64)
9c2149c8 9707 case OPC_DMFC1:
72c3a3ee 9708 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 9709 gen_store_gpr(t0, rt);
5a5012ec 9710 break;
9c2149c8 9711 case OPC_DMTC1:
6c5c1e20 9712 gen_load_gpr(t0, rt);
72c3a3ee 9713 gen_store_fpr64(ctx, t0, fs);
5a5012ec 9714 break;
72c3a3ee 9715#endif
5a5012ec 9716 case OPC_MFHC1:
b6d96bed 9717 {
a7812ae4 9718 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9719
7f6613ce 9720 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 9721 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9722 tcg_temp_free_i32(fp0);
6958549d 9723 }
6c5c1e20 9724 gen_store_gpr(t0, rt);
5a5012ec
TS
9725 break;
9726 case OPC_MTHC1:
6c5c1e20 9727 gen_load_gpr(t0, rt);
b6d96bed 9728 {
a7812ae4 9729 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9730
9731 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9732 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 9733 tcg_temp_free_i32(fp0);
6958549d 9734 }
5a5012ec 9735 break;
6ea83fed 9736 default:
9d68ac14 9737 MIPS_INVAL("cp1 move");
3a4ef3b7 9738 gen_reserved_instruction(ctx);
6c5c1e20 9739 goto out;
6ea83fed 9740 }
6c5c1e20
TS
9741
9742 out:
9743 tcg_temp_free(t0);
6ea83fed
FB
9744}
9745
235785e8 9746static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
5a5012ec 9747{
42a268c2 9748 TCGLabel *l1;
e214b9bb 9749 TCGCond cond;
af58f9ca
AJ
9750 TCGv_i32 t0;
9751
9752 if (rd == 0) {
9753 /* Treat as NOP. */
9754 return;
9755 }
6ea83fed 9756
1f8929d2 9757 if (tf) {
e214b9bb 9758 cond = TCG_COND_EQ;
1f8929d2 9759 } else {
27848470 9760 cond = TCG_COND_NE;
1f8929d2 9761 }
27848470 9762
af58f9ca
AJ
9763 l1 = gen_new_label();
9764 t0 = tcg_temp_new_i32();
fa31af0e 9765 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 9766 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9767 tcg_temp_free_i32(t0);
c27b4579 9768 gen_load_gpr(cpu_gpr[rd], rs);
e214b9bb 9769 gen_set_label(l1);
5a5012ec
TS
9770}
9771
7c979afd
LA
9772static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9773 int tf)
a16336e4 9774{
a16336e4 9775 int cond;
cbc37b28 9776 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 9777 TCGLabel *l1 = gen_new_label();
a16336e4 9778
1f8929d2 9779 if (tf) {
a16336e4 9780 cond = TCG_COND_EQ;
1f8929d2 9781 } else {
a16336e4 9782 cond = TCG_COND_NE;
1f8929d2 9783 }
a16336e4 9784
fa31af0e 9785 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9786 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9787 gen_load_fpr32(ctx, t0, fs);
9788 gen_store_fpr32(ctx, t0, fd);
a16336e4 9789 gen_set_label(l1);
cbc37b28 9790 tcg_temp_free_i32(t0);
5a5012ec 9791}
a16336e4 9792
235785e8
AM
9793static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9794 int tf)
a16336e4 9795{
a16336e4 9796 int cond;
cbc37b28
AJ
9797 TCGv_i32 t0 = tcg_temp_new_i32();
9798 TCGv_i64 fp0;
42a268c2 9799 TCGLabel *l1 = gen_new_label();
a16336e4 9800
1f8929d2 9801 if (tf) {
a16336e4 9802 cond = TCG_COND_EQ;
1f8929d2 9803 } else {
a16336e4 9804 cond = TCG_COND_NE;
1f8929d2 9805 }
a16336e4 9806
fa31af0e 9807 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9808 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9809 tcg_temp_free_i32(t0);
11f94258 9810 fp0 = tcg_temp_new_i64();
9bf3eb2c 9811 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 9812 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9813 tcg_temp_free_i64(fp0);
cbc37b28 9814 gen_set_label(l1);
a16336e4
TS
9815}
9816
7f6613ce
PJ
9817static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9818 int cc, int tf)
a16336e4
TS
9819{
9820 int cond;
cbc37b28 9821 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
9822 TCGLabel *l1 = gen_new_label();
9823 TCGLabel *l2 = gen_new_label();
a16336e4 9824
1f8929d2 9825 if (tf) {
a16336e4 9826 cond = TCG_COND_EQ;
1f8929d2 9827 } else {
a16336e4 9828 cond = TCG_COND_NE;
1f8929d2 9829 }
a16336e4 9830
fa31af0e 9831 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9832 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9833 gen_load_fpr32(ctx, t0, fs);
9834 gen_store_fpr32(ctx, t0, fd);
a16336e4 9835 gen_set_label(l1);
9bf3eb2c 9836
71375b59 9837 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
cbc37b28 9838 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
9839 gen_load_fpr32h(ctx, t0, fs);
9840 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 9841 tcg_temp_free_i32(t0);
a16336e4 9842 gen_set_label(l2);
a16336e4
TS
9843}
9844
e7f16abb
LA
9845static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9846 int fs)
9847{
9848 TCGv_i32 t1 = tcg_const_i32(0);
9849 TCGv_i32 fp0 = tcg_temp_new_i32();
9850 TCGv_i32 fp1 = tcg_temp_new_i32();
9851 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9852 gen_load_fpr32(ctx, fp0, fd);
9853 gen_load_fpr32(ctx, fp1, ft);
9854 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9855
9856 switch (op1) {
9857 case OPC_SEL_S:
9858 tcg_gen_andi_i32(fp0, fp0, 1);
9859 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9860 break;
9861 case OPC_SELEQZ_S:
9862 tcg_gen_andi_i32(fp1, fp1, 1);
9863 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9864 break;
9865 case OPC_SELNEZ_S:
9866 tcg_gen_andi_i32(fp1, fp1, 1);
9867 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9868 break;
9869 default:
9870 MIPS_INVAL("gen_sel_s");
3a4ef3b7 9871 gen_reserved_instruction(ctx);
e7f16abb
LA
9872 break;
9873 }
9874
7c979afd 9875 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9876 tcg_temp_free_i32(fp2);
9877 tcg_temp_free_i32(fp1);
9878 tcg_temp_free_i32(fp0);
9879 tcg_temp_free_i32(t1);
9880}
9881
9882static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9883 int fs)
9884{
9885 TCGv_i64 t1 = tcg_const_i64(0);
9886 TCGv_i64 fp0 = tcg_temp_new_i64();
9887 TCGv_i64 fp1 = tcg_temp_new_i64();
9888 TCGv_i64 fp2 = tcg_temp_new_i64();
9889 gen_load_fpr64(ctx, fp0, fd);
9890 gen_load_fpr64(ctx, fp1, ft);
9891 gen_load_fpr64(ctx, fp2, fs);
9892
9893 switch (op1) {
9894 case OPC_SEL_D:
9895 tcg_gen_andi_i64(fp0, fp0, 1);
9896 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9897 break;
9898 case OPC_SELEQZ_D:
9899 tcg_gen_andi_i64(fp1, fp1, 1);
9900 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9901 break;
9902 case OPC_SELNEZ_D:
9903 tcg_gen_andi_i64(fp1, fp1, 1);
9904 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9905 break;
9906 default:
9907 MIPS_INVAL("gen_sel_d");
3a4ef3b7 9908 gen_reserved_instruction(ctx);
e7f16abb
LA
9909 break;
9910 }
9911
9912 gen_store_fpr64(ctx, fp0, fd);
9913 tcg_temp_free_i64(fp2);
9914 tcg_temp_free_i64(fp1);
9915 tcg_temp_free_i64(fp0);
9916 tcg_temp_free_i64(t1);
9917}
6ea83fed 9918
235785e8
AM
9919static void gen_farith(DisasContext *ctx, enum fopcode op1,
9920 int ft, int fs, int fd, int cc)
6ea83fed 9921{
7a387fff 9922 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9923 switch (op1) {
9924 case OPC_ADD_S:
b6d96bed 9925 {
a7812ae4
PB
9926 TCGv_i32 fp0 = tcg_temp_new_i32();
9927 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9928
7c979afd
LA
9929 gen_load_fpr32(ctx, fp0, fs);
9930 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9931 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9932 tcg_temp_free_i32(fp1);
7c979afd 9933 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9934 tcg_temp_free_i32(fp0);
b6d96bed 9935 }
5a5012ec 9936 break;
bf4120ad 9937 case OPC_SUB_S:
b6d96bed 9938 {
a7812ae4
PB
9939 TCGv_i32 fp0 = tcg_temp_new_i32();
9940 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9941
7c979afd
LA
9942 gen_load_fpr32(ctx, fp0, fs);
9943 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9944 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9945 tcg_temp_free_i32(fp1);
7c979afd 9946 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9947 tcg_temp_free_i32(fp0);
b6d96bed 9948 }
5a5012ec 9949 break;
bf4120ad 9950 case OPC_MUL_S:
b6d96bed 9951 {
a7812ae4
PB
9952 TCGv_i32 fp0 = tcg_temp_new_i32();
9953 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9954
7c979afd
LA
9955 gen_load_fpr32(ctx, fp0, fs);
9956 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9957 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9958 tcg_temp_free_i32(fp1);
7c979afd 9959 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9960 tcg_temp_free_i32(fp0);
b6d96bed 9961 }
5a5012ec 9962 break;
bf4120ad 9963 case OPC_DIV_S:
b6d96bed 9964 {
a7812ae4
PB
9965 TCGv_i32 fp0 = tcg_temp_new_i32();
9966 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9967
7c979afd
LA
9968 gen_load_fpr32(ctx, fp0, fs);
9969 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9970 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9971 tcg_temp_free_i32(fp1);
7c979afd 9972 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9973 tcg_temp_free_i32(fp0);
b6d96bed 9974 }
5a5012ec 9975 break;
bf4120ad 9976 case OPC_SQRT_S:
b6d96bed 9977 {
a7812ae4 9978 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9979
7c979afd 9980 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9981 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9982 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9983 tcg_temp_free_i32(fp0);
b6d96bed 9984 }
5a5012ec 9985 break;
bf4120ad 9986 case OPC_ABS_S:
b6d96bed 9987 {
a7812ae4 9988 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9989
7c979afd 9990 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9991 if (ctx->abs2008) {
9992 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9993 } else {
9994 gen_helper_float_abs_s(fp0, fp0);
9995 }
7c979afd 9996 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9997 tcg_temp_free_i32(fp0);
b6d96bed 9998 }
5a5012ec 9999 break;
bf4120ad 10000 case OPC_MOV_S:
b6d96bed 10001 {
a7812ae4 10002 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10003
7c979afd
LA
10004 gen_load_fpr32(ctx, fp0, fs);
10005 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10006 tcg_temp_free_i32(fp0);
b6d96bed 10007 }
5a5012ec 10008 break;
bf4120ad 10009 case OPC_NEG_S:
b6d96bed 10010 {
a7812ae4 10011 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10012
7c979afd 10013 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10014 if (ctx->abs2008) {
10015 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10016 } else {
10017 gen_helper_float_chs_s(fp0, fp0);
10018 }
7c979afd 10019 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10020 tcg_temp_free_i32(fp0);
b6d96bed 10021 }
5a5012ec 10022 break;
bf4120ad 10023 case OPC_ROUND_L_S:
5e755519 10024 check_cp1_64bitmode(ctx);
b6d96bed 10025 {
a7812ae4
PB
10026 TCGv_i32 fp32 = tcg_temp_new_i32();
10027 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10028
7c979afd 10029 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10030 if (ctx->nan2008) {
10031 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10032 } else {
10033 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10034 }
a7812ae4 10035 tcg_temp_free_i32(fp32);
b6d96bed 10036 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10037 tcg_temp_free_i64(fp64);
b6d96bed 10038 }
5a5012ec 10039 break;
bf4120ad 10040 case OPC_TRUNC_L_S:
5e755519 10041 check_cp1_64bitmode(ctx);
b6d96bed 10042 {
a7812ae4
PB
10043 TCGv_i32 fp32 = tcg_temp_new_i32();
10044 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10045
7c979afd 10046 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10047 if (ctx->nan2008) {
10048 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10049 } else {
10050 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10051 }
a7812ae4 10052 tcg_temp_free_i32(fp32);
b6d96bed 10053 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10054 tcg_temp_free_i64(fp64);
b6d96bed 10055 }
5a5012ec 10056 break;
bf4120ad 10057 case OPC_CEIL_L_S:
5e755519 10058 check_cp1_64bitmode(ctx);
b6d96bed 10059 {
a7812ae4
PB
10060 TCGv_i32 fp32 = tcg_temp_new_i32();
10061 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10062
7c979afd 10063 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10064 if (ctx->nan2008) {
10065 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10066 } else {
10067 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10068 }
a7812ae4 10069 tcg_temp_free_i32(fp32);
b6d96bed 10070 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10071 tcg_temp_free_i64(fp64);
b6d96bed 10072 }
5a5012ec 10073 break;
bf4120ad 10074 case OPC_FLOOR_L_S:
5e755519 10075 check_cp1_64bitmode(ctx);
b6d96bed 10076 {
a7812ae4
PB
10077 TCGv_i32 fp32 = tcg_temp_new_i32();
10078 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10079
7c979afd 10080 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10081 if (ctx->nan2008) {
10082 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10083 } else {
10084 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10085 }
a7812ae4 10086 tcg_temp_free_i32(fp32);
b6d96bed 10087 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10088 tcg_temp_free_i64(fp64);
b6d96bed 10089 }
5a5012ec 10090 break;
bf4120ad 10091 case OPC_ROUND_W_S:
b6d96bed 10092 {
a7812ae4 10093 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10094
7c979afd 10095 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10096 if (ctx->nan2008) {
10097 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10098 } else {
10099 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10100 }
7c979afd 10101 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10102 tcg_temp_free_i32(fp0);
b6d96bed 10103 }
5a5012ec 10104 break;
bf4120ad 10105 case OPC_TRUNC_W_S:
b6d96bed 10106 {
a7812ae4 10107 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10108
7c979afd 10109 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10110 if (ctx->nan2008) {
10111 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10112 } else {
10113 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10114 }
7c979afd 10115 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10116 tcg_temp_free_i32(fp0);
b6d96bed 10117 }
5a5012ec 10118 break;
bf4120ad 10119 case OPC_CEIL_W_S:
b6d96bed 10120 {
a7812ae4 10121 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10122
7c979afd 10123 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10124 if (ctx->nan2008) {
10125 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10126 } else {
10127 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10128 }
7c979afd 10129 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10130 tcg_temp_free_i32(fp0);
b6d96bed 10131 }
5a5012ec 10132 break;
bf4120ad 10133 case OPC_FLOOR_W_S:
b6d96bed 10134 {
a7812ae4 10135 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10136
7c979afd 10137 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10138 if (ctx->nan2008) {
10139 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10140 } else {
10141 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10142 }
7c979afd 10143 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10144 tcg_temp_free_i32(fp0);
b6d96bed 10145 }
5a5012ec 10146 break;
e7f16abb 10147 case OPC_SEL_S:
2e211e0a 10148 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10149 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10150 break;
10151 case OPC_SELEQZ_S:
2e211e0a 10152 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10153 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10154 break;
10155 case OPC_SELNEZ_S:
2e211e0a 10156 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10157 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 10158 break;
bf4120ad 10159 case OPC_MOVCF_S:
2e211e0a 10160 check_insn_opc_removed(ctx, ISA_MIPS_R6);
7c979afd 10161 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 10162 break;
bf4120ad 10163 case OPC_MOVZ_S:
2e211e0a 10164 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10165 {
42a268c2 10166 TCGLabel *l1 = gen_new_label();
c9297f4d 10167 TCGv_i32 fp0;
a16336e4 10168
c9297f4d
AJ
10169 if (ft != 0) {
10170 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10171 }
10172 fp0 = tcg_temp_new_i32();
7c979afd
LA
10173 gen_load_fpr32(ctx, fp0, fs);
10174 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10175 tcg_temp_free_i32(fp0);
a16336e4
TS
10176 gen_set_label(l1);
10177 }
5a5012ec 10178 break;
bf4120ad 10179 case OPC_MOVN_S:
2e211e0a 10180 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10181 {
42a268c2 10182 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10183 TCGv_i32 fp0;
10184
10185 if (ft != 0) {
10186 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10187 fp0 = tcg_temp_new_i32();
7c979afd
LA
10188 gen_load_fpr32(ctx, fp0, fs);
10189 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
10190 tcg_temp_free_i32(fp0);
10191 gen_set_label(l1);
10192 }
a16336e4 10193 }
5a5012ec 10194 break;
bf4120ad 10195 case OPC_RECIP_S:
b6d96bed 10196 {
a7812ae4 10197 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10198
7c979afd 10199 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10200 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 10201 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10202 tcg_temp_free_i32(fp0);
b6d96bed 10203 }
57fa1fb3 10204 break;
bf4120ad 10205 case OPC_RSQRT_S:
b6d96bed 10206 {
a7812ae4 10207 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10208
7c979afd 10209 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10210 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 10211 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10212 tcg_temp_free_i32(fp0);
b6d96bed 10213 }
57fa1fb3 10214 break;
e7f16abb 10215 case OPC_MADDF_S:
2e211e0a 10216 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10217 {
a7812ae4
PB
10218 TCGv_i32 fp0 = tcg_temp_new_i32();
10219 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10220 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10221 gen_load_fpr32(ctx, fp0, fs);
10222 gen_load_fpr32(ctx, fp1, ft);
10223 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10224 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10225 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 10226 tcg_temp_free_i32(fp2);
a7812ae4 10227 tcg_temp_free_i32(fp1);
a7812ae4 10228 tcg_temp_free_i32(fp0);
b6d96bed 10229 }
57fa1fb3 10230 break;
e7f16abb 10231 case OPC_MSUBF_S:
2e211e0a 10232 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10233 {
a7812ae4 10234 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
10235 TCGv_i32 fp1 = tcg_temp_new_i32();
10236 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10237 gen_load_fpr32(ctx, fp0, fs);
10238 gen_load_fpr32(ctx, fp1, ft);
10239 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10240 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10241 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10242 tcg_temp_free_i32(fp2);
10243 tcg_temp_free_i32(fp1);
a7812ae4 10244 tcg_temp_free_i32(fp0);
b6d96bed 10245 }
57fa1fb3 10246 break;
e7f16abb 10247 case OPC_RINT_S:
2e211e0a 10248 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10249 {
a7812ae4 10250 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10251 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10252 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 10253 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10254 tcg_temp_free_i32(fp0);
b6d96bed 10255 }
57fa1fb3 10256 break;
e7f16abb 10257 case OPC_CLASS_S:
2e211e0a 10258 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10259 {
e7f16abb 10260 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10261 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 10262 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 10263 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 10264 tcg_temp_free_i32(fp0);
e7f16abb
LA
10265 }
10266 break;
10267 case OPC_MIN_S: /* OPC_RECIP2_S */
2e211e0a 10268 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb 10269 /* OPC_MIN_S */
a7812ae4
PB
10270 TCGv_i32 fp0 = tcg_temp_new_i32();
10271 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10272 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10273 gen_load_fpr32(ctx, fp0, fs);
10274 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10275 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 10276 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10277 tcg_temp_free_i32(fp2);
10278 tcg_temp_free_i32(fp1);
10279 tcg_temp_free_i32(fp0);
e7f16abb
LA
10280 } else {
10281 /* OPC_RECIP2_S */
10282 check_cp1_64bitmode(ctx);
10283 {
10284 TCGv_i32 fp0 = tcg_temp_new_i32();
10285 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10286
7c979afd
LA
10287 gen_load_fpr32(ctx, fp0, fs);
10288 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10289 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10290 tcg_temp_free_i32(fp1);
7c979afd 10291 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10292 tcg_temp_free_i32(fp0);
10293 }
e7f16abb
LA
10294 }
10295 break;
10296 case OPC_MINA_S: /* OPC_RECIP1_S */
2e211e0a 10297 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10298 /* OPC_MINA_S */
10299 TCGv_i32 fp0 = tcg_temp_new_i32();
10300 TCGv_i32 fp1 = tcg_temp_new_i32();
10301 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10302 gen_load_fpr32(ctx, fp0, fs);
10303 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10304 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 10305 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10306 tcg_temp_free_i32(fp2);
10307 tcg_temp_free_i32(fp1);
10308 tcg_temp_free_i32(fp0);
e7f16abb
LA
10309 } else {
10310 /* OPC_RECIP1_S */
10311 check_cp1_64bitmode(ctx);
10312 {
10313 TCGv_i32 fp0 = tcg_temp_new_i32();
10314
7c979afd 10315 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10316 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 10317 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10318 tcg_temp_free_i32(fp0);
10319 }
e7f16abb
LA
10320 }
10321 break;
10322 case OPC_MAX_S: /* OPC_RSQRT1_S */
2e211e0a 10323 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10324 /* OPC_MAX_S */
10325 TCGv_i32 fp0 = tcg_temp_new_i32();
10326 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10327 gen_load_fpr32(ctx, fp0, fs);
10328 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10329 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 10330 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
10331 tcg_temp_free_i32(fp1);
10332 tcg_temp_free_i32(fp0);
e7f16abb
LA
10333 } else {
10334 /* OPC_RSQRT1_S */
10335 check_cp1_64bitmode(ctx);
10336 {
10337 TCGv_i32 fp0 = tcg_temp_new_i32();
10338
7c979afd 10339 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10340 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 10341 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10342 tcg_temp_free_i32(fp0);
10343 }
e7f16abb
LA
10344 }
10345 break;
10346 case OPC_MAXA_S: /* OPC_RSQRT2_S */
2e211e0a 10347 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10348 /* OPC_MAXA_S */
10349 TCGv_i32 fp0 = tcg_temp_new_i32();
10350 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10351 gen_load_fpr32(ctx, fp0, fs);
10352 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10353 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 10354 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 10355 tcg_temp_free_i32(fp1);
a7812ae4 10356 tcg_temp_free_i32(fp0);
e7f16abb
LA
10357 } else {
10358 /* OPC_RSQRT2_S */
10359 check_cp1_64bitmode(ctx);
10360 {
10361 TCGv_i32 fp0 = tcg_temp_new_i32();
10362 TCGv_i32 fp1 = tcg_temp_new_i32();
10363
7c979afd
LA
10364 gen_load_fpr32(ctx, fp0, fs);
10365 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10366 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10367 tcg_temp_free_i32(fp1);
7c979afd 10368 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10369 tcg_temp_free_i32(fp0);
10370 }
b6d96bed 10371 }
57fa1fb3 10372 break;
bf4120ad 10373 case OPC_CVT_D_S:
5e755519 10374 check_cp1_registers(ctx, fd);
b6d96bed 10375 {
a7812ae4
PB
10376 TCGv_i32 fp32 = tcg_temp_new_i32();
10377 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10378
7c979afd 10379 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10380 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 10381 tcg_temp_free_i32(fp32);
b6d96bed 10382 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10383 tcg_temp_free_i64(fp64);
b6d96bed 10384 }
5a5012ec 10385 break;
bf4120ad 10386 case OPC_CVT_W_S:
b6d96bed 10387 {
a7812ae4 10388 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10389
7c979afd 10390 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10391 if (ctx->nan2008) {
10392 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10393 } else {
10394 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10395 }
7c979afd 10396 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10397 tcg_temp_free_i32(fp0);
b6d96bed 10398 }
5a5012ec 10399 break;
bf4120ad 10400 case OPC_CVT_L_S:
5e755519 10401 check_cp1_64bitmode(ctx);
b6d96bed 10402 {
a7812ae4
PB
10403 TCGv_i32 fp32 = tcg_temp_new_i32();
10404 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10405
7c979afd 10406 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10407 if (ctx->nan2008) {
10408 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10409 } else {
10410 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10411 }
a7812ae4 10412 tcg_temp_free_i32(fp32);
b6d96bed 10413 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10414 tcg_temp_free_i64(fp64);
b6d96bed 10415 }
5a5012ec 10416 break;
bf4120ad 10417 case OPC_CVT_PS_S:
e29c9628 10418 check_ps(ctx);
b6d96bed 10419 {
a7812ae4
PB
10420 TCGv_i64 fp64 = tcg_temp_new_i64();
10421 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10422 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 10423
7c979afd
LA
10424 gen_load_fpr32(ctx, fp32_0, fs);
10425 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 10426 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
10427 tcg_temp_free_i32(fp32_1);
10428 tcg_temp_free_i32(fp32_0);
36aa55dc 10429 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10430 tcg_temp_free_i64(fp64);
b6d96bed 10431 }
5a5012ec 10432 break;
bf4120ad
NF
10433 case OPC_CMP_F_S:
10434 case OPC_CMP_UN_S:
10435 case OPC_CMP_EQ_S:
10436 case OPC_CMP_UEQ_S:
10437 case OPC_CMP_OLT_S:
10438 case OPC_CMP_ULT_S:
10439 case OPC_CMP_OLE_S:
10440 case OPC_CMP_ULE_S:
10441 case OPC_CMP_SF_S:
10442 case OPC_CMP_NGLE_S:
10443 case OPC_CMP_SEQ_S:
10444 case OPC_CMP_NGL_S:
10445 case OPC_CMP_LT_S:
10446 case OPC_CMP_NGE_S:
10447 case OPC_CMP_LE_S:
10448 case OPC_CMP_NGT_S:
2e211e0a 10449 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8153667c 10450 if (ctx->opcode & (1 << 6)) {
71375b59 10451 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
8153667c 10452 } else {
71375b59 10453 gen_cmp_s(ctx, func - 48, ft, fs, cc);
5a1e8ffb 10454 }
5a5012ec 10455 break;
bf4120ad 10456 case OPC_ADD_D:
5e755519 10457 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10458 {
a7812ae4
PB
10459 TCGv_i64 fp0 = tcg_temp_new_i64();
10460 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10461
10462 gen_load_fpr64(ctx, fp0, fs);
10463 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10464 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10465 tcg_temp_free_i64(fp1);
b6d96bed 10466 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10467 tcg_temp_free_i64(fp0);
b6d96bed 10468 }
6ea83fed 10469 break;
bf4120ad 10470 case OPC_SUB_D:
5e755519 10471 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10472 {
a7812ae4
PB
10473 TCGv_i64 fp0 = tcg_temp_new_i64();
10474 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10475
10476 gen_load_fpr64(ctx, fp0, fs);
10477 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10478 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10479 tcg_temp_free_i64(fp1);
b6d96bed 10480 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10481 tcg_temp_free_i64(fp0);
b6d96bed 10482 }
6ea83fed 10483 break;
bf4120ad 10484 case OPC_MUL_D:
5e755519 10485 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10486 {
a7812ae4
PB
10487 TCGv_i64 fp0 = tcg_temp_new_i64();
10488 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10489
10490 gen_load_fpr64(ctx, fp0, fs);
10491 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10492 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10493 tcg_temp_free_i64(fp1);
b6d96bed 10494 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10495 tcg_temp_free_i64(fp0);
b6d96bed 10496 }
6ea83fed 10497 break;
bf4120ad 10498 case OPC_DIV_D:
5e755519 10499 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10500 {
a7812ae4
PB
10501 TCGv_i64 fp0 = tcg_temp_new_i64();
10502 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10503
10504 gen_load_fpr64(ctx, fp0, fs);
10505 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10506 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10507 tcg_temp_free_i64(fp1);
b6d96bed 10508 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10509 tcg_temp_free_i64(fp0);
b6d96bed 10510 }
6ea83fed 10511 break;
bf4120ad 10512 case OPC_SQRT_D:
5e755519 10513 check_cp1_registers(ctx, fs | fd);
b6d96bed 10514 {
a7812ae4 10515 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10516
10517 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10518 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 10519 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10520 tcg_temp_free_i64(fp0);
b6d96bed 10521 }
6ea83fed 10522 break;
bf4120ad 10523 case OPC_ABS_D:
5e755519 10524 check_cp1_registers(ctx, fs | fd);
b6d96bed 10525 {
a7812ae4 10526 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10527
10528 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
10529 if (ctx->abs2008) {
10530 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10531 } else {
10532 gen_helper_float_abs_d(fp0, fp0);
10533 }
b6d96bed 10534 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10535 tcg_temp_free_i64(fp0);
b6d96bed 10536 }
6ea83fed 10537 break;
bf4120ad 10538 case OPC_MOV_D:
5e755519 10539 check_cp1_registers(ctx, fs | fd);
b6d96bed 10540 {
a7812ae4 10541 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10542
10543 gen_load_fpr64(ctx, fp0, fs);
10544 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10545 tcg_temp_free_i64(fp0);
b6d96bed 10546 }
6ea83fed 10547 break;
bf4120ad 10548 case OPC_NEG_D:
5e755519 10549 check_cp1_registers(ctx, fs | fd);
b6d96bed 10550 {
a7812ae4 10551 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10552
10553 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
10554 if (ctx->abs2008) {
10555 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10556 } else {
10557 gen_helper_float_chs_d(fp0, fp0);
10558 }
b6d96bed 10559 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10560 tcg_temp_free_i64(fp0);
b6d96bed 10561 }
6ea83fed 10562 break;
bf4120ad 10563 case OPC_ROUND_L_D:
5e755519 10564 check_cp1_64bitmode(ctx);
b6d96bed 10565 {
a7812ae4 10566 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10567
10568 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10569 if (ctx->nan2008) {
10570 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10571 } else {
10572 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10573 }
b6d96bed 10574 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10575 tcg_temp_free_i64(fp0);
b6d96bed 10576 }
5a5012ec 10577 break;
bf4120ad 10578 case OPC_TRUNC_L_D:
5e755519 10579 check_cp1_64bitmode(ctx);
b6d96bed 10580 {
a7812ae4 10581 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10582
10583 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10584 if (ctx->nan2008) {
10585 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10586 } else {
10587 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10588 }
b6d96bed 10589 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10590 tcg_temp_free_i64(fp0);
b6d96bed 10591 }
5a5012ec 10592 break;
bf4120ad 10593 case OPC_CEIL_L_D:
5e755519 10594 check_cp1_64bitmode(ctx);
b6d96bed 10595 {
a7812ae4 10596 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10597
10598 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10599 if (ctx->nan2008) {
10600 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10601 } else {
10602 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10603 }
b6d96bed 10604 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10605 tcg_temp_free_i64(fp0);
b6d96bed 10606 }
5a5012ec 10607 break;
bf4120ad 10608 case OPC_FLOOR_L_D:
5e755519 10609 check_cp1_64bitmode(ctx);
b6d96bed 10610 {
a7812ae4 10611 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10612
10613 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10614 if (ctx->nan2008) {
10615 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10616 } else {
10617 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10618 }
b6d96bed 10619 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10620 tcg_temp_free_i64(fp0);
b6d96bed 10621 }
5a5012ec 10622 break;
bf4120ad 10623 case OPC_ROUND_W_D:
5e755519 10624 check_cp1_registers(ctx, fs);
b6d96bed 10625 {
a7812ae4
PB
10626 TCGv_i32 fp32 = tcg_temp_new_i32();
10627 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10628
10629 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10630 if (ctx->nan2008) {
10631 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10632 } else {
10633 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10634 }
a7812ae4 10635 tcg_temp_free_i64(fp64);
7c979afd 10636 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10637 tcg_temp_free_i32(fp32);
b6d96bed 10638 }
6ea83fed 10639 break;
bf4120ad 10640 case OPC_TRUNC_W_D:
5e755519 10641 check_cp1_registers(ctx, fs);
b6d96bed 10642 {
a7812ae4
PB
10643 TCGv_i32 fp32 = tcg_temp_new_i32();
10644 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10645
10646 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10647 if (ctx->nan2008) {
10648 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10649 } else {
10650 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10651 }
a7812ae4 10652 tcg_temp_free_i64(fp64);
7c979afd 10653 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10654 tcg_temp_free_i32(fp32);
b6d96bed 10655 }
6ea83fed 10656 break;
bf4120ad 10657 case OPC_CEIL_W_D:
5e755519 10658 check_cp1_registers(ctx, fs);
b6d96bed 10659 {
a7812ae4
PB
10660 TCGv_i32 fp32 = tcg_temp_new_i32();
10661 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10662
10663 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10664 if (ctx->nan2008) {
10665 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10666 } else {
10667 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10668 }
a7812ae4 10669 tcg_temp_free_i64(fp64);
7c979afd 10670 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10671 tcg_temp_free_i32(fp32);
b6d96bed 10672 }
6ea83fed 10673 break;
bf4120ad 10674 case OPC_FLOOR_W_D:
5e755519 10675 check_cp1_registers(ctx, fs);
b6d96bed 10676 {
a7812ae4
PB
10677 TCGv_i32 fp32 = tcg_temp_new_i32();
10678 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10679
10680 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10681 if (ctx->nan2008) {
10682 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10683 } else {
10684 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10685 }
a7812ae4 10686 tcg_temp_free_i64(fp64);
7c979afd 10687 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10688 tcg_temp_free_i32(fp32);
b6d96bed 10689 }
6ea83fed 10690 break;
e7f16abb 10691 case OPC_SEL_D:
2e211e0a 10692 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10693 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10694 break;
10695 case OPC_SELEQZ_D:
2e211e0a 10696 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10697 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10698 break;
10699 case OPC_SELNEZ_D:
2e211e0a 10700 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10701 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 10702 break;
bf4120ad 10703 case OPC_MOVCF_D:
2e211e0a 10704 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b6d96bed 10705 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 10706 break;
bf4120ad 10707 case OPC_MOVZ_D:
2e211e0a 10708 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10709 {
42a268c2 10710 TCGLabel *l1 = gen_new_label();
c9297f4d 10711 TCGv_i64 fp0;
a16336e4 10712
c9297f4d
AJ
10713 if (ft != 0) {
10714 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10715 }
10716 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10717 gen_load_fpr64(ctx, fp0, fs);
10718 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10719 tcg_temp_free_i64(fp0);
a16336e4
TS
10720 gen_set_label(l1);
10721 }
5a5012ec 10722 break;
bf4120ad 10723 case OPC_MOVN_D:
2e211e0a 10724 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10725 {
42a268c2 10726 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10727 TCGv_i64 fp0;
10728
10729 if (ft != 0) {
10730 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10731 fp0 = tcg_temp_new_i64();
10732 gen_load_fpr64(ctx, fp0, fs);
10733 gen_store_fpr64(ctx, fp0, fd);
10734 tcg_temp_free_i64(fp0);
10735 gen_set_label(l1);
10736 }
a16336e4 10737 }
6ea83fed 10738 break;
bf4120ad 10739 case OPC_RECIP_D:
ca6c7803 10740 check_cp1_registers(ctx, fs | fd);
b6d96bed 10741 {
a7812ae4 10742 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10743
10744 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10745 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 10746 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10747 tcg_temp_free_i64(fp0);
b6d96bed 10748 }
57fa1fb3 10749 break;
bf4120ad 10750 case OPC_RSQRT_D:
ca6c7803 10751 check_cp1_registers(ctx, fs | fd);
b6d96bed 10752 {
a7812ae4 10753 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10754
10755 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10756 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 10757 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10758 tcg_temp_free_i64(fp0);
b6d96bed 10759 }
57fa1fb3 10760 break;
e7f16abb 10761 case OPC_MADDF_D:
2e211e0a 10762 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10763 {
a7812ae4
PB
10764 TCGv_i64 fp0 = tcg_temp_new_i64();
10765 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 10766 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10767 gen_load_fpr64(ctx, fp0, fs);
10768 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10769 gen_load_fpr64(ctx, fp2, fd);
10770 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10771 gen_store_fpr64(ctx, fp2, fd);
10772 tcg_temp_free_i64(fp2);
a7812ae4 10773 tcg_temp_free_i64(fp1);
a7812ae4 10774 tcg_temp_free_i64(fp0);
b6d96bed 10775 }
57fa1fb3 10776 break;
e7f16abb 10777 case OPC_MSUBF_D:
2e211e0a 10778 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10779 {
a7812ae4 10780 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
10781 TCGv_i64 fp1 = tcg_temp_new_i64();
10782 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 10783 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
10784 gen_load_fpr64(ctx, fp1, ft);
10785 gen_load_fpr64(ctx, fp2, fd);
10786 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10787 gen_store_fpr64(ctx, fp2, fd);
10788 tcg_temp_free_i64(fp2);
10789 tcg_temp_free_i64(fp1);
a7812ae4 10790 tcg_temp_free_i64(fp0);
b6d96bed 10791 }
57fa1fb3 10792 break;
e7f16abb 10793 case OPC_RINT_D:
2e211e0a 10794 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10795 {
a7812ae4 10796 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10797 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 10798 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 10799 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10800 tcg_temp_free_i64(fp0);
b6d96bed 10801 }
57fa1fb3 10802 break;
e7f16abb 10803 case OPC_CLASS_D:
2e211e0a 10804 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10805 {
e7f16abb
LA
10806 TCGv_i64 fp0 = tcg_temp_new_i64();
10807 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 10808 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
10809 gen_store_fpr64(ctx, fp0, fd);
10810 tcg_temp_free_i64(fp0);
e7f16abb
LA
10811 }
10812 break;
10813 case OPC_MIN_D: /* OPC_RECIP2_D */
2e211e0a 10814 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb 10815 /* OPC_MIN_D */
a7812ae4
PB
10816 TCGv_i64 fp0 = tcg_temp_new_i64();
10817 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
10818 gen_load_fpr64(ctx, fp0, fs);
10819 gen_load_fpr64(ctx, fp1, ft);
10820 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10821 gen_store_fpr64(ctx, fp1, fd);
10822 tcg_temp_free_i64(fp1);
10823 tcg_temp_free_i64(fp0);
e7f16abb
LA
10824 } else {
10825 /* OPC_RECIP2_D */
10826 check_cp1_64bitmode(ctx);
10827 {
10828 TCGv_i64 fp0 = tcg_temp_new_i64();
10829 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 10830
e7f16abb
LA
10831 gen_load_fpr64(ctx, fp0, fs);
10832 gen_load_fpr64(ctx, fp1, ft);
10833 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10834 tcg_temp_free_i64(fp1);
10835 gen_store_fpr64(ctx, fp0, fd);
10836 tcg_temp_free_i64(fp0);
10837 }
e7f16abb
LA
10838 }
10839 break;
10840 case OPC_MINA_D: /* OPC_RECIP1_D */
2e211e0a 10841 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10842 /* OPC_MINA_D */
10843 TCGv_i64 fp0 = tcg_temp_new_i64();
10844 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10845 gen_load_fpr64(ctx, fp0, fs);
10846 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10847 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10848 gen_store_fpr64(ctx, fp1, fd);
10849 tcg_temp_free_i64(fp1);
10850 tcg_temp_free_i64(fp0);
e7f16abb
LA
10851 } else {
10852 /* OPC_RECIP1_D */
10853 check_cp1_64bitmode(ctx);
10854 {
10855 TCGv_i64 fp0 = tcg_temp_new_i64();
10856
10857 gen_load_fpr64(ctx, fp0, fs);
10858 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10859 gen_store_fpr64(ctx, fp0, fd);
10860 tcg_temp_free_i64(fp0);
10861 }
e7f16abb
LA
10862 }
10863 break;
10864 case OPC_MAX_D: /* OPC_RSQRT1_D */
2e211e0a 10865 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10866 /* OPC_MAX_D */
10867 TCGv_i64 fp0 = tcg_temp_new_i64();
10868 TCGv_i64 fp1 = tcg_temp_new_i64();
10869 gen_load_fpr64(ctx, fp0, fs);
10870 gen_load_fpr64(ctx, fp1, ft);
10871 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10872 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10873 tcg_temp_free_i64(fp1);
a7812ae4 10874 tcg_temp_free_i64(fp0);
e7f16abb
LA
10875 } else {
10876 /* OPC_RSQRT1_D */
10877 check_cp1_64bitmode(ctx);
10878 {
10879 TCGv_i64 fp0 = tcg_temp_new_i64();
10880
10881 gen_load_fpr64(ctx, fp0, fs);
10882 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10883 gen_store_fpr64(ctx, fp0, fd);
10884 tcg_temp_free_i64(fp0);
10885 }
e7f16abb
LA
10886 }
10887 break;
10888 case OPC_MAXA_D: /* OPC_RSQRT2_D */
2e211e0a 10889 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10890 /* OPC_MAXA_D */
10891 TCGv_i64 fp0 = tcg_temp_new_i64();
10892 TCGv_i64 fp1 = tcg_temp_new_i64();
10893 gen_load_fpr64(ctx, fp0, fs);
10894 gen_load_fpr64(ctx, fp1, ft);
10895 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10896 gen_store_fpr64(ctx, fp1, fd);
10897 tcg_temp_free_i64(fp1);
10898 tcg_temp_free_i64(fp0);
e7f16abb
LA
10899 } else {
10900 /* OPC_RSQRT2_D */
10901 check_cp1_64bitmode(ctx);
10902 {
10903 TCGv_i64 fp0 = tcg_temp_new_i64();
10904 TCGv_i64 fp1 = tcg_temp_new_i64();
10905
10906 gen_load_fpr64(ctx, fp0, fs);
10907 gen_load_fpr64(ctx, fp1, ft);
10908 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10909 tcg_temp_free_i64(fp1);
10910 gen_store_fpr64(ctx, fp0, fd);
10911 tcg_temp_free_i64(fp0);
10912 }
b6d96bed 10913 }
57fa1fb3 10914 break;
bf4120ad
NF
10915 case OPC_CMP_F_D:
10916 case OPC_CMP_UN_D:
10917 case OPC_CMP_EQ_D:
10918 case OPC_CMP_UEQ_D:
10919 case OPC_CMP_OLT_D:
10920 case OPC_CMP_ULT_D:
10921 case OPC_CMP_OLE_D:
10922 case OPC_CMP_ULE_D:
10923 case OPC_CMP_SF_D:
10924 case OPC_CMP_NGLE_D:
10925 case OPC_CMP_SEQ_D:
10926 case OPC_CMP_NGL_D:
10927 case OPC_CMP_LT_D:
10928 case OPC_CMP_NGE_D:
10929 case OPC_CMP_LE_D:
10930 case OPC_CMP_NGT_D:
2e211e0a 10931 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8153667c 10932 if (ctx->opcode & (1 << 6)) {
71375b59 10933 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
8153667c 10934 } else {
71375b59 10935 gen_cmp_d(ctx, func - 48, ft, fs, cc);
5a1e8ffb 10936 }
6ea83fed 10937 break;
bf4120ad 10938 case OPC_CVT_S_D:
5e755519 10939 check_cp1_registers(ctx, fs);
b6d96bed 10940 {
a7812ae4
PB
10941 TCGv_i32 fp32 = tcg_temp_new_i32();
10942 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10943
10944 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10945 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10946 tcg_temp_free_i64(fp64);
7c979afd 10947 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10948 tcg_temp_free_i32(fp32);
b6d96bed 10949 }
5a5012ec 10950 break;
bf4120ad 10951 case OPC_CVT_W_D:
5e755519 10952 check_cp1_registers(ctx, fs);
b6d96bed 10953 {
a7812ae4
PB
10954 TCGv_i32 fp32 = tcg_temp_new_i32();
10955 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10956
10957 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10958 if (ctx->nan2008) {
10959 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10960 } else {
10961 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10962 }
a7812ae4 10963 tcg_temp_free_i64(fp64);
7c979afd 10964 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10965 tcg_temp_free_i32(fp32);
b6d96bed 10966 }
5a5012ec 10967 break;
bf4120ad 10968 case OPC_CVT_L_D:
5e755519 10969 check_cp1_64bitmode(ctx);
b6d96bed 10970 {
a7812ae4 10971 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10972
10973 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10974 if (ctx->nan2008) {
10975 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10976 } else {
10977 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10978 }
b6d96bed 10979 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10980 tcg_temp_free_i64(fp0);
b6d96bed 10981 }
5a5012ec 10982 break;
bf4120ad 10983 case OPC_CVT_S_W:
b6d96bed 10984 {
a7812ae4 10985 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10986
7c979afd 10987 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10988 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10989 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10990 tcg_temp_free_i32(fp0);
b6d96bed 10991 }
6ea83fed 10992 break;
bf4120ad 10993 case OPC_CVT_D_W:
5e755519 10994 check_cp1_registers(ctx, fd);
b6d96bed 10995 {
a7812ae4
PB
10996 TCGv_i32 fp32 = tcg_temp_new_i32();
10997 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10998
7c979afd 10999 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11000 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 11001 tcg_temp_free_i32(fp32);
b6d96bed 11002 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11003 tcg_temp_free_i64(fp64);
b6d96bed 11004 }
5a5012ec 11005 break;
bf4120ad 11006 case OPC_CVT_S_L:
5e755519 11007 check_cp1_64bitmode(ctx);
b6d96bed 11008 {
a7812ae4
PB
11009 TCGv_i32 fp32 = tcg_temp_new_i32();
11010 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11011
11012 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11013 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 11014 tcg_temp_free_i64(fp64);
7c979afd 11015 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11016 tcg_temp_free_i32(fp32);
b6d96bed 11017 }
5a5012ec 11018 break;
bf4120ad 11019 case OPC_CVT_D_L:
5e755519 11020 check_cp1_64bitmode(ctx);
b6d96bed 11021 {
a7812ae4 11022 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11023
11024 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11025 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 11026 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11027 tcg_temp_free_i64(fp0);
b6d96bed 11028 }
5a5012ec 11029 break;
bf4120ad 11030 case OPC_CVT_PS_PW:
e29c9628 11031 check_ps(ctx);
b6d96bed 11032 {
a7812ae4 11033 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11034
11035 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11036 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 11037 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11038 tcg_temp_free_i64(fp0);
b6d96bed 11039 }
5a5012ec 11040 break;
bf4120ad 11041 case OPC_ADD_PS:
e29c9628 11042 check_ps(ctx);
b6d96bed 11043 {
a7812ae4
PB
11044 TCGv_i64 fp0 = tcg_temp_new_i64();
11045 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11046
11047 gen_load_fpr64(ctx, fp0, fs);
11048 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11049 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11050 tcg_temp_free_i64(fp1);
b6d96bed 11051 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11052 tcg_temp_free_i64(fp0);
b6d96bed 11053 }
6ea83fed 11054 break;
bf4120ad 11055 case OPC_SUB_PS:
e29c9628 11056 check_ps(ctx);
b6d96bed 11057 {
a7812ae4
PB
11058 TCGv_i64 fp0 = tcg_temp_new_i64();
11059 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11060
11061 gen_load_fpr64(ctx, fp0, fs);
11062 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11063 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11064 tcg_temp_free_i64(fp1);
b6d96bed 11065 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11066 tcg_temp_free_i64(fp0);
b6d96bed 11067 }
6ea83fed 11068 break;
bf4120ad 11069 case OPC_MUL_PS:
e29c9628 11070 check_ps(ctx);
b6d96bed 11071 {
a7812ae4
PB
11072 TCGv_i64 fp0 = tcg_temp_new_i64();
11073 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11074
11075 gen_load_fpr64(ctx, fp0, fs);
11076 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11077 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11078 tcg_temp_free_i64(fp1);
b6d96bed 11079 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11080 tcg_temp_free_i64(fp0);
b6d96bed 11081 }
6ea83fed 11082 break;
bf4120ad 11083 case OPC_ABS_PS:
e29c9628 11084 check_ps(ctx);
b6d96bed 11085 {
a7812ae4 11086 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11087
11088 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11089 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 11090 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11091 tcg_temp_free_i64(fp0);
b6d96bed 11092 }
6ea83fed 11093 break;
bf4120ad 11094 case OPC_MOV_PS:
e29c9628 11095 check_ps(ctx);
b6d96bed 11096 {
a7812ae4 11097 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11098
11099 gen_load_fpr64(ctx, fp0, fs);
11100 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11101 tcg_temp_free_i64(fp0);
b6d96bed 11102 }
6ea83fed 11103 break;
bf4120ad 11104 case OPC_NEG_PS:
e29c9628 11105 check_ps(ctx);
b6d96bed 11106 {
a7812ae4 11107 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11108
11109 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11110 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 11111 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11112 tcg_temp_free_i64(fp0);
b6d96bed 11113 }
6ea83fed 11114 break;
bf4120ad 11115 case OPC_MOVCF_PS:
e29c9628 11116 check_ps(ctx);
7f6613ce 11117 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 11118 break;
bf4120ad 11119 case OPC_MOVZ_PS:
e29c9628 11120 check_ps(ctx);
a16336e4 11121 {
42a268c2 11122 TCGLabel *l1 = gen_new_label();
30a3848b 11123 TCGv_i64 fp0;
a16336e4 11124
1f8929d2 11125 if (ft != 0) {
c9297f4d 11126 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
1f8929d2 11127 }
c9297f4d
AJ
11128 fp0 = tcg_temp_new_i64();
11129 gen_load_fpr64(ctx, fp0, fs);
11130 gen_store_fpr64(ctx, fp0, fd);
11131 tcg_temp_free_i64(fp0);
a16336e4
TS
11132 gen_set_label(l1);
11133 }
6ea83fed 11134 break;
bf4120ad 11135 case OPC_MOVN_PS:
e29c9628 11136 check_ps(ctx);
a16336e4 11137 {
42a268c2 11138 TCGLabel *l1 = gen_new_label();
30a3848b 11139 TCGv_i64 fp0;
c9297f4d
AJ
11140
11141 if (ft != 0) {
11142 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11143 fp0 = tcg_temp_new_i64();
11144 gen_load_fpr64(ctx, fp0, fs);
11145 gen_store_fpr64(ctx, fp0, fd);
11146 tcg_temp_free_i64(fp0);
11147 gen_set_label(l1);
11148 }
a16336e4 11149 }
6ea83fed 11150 break;
bf4120ad 11151 case OPC_ADDR_PS:
e29c9628 11152 check_ps(ctx);
b6d96bed 11153 {
a7812ae4
PB
11154 TCGv_i64 fp0 = tcg_temp_new_i64();
11155 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11156
11157 gen_load_fpr64(ctx, fp0, ft);
11158 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11159 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11160 tcg_temp_free_i64(fp1);
b6d96bed 11161 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11162 tcg_temp_free_i64(fp0);
b6d96bed 11163 }
fbcc6828 11164 break;
bf4120ad 11165 case OPC_MULR_PS:
e29c9628 11166 check_ps(ctx);
b6d96bed 11167 {
a7812ae4
PB
11168 TCGv_i64 fp0 = tcg_temp_new_i64();
11169 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11170
11171 gen_load_fpr64(ctx, fp0, ft);
11172 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11173 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11174 tcg_temp_free_i64(fp1);
b6d96bed 11175 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11176 tcg_temp_free_i64(fp0);
b6d96bed 11177 }
57fa1fb3 11178 break;
bf4120ad 11179 case OPC_RECIP2_PS:
e29c9628 11180 check_ps(ctx);
b6d96bed 11181 {
a7812ae4
PB
11182 TCGv_i64 fp0 = tcg_temp_new_i64();
11183 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11184
11185 gen_load_fpr64(ctx, fp0, fs);
d22d7289 11186 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11187 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11188 tcg_temp_free_i64(fp1);
b6d96bed 11189 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11190 tcg_temp_free_i64(fp0);
b6d96bed 11191 }
57fa1fb3 11192 break;
bf4120ad 11193 case OPC_RECIP1_PS:
e29c9628 11194 check_ps(ctx);
b6d96bed 11195 {
a7812ae4 11196 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11197
11198 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11199 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 11200 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11201 tcg_temp_free_i64(fp0);
b6d96bed 11202 }
57fa1fb3 11203 break;
bf4120ad 11204 case OPC_RSQRT1_PS:
e29c9628 11205 check_ps(ctx);
b6d96bed 11206 {
a7812ae4 11207 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11208
11209 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11210 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 11211 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11212 tcg_temp_free_i64(fp0);
b6d96bed 11213 }
57fa1fb3 11214 break;
bf4120ad 11215 case OPC_RSQRT2_PS:
e29c9628 11216 check_ps(ctx);
b6d96bed 11217 {
a7812ae4
PB
11218 TCGv_i64 fp0 = tcg_temp_new_i64();
11219 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11220
11221 gen_load_fpr64(ctx, fp0, fs);
11222 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11223 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11224 tcg_temp_free_i64(fp1);
b6d96bed 11225 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11226 tcg_temp_free_i64(fp0);
b6d96bed 11227 }
57fa1fb3 11228 break;
bf4120ad 11229 case OPC_CVT_S_PU:
5e755519 11230 check_cp1_64bitmode(ctx);
b6d96bed 11231 {
a7812ae4 11232 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11233
7f6613ce 11234 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 11235 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 11236 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11237 tcg_temp_free_i32(fp0);
b6d96bed 11238 }
dd016883 11239 break;
bf4120ad 11240 case OPC_CVT_PW_PS:
e29c9628 11241 check_ps(ctx);
b6d96bed 11242 {
a7812ae4 11243 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11244
11245 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11246 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 11247 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11248 tcg_temp_free_i64(fp0);
b6d96bed 11249 }
6ea83fed 11250 break;
bf4120ad 11251 case OPC_CVT_S_PL:
5e755519 11252 check_cp1_64bitmode(ctx);
b6d96bed 11253 {
a7812ae4 11254 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11255
7c979afd 11256 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11257 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 11258 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11259 tcg_temp_free_i32(fp0);
b6d96bed 11260 }
6ea83fed 11261 break;
bf4120ad 11262 case OPC_PLL_PS:
e29c9628 11263 check_ps(ctx);
b6d96bed 11264 {
a7812ae4
PB
11265 TCGv_i32 fp0 = tcg_temp_new_i32();
11266 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11267
7c979afd
LA
11268 gen_load_fpr32(ctx, fp0, fs);
11269 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 11270 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 11271 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
11272 tcg_temp_free_i32(fp0);
11273 tcg_temp_free_i32(fp1);
b6d96bed 11274 }
6ea83fed 11275 break;
bf4120ad 11276 case OPC_PLU_PS:
e29c9628 11277 check_ps(ctx);
b6d96bed 11278 {
a7812ae4
PB
11279 TCGv_i32 fp0 = tcg_temp_new_i32();
11280 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11281
7c979afd 11282 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 11283 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11284 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11285 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11286 tcg_temp_free_i32(fp0);
11287 tcg_temp_free_i32(fp1);
b6d96bed 11288 }
5a5012ec 11289 break;
bf4120ad 11290 case OPC_PUL_PS:
e29c9628 11291 check_ps(ctx);
b6d96bed 11292 {
a7812ae4
PB
11293 TCGv_i32 fp0 = tcg_temp_new_i32();
11294 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11295
7f6613ce 11296 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
11297 gen_load_fpr32(ctx, fp1, ft);
11298 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11299 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11300 tcg_temp_free_i32(fp0);
11301 tcg_temp_free_i32(fp1);
b6d96bed 11302 }
5a5012ec 11303 break;
bf4120ad 11304 case OPC_PUU_PS:
e29c9628 11305 check_ps(ctx);
b6d96bed 11306 {
a7812ae4
PB
11307 TCGv_i32 fp0 = tcg_temp_new_i32();
11308 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11309
7f6613ce
PJ
11310 gen_load_fpr32h(ctx, fp0, fs);
11311 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11312 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11313 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11314 tcg_temp_free_i32(fp0);
11315 tcg_temp_free_i32(fp1);
b6d96bed 11316 }
5a5012ec 11317 break;
bf4120ad
NF
11318 case OPC_CMP_F_PS:
11319 case OPC_CMP_UN_PS:
11320 case OPC_CMP_EQ_PS:
11321 case OPC_CMP_UEQ_PS:
11322 case OPC_CMP_OLT_PS:
11323 case OPC_CMP_ULT_PS:
11324 case OPC_CMP_OLE_PS:
11325 case OPC_CMP_ULE_PS:
11326 case OPC_CMP_SF_PS:
11327 case OPC_CMP_NGLE_PS:
11328 case OPC_CMP_SEQ_PS:
11329 case OPC_CMP_NGL_PS:
11330 case OPC_CMP_LT_PS:
11331 case OPC_CMP_NGE_PS:
11332 case OPC_CMP_LE_PS:
11333 case OPC_CMP_NGT_PS:
8153667c 11334 if (ctx->opcode & (1 << 6)) {
71375b59 11335 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
8153667c 11336 } else {
71375b59 11337 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
5a1e8ffb 11338 }
6ea83fed 11339 break;
5a5012ec 11340 default:
9d68ac14 11341 MIPS_INVAL("farith");
3a4ef3b7 11342 gen_reserved_instruction(ctx);
6ea83fed
FB
11343 return;
11344 }
6ea83fed 11345}
6af0bf9c 11346
5a5012ec 11347/* Coprocessor 3 (FPU) */
235785e8
AM
11348static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11349 int fd, int fs, int base, int index)
7a387fff 11350{
4e2474d6 11351 TCGv t0 = tcg_temp_new();
7a387fff 11352
93b12ccc 11353 if (base == 0) {
6c5c1e20 11354 gen_load_gpr(t0, index);
93b12ccc 11355 } else if (index == 0) {
6c5c1e20 11356 gen_load_gpr(t0, base);
93b12ccc 11357 } else {
05168674 11358 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 11359 }
7480515f
AM
11360 /*
11361 * Don't do NOP if destination is zero: we must perform the actual
11362 * memory access.
11363 */
5a5012ec
TS
11364 switch (opc) {
11365 case OPC_LWXC1:
8c0ab41f 11366 check_cop1x(ctx);
b6d96bed 11367 {
a7812ae4 11368 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11369
5f68f5ae 11370 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 11371 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 11372 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11373 tcg_temp_free_i32(fp0);
b6d96bed 11374 }
5a5012ec
TS
11375 break;
11376 case OPC_LDXC1:
8c0ab41f
AJ
11377 check_cop1x(ctx);
11378 check_cp1_registers(ctx, fd);
b6d96bed 11379 {
a7812ae4 11380 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 11381 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11382 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11383 tcg_temp_free_i64(fp0);
b6d96bed 11384 }
5a5012ec
TS
11385 break;
11386 case OPC_LUXC1:
8c0ab41f 11387 check_cp1_64bitmode(ctx);
6c5c1e20 11388 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11389 {
a7812ae4 11390 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11391
5f68f5ae 11392 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11393 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11394 tcg_temp_free_i64(fp0);
b6d96bed 11395 }
5a5012ec
TS
11396 break;
11397 case OPC_SWXC1:
8c0ab41f 11398 check_cop1x(ctx);
b6d96bed 11399 {
a7812ae4 11400 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11401 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 11402 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 11403 tcg_temp_free_i32(fp0);
b6d96bed 11404 }
5a5012ec
TS
11405 break;
11406 case OPC_SDXC1:
8c0ab41f
AJ
11407 check_cop1x(ctx);
11408 check_cp1_registers(ctx, fs);
b6d96bed 11409 {
a7812ae4 11410 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11411 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11412 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11413 tcg_temp_free_i64(fp0);
b6d96bed 11414 }
5a5012ec
TS
11415 break;
11416 case OPC_SUXC1:
8c0ab41f 11417 check_cp1_64bitmode(ctx);
6c5c1e20 11418 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11419 {
a7812ae4 11420 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11421 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11422 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11423 tcg_temp_free_i64(fp0);
b6d96bed 11424 }
5a5012ec 11425 break;
5a5012ec 11426 }
6c5c1e20 11427 tcg_temp_free(t0);
5a5012ec
TS
11428}
11429
235785e8
AM
11430static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11431 int fd, int fr, int fs, int ft)
5a5012ec 11432{
5a5012ec
TS
11433 switch (opc) {
11434 case OPC_ALNV_PS:
e29c9628 11435 check_ps(ctx);
a16336e4 11436 {
a7812ae4 11437 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
11438 TCGv_i32 fp = tcg_temp_new_i32();
11439 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
11440 TCGLabel *l1 = gen_new_label();
11441 TCGLabel *l2 = gen_new_label();
a16336e4 11442
6c5c1e20
TS
11443 gen_load_gpr(t0, fr);
11444 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
11445
11446 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 11447 gen_load_fpr32(ctx, fp, fs);
7f6613ce 11448 gen_load_fpr32h(ctx, fph, fs);
7c979afd 11449 gen_store_fpr32(ctx, fp, fd);
7f6613ce 11450 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
11451 tcg_gen_br(l2);
11452 gen_set_label(l1);
6c5c1e20
TS
11453 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11454 tcg_temp_free(t0);
a16336e4 11455#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 11456 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
11457 gen_load_fpr32h(ctx, fph, ft);
11458 gen_store_fpr32h(ctx, fp, fd);
7c979afd 11459 gen_store_fpr32(ctx, fph, fd);
a16336e4 11460#else
7f6613ce 11461 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
11462 gen_load_fpr32(ctx, fp, ft);
11463 gen_store_fpr32(ctx, fph, fd);
7f6613ce 11464 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
11465#endif
11466 gen_set_label(l2);
c905fdac
AJ
11467 tcg_temp_free_i32(fp);
11468 tcg_temp_free_i32(fph);
a16336e4 11469 }
5a5012ec
TS
11470 break;
11471 case OPC_MADD_S:
b8aa4598 11472 check_cop1x(ctx);
b6d96bed 11473 {
a7812ae4
PB
11474 TCGv_i32 fp0 = tcg_temp_new_i32();
11475 TCGv_i32 fp1 = tcg_temp_new_i32();
11476 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11477
7c979afd
LA
11478 gen_load_fpr32(ctx, fp0, fs);
11479 gen_load_fpr32(ctx, fp1, ft);
11480 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11481 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11482 tcg_temp_free_i32(fp0);
11483 tcg_temp_free_i32(fp1);
7c979afd 11484 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11485 tcg_temp_free_i32(fp2);
b6d96bed 11486 }
5a5012ec
TS
11487 break;
11488 case OPC_MADD_D:
b8aa4598
TS
11489 check_cop1x(ctx);
11490 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11491 {
a7812ae4
PB
11492 TCGv_i64 fp0 = tcg_temp_new_i64();
11493 TCGv_i64 fp1 = tcg_temp_new_i64();
11494 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11495
11496 gen_load_fpr64(ctx, fp0, fs);
11497 gen_load_fpr64(ctx, fp1, ft);
11498 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11499 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11500 tcg_temp_free_i64(fp0);
11501 tcg_temp_free_i64(fp1);
b6d96bed 11502 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11503 tcg_temp_free_i64(fp2);
b6d96bed 11504 }
5a5012ec
TS
11505 break;
11506 case OPC_MADD_PS:
e29c9628 11507 check_ps(ctx);
b6d96bed 11508 {
a7812ae4
PB
11509 TCGv_i64 fp0 = tcg_temp_new_i64();
11510 TCGv_i64 fp1 = tcg_temp_new_i64();
11511 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11512
11513 gen_load_fpr64(ctx, fp0, fs);
11514 gen_load_fpr64(ctx, fp1, ft);
11515 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11516 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11517 tcg_temp_free_i64(fp0);
11518 tcg_temp_free_i64(fp1);
b6d96bed 11519 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11520 tcg_temp_free_i64(fp2);
b6d96bed 11521 }
5a5012ec
TS
11522 break;
11523 case OPC_MSUB_S:
b8aa4598 11524 check_cop1x(ctx);
b6d96bed 11525 {
a7812ae4
PB
11526 TCGv_i32 fp0 = tcg_temp_new_i32();
11527 TCGv_i32 fp1 = tcg_temp_new_i32();
11528 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11529
7c979afd
LA
11530 gen_load_fpr32(ctx, fp0, fs);
11531 gen_load_fpr32(ctx, fp1, ft);
11532 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11533 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11534 tcg_temp_free_i32(fp0);
11535 tcg_temp_free_i32(fp1);
7c979afd 11536 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11537 tcg_temp_free_i32(fp2);
b6d96bed 11538 }
5a5012ec
TS
11539 break;
11540 case OPC_MSUB_D:
b8aa4598
TS
11541 check_cop1x(ctx);
11542 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11543 {
a7812ae4
PB
11544 TCGv_i64 fp0 = tcg_temp_new_i64();
11545 TCGv_i64 fp1 = tcg_temp_new_i64();
11546 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11547
11548 gen_load_fpr64(ctx, fp0, fs);
11549 gen_load_fpr64(ctx, fp1, ft);
11550 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11551 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11552 tcg_temp_free_i64(fp0);
11553 tcg_temp_free_i64(fp1);
b6d96bed 11554 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11555 tcg_temp_free_i64(fp2);
b6d96bed 11556 }
5a5012ec
TS
11557 break;
11558 case OPC_MSUB_PS:
e29c9628 11559 check_ps(ctx);
b6d96bed 11560 {
a7812ae4
PB
11561 TCGv_i64 fp0 = tcg_temp_new_i64();
11562 TCGv_i64 fp1 = tcg_temp_new_i64();
11563 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11564
11565 gen_load_fpr64(ctx, fp0, fs);
11566 gen_load_fpr64(ctx, fp1, ft);
11567 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11568 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11569 tcg_temp_free_i64(fp0);
11570 tcg_temp_free_i64(fp1);
b6d96bed 11571 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11572 tcg_temp_free_i64(fp2);
b6d96bed 11573 }
5a5012ec
TS
11574 break;
11575 case OPC_NMADD_S:
b8aa4598 11576 check_cop1x(ctx);
b6d96bed 11577 {
a7812ae4
PB
11578 TCGv_i32 fp0 = tcg_temp_new_i32();
11579 TCGv_i32 fp1 = tcg_temp_new_i32();
11580 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11581
7c979afd
LA
11582 gen_load_fpr32(ctx, fp0, fs);
11583 gen_load_fpr32(ctx, fp1, ft);
11584 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11585 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11586 tcg_temp_free_i32(fp0);
11587 tcg_temp_free_i32(fp1);
7c979afd 11588 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11589 tcg_temp_free_i32(fp2);
b6d96bed 11590 }
5a5012ec
TS
11591 break;
11592 case OPC_NMADD_D:
b8aa4598
TS
11593 check_cop1x(ctx);
11594 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11595 {
a7812ae4
PB
11596 TCGv_i64 fp0 = tcg_temp_new_i64();
11597 TCGv_i64 fp1 = tcg_temp_new_i64();
11598 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11599
11600 gen_load_fpr64(ctx, fp0, fs);
11601 gen_load_fpr64(ctx, fp1, ft);
11602 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11603 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11604 tcg_temp_free_i64(fp0);
11605 tcg_temp_free_i64(fp1);
b6d96bed 11606 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11607 tcg_temp_free_i64(fp2);
b6d96bed 11608 }
5a5012ec
TS
11609 break;
11610 case OPC_NMADD_PS:
e29c9628 11611 check_ps(ctx);
b6d96bed 11612 {
a7812ae4
PB
11613 TCGv_i64 fp0 = tcg_temp_new_i64();
11614 TCGv_i64 fp1 = tcg_temp_new_i64();
11615 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11616
11617 gen_load_fpr64(ctx, fp0, fs);
11618 gen_load_fpr64(ctx, fp1, ft);
11619 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11620 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11621 tcg_temp_free_i64(fp0);
11622 tcg_temp_free_i64(fp1);
b6d96bed 11623 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11624 tcg_temp_free_i64(fp2);
b6d96bed 11625 }
5a5012ec
TS
11626 break;
11627 case OPC_NMSUB_S:
b8aa4598 11628 check_cop1x(ctx);
b6d96bed 11629 {
a7812ae4
PB
11630 TCGv_i32 fp0 = tcg_temp_new_i32();
11631 TCGv_i32 fp1 = tcg_temp_new_i32();
11632 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11633
7c979afd
LA
11634 gen_load_fpr32(ctx, fp0, fs);
11635 gen_load_fpr32(ctx, fp1, ft);
11636 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11637 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11638 tcg_temp_free_i32(fp0);
11639 tcg_temp_free_i32(fp1);
7c979afd 11640 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11641 tcg_temp_free_i32(fp2);
b6d96bed 11642 }
5a5012ec
TS
11643 break;
11644 case OPC_NMSUB_D:
b8aa4598
TS
11645 check_cop1x(ctx);
11646 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11647 {
a7812ae4
PB
11648 TCGv_i64 fp0 = tcg_temp_new_i64();
11649 TCGv_i64 fp1 = tcg_temp_new_i64();
11650 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11651
11652 gen_load_fpr64(ctx, fp0, fs);
11653 gen_load_fpr64(ctx, fp1, ft);
11654 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11655 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11656 tcg_temp_free_i64(fp0);
11657 tcg_temp_free_i64(fp1);
b6d96bed 11658 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11659 tcg_temp_free_i64(fp2);
b6d96bed 11660 }
5a5012ec
TS
11661 break;
11662 case OPC_NMSUB_PS:
e29c9628 11663 check_ps(ctx);
b6d96bed 11664 {
a7812ae4
PB
11665 TCGv_i64 fp0 = tcg_temp_new_i64();
11666 TCGv_i64 fp1 = tcg_temp_new_i64();
11667 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11668
11669 gen_load_fpr64(ctx, fp0, fs);
11670 gen_load_fpr64(ctx, fp1, ft);
11671 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11672 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11673 tcg_temp_free_i64(fp0);
11674 tcg_temp_free_i64(fp1);
b6d96bed 11675 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11676 tcg_temp_free_i64(fp2);
b6d96bed 11677 }
5a5012ec 11678 break;
923617a3 11679 default:
9d68ac14 11680 MIPS_INVAL("flt3_arith");
3a4ef3b7 11681 gen_reserved_instruction(ctx);
5a5012ec
TS
11682 return;
11683 }
7a387fff
TS
11684}
11685
f9fa53f1 11686void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
11687{
11688 TCGv t0;
11689
b3167288 11690#if !defined(CONFIG_USER_ONLY)
7480515f
AM
11691 /*
11692 * The Linux kernel will emulate rdhwr if it's not supported natively.
11693 * Therefore only check the ISA in system mode.
11694 */
7a47bae5 11695 check_insn(ctx, ISA_MIPS_R2);
b3167288 11696#endif
26ebe468
NF
11697 t0 = tcg_temp_new();
11698
11699 switch (rd) {
11700 case 0:
895c2d04 11701 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
11702 gen_store_gpr(t0, rt);
11703 break;
11704 case 1:
895c2d04 11705 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
11706 gen_store_gpr(t0, rt);
11707 break;
11708 case 2:
eeb3bba8 11709 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
11710 gen_io_start();
11711 }
895c2d04 11712 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468 11713 gen_store_gpr(t0, rt);
7480515f
AM
11714 /*
11715 * Break the TB to be able to take timer interrupts immediately
11716 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11717 * we break completely out of translated code.
11718 */
eeb3bba8
EC
11719 gen_save_pc(ctx->base.pc_next + 4);
11720 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
11721 break;
11722 case 3:
895c2d04 11723 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
11724 gen_store_gpr(t0, rt);
11725 break;
b00c7218 11726 case 4:
2e211e0a 11727 check_insn(ctx, ISA_MIPS_R6);
b00c7218 11728 if (sel != 0) {
7480515f
AM
11729 /*
11730 * Performance counter registers are not implemented other than
b00c7218
YK
11731 * control register 0.
11732 */
11733 generate_exception(ctx, EXCP_RI);
11734 }
11735 gen_helper_rdhwr_performance(t0, cpu_env);
11736 gen_store_gpr(t0, rt);
11737 break;
11738 case 5:
2e211e0a 11739 check_insn(ctx, ISA_MIPS_R6);
b00c7218
YK
11740 gen_helper_rdhwr_xnp(t0, cpu_env);
11741 gen_store_gpr(t0, rt);
11742 break;
26ebe468
NF
11743 case 29:
11744#if defined(CONFIG_USER_ONLY)
d279279e
PJ
11745 tcg_gen_ld_tl(t0, cpu_env,
11746 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
11747 gen_store_gpr(t0, rt);
11748 break;
11749#else
d279279e
PJ
11750 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11751 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11752 tcg_gen_ld_tl(t0, cpu_env,
11753 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11754 gen_store_gpr(t0, rt);
11755 } else {
3a4ef3b7 11756 gen_reserved_instruction(ctx);
d279279e
PJ
11757 }
11758 break;
26ebe468
NF
11759#endif
11760 default: /* Invalid */
11761 MIPS_INVAL("rdhwr");
3a4ef3b7 11762 gen_reserved_instruction(ctx);
26ebe468
NF
11763 break;
11764 }
11765 tcg_temp_free(t0);
11766}
11767
a5f53390
LA
11768static inline void clear_branch_hflags(DisasContext *ctx)
11769{
11770 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 11771 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
11772 save_cpu_state(ctx, 0);
11773 } else {
7480515f
AM
11774 /*
11775 * It is not safe to save ctx->hflags as hflags may be changed
11776 * in execution time by the instruction in delay / forbidden slot.
11777 */
a5f53390
LA
11778 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11779 }
11780}
11781
31837be3 11782static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
11783{
11784 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 11785 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 11786 /* Branches completion */
a5f53390 11787 clear_branch_hflags(ctx);
eeb3bba8 11788 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 11789 /* FIXME: Need to clear can_do_io. */
364d4831 11790 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 11791 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 11792 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 11793 break;
c9602061
NF
11794 case MIPS_HFLAG_B:
11795 /* unconditional branch */
364d4831
NF
11796 if (proc_hflags & MIPS_HFLAG_BX) {
11797 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11798 }
c9602061
NF
11799 gen_goto_tb(ctx, 0, ctx->btarget);
11800 break;
11801 case MIPS_HFLAG_BL:
11802 /* blikely taken case */
c9602061
NF
11803 gen_goto_tb(ctx, 0, ctx->btarget);
11804 break;
11805 case MIPS_HFLAG_BC:
11806 /* Conditional branch */
c9602061 11807 {
42a268c2 11808 TCGLabel *l1 = gen_new_label();
c9602061
NF
11809
11810 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 11811 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
11812 gen_set_label(l1);
11813 gen_goto_tb(ctx, 0, ctx->btarget);
11814 }
11815 break;
11816 case MIPS_HFLAG_BR:
11817 /* unconditional branch to register */
d75c135e 11818 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
11819 TCGv t0 = tcg_temp_new();
11820 TCGv_i32 t1 = tcg_temp_new_i32();
11821
11822 tcg_gen_andi_tl(t0, btarget, 0x1);
11823 tcg_gen_trunc_tl_i32(t1, t0);
11824 tcg_temp_free(t0);
11825 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11826 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11827 tcg_gen_or_i32(hflags, hflags, t1);
11828 tcg_temp_free_i32(t1);
11829
11830 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11831 } else {
11832 tcg_gen_mov_tl(cpu_PC, btarget);
11833 }
eeb3bba8 11834 if (ctx->base.singlestep_enabled) {
c9602061 11835 save_cpu_state(ctx, 0);
9c708c7f 11836 gen_helper_raise_exception_debug(cpu_env);
c9602061 11837 }
7f11636d 11838 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
11839 break;
11840 default:
05d9d035
PMD
11841 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11842 gen_reserved_instruction(ctx);
c9602061
NF
11843 }
11844 }
11845}
11846
6893f074
YK
11847/* Compact Branches */
11848static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11849 int rs, int rt, int32_t offset)
11850{
11851 int bcond_compute = 0;
11852 TCGv t0 = tcg_temp_new();
11853 TCGv t1 = tcg_temp_new();
65935f07 11854 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
11855
11856 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11857#ifdef MIPS_DEBUG_DISAS
11858 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 11859 "\n", ctx->base.pc_next);
6893f074 11860#endif
3a4ef3b7 11861 gen_reserved_instruction(ctx);
6893f074
YK
11862 goto out;
11863 }
11864
11865 /* Load needed operands and calculate btarget */
11866 switch (opc) {
11867 /* compact branch */
11868 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11869 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11870 gen_load_gpr(t0, rs);
11871 gen_load_gpr(t1, rt);
11872 bcond_compute = 1;
eeb3bba8 11873 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11874 if (rs <= rt && rs == 0) {
11875 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11876 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11877 }
11878 break;
11879 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11880 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11881 gen_load_gpr(t0, rs);
11882 gen_load_gpr(t1, rt);
11883 bcond_compute = 1;
eeb3bba8 11884 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11885 break;
11886 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11887 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11888 if (rs == 0 || rs == rt) {
11889 /* OPC_BLEZALC, OPC_BGEZALC */
11890 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11891 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11892 }
11893 gen_load_gpr(t0, rs);
11894 gen_load_gpr(t1, rt);
11895 bcond_compute = 1;
eeb3bba8 11896 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11897 break;
11898 case OPC_BC:
11899 case OPC_BALC:
eeb3bba8 11900 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11901 break;
11902 case OPC_BEQZC:
11903 case OPC_BNEZC:
11904 if (rs != 0) {
11905 /* OPC_BEQZC, OPC_BNEZC */
11906 gen_load_gpr(t0, rs);
11907 bcond_compute = 1;
eeb3bba8 11908 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11909 } else {
11910 /* OPC_JIC, OPC_JIALC */
11911 TCGv tbase = tcg_temp_new();
11912 TCGv toffset = tcg_temp_new();
11913
11914 gen_load_gpr(tbase, rt);
11915 tcg_gen_movi_tl(toffset, offset);
11916 gen_op_addr_add(ctx, btarget, tbase, toffset);
11917 tcg_temp_free(tbase);
11918 tcg_temp_free(toffset);
11919 }
11920 break;
11921 default:
11922 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 11923 gen_reserved_instruction(ctx);
6893f074
YK
11924 goto out;
11925 }
11926
11927 if (bcond_compute == 0) {
63978560 11928 /* Unconditional compact branch */
6893f074
YK
11929 switch (opc) {
11930 case OPC_JIALC:
eeb3bba8 11931 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11932 /* Fallthrough */
11933 case OPC_JIC:
11934 ctx->hflags |= MIPS_HFLAG_BR;
11935 break;
11936 case OPC_BALC:
eeb3bba8 11937 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11938 /* Fallthrough */
11939 case OPC_BC:
11940 ctx->hflags |= MIPS_HFLAG_B;
11941 break;
11942 default:
11943 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 11944 gen_reserved_instruction(ctx);
6893f074
YK
11945 goto out;
11946 }
11947
11948 /* Generating branch here as compact branches don't have delay slot */
11949 gen_branch(ctx, 4);
11950 } else {
11951 /* Conditional compact branch */
11952 TCGLabel *fs = gen_new_label();
11953 save_cpu_state(ctx, 0);
11954
11955 switch (opc) {
11956 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11957 if (rs == 0 && rt != 0) {
11958 /* OPC_BLEZALC */
11959 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11960 } else if (rs != 0 && rt != 0 && rs == rt) {
11961 /* OPC_BGEZALC */
11962 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11963 } else {
11964 /* OPC_BGEUC */
11965 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11966 }
11967 break;
11968 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11969 if (rs == 0 && rt != 0) {
11970 /* OPC_BGTZALC */
11971 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11972 } else if (rs != 0 && rt != 0 && rs == rt) {
11973 /* OPC_BLTZALC */
11974 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11975 } else {
11976 /* OPC_BLTUC */
11977 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11978 }
11979 break;
11980 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11981 if (rs == 0 && rt != 0) {
11982 /* OPC_BLEZC */
11983 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11984 } else if (rs != 0 && rt != 0 && rs == rt) {
11985 /* OPC_BGEZC */
11986 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11987 } else {
11988 /* OPC_BGEC */
11989 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11990 }
11991 break;
11992 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11993 if (rs == 0 && rt != 0) {
11994 /* OPC_BGTZC */
11995 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11996 } else if (rs != 0 && rt != 0 && rs == rt) {
11997 /* OPC_BLTZC */
11998 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11999 } else {
12000 /* OPC_BLTC */
12001 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12002 }
12003 break;
12004 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12005 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12006 if (rs >= rt) {
12007 /* OPC_BOVC, OPC_BNVC */
12008 TCGv t2 = tcg_temp_new();
12009 TCGv t3 = tcg_temp_new();
12010 TCGv t4 = tcg_temp_new();
12011 TCGv input_overflow = tcg_temp_new();
12012
12013 gen_load_gpr(t0, rs);
12014 gen_load_gpr(t1, rt);
12015 tcg_gen_ext32s_tl(t2, t0);
12016 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12017 tcg_gen_ext32s_tl(t3, t1);
12018 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12019 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12020
12021 tcg_gen_add_tl(t4, t2, t3);
12022 tcg_gen_ext32s_tl(t4, t4);
12023 tcg_gen_xor_tl(t2, t2, t3);
12024 tcg_gen_xor_tl(t3, t4, t3);
12025 tcg_gen_andc_tl(t2, t3, t2);
12026 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12027 tcg_gen_or_tl(t4, t4, input_overflow);
12028 if (opc == OPC_BOVC) {
12029 /* OPC_BOVC */
12030 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12031 } else {
12032 /* OPC_BNVC */
12033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12034 }
12035 tcg_temp_free(input_overflow);
12036 tcg_temp_free(t4);
12037 tcg_temp_free(t3);
12038 tcg_temp_free(t2);
12039 } else if (rs < rt && rs == 0) {
12040 /* OPC_BEQZALC, OPC_BNEZALC */
12041 if (opc == OPC_BEQZALC) {
12042 /* OPC_BEQZALC */
12043 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12044 } else {
12045 /* OPC_BNEZALC */
12046 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12047 }
12048 } else {
12049 /* OPC_BEQC, OPC_BNEC */
12050 if (opc == OPC_BEQC) {
12051 /* OPC_BEQC */
12052 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12053 } else {
12054 /* OPC_BNEC */
12055 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12056 }
12057 }
12058 break;
12059 case OPC_BEQZC:
12060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12061 break;
12062 case OPC_BNEZC:
12063 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12064 break;
12065 default:
12066 MIPS_INVAL("Compact conditional branch/jump");
3a4ef3b7 12067 gen_reserved_instruction(ctx);
6893f074
YK
12068 goto out;
12069 }
12070
12071 /* Generating branch here as compact branches don't have delay slot */
12072 gen_goto_tb(ctx, 1, ctx->btarget);
12073 gen_set_label(fs);
12074
12075 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
12076 }
12077
12078out:
12079 tcg_temp_free(t0);
12080 tcg_temp_free(t1);
12081}
12082
d5076631
PMD
12083void gen_addiupc(DisasContext *ctx, int rx, int imm,
12084 int is_64_bit, int extended)
364d4831
NF
12085{
12086 TCGv t0;
12087
12088 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 12089 gen_reserved_instruction(ctx);
364d4831
NF
12090 return;
12091 }
12092
12093 t0 = tcg_temp_new();
12094
12095 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12096 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12097 if (!is_64_bit) {
12098 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12099 }
12100
12101 tcg_temp_free(t0);
12102}
12103
0d74a222
LA
12104static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12105 int16_t offset)
12106{
12107 TCGv_i32 t0 = tcg_const_i32(op);
12108 TCGv t1 = tcg_temp_new();
12109 gen_base_offset_addr(ctx, t1, base, offset);
12110 gen_helper_cache(cpu_env, t1, t0);
f4349ba9
PMD
12111 tcg_temp_free(t1);
12112 tcg_temp_free_i32(t0);
0d74a222
LA
12113}
12114
3b3c1694
LA
12115static inline bool is_uhi(int sdbbp_code)
12116{
12117#ifdef CONFIG_USER_ONLY
12118 return false;
12119#else
12120 return semihosting_enabled() && sdbbp_code == 1;
12121#endif
12122}
12123
82ba4266
AB
12124#ifdef CONFIG_USER_ONLY
12125/* The above should dead-code away any calls to this..*/
12126static inline void gen_helper_do_semihosting(void *env)
12127{
12128 g_assert_not_reached();
12129}
12130#endif
12131
d5076631 12132void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
3c824109
NF
12133{
12134 TCGv t0 = tcg_temp_new();
12135 TCGv t1 = tcg_temp_new();
12136
12137 gen_load_gpr(t0, base);
12138
12139 if (index != 0) {
12140 gen_load_gpr(t1, index);
12141 tcg_gen_shli_tl(t1, t1, 2);
12142 gen_op_addr_add(ctx, t0, t1, t0);
12143 }
12144
5f68f5ae 12145 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12146 gen_store_gpr(t1, rd);
12147
12148 tcg_temp_free(t0);
12149 tcg_temp_free(t1);
12150}
12151
d208ac0c
LA
12152static void gen_sync(int stype)
12153{
12154 TCGBar tcg_mo = TCG_BAR_SC;
12155
12156 switch (stype) {
12157 case 0x4: /* SYNC_WMB */
12158 tcg_mo |= TCG_MO_ST_ST;
12159 break;
12160 case 0x10: /* SYNC_MB */
12161 tcg_mo |= TCG_MO_ALL;
12162 break;
12163 case 0x11: /* SYNC_ACQUIRE */
12164 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12165 break;
12166 case 0x12: /* SYNC_RELEASE */
12167 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12168 break;
12169 case 0x13: /* SYNC_RMB */
12170 tcg_mo |= TCG_MO_LD_LD;
12171 break;
12172 default:
12173 tcg_mo |= TCG_MO_ALL;
12174 break;
12175 }
12176
12177 tcg_gen_mb(tcg_mo);
12178}
12179
bf52c45a 12180/* ISA extensions (ASEs) */
3c824109 12181
bf52c45a
PMD
12182/* MIPS16 extension to MIPS32 */
12183#include "mips16e_translate.c.inc"
3c824109 12184
bf52c45a 12185/* microMIPS extension to MIPS32/MIPS64 */
3c824109 12186
7480515f
AM
12187/*
12188 * Values for microMIPS fmt field. Variable-width, depending on which
12189 * formats the instruction supports.
12190 */
3c824109
NF
12191enum {
12192 FMT_SD_S = 0,
12193 FMT_SD_D = 1,
12194
12195 FMT_SDPS_S = 0,
12196 FMT_SDPS_D = 1,
12197 FMT_SDPS_PS = 2,
12198
12199 FMT_SWL_S = 0,
12200 FMT_SWL_W = 1,
12201 FMT_SWL_L = 2,
12202
12203 FMT_DWL_D = 0,
12204 FMT_DWL_W = 1,
12205 FMT_DWL_L = 2
12206};
12207
bf52c45a 12208#include "micromips_translate.c.inc"
3230bad9 12209
3f178b8d 12210#include "nanomips_translate.c.inc"
c533c0f4 12211
9b1a1d68 12212/* MIPSDSP functions. */
d75c135e 12213static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12214 int rd, int base, int offset)
12215{
9b1a1d68
JL
12216 TCGv t0;
12217
9b1a1d68
JL
12218 check_dsp(ctx);
12219 t0 = tcg_temp_new();
12220
12221 if (base == 0) {
12222 gen_load_gpr(t0, offset);
12223 } else if (offset == 0) {
12224 gen_load_gpr(t0, base);
12225 } else {
12226 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12227 }
12228
9b1a1d68
JL
12229 switch (opc) {
12230 case OPC_LBUX:
5f68f5ae 12231 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 12232 gen_store_gpr(t0, rd);
9b1a1d68
JL
12233 break;
12234 case OPC_LHX:
5f68f5ae 12235 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 12236 gen_store_gpr(t0, rd);
9b1a1d68
JL
12237 break;
12238 case OPC_LWX:
5f68f5ae 12239 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 12240 gen_store_gpr(t0, rd);
9b1a1d68
JL
12241 break;
12242#if defined(TARGET_MIPS64)
12243 case OPC_LDX:
5f68f5ae 12244 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 12245 gen_store_gpr(t0, rd);
9b1a1d68
JL
12246 break;
12247#endif
12248 }
9b1a1d68
JL
12249 tcg_temp_free(t0);
12250}
12251
461c08df
JL
12252static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12253 int ret, int v1, int v2)
12254{
461c08df
JL
12255 TCGv v1_t;
12256 TCGv v2_t;
12257
12258 if (ret == 0) {
12259 /* Treat as NOP. */
461c08df
JL
12260 return;
12261 }
12262
12263 v1_t = tcg_temp_new();
12264 v2_t = tcg_temp_new();
12265
12266 gen_load_gpr(v1_t, v1);
12267 gen_load_gpr(v2_t, v2);
12268
12269 switch (op1) {
12270 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12271 case OPC_MULT_G_2E:
908f6be1 12272 check_dsp_r2(ctx);
461c08df
JL
12273 switch (op2) {
12274 case OPC_ADDUH_QB:
12275 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12276 break;
12277 case OPC_ADDUH_R_QB:
12278 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12279 break;
12280 case OPC_ADDQH_PH:
12281 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12282 break;
12283 case OPC_ADDQH_R_PH:
12284 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12285 break;
12286 case OPC_ADDQH_W:
12287 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12288 break;
12289 case OPC_ADDQH_R_W:
12290 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12291 break;
12292 case OPC_SUBUH_QB:
12293 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12294 break;
12295 case OPC_SUBUH_R_QB:
12296 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12297 break;
12298 case OPC_SUBQH_PH:
12299 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12300 break;
12301 case OPC_SUBQH_R_PH:
12302 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12303 break;
12304 case OPC_SUBQH_W:
12305 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12306 break;
12307 case OPC_SUBQH_R_W:
12308 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12309 break;
12310 }
12311 break;
12312 case OPC_ABSQ_S_PH_DSP:
12313 switch (op2) {
12314 case OPC_ABSQ_S_QB:
908f6be1 12315 check_dsp_r2(ctx);
461c08df
JL
12316 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12317 break;
12318 case OPC_ABSQ_S_PH:
12319 check_dsp(ctx);
12320 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12321 break;
12322 case OPC_ABSQ_S_W:
12323 check_dsp(ctx);
12324 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12325 break;
12326 case OPC_PRECEQ_W_PHL:
12327 check_dsp(ctx);
12328 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12329 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12330 break;
12331 case OPC_PRECEQ_W_PHR:
12332 check_dsp(ctx);
12333 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12334 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12335 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12336 break;
12337 case OPC_PRECEQU_PH_QBL:
12338 check_dsp(ctx);
12339 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12340 break;
12341 case OPC_PRECEQU_PH_QBR:
12342 check_dsp(ctx);
12343 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12344 break;
12345 case OPC_PRECEQU_PH_QBLA:
12346 check_dsp(ctx);
12347 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12348 break;
12349 case OPC_PRECEQU_PH_QBRA:
12350 check_dsp(ctx);
12351 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12352 break;
12353 case OPC_PRECEU_PH_QBL:
12354 check_dsp(ctx);
12355 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12356 break;
12357 case OPC_PRECEU_PH_QBR:
12358 check_dsp(ctx);
12359 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12360 break;
12361 case OPC_PRECEU_PH_QBLA:
12362 check_dsp(ctx);
12363 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12364 break;
12365 case OPC_PRECEU_PH_QBRA:
12366 check_dsp(ctx);
12367 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12368 break;
12369 }
12370 break;
12371 case OPC_ADDU_QB_DSP:
12372 switch (op2) {
12373 case OPC_ADDQ_PH:
12374 check_dsp(ctx);
12375 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12376 break;
12377 case OPC_ADDQ_S_PH:
12378 check_dsp(ctx);
12379 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12380 break;
12381 case OPC_ADDQ_S_W:
12382 check_dsp(ctx);
12383 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12384 break;
12385 case OPC_ADDU_QB:
12386 check_dsp(ctx);
12387 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12388 break;
12389 case OPC_ADDU_S_QB:
12390 check_dsp(ctx);
12391 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12392 break;
12393 case OPC_ADDU_PH:
908f6be1 12394 check_dsp_r2(ctx);
461c08df
JL
12395 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12396 break;
12397 case OPC_ADDU_S_PH:
908f6be1 12398 check_dsp_r2(ctx);
461c08df
JL
12399 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12400 break;
12401 case OPC_SUBQ_PH:
12402 check_dsp(ctx);
12403 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12404 break;
12405 case OPC_SUBQ_S_PH:
12406 check_dsp(ctx);
12407 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12408 break;
12409 case OPC_SUBQ_S_W:
12410 check_dsp(ctx);
12411 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12412 break;
12413 case OPC_SUBU_QB:
12414 check_dsp(ctx);
12415 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12416 break;
12417 case OPC_SUBU_S_QB:
12418 check_dsp(ctx);
12419 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12420 break;
12421 case OPC_SUBU_PH:
908f6be1 12422 check_dsp_r2(ctx);
461c08df
JL
12423 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12424 break;
12425 case OPC_SUBU_S_PH:
908f6be1 12426 check_dsp_r2(ctx);
461c08df
JL
12427 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12428 break;
12429 case OPC_ADDSC:
12430 check_dsp(ctx);
12431 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12432 break;
12433 case OPC_ADDWC:
12434 check_dsp(ctx);
12435 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12436 break;
12437 case OPC_MODSUB:
12438 check_dsp(ctx);
12439 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12440 break;
12441 case OPC_RADDU_W_QB:
12442 check_dsp(ctx);
12443 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12444 break;
12445 }
12446 break;
12447 case OPC_CMPU_EQ_QB_DSP:
12448 switch (op2) {
12449 case OPC_PRECR_QB_PH:
908f6be1 12450 check_dsp_r2(ctx);
461c08df
JL
12451 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12452 break;
12453 case OPC_PRECRQ_QB_PH:
12454 check_dsp(ctx);
12455 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12456 break;
12457 case OPC_PRECR_SRA_PH_W:
908f6be1 12458 check_dsp_r2(ctx);
461c08df
JL
12459 {
12460 TCGv_i32 sa_t = tcg_const_i32(v2);
12461 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12462 cpu_gpr[ret]);
12463 tcg_temp_free_i32(sa_t);
12464 break;
12465 }
12466 case OPC_PRECR_SRA_R_PH_W:
908f6be1 12467 check_dsp_r2(ctx);
461c08df
JL
12468 {
12469 TCGv_i32 sa_t = tcg_const_i32(v2);
12470 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12471 cpu_gpr[ret]);
12472 tcg_temp_free_i32(sa_t);
12473 break;
12474 }
12475 case OPC_PRECRQ_PH_W:
12476 check_dsp(ctx);
12477 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12478 break;
12479 case OPC_PRECRQ_RS_PH_W:
12480 check_dsp(ctx);
12481 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12482 break;
12483 case OPC_PRECRQU_S_QB_PH:
12484 check_dsp(ctx);
12485 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12486 break;
12487 }
12488 break;
12489#ifdef TARGET_MIPS64
12490 case OPC_ABSQ_S_QH_DSP:
12491 switch (op2) {
12492 case OPC_PRECEQ_L_PWL:
12493 check_dsp(ctx);
12494 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12495 break;
12496 case OPC_PRECEQ_L_PWR:
12497 check_dsp(ctx);
12498 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12499 break;
12500 case OPC_PRECEQ_PW_QHL:
12501 check_dsp(ctx);
12502 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12503 break;
12504 case OPC_PRECEQ_PW_QHR:
12505 check_dsp(ctx);
12506 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12507 break;
12508 case OPC_PRECEQ_PW_QHLA:
12509 check_dsp(ctx);
12510 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12511 break;
12512 case OPC_PRECEQ_PW_QHRA:
12513 check_dsp(ctx);
12514 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12515 break;
12516 case OPC_PRECEQU_QH_OBL:
12517 check_dsp(ctx);
12518 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12519 break;
12520 case OPC_PRECEQU_QH_OBR:
12521 check_dsp(ctx);
12522 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12523 break;
12524 case OPC_PRECEQU_QH_OBLA:
12525 check_dsp(ctx);
12526 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12527 break;
12528 case OPC_PRECEQU_QH_OBRA:
12529 check_dsp(ctx);
12530 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12531 break;
12532 case OPC_PRECEU_QH_OBL:
12533 check_dsp(ctx);
12534 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12535 break;
12536 case OPC_PRECEU_QH_OBR:
12537 check_dsp(ctx);
12538 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12539 break;
12540 case OPC_PRECEU_QH_OBLA:
12541 check_dsp(ctx);
12542 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12543 break;
12544 case OPC_PRECEU_QH_OBRA:
12545 check_dsp(ctx);
12546 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12547 break;
12548 case OPC_ABSQ_S_OB:
908f6be1 12549 check_dsp_r2(ctx);
461c08df
JL
12550 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12551 break;
12552 case OPC_ABSQ_S_PW:
12553 check_dsp(ctx);
12554 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12555 break;
12556 case OPC_ABSQ_S_QH:
12557 check_dsp(ctx);
12558 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12559 break;
12560 }
12561 break;
12562 case OPC_ADDU_OB_DSP:
12563 switch (op2) {
12564 case OPC_RADDU_L_OB:
12565 check_dsp(ctx);
12566 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12567 break;
12568 case OPC_SUBQ_PW:
12569 check_dsp(ctx);
12570 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12571 break;
12572 case OPC_SUBQ_S_PW:
12573 check_dsp(ctx);
12574 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12575 break;
12576 case OPC_SUBQ_QH:
12577 check_dsp(ctx);
12578 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12579 break;
12580 case OPC_SUBQ_S_QH:
12581 check_dsp(ctx);
12582 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12583 break;
12584 case OPC_SUBU_OB:
12585 check_dsp(ctx);
12586 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12587 break;
12588 case OPC_SUBU_S_OB:
12589 check_dsp(ctx);
12590 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12591 break;
12592 case OPC_SUBU_QH:
908f6be1 12593 check_dsp_r2(ctx);
461c08df
JL
12594 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12595 break;
12596 case OPC_SUBU_S_QH:
908f6be1 12597 check_dsp_r2(ctx);
461c08df
JL
12598 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12599 break;
12600 case OPC_SUBUH_OB:
908f6be1 12601 check_dsp_r2(ctx);
461c08df
JL
12602 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12603 break;
12604 case OPC_SUBUH_R_OB:
908f6be1 12605 check_dsp_r2(ctx);
461c08df
JL
12606 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12607 break;
12608 case OPC_ADDQ_PW:
12609 check_dsp(ctx);
12610 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12611 break;
12612 case OPC_ADDQ_S_PW:
12613 check_dsp(ctx);
12614 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12615 break;
12616 case OPC_ADDQ_QH:
12617 check_dsp(ctx);
12618 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12619 break;
12620 case OPC_ADDQ_S_QH:
12621 check_dsp(ctx);
12622 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12623 break;
12624 case OPC_ADDU_OB:
12625 check_dsp(ctx);
12626 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12627 break;
12628 case OPC_ADDU_S_OB:
12629 check_dsp(ctx);
12630 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12631 break;
12632 case OPC_ADDU_QH:
908f6be1 12633 check_dsp_r2(ctx);
461c08df
JL
12634 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12635 break;
12636 case OPC_ADDU_S_QH:
908f6be1 12637 check_dsp_r2(ctx);
461c08df
JL
12638 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12639 break;
12640 case OPC_ADDUH_OB:
908f6be1 12641 check_dsp_r2(ctx);
461c08df
JL
12642 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12643 break;
12644 case OPC_ADDUH_R_OB:
908f6be1 12645 check_dsp_r2(ctx);
461c08df
JL
12646 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12647 break;
12648 }
12649 break;
12650 case OPC_CMPU_EQ_OB_DSP:
12651 switch (op2) {
12652 case OPC_PRECR_OB_QH:
908f6be1 12653 check_dsp_r2(ctx);
461c08df
JL
12654 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12655 break;
12656 case OPC_PRECR_SRA_QH_PW:
908f6be1 12657 check_dsp_r2(ctx);
461c08df
JL
12658 {
12659 TCGv_i32 ret_t = tcg_const_i32(ret);
12660 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12661 tcg_temp_free_i32(ret_t);
12662 break;
12663 }
12664 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 12665 check_dsp_r2(ctx);
461c08df
JL
12666 {
12667 TCGv_i32 sa_v = tcg_const_i32(ret);
12668 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12669 tcg_temp_free_i32(sa_v);
12670 break;
12671 }
12672 case OPC_PRECRQ_OB_QH:
12673 check_dsp(ctx);
12674 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12675 break;
12676 case OPC_PRECRQ_PW_L:
12677 check_dsp(ctx);
12678 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12679 break;
12680 case OPC_PRECRQ_QH_PW:
12681 check_dsp(ctx);
12682 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12683 break;
12684 case OPC_PRECRQ_RS_QH_PW:
12685 check_dsp(ctx);
12686 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12687 break;
12688 case OPC_PRECRQU_S_OB_QH:
12689 check_dsp(ctx);
12690 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12691 break;
12692 }
12693 break;
12694#endif
12695 }
12696
12697 tcg_temp_free(v1_t);
12698 tcg_temp_free(v2_t);
461c08df 12699}
9b1a1d68 12700
77c5fa8b
JL
12701static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12702 int ret, int v1, int v2)
12703{
12704 uint32_t op2;
77c5fa8b
JL
12705 TCGv t0;
12706 TCGv v1_t;
12707 TCGv v2_t;
12708
12709 if (ret == 0) {
12710 /* Treat as NOP. */
77c5fa8b
JL
12711 return;
12712 }
12713
12714 t0 = tcg_temp_new();
12715 v1_t = tcg_temp_new();
12716 v2_t = tcg_temp_new();
12717
12718 tcg_gen_movi_tl(t0, v1);
12719 gen_load_gpr(v1_t, v1);
12720 gen_load_gpr(v2_t, v2);
12721
12722 switch (opc) {
12723 case OPC_SHLL_QB_DSP:
12724 {
12725 op2 = MASK_SHLL_QB(ctx->opcode);
12726 switch (op2) {
12727 case OPC_SHLL_QB:
12728 check_dsp(ctx);
12729 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12730 break;
12731 case OPC_SHLLV_QB:
12732 check_dsp(ctx);
12733 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12734 break;
12735 case OPC_SHLL_PH:
12736 check_dsp(ctx);
12737 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12738 break;
12739 case OPC_SHLLV_PH:
12740 check_dsp(ctx);
12741 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12742 break;
12743 case OPC_SHLL_S_PH:
12744 check_dsp(ctx);
12745 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12746 break;
12747 case OPC_SHLLV_S_PH:
12748 check_dsp(ctx);
12749 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12750 break;
12751 case OPC_SHLL_S_W:
12752 check_dsp(ctx);
12753 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12754 break;
12755 case OPC_SHLLV_S_W:
12756 check_dsp(ctx);
12757 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12758 break;
12759 case OPC_SHRL_QB:
12760 check_dsp(ctx);
12761 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12762 break;
12763 case OPC_SHRLV_QB:
12764 check_dsp(ctx);
12765 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12766 break;
12767 case OPC_SHRL_PH:
908f6be1 12768 check_dsp_r2(ctx);
77c5fa8b
JL
12769 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12770 break;
12771 case OPC_SHRLV_PH:
908f6be1 12772 check_dsp_r2(ctx);
77c5fa8b
JL
12773 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12774 break;
12775 case OPC_SHRA_QB:
908f6be1 12776 check_dsp_r2(ctx);
77c5fa8b
JL
12777 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12778 break;
12779 case OPC_SHRA_R_QB:
908f6be1 12780 check_dsp_r2(ctx);
77c5fa8b
JL
12781 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12782 break;
12783 case OPC_SHRAV_QB:
908f6be1 12784 check_dsp_r2(ctx);
77c5fa8b
JL
12785 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12786 break;
12787 case OPC_SHRAV_R_QB:
908f6be1 12788 check_dsp_r2(ctx);
77c5fa8b
JL
12789 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12790 break;
12791 case OPC_SHRA_PH:
12792 check_dsp(ctx);
12793 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12794 break;
12795 case OPC_SHRA_R_PH:
12796 check_dsp(ctx);
12797 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12798 break;
12799 case OPC_SHRAV_PH:
12800 check_dsp(ctx);
12801 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12802 break;
12803 case OPC_SHRAV_R_PH:
12804 check_dsp(ctx);
12805 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12806 break;
12807 case OPC_SHRA_R_W:
12808 check_dsp(ctx);
12809 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12810 break;
12811 case OPC_SHRAV_R_W:
12812 check_dsp(ctx);
12813 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12814 break;
12815 default: /* Invalid */
12816 MIPS_INVAL("MASK SHLL.QB");
3a4ef3b7 12817 gen_reserved_instruction(ctx);
77c5fa8b
JL
12818 break;
12819 }
12820 break;
12821 }
12822#ifdef TARGET_MIPS64
12823 case OPC_SHLL_OB_DSP:
12824 op2 = MASK_SHLL_OB(ctx->opcode);
12825 switch (op2) {
12826 case OPC_SHLL_PW:
12827 check_dsp(ctx);
12828 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12829 break;
12830 case OPC_SHLLV_PW:
12831 check_dsp(ctx);
12832 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12833 break;
12834 case OPC_SHLL_S_PW:
12835 check_dsp(ctx);
12836 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12837 break;
12838 case OPC_SHLLV_S_PW:
12839 check_dsp(ctx);
12840 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12841 break;
12842 case OPC_SHLL_OB:
12843 check_dsp(ctx);
12844 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12845 break;
12846 case OPC_SHLLV_OB:
12847 check_dsp(ctx);
12848 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12849 break;
12850 case OPC_SHLL_QH:
12851 check_dsp(ctx);
12852 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12853 break;
12854 case OPC_SHLLV_QH:
12855 check_dsp(ctx);
12856 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12857 break;
12858 case OPC_SHLL_S_QH:
12859 check_dsp(ctx);
12860 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12861 break;
12862 case OPC_SHLLV_S_QH:
12863 check_dsp(ctx);
12864 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12865 break;
12866 case OPC_SHRA_OB:
908f6be1 12867 check_dsp_r2(ctx);
77c5fa8b
JL
12868 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12869 break;
12870 case OPC_SHRAV_OB:
908f6be1 12871 check_dsp_r2(ctx);
77c5fa8b
JL
12872 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12873 break;
12874 case OPC_SHRA_R_OB:
908f6be1 12875 check_dsp_r2(ctx);
77c5fa8b
JL
12876 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12877 break;
12878 case OPC_SHRAV_R_OB:
908f6be1 12879 check_dsp_r2(ctx);
77c5fa8b
JL
12880 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12881 break;
12882 case OPC_SHRA_PW:
12883 check_dsp(ctx);
12884 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12885 break;
12886 case OPC_SHRAV_PW:
12887 check_dsp(ctx);
12888 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12889 break;
12890 case OPC_SHRA_R_PW:
12891 check_dsp(ctx);
12892 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12893 break;
12894 case OPC_SHRAV_R_PW:
12895 check_dsp(ctx);
12896 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12897 break;
12898 case OPC_SHRA_QH:
12899 check_dsp(ctx);
12900 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12901 break;
12902 case OPC_SHRAV_QH:
12903 check_dsp(ctx);
12904 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12905 break;
12906 case OPC_SHRA_R_QH:
12907 check_dsp(ctx);
12908 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12909 break;
12910 case OPC_SHRAV_R_QH:
12911 check_dsp(ctx);
12912 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12913 break;
12914 case OPC_SHRL_OB:
12915 check_dsp(ctx);
12916 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12917 break;
12918 case OPC_SHRLV_OB:
12919 check_dsp(ctx);
12920 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12921 break;
12922 case OPC_SHRL_QH:
908f6be1 12923 check_dsp_r2(ctx);
77c5fa8b
JL
12924 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12925 break;
12926 case OPC_SHRLV_QH:
908f6be1 12927 check_dsp_r2(ctx);
77c5fa8b
JL
12928 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12929 break;
12930 default: /* Invalid */
12931 MIPS_INVAL("MASK SHLL.OB");
3a4ef3b7 12932 gen_reserved_instruction(ctx);
77c5fa8b
JL
12933 break;
12934 }
12935 break;
12936#endif
12937 }
12938
12939 tcg_temp_free(t0);
12940 tcg_temp_free(v1_t);
12941 tcg_temp_free(v2_t);
77c5fa8b
JL
12942}
12943
a22260ae
JL
12944static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12945 int ret, int v1, int v2, int check_ret)
12946{
a22260ae
JL
12947 TCGv_i32 t0;
12948 TCGv v1_t;
12949 TCGv v2_t;
12950
12951 if ((ret == 0) && (check_ret == 1)) {
12952 /* Treat as NOP. */
a22260ae
JL
12953 return;
12954 }
12955
12956 t0 = tcg_temp_new_i32();
12957 v1_t = tcg_temp_new();
12958 v2_t = tcg_temp_new();
12959
12960 tcg_gen_movi_i32(t0, ret);
12961 gen_load_gpr(v1_t, v1);
12962 gen_load_gpr(v2_t, v2);
12963
12964 switch (op1) {
7480515f
AM
12965 /*
12966 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12967 * the same mask and op1.
12968 */
a22260ae 12969 case OPC_MULT_G_2E:
908f6be1 12970 check_dsp_r2(ctx);
a22260ae
JL
12971 switch (op2) {
12972 case OPC_MUL_PH:
12973 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12974 break;
12975 case OPC_MUL_S_PH:
12976 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12977 break;
12978 case OPC_MULQ_S_W:
12979 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12980 break;
12981 case OPC_MULQ_RS_W:
12982 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12983 break;
12984 }
12985 break;
12986 case OPC_DPA_W_PH_DSP:
12987 switch (op2) {
12988 case OPC_DPAU_H_QBL:
12989 check_dsp(ctx);
12990 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12991 break;
12992 case OPC_DPAU_H_QBR:
12993 check_dsp(ctx);
12994 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12995 break;
12996 case OPC_DPSU_H_QBL:
12997 check_dsp(ctx);
12998 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12999 break;
13000 case OPC_DPSU_H_QBR:
13001 check_dsp(ctx);
13002 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13003 break;
13004 case OPC_DPA_W_PH:
908f6be1 13005 check_dsp_r2(ctx);
a22260ae
JL
13006 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13007 break;
13008 case OPC_DPAX_W_PH:
908f6be1 13009 check_dsp_r2(ctx);
a22260ae
JL
13010 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13011 break;
13012 case OPC_DPAQ_S_W_PH:
13013 check_dsp(ctx);
13014 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13015 break;
13016 case OPC_DPAQX_S_W_PH:
908f6be1 13017 check_dsp_r2(ctx);
a22260ae
JL
13018 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13019 break;
13020 case OPC_DPAQX_SA_W_PH:
908f6be1 13021 check_dsp_r2(ctx);
a22260ae
JL
13022 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13023 break;
13024 case OPC_DPS_W_PH:
908f6be1 13025 check_dsp_r2(ctx);
a22260ae
JL
13026 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13027 break;
13028 case OPC_DPSX_W_PH:
908f6be1 13029 check_dsp_r2(ctx);
a22260ae
JL
13030 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13031 break;
13032 case OPC_DPSQ_S_W_PH:
13033 check_dsp(ctx);
13034 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13035 break;
13036 case OPC_DPSQX_S_W_PH:
908f6be1 13037 check_dsp_r2(ctx);
a22260ae
JL
13038 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13039 break;
13040 case OPC_DPSQX_SA_W_PH:
908f6be1 13041 check_dsp_r2(ctx);
a22260ae
JL
13042 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13043 break;
13044 case OPC_MULSAQ_S_W_PH:
13045 check_dsp(ctx);
13046 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13047 break;
13048 case OPC_DPAQ_SA_L_W:
13049 check_dsp(ctx);
13050 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13051 break;
13052 case OPC_DPSQ_SA_L_W:
13053 check_dsp(ctx);
13054 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13055 break;
13056 case OPC_MAQ_S_W_PHL:
13057 check_dsp(ctx);
13058 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13059 break;
13060 case OPC_MAQ_S_W_PHR:
13061 check_dsp(ctx);
13062 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13063 break;
13064 case OPC_MAQ_SA_W_PHL:
13065 check_dsp(ctx);
13066 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13067 break;
13068 case OPC_MAQ_SA_W_PHR:
13069 check_dsp(ctx);
13070 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13071 break;
13072 case OPC_MULSA_W_PH:
908f6be1 13073 check_dsp_r2(ctx);
a22260ae
JL
13074 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13075 break;
13076 }
13077 break;
13078#ifdef TARGET_MIPS64
13079 case OPC_DPAQ_W_QH_DSP:
13080 {
13081 int ac = ret & 0x03;
13082 tcg_gen_movi_i32(t0, ac);
13083
13084 switch (op2) {
13085 case OPC_DMADD:
13086 check_dsp(ctx);
13087 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13088 break;
13089 case OPC_DMADDU:
13090 check_dsp(ctx);
13091 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13092 break;
13093 case OPC_DMSUB:
13094 check_dsp(ctx);
13095 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13096 break;
13097 case OPC_DMSUBU:
13098 check_dsp(ctx);
13099 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13100 break;
13101 case OPC_DPA_W_QH:
908f6be1 13102 check_dsp_r2(ctx);
a22260ae
JL
13103 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13104 break;
13105 case OPC_DPAQ_S_W_QH:
13106 check_dsp(ctx);
13107 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13108 break;
13109 case OPC_DPAQ_SA_L_PW:
13110 check_dsp(ctx);
13111 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13112 break;
13113 case OPC_DPAU_H_OBL:
13114 check_dsp(ctx);
13115 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13116 break;
13117 case OPC_DPAU_H_OBR:
13118 check_dsp(ctx);
13119 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13120 break;
13121 case OPC_DPS_W_QH:
908f6be1 13122 check_dsp_r2(ctx);
a22260ae
JL
13123 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13124 break;
13125 case OPC_DPSQ_S_W_QH:
13126 check_dsp(ctx);
13127 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13128 break;
13129 case OPC_DPSQ_SA_L_PW:
13130 check_dsp(ctx);
13131 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13132 break;
13133 case OPC_DPSU_H_OBL:
13134 check_dsp(ctx);
13135 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13136 break;
13137 case OPC_DPSU_H_OBR:
13138 check_dsp(ctx);
13139 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13140 break;
13141 case OPC_MAQ_S_L_PWL:
13142 check_dsp(ctx);
13143 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13144 break;
13145 case OPC_MAQ_S_L_PWR:
13146 check_dsp(ctx);
13147 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13148 break;
13149 case OPC_MAQ_S_W_QHLL:
13150 check_dsp(ctx);
13151 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13152 break;
13153 case OPC_MAQ_SA_W_QHLL:
13154 check_dsp(ctx);
13155 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13156 break;
13157 case OPC_MAQ_S_W_QHLR:
13158 check_dsp(ctx);
13159 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13160 break;
13161 case OPC_MAQ_SA_W_QHLR:
13162 check_dsp(ctx);
13163 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13164 break;
13165 case OPC_MAQ_S_W_QHRL:
13166 check_dsp(ctx);
13167 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13168 break;
13169 case OPC_MAQ_SA_W_QHRL:
13170 check_dsp(ctx);
13171 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13172 break;
13173 case OPC_MAQ_S_W_QHRR:
13174 check_dsp(ctx);
13175 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13176 break;
13177 case OPC_MAQ_SA_W_QHRR:
13178 check_dsp(ctx);
13179 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13180 break;
13181 case OPC_MULSAQ_S_L_PW:
13182 check_dsp(ctx);
13183 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13184 break;
13185 case OPC_MULSAQ_S_W_QH:
13186 check_dsp(ctx);
13187 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13188 break;
13189 }
13190 }
13191 break;
13192#endif
13193 case OPC_ADDU_QB_DSP:
13194 switch (op2) {
13195 case OPC_MULEU_S_PH_QBL:
13196 check_dsp(ctx);
13197 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 break;
13199 case OPC_MULEU_S_PH_QBR:
13200 check_dsp(ctx);
13201 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13202 break;
13203 case OPC_MULQ_RS_PH:
13204 check_dsp(ctx);
13205 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13206 break;
13207 case OPC_MULEQ_S_W_PHL:
13208 check_dsp(ctx);
13209 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13210 break;
13211 case OPC_MULEQ_S_W_PHR:
13212 check_dsp(ctx);
13213 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13214 break;
13215 case OPC_MULQ_S_PH:
908f6be1 13216 check_dsp_r2(ctx);
a22260ae
JL
13217 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13218 break;
13219 }
13220 break;
13221#ifdef TARGET_MIPS64
13222 case OPC_ADDU_OB_DSP:
13223 switch (op2) {
13224 case OPC_MULEQ_S_PW_QHL:
13225 check_dsp(ctx);
13226 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13227 break;
13228 case OPC_MULEQ_S_PW_QHR:
13229 check_dsp(ctx);
13230 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13231 break;
13232 case OPC_MULEU_S_QH_OBL:
13233 check_dsp(ctx);
13234 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13235 break;
13236 case OPC_MULEU_S_QH_OBR:
13237 check_dsp(ctx);
13238 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13239 break;
13240 case OPC_MULQ_RS_QH:
13241 check_dsp(ctx);
13242 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13243 break;
13244 }
13245 break;
13246#endif
13247 }
13248
13249 tcg_temp_free_i32(t0);
13250 tcg_temp_free(v1_t);
13251 tcg_temp_free(v2_t);
a22260ae
JL
13252}
13253
d75c135e 13254static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13255 int ret, int val)
13256{
1cb6686c
JL
13257 int16_t imm;
13258 TCGv t0;
13259 TCGv val_t;
13260
13261 if (ret == 0) {
13262 /* Treat as NOP. */
1cb6686c
JL
13263 return;
13264 }
13265
13266 t0 = tcg_temp_new();
13267 val_t = tcg_temp_new();
13268 gen_load_gpr(val_t, val);
13269
13270 switch (op1) {
13271 case OPC_ABSQ_S_PH_DSP:
13272 switch (op2) {
13273 case OPC_BITREV:
13274 check_dsp(ctx);
13275 gen_helper_bitrev(cpu_gpr[ret], val_t);
13276 break;
13277 case OPC_REPL_QB:
13278 check_dsp(ctx);
13279 {
13280 target_long result;
13281 imm = (ctx->opcode >> 16) & 0xFF;
13282 result = (uint32_t)imm << 24 |
13283 (uint32_t)imm << 16 |
13284 (uint32_t)imm << 8 |
13285 (uint32_t)imm;
13286 result = (int32_t)result;
13287 tcg_gen_movi_tl(cpu_gpr[ret], result);
13288 }
13289 break;
13290 case OPC_REPLV_QB:
13291 check_dsp(ctx);
13292 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13293 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13294 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13295 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13296 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13297 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13298 break;
13299 case OPC_REPL_PH:
13300 check_dsp(ctx);
13301 {
13302 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13303 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13304 tcg_gen_movi_tl(cpu_gpr[ret], \
13305 (target_long)((int32_t)imm << 16 | \
c4aaba92 13306 (uint16_t)imm));
1cb6686c
JL
13307 }
13308 break;
13309 case OPC_REPLV_PH:
13310 check_dsp(ctx);
13311 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13312 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13313 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13314 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13315 break;
13316 }
13317 break;
13318#ifdef TARGET_MIPS64
13319 case OPC_ABSQ_S_QH_DSP:
13320 switch (op2) {
13321 case OPC_REPL_OB:
13322 check_dsp(ctx);
13323 {
13324 target_long temp;
13325
13326 imm = (ctx->opcode >> 16) & 0xFF;
13327 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13328 temp = (temp << 16) | temp;
13329 temp = (temp << 32) | temp;
13330 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13331 break;
13332 }
13333 case OPC_REPL_PW:
13334 check_dsp(ctx);
13335 {
13336 target_long temp;
13337
13338 imm = (ctx->opcode >> 16) & 0x03FF;
13339 imm = (int16_t)(imm << 6) >> 6;
13340 temp = ((target_long)imm << 32) \
13341 | ((target_long)imm & 0xFFFFFFFF);
13342 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13343 break;
13344 }
13345 case OPC_REPL_QH:
13346 check_dsp(ctx);
13347 {
13348 target_long temp;
13349
13350 imm = (ctx->opcode >> 16) & 0x03FF;
13351 imm = (int16_t)(imm << 6) >> 6;
13352
13353 temp = ((uint64_t)(uint16_t)imm << 48) |
13354 ((uint64_t)(uint16_t)imm << 32) |
13355 ((uint64_t)(uint16_t)imm << 16) |
13356 (uint64_t)(uint16_t)imm;
13357 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13358 break;
13359 }
13360 case OPC_REPLV_OB:
13361 check_dsp(ctx);
13362 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13363 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13364 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13365 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13366 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13367 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13368 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13369 break;
13370 case OPC_REPLV_PW:
13371 check_dsp(ctx);
13372 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13373 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13374 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13375 break;
13376 case OPC_REPLV_QH:
13377 check_dsp(ctx);
13378 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13379 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13380 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13381 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13382 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13383 break;
13384 }
13385 break;
13386#endif
13387 }
13388 tcg_temp_free(t0);
13389 tcg_temp_free(val_t);
1cb6686c
JL
13390}
13391
26690560
JL
13392static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13393 uint32_t op1, uint32_t op2,
13394 int ret, int v1, int v2, int check_ret)
13395{
26690560
JL
13396 TCGv t1;
13397 TCGv v1_t;
13398 TCGv v2_t;
13399
13400 if ((ret == 0) && (check_ret == 1)) {
13401 /* Treat as NOP. */
26690560
JL
13402 return;
13403 }
13404
26690560
JL
13405 t1 = tcg_temp_new();
13406 v1_t = tcg_temp_new();
13407 v2_t = tcg_temp_new();
13408
13409 gen_load_gpr(v1_t, v1);
13410 gen_load_gpr(v2_t, v2);
13411
13412 switch (op1) {
26690560
JL
13413 case OPC_CMPU_EQ_QB_DSP:
13414 switch (op2) {
13415 case OPC_CMPU_EQ_QB:
13416 check_dsp(ctx);
13417 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13418 break;
13419 case OPC_CMPU_LT_QB:
13420 check_dsp(ctx);
13421 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13422 break;
13423 case OPC_CMPU_LE_QB:
13424 check_dsp(ctx);
13425 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13426 break;
13427 case OPC_CMPGU_EQ_QB:
13428 check_dsp(ctx);
13429 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13430 break;
13431 case OPC_CMPGU_LT_QB:
13432 check_dsp(ctx);
13433 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13434 break;
13435 case OPC_CMPGU_LE_QB:
13436 check_dsp(ctx);
13437 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13438 break;
13439 case OPC_CMPGDU_EQ_QB:
908f6be1 13440 check_dsp_r2(ctx);
26690560
JL
13441 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13442 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13443 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13444 tcg_gen_shli_tl(t1, t1, 24);
13445 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13446 break;
13447 case OPC_CMPGDU_LT_QB:
908f6be1 13448 check_dsp_r2(ctx);
26690560
JL
13449 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13450 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13451 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13452 tcg_gen_shli_tl(t1, t1, 24);
13453 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13454 break;
13455 case OPC_CMPGDU_LE_QB:
908f6be1 13456 check_dsp_r2(ctx);
26690560
JL
13457 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13458 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13459 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13460 tcg_gen_shli_tl(t1, t1, 24);
13461 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13462 break;
13463 case OPC_CMP_EQ_PH:
13464 check_dsp(ctx);
13465 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13466 break;
13467 case OPC_CMP_LT_PH:
13468 check_dsp(ctx);
13469 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13470 break;
13471 case OPC_CMP_LE_PH:
13472 check_dsp(ctx);
13473 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13474 break;
13475 case OPC_PICK_QB:
13476 check_dsp(ctx);
13477 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13478 break;
13479 case OPC_PICK_PH:
13480 check_dsp(ctx);
13481 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13482 break;
13483 case OPC_PACKRL_PH:
13484 check_dsp(ctx);
13485 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13486 break;
13487 }
13488 break;
13489#ifdef TARGET_MIPS64
13490 case OPC_CMPU_EQ_OB_DSP:
13491 switch (op2) {
13492 case OPC_CMP_EQ_PW:
13493 check_dsp(ctx);
13494 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_CMP_LT_PW:
13497 check_dsp(ctx);
13498 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_CMP_LE_PW:
13501 check_dsp(ctx);
13502 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_CMP_EQ_QH:
13505 check_dsp(ctx);
13506 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13507 break;
13508 case OPC_CMP_LT_QH:
13509 check_dsp(ctx);
13510 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_CMP_LE_QH:
13513 check_dsp(ctx);
13514 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13515 break;
13516 case OPC_CMPGDU_EQ_OB:
908f6be1 13517 check_dsp_r2(ctx);
26690560
JL
13518 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13519 break;
13520 case OPC_CMPGDU_LT_OB:
908f6be1 13521 check_dsp_r2(ctx);
26690560
JL
13522 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13523 break;
13524 case OPC_CMPGDU_LE_OB:
908f6be1 13525 check_dsp_r2(ctx);
26690560
JL
13526 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13527 break;
13528 case OPC_CMPGU_EQ_OB:
13529 check_dsp(ctx);
13530 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13531 break;
13532 case OPC_CMPGU_LT_OB:
13533 check_dsp(ctx);
13534 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13535 break;
13536 case OPC_CMPGU_LE_OB:
13537 check_dsp(ctx);
13538 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13539 break;
13540 case OPC_CMPU_EQ_OB:
13541 check_dsp(ctx);
13542 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13543 break;
13544 case OPC_CMPU_LT_OB:
13545 check_dsp(ctx);
13546 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13547 break;
13548 case OPC_CMPU_LE_OB:
13549 check_dsp(ctx);
13550 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13551 break;
13552 case OPC_PACKRL_PW:
13553 check_dsp(ctx);
13554 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13555 break;
13556 case OPC_PICK_OB:
13557 check_dsp(ctx);
13558 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13559 break;
13560 case OPC_PICK_PW:
13561 check_dsp(ctx);
13562 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13563 break;
13564 case OPC_PICK_QH:
13565 check_dsp(ctx);
13566 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13567 break;
13568 }
13569 break;
df6126a7
AJ
13570#endif
13571 }
13572
13573 tcg_temp_free(t1);
13574 tcg_temp_free(v1_t);
13575 tcg_temp_free(v2_t);
df6126a7
AJ
13576}
13577
13578static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13579 uint32_t op1, int rt, int rs, int sa)
13580{
df6126a7
AJ
13581 TCGv t0;
13582
908f6be1 13583 check_dsp_r2(ctx);
df6126a7
AJ
13584
13585 if (rt == 0) {
13586 /* Treat as NOP. */
df6126a7
AJ
13587 return;
13588 }
13589
13590 t0 = tcg_temp_new();
13591 gen_load_gpr(t0, rs);
13592
13593 switch (op1) {
13594 case OPC_APPEND_DSP:
13595 switch (MASK_APPEND(ctx->opcode)) {
13596 case OPC_APPEND:
13597 if (sa != 0) {
13598 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13599 }
13600 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13601 break;
13602 case OPC_PREPEND:
13603 if (sa != 0) {
13604 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13605 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13606 tcg_gen_shli_tl(t0, t0, 32 - sa);
13607 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13608 }
13609 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13610 break;
13611 case OPC_BALIGN:
13612 sa &= 3;
13613 if (sa != 0 && sa != 2) {
13614 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13615 tcg_gen_ext32u_tl(t0, t0);
13616 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13617 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13618 }
13619 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13620 break;
13621 default: /* Invalid */
13622 MIPS_INVAL("MASK APPEND");
3a4ef3b7 13623 gen_reserved_instruction(ctx);
df6126a7
AJ
13624 break;
13625 }
13626 break;
13627#ifdef TARGET_MIPS64
26690560 13628 case OPC_DAPPEND_DSP:
df6126a7 13629 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 13630 case OPC_DAPPEND:
df6126a7
AJ
13631 if (sa != 0) {
13632 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13633 }
26690560
JL
13634 break;
13635 case OPC_PREPENDD:
df6126a7
AJ
13636 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13637 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13638 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
13639 break;
13640 case OPC_PREPENDW:
df6126a7
AJ
13641 if (sa != 0) {
13642 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13643 tcg_gen_shli_tl(t0, t0, 64 - sa);
13644 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13645 }
26690560
JL
13646 break;
13647 case OPC_DBALIGN:
df6126a7
AJ
13648 sa &= 7;
13649 if (sa != 0 && sa != 2 && sa != 4) {
13650 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13651 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13652 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13653 }
26690560
JL
13654 break;
13655 default: /* Invalid */
13656 MIPS_INVAL("MASK DAPPEND");
3a4ef3b7 13657 gen_reserved_instruction(ctx);
26690560
JL
13658 break;
13659 }
13660 break;
13661#endif
13662 }
df6126a7 13663 tcg_temp_free(t0);
26690560
JL
13664}
13665
b53371ed
JL
13666static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13667 int ret, int v1, int v2, int check_ret)
13668
13669{
b53371ed
JL
13670 TCGv t0;
13671 TCGv t1;
13672 TCGv v1_t;
13673 TCGv v2_t;
13674 int16_t imm;
13675
13676 if ((ret == 0) && (check_ret == 1)) {
13677 /* Treat as NOP. */
b53371ed
JL
13678 return;
13679 }
13680
13681 t0 = tcg_temp_new();
13682 t1 = tcg_temp_new();
13683 v1_t = tcg_temp_new();
13684 v2_t = tcg_temp_new();
13685
13686 gen_load_gpr(v1_t, v1);
13687 gen_load_gpr(v2_t, v2);
13688
13689 switch (op1) {
13690 case OPC_EXTR_W_DSP:
13691 check_dsp(ctx);
13692 switch (op2) {
13693 case OPC_EXTR_W:
13694 tcg_gen_movi_tl(t0, v2);
13695 tcg_gen_movi_tl(t1, v1);
13696 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13697 break;
13698 case OPC_EXTR_R_W:
13699 tcg_gen_movi_tl(t0, v2);
13700 tcg_gen_movi_tl(t1, v1);
13701 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13702 break;
13703 case OPC_EXTR_RS_W:
13704 tcg_gen_movi_tl(t0, v2);
13705 tcg_gen_movi_tl(t1, v1);
13706 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13707 break;
13708 case OPC_EXTR_S_H:
13709 tcg_gen_movi_tl(t0, v2);
13710 tcg_gen_movi_tl(t1, v1);
13711 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13712 break;
13713 case OPC_EXTRV_S_H:
13714 tcg_gen_movi_tl(t0, v2);
13715 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13716 break;
13717 case OPC_EXTRV_W:
13718 tcg_gen_movi_tl(t0, v2);
13719 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13720 break;
13721 case OPC_EXTRV_R_W:
13722 tcg_gen_movi_tl(t0, v2);
13723 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13724 break;
13725 case OPC_EXTRV_RS_W:
13726 tcg_gen_movi_tl(t0, v2);
13727 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13728 break;
13729 case OPC_EXTP:
13730 tcg_gen_movi_tl(t0, v2);
13731 tcg_gen_movi_tl(t1, v1);
13732 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13733 break;
13734 case OPC_EXTPV:
13735 tcg_gen_movi_tl(t0, v2);
13736 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13737 break;
13738 case OPC_EXTPDP:
13739 tcg_gen_movi_tl(t0, v2);
13740 tcg_gen_movi_tl(t1, v1);
13741 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13742 break;
13743 case OPC_EXTPDPV:
13744 tcg_gen_movi_tl(t0, v2);
13745 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13746 break;
13747 case OPC_SHILO:
13748 imm = (ctx->opcode >> 20) & 0x3F;
13749 tcg_gen_movi_tl(t0, ret);
13750 tcg_gen_movi_tl(t1, imm);
13751 gen_helper_shilo(t0, t1, cpu_env);
13752 break;
13753 case OPC_SHILOV:
13754 tcg_gen_movi_tl(t0, ret);
13755 gen_helper_shilo(t0, v1_t, cpu_env);
13756 break;
13757 case OPC_MTHLIP:
13758 tcg_gen_movi_tl(t0, ret);
13759 gen_helper_mthlip(t0, v1_t, cpu_env);
13760 break;
13761 case OPC_WRDSP:
13762 imm = (ctx->opcode >> 11) & 0x3FF;
13763 tcg_gen_movi_tl(t0, imm);
13764 gen_helper_wrdsp(v1_t, t0, cpu_env);
13765 break;
13766 case OPC_RDDSP:
13767 imm = (ctx->opcode >> 16) & 0x03FF;
13768 tcg_gen_movi_tl(t0, imm);
13769 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13770 break;
13771 }
13772 break;
13773#ifdef TARGET_MIPS64
13774 case OPC_DEXTR_W_DSP:
13775 check_dsp(ctx);
13776 switch (op2) {
13777 case OPC_DMTHLIP:
13778 tcg_gen_movi_tl(t0, ret);
13779 gen_helper_dmthlip(v1_t, t0, cpu_env);
13780 break;
13781 case OPC_DSHILO:
13782 {
13783 int shift = (ctx->opcode >> 19) & 0x7F;
13784 int ac = (ctx->opcode >> 11) & 0x03;
13785 tcg_gen_movi_tl(t0, shift);
13786 tcg_gen_movi_tl(t1, ac);
13787 gen_helper_dshilo(t0, t1, cpu_env);
13788 break;
13789 }
13790 case OPC_DSHILOV:
13791 {
13792 int ac = (ctx->opcode >> 11) & 0x03;
13793 tcg_gen_movi_tl(t0, ac);
13794 gen_helper_dshilo(v1_t, t0, cpu_env);
13795 break;
13796 }
13797 case OPC_DEXTP:
13798 tcg_gen_movi_tl(t0, v2);
13799 tcg_gen_movi_tl(t1, v1);
13800
13801 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13802 break;
13803 case OPC_DEXTPV:
13804 tcg_gen_movi_tl(t0, v2);
13805 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13806 break;
13807 case OPC_DEXTPDP:
13808 tcg_gen_movi_tl(t0, v2);
13809 tcg_gen_movi_tl(t1, v1);
13810 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13811 break;
13812 case OPC_DEXTPDPV:
13813 tcg_gen_movi_tl(t0, v2);
13814 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13815 break;
13816 case OPC_DEXTR_L:
13817 tcg_gen_movi_tl(t0, v2);
13818 tcg_gen_movi_tl(t1, v1);
13819 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13820 break;
13821 case OPC_DEXTR_R_L:
13822 tcg_gen_movi_tl(t0, v2);
13823 tcg_gen_movi_tl(t1, v1);
13824 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13825 break;
13826 case OPC_DEXTR_RS_L:
13827 tcg_gen_movi_tl(t0, v2);
13828 tcg_gen_movi_tl(t1, v1);
13829 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13830 break;
13831 case OPC_DEXTR_W:
13832 tcg_gen_movi_tl(t0, v2);
13833 tcg_gen_movi_tl(t1, v1);
13834 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13835 break;
13836 case OPC_DEXTR_R_W:
13837 tcg_gen_movi_tl(t0, v2);
13838 tcg_gen_movi_tl(t1, v1);
13839 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13840 break;
13841 case OPC_DEXTR_RS_W:
13842 tcg_gen_movi_tl(t0, v2);
13843 tcg_gen_movi_tl(t1, v1);
13844 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13845 break;
13846 case OPC_DEXTR_S_H:
13847 tcg_gen_movi_tl(t0, v2);
13848 tcg_gen_movi_tl(t1, v1);
13849 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13850 break;
13851 case OPC_DEXTRV_S_H:
13852 tcg_gen_movi_tl(t0, v2);
13853 tcg_gen_movi_tl(t1, v1);
13854 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13855 break;
13856 case OPC_DEXTRV_L:
13857 tcg_gen_movi_tl(t0, v2);
13858 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13859 break;
13860 case OPC_DEXTRV_R_L:
13861 tcg_gen_movi_tl(t0, v2);
13862 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13863 break;
13864 case OPC_DEXTRV_RS_L:
13865 tcg_gen_movi_tl(t0, v2);
13866 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13867 break;
13868 case OPC_DEXTRV_W:
13869 tcg_gen_movi_tl(t0, v2);
13870 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13871 break;
13872 case OPC_DEXTRV_R_W:
13873 tcg_gen_movi_tl(t0, v2);
13874 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13875 break;
13876 case OPC_DEXTRV_RS_W:
13877 tcg_gen_movi_tl(t0, v2);
13878 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13879 break;
13880 }
13881 break;
13882#endif
13883 }
13884
13885 tcg_temp_free(t0);
13886 tcg_temp_free(t1);
13887 tcg_temp_free(v1_t);
13888 tcg_temp_free(v2_t);
b53371ed
JL
13889}
13890
9b1a1d68
JL
13891/* End MIPSDSP functions. */
13892
10dc65db
LA
13893static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13894{
4267d3e6 13895 int rs, rt, rd, sa;
b42ee5e1 13896 uint32_t op1, op2;
10dc65db
LA
13897
13898 rs = (ctx->opcode >> 21) & 0x1f;
13899 rt = (ctx->opcode >> 16) & 0x1f;
13900 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 13901 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
13902
13903 op1 = MASK_SPECIAL(ctx->opcode);
13904 switch (op1) {
c2e19f3c
AM
13905 case OPC_MULT:
13906 case OPC_MULTU:
13907 case OPC_DIV:
13908 case OPC_DIVU:
b42ee5e1
LA
13909 op2 = MASK_R6_MULDIV(ctx->opcode);
13910 switch (op2) {
13911 case R6_OPC_MUL:
13912 case R6_OPC_MUH:
13913 case R6_OPC_MULU:
13914 case R6_OPC_MUHU:
13915 case R6_OPC_DIV:
13916 case R6_OPC_MOD:
13917 case R6_OPC_DIVU:
13918 case R6_OPC_MODU:
13919 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13920 break;
13921 default:
13922 MIPS_INVAL("special_r6 muldiv");
3a4ef3b7 13923 gen_reserved_instruction(ctx);
b42ee5e1
LA
13924 break;
13925 }
13926 break;
10dc65db
LA
13927 case OPC_SELEQZ:
13928 case OPC_SELNEZ:
13929 gen_cond_move(ctx, op1, rd, rs, rt);
13930 break;
4267d3e6
LA
13931 case R6_OPC_CLO:
13932 case R6_OPC_CLZ:
13933 if (rt == 0 && sa == 1) {
7480515f
AM
13934 /*
13935 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13936 * We need additionally to check other fields.
13937 */
4267d3e6
LA
13938 gen_cl(ctx, op1, rd, rs);
13939 } else {
3a4ef3b7 13940 gen_reserved_instruction(ctx);
4267d3e6
LA
13941 }
13942 break;
13943 case R6_OPC_SDBBP:
3b3c1694
LA
13944 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13945 gen_helper_do_semihosting(cpu_env);
faf1f68b 13946 } else {
3b3c1694 13947 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3a4ef3b7 13948 gen_reserved_instruction(ctx);
3b3c1694 13949 } else {
9c708c7f 13950 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13951 }
faf1f68b 13952 }
4267d3e6 13953 break;
b42ee5e1 13954#if defined(TARGET_MIPS64)
4267d3e6
LA
13955 case R6_OPC_DCLO:
13956 case R6_OPC_DCLZ:
13957 if (rt == 0 && sa == 1) {
7480515f
AM
13958 /*
13959 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13960 * We need additionally to check other fields.
13961 */
4267d3e6
LA
13962 check_mips_64(ctx);
13963 gen_cl(ctx, op1, rd, rs);
13964 } else {
3a4ef3b7 13965 gen_reserved_instruction(ctx);
4267d3e6
LA
13966 }
13967 break;
c2e19f3c
AM
13968 case OPC_DMULT:
13969 case OPC_DMULTU:
13970 case OPC_DDIV:
13971 case OPC_DDIVU:
13972
b42ee5e1
LA
13973 op2 = MASK_R6_MULDIV(ctx->opcode);
13974 switch (op2) {
13975 case R6_OPC_DMUL:
13976 case R6_OPC_DMUH:
13977 case R6_OPC_DMULU:
13978 case R6_OPC_DMUHU:
13979 case R6_OPC_DDIV:
13980 case R6_OPC_DMOD:
13981 case R6_OPC_DDIVU:
13982 case R6_OPC_DMODU:
13983 check_mips_64(ctx);
13984 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13985 break;
13986 default:
13987 MIPS_INVAL("special_r6 muldiv");
3a4ef3b7 13988 gen_reserved_instruction(ctx);
b42ee5e1
LA
13989 break;
13990 }
13991 break;
13992#endif
10dc65db
LA
13993 default: /* Invalid */
13994 MIPS_INVAL("special_r6");
3a4ef3b7 13995 gen_reserved_instruction(ctx);
10dc65db
LA
13996 break;
13997 }
13998}
13999
9dc324ce
FN
14000static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
14001{
14002 int rs = extract32(ctx->opcode, 21, 5);
14003 int rt = extract32(ctx->opcode, 16, 5);
14004 int rd = extract32(ctx->opcode, 11, 5);
14005 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
14006
14007 switch (op1) {
14008 case OPC_MOVN: /* Conditional move */
14009 case OPC_MOVZ:
14010 gen_cond_move(ctx, op1, rd, rs, rt);
14011 break;
14012 case OPC_MFHI: /* Move from HI/LO */
14013 case OPC_MFLO:
14014 gen_HILO(ctx, op1, 0, rd);
14015 break;
14016 case OPC_MTHI:
14017 case OPC_MTLO: /* Move to HI/LO */
14018 gen_HILO(ctx, op1, 0, rs);
14019 break;
14020 case OPC_MULT:
14021 case OPC_MULTU:
14022 gen_mul_txx9(ctx, op1, rd, rs, rt);
14023 break;
14024 case OPC_DIV:
14025 case OPC_DIVU:
14026 gen_muldiv(ctx, op1, 0, rs, rt);
14027 break;
14028#if defined(TARGET_MIPS64)
14029 case OPC_DMULT:
14030 case OPC_DMULTU:
14031 case OPC_DDIV:
14032 case OPC_DDIVU:
14033 check_insn_opc_user_only(ctx, INSN_R5900);
14034 gen_muldiv(ctx, op1, 0, rs, rt);
14035 break;
14036#endif
14037 case OPC_JR:
14038 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14039 break;
14040 default: /* Invalid */
14041 MIPS_INVAL("special_tx79");
3a4ef3b7 14042 gen_reserved_instruction(ctx);
9dc324ce
FN
14043 break;
14044 }
14045}
14046
10dc65db
LA
14047static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14048{
bf772002 14049 int rs, rt, rd;
10dc65db
LA
14050 uint32_t op1;
14051
14052 rs = (ctx->opcode >> 21) & 0x1f;
14053 rt = (ctx->opcode >> 16) & 0x1f;
14054 rd = (ctx->opcode >> 11) & 0x1f;
14055
14056 op1 = MASK_SPECIAL(ctx->opcode);
14057 switch (op1) {
14058 case OPC_MOVN: /* Conditional move */
14059 case OPC_MOVZ:
bbd5e4a2 14060 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
9dc324ce 14061 INSN_LOONGSON2E | INSN_LOONGSON2F);
10dc65db
LA
14062 gen_cond_move(ctx, op1, rd, rs, rt);
14063 break;
14064 case OPC_MFHI: /* Move from HI/LO */
14065 case OPC_MFLO:
14066 gen_HILO(ctx, op1, rs & 3, rd);
14067 break;
14068 case OPC_MTHI:
14069 case OPC_MTLO: /* Move to HI/LO */
14070 gen_HILO(ctx, op1, rd & 3, rs);
14071 break;
14072 case OPC_MOVCI:
bbd5e4a2 14073 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
10dc65db
LA
14074 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14075 check_cp1_enabled(ctx);
14076 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14077 (ctx->opcode >> 16) & 1);
14078 } else {
14079 generate_exception_err(ctx, EXCP_CpU, 1);
14080 }
14081 break;
b42ee5e1
LA
14082 case OPC_MULT:
14083 case OPC_MULTU:
bf772002 14084 gen_muldiv(ctx, op1, rd & 3, rs, rt);
b42ee5e1
LA
14085 break;
14086 case OPC_DIV:
14087 case OPC_DIVU:
14088 gen_muldiv(ctx, op1, 0, rs, rt);
14089 break;
14090#if defined(TARGET_MIPS64)
c2e19f3c
AM
14091 case OPC_DMULT:
14092 case OPC_DMULTU:
14093 case OPC_DDIV:
14094 case OPC_DDIVU:
b42ee5e1
LA
14095 check_insn(ctx, ISA_MIPS3);
14096 check_mips_64(ctx);
14097 gen_muldiv(ctx, op1, 0, rs, rt);
14098 break;
14099#endif
0aefa333 14100 case OPC_JR:
c8b69a2a 14101 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
0aefa333 14102 break;
4267d3e6
LA
14103 case OPC_SPIM:
14104#ifdef MIPS_STRICT_STANDARD
14105 MIPS_INVAL("SPIM");
3a4ef3b7 14106 gen_reserved_instruction(ctx);
4267d3e6
LA
14107#else
14108 /* Implemented as RI exception for now. */
14109 MIPS_INVAL("spim (unofficial)");
3a4ef3b7 14110 gen_reserved_instruction(ctx);
4267d3e6
LA
14111#endif
14112 break;
10dc65db
LA
14113 default: /* Invalid */
14114 MIPS_INVAL("special_legacy");
3a4ef3b7 14115 gen_reserved_instruction(ctx);
10dc65db
LA
14116 break;
14117 }
14118}
14119
099e5b4d 14120static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 14121{
3c824109 14122 int rs, rt, rd, sa;
099e5b4d 14123 uint32_t op1;
3c824109 14124
3c824109
NF
14125 rs = (ctx->opcode >> 21) & 0x1f;
14126 rt = (ctx->opcode >> 16) & 0x1f;
14127 rd = (ctx->opcode >> 11) & 0x1f;
14128 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
14129
14130 op1 = MASK_SPECIAL(ctx->opcode);
14131 switch (op1) {
14132 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
14133 if (sa == 5 && rd == 0 &&
14134 rs == 0 && rt == 0) { /* PAUSE */
2e211e0a 14135 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 14136 (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 14137 gen_reserved_instruction(ctx);
339cd2a8
LA
14138 break;
14139 }
14140 }
14141 /* Fallthrough */
099e5b4d
LA
14142 case OPC_SRA:
14143 gen_shift_imm(ctx, op1, rd, rt, sa);
14144 break;
14145 case OPC_SRL:
14146 switch ((ctx->opcode >> 21) & 0x1f) {
14147 case 1:
14148 /* rotr is decoded as srl on non-R2 CPUs */
7a47bae5 14149 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14150 op1 = OPC_ROTR;
ea63e2c3 14151 }
099e5b4d
LA
14152 /* Fallthrough */
14153 case 0:
14154 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 14155 break;
099e5b4d 14156 default:
3a4ef3b7 14157 gen_reserved_instruction(ctx);
ea63e2c3 14158 break;
099e5b4d
LA
14159 }
14160 break;
c2e19f3c
AM
14161 case OPC_ADD:
14162 case OPC_ADDU:
14163 case OPC_SUB:
14164 case OPC_SUBU:
099e5b4d
LA
14165 gen_arith(ctx, op1, rd, rs, rt);
14166 break;
14167 case OPC_SLLV: /* Shifts */
14168 case OPC_SRAV:
14169 gen_shift(ctx, op1, rd, rs, rt);
14170 break;
14171 case OPC_SRLV:
14172 switch ((ctx->opcode >> 6) & 0x1f) {
14173 case 1:
14174 /* rotrv is decoded as srlv on non-R2 CPUs */
7a47bae5 14175 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14176 op1 = OPC_ROTRV;
26135ead 14177 }
099e5b4d
LA
14178 /* Fallthrough */
14179 case 0:
14180 gen_shift(ctx, op1, rd, rs, rt);
26135ead 14181 break;
099e5b4d 14182 default:
3a4ef3b7 14183 gen_reserved_instruction(ctx);
6af0bf9c 14184 break;
099e5b4d
LA
14185 }
14186 break;
14187 case OPC_SLT: /* Set on less than */
14188 case OPC_SLTU:
14189 gen_slt(ctx, op1, rd, rs, rt);
14190 break;
14191 case OPC_AND: /* Logic*/
14192 case OPC_OR:
14193 case OPC_NOR:
14194 case OPC_XOR:
14195 gen_logic(ctx, op1, rd, rs, rt);
14196 break;
0aefa333 14197 case OPC_JALR:
b231c103 14198 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 14199 break;
c2e19f3c
AM
14200 case OPC_TGE: /* Traps */
14201 case OPC_TGEU:
14202 case OPC_TLT:
14203 case OPC_TLTU:
14204 case OPC_TEQ:
099e5b4d 14205 case OPC_TNE:
d9224450 14206 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
14207 gen_trap(ctx, op1, rs, rt, -1);
14208 break;
0e9524af
PMD
14209 case OPC_PMON:
14210 /* Pmon entry point, also R4010 selsl */
b48cfdff 14211#ifdef MIPS_STRICT_STANDARD
0e9524af
PMD
14212 MIPS_INVAL("PMON / selsl");
14213 gen_reserved_instruction(ctx);
b48cfdff 14214#else
0e9524af 14215 gen_helper_0e0i(pmon, sa);
b48cfdff 14216#endif
099e5b4d
LA
14217 break;
14218 case OPC_SYSCALL:
9c708c7f 14219 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
14220 break;
14221 case OPC_BREAK:
9c708c7f 14222 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 14223 break;
099e5b4d 14224 case OPC_SYNC:
d9224450 14225 check_insn(ctx, ISA_MIPS2);
d208ac0c 14226 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 14227 break;
4ad40f36 14228
d26bc211 14229#if defined(TARGET_MIPS64)
099e5b4d
LA
14230 /* MIPS64 specific opcodes */
14231 case OPC_DSLL:
14232 case OPC_DSRA:
14233 case OPC_DSLL32:
14234 case OPC_DSRA32:
14235 check_insn(ctx, ISA_MIPS3);
14236 check_mips_64(ctx);
14237 gen_shift_imm(ctx, op1, rd, rt, sa);
14238 break;
14239 case OPC_DSRL:
14240 switch ((ctx->opcode >> 21) & 0x1f) {
14241 case 1:
14242 /* drotr is decoded as dsrl on non-R2 CPUs */
7a47bae5 14243 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14244 op1 = OPC_DROTR;
ea63e2c3 14245 }
099e5b4d
LA
14246 /* Fallthrough */
14247 case 0:
d75c135e 14248 check_insn(ctx, ISA_MIPS3);
e189e748 14249 check_mips_64(ctx);
099e5b4d 14250 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14251 break;
099e5b4d 14252 default:
3a4ef3b7 14253 gen_reserved_instruction(ctx);
460f00c4 14254 break;
099e5b4d
LA
14255 }
14256 break;
14257 case OPC_DSRL32:
14258 switch ((ctx->opcode >> 21) & 0x1f) {
14259 case 1:
14260 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
7a47bae5 14261 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14262 op1 = OPC_DROTR32;
ea63e2c3 14263 }
099e5b4d
LA
14264 /* Fallthrough */
14265 case 0:
d75c135e 14266 check_insn(ctx, ISA_MIPS3);
e189e748 14267 check_mips_64(ctx);
099e5b4d 14268 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14269 break;
099e5b4d 14270 default:
3a4ef3b7 14271 gen_reserved_instruction(ctx);
6af0bf9c
FB
14272 break;
14273 }
14274 break;
c2e19f3c
AM
14275 case OPC_DADD:
14276 case OPC_DADDU:
14277 case OPC_DSUB:
14278 case OPC_DSUBU:
099e5b4d
LA
14279 check_insn(ctx, ISA_MIPS3);
14280 check_mips_64(ctx);
14281 gen_arith(ctx, op1, rd, rs, rt);
14282 break;
14283 case OPC_DSLLV:
14284 case OPC_DSRAV:
14285 check_insn(ctx, ISA_MIPS3);
14286 check_mips_64(ctx);
14287 gen_shift(ctx, op1, rd, rs, rt);
14288 break;
14289 case OPC_DSRLV:
14290 switch ((ctx->opcode >> 6) & 0x1f) {
14291 case 1:
14292 /* drotrv is decoded as dsrlv on non-R2 CPUs */
7a47bae5 14293 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14294 op1 = OPC_DROTRV;
6af0bf9c 14295 }
099e5b4d
LA
14296 /* Fallthrough */
14297 case 0:
14298 check_insn(ctx, ISA_MIPS3);
e189e748 14299 check_mips_64(ctx);
099e5b4d 14300 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 14301 break;
099e5b4d 14302 default:
3a4ef3b7 14303 gen_reserved_instruction(ctx);
6af0bf9c
FB
14304 break;
14305 }
14306 break;
099e5b4d 14307#endif
10dc65db 14308 default:
2e211e0a 14309 if (ctx->insn_flags & ISA_MIPS_R6) {
10dc65db 14310 decode_opc_special_r6(env, ctx);
9dc324ce
FN
14311 } else if (ctx->insn_flags & INSN_R5900) {
14312 decode_opc_special_tx79(env, ctx);
10dc65db
LA
14313 } else {
14314 decode_opc_special_legacy(env, ctx);
14315 }
14316 }
14317}
14318
d67da337 14319
10dc65db 14320static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
14321{
14322 int rs, rt, rd;
14323 uint32_t op1;
6c5c1e20 14324
099e5b4d
LA
14325 rs = (ctx->opcode >> 21) & 0x1f;
14326 rt = (ctx->opcode >> 16) & 0x1f;
14327 rd = (ctx->opcode >> 11) & 0x1f;
14328
14329 op1 = MASK_SPECIAL2(ctx->opcode);
14330 switch (op1) {
c2e19f3c
AM
14331 case OPC_MADD: /* Multiply and add/sub */
14332 case OPC_MADDU:
14333 case OPC_MSUB:
14334 case OPC_MSUBU:
bbd5e4a2 14335 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
14336 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14337 break;
14338 case OPC_MUL:
099e5b4d
LA
14339 gen_arith(ctx, op1, rd, rs, rt);
14340 break;
fac5a073
LA
14341 case OPC_DIV_G_2F:
14342 case OPC_DIVU_G_2F:
14343 case OPC_MULT_G_2F:
14344 case OPC_MULTU_G_2F:
14345 case OPC_MOD_G_2F:
14346 case OPC_MODU_G_2F:
8e2d5831 14347 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
fac5a073
LA
14348 gen_loongson_integer(ctx, op1, rd, rs, rt);
14349 break;
099e5b4d
LA
14350 case OPC_CLO:
14351 case OPC_CLZ:
bbd5e4a2 14352 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
14353 gen_cl(ctx, op1, rd, rs);
14354 break;
14355 case OPC_SDBBP:
3b3c1694
LA
14356 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14357 gen_helper_do_semihosting(cpu_env);
14358 } else {
7480515f
AM
14359 /*
14360 * XXX: not clear which exception should be raised
3b3c1694
LA
14361 * when in debug mode...
14362 */
bbd5e4a2 14363 check_insn(ctx, ISA_MIPS_R1);
9c708c7f 14364 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14365 }
099e5b4d 14366 break;
9b1a1d68 14367#if defined(TARGET_MIPS64)
099e5b4d
LA
14368 case OPC_DCLO:
14369 case OPC_DCLZ:
bbd5e4a2 14370 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
14371 check_mips_64(ctx);
14372 gen_cl(ctx, op1, rd, rs);
14373 break;
4267d3e6
LA
14374 case OPC_DMULT_G_2F:
14375 case OPC_DMULTU_G_2F:
14376 case OPC_DDIV_G_2F:
14377 case OPC_DDIVU_G_2F:
14378 case OPC_DMOD_G_2F:
14379 case OPC_DMODU_G_2F:
8e2d5831 14380 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
4267d3e6
LA
14381 gen_loongson_integer(ctx, op1, rd, rs, rt);
14382 break;
10dc65db 14383#endif
4267d3e6
LA
14384 default: /* Invalid */
14385 MIPS_INVAL("special2_legacy");
3a4ef3b7 14386 gen_reserved_instruction(ctx);
4267d3e6 14387 break;
10dc65db
LA
14388 }
14389}
14390
14391static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14392{
15eacb9b
YK
14393 int rs, rt, rd, sa;
14394 uint32_t op1, op2;
10dc65db
LA
14395 int16_t imm;
14396
14397 rs = (ctx->opcode >> 21) & 0x1f;
14398 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
14399 rd = (ctx->opcode >> 11) & 0x1f;
14400 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
14401 imm = (int16_t)ctx->opcode >> 7;
14402
14403 op1 = MASK_SPECIAL3(ctx->opcode);
14404 switch (op1) {
bf7910c6
LA
14405 case R6_OPC_PREF:
14406 if (rt >= 24) {
14407 /* hint codes 24-31 are reserved and signal RI */
3a4ef3b7 14408 gen_reserved_instruction(ctx);
bf7910c6
LA
14409 }
14410 /* Treat as NOP. */
14411 break;
14412 case R6_OPC_CACHE:
40d48212 14413 check_cp0_enabled(ctx);
0d74a222
LA
14414 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14415 gen_cache_operation(ctx, rt, rs, imm);
14416 }
bf7910c6 14417 break;
10dc65db 14418 case R6_OPC_SC:
33a07fa2 14419 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
10dc65db
LA
14420 break;
14421 case R6_OPC_LL:
14422 gen_ld(ctx, op1, rt, rs, imm);
14423 break;
15eacb9b
YK
14424 case OPC_BSHFL:
14425 {
14426 if (rd == 0) {
14427 /* Treat as NOP. */
14428 break;
14429 }
15eacb9b
YK
14430 op2 = MASK_BSHFL(ctx->opcode);
14431 switch (op2) {
c2e19f3c 14432 case OPC_ALIGN:
373ecd38
AM
14433 case OPC_ALIGN_1:
14434 case OPC_ALIGN_2:
14435 case OPC_ALIGN_3:
821f2008 14436 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
14437 break;
14438 case OPC_BITSWAP:
1f1b4c00 14439 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
14440 break;
14441 }
15eacb9b
YK
14442 }
14443 break;
99029be1
YK
14444#ifndef CONFIG_USER_ONLY
14445 case OPC_GINV:
14446 if (unlikely(ctx->gi <= 1)) {
3a4ef3b7 14447 gen_reserved_instruction(ctx);
99029be1
YK
14448 }
14449 check_cp0_enabled(ctx);
14450 switch ((ctx->opcode >> 6) & 3) {
14451 case 0: /* GINVI */
14452 /* Treat as NOP. */
14453 break;
14454 case 2: /* GINVT */
14455 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14456 break;
14457 default:
3a4ef3b7 14458 gen_reserved_instruction(ctx);
99029be1
YK
14459 break;
14460 }
14461 break;
14462#endif
bf7910c6
LA
14463#if defined(TARGET_MIPS64)
14464 case R6_OPC_SCD:
33a07fa2 14465 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
bf7910c6
LA
14466 break;
14467 case R6_OPC_LLD:
14468 gen_ld(ctx, op1, rt, rs, imm);
14469 break;
15eacb9b
YK
14470 case OPC_DBSHFL:
14471 check_mips_64(ctx);
14472 {
14473 if (rd == 0) {
14474 /* Treat as NOP. */
14475 break;
14476 }
15eacb9b
YK
14477 op2 = MASK_DBSHFL(ctx->opcode);
14478 switch (op2) {
c2e19f3c 14479 case OPC_DALIGN:
373ecd38
AM
14480 case OPC_DALIGN_1:
14481 case OPC_DALIGN_2:
14482 case OPC_DALIGN_3:
14483 case OPC_DALIGN_4:
14484 case OPC_DALIGN_5:
14485 case OPC_DALIGN_6:
14486 case OPC_DALIGN_7:
821f2008 14487 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
14488 break;
14489 case OPC_DBITSWAP:
1f1b4c00 14490 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
14491 break;
14492 }
1f1b4c00 14493
15eacb9b
YK
14494 }
14495 break;
bf7910c6 14496#endif
10dc65db
LA
14497 default: /* Invalid */
14498 MIPS_INVAL("special3_r6");
3a4ef3b7 14499 gen_reserved_instruction(ctx);
10dc65db
LA
14500 break;
14501 }
14502}
14503
14504static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14505{
fac5a073 14506 int rs, rt, rd;
099e5b4d 14507 uint32_t op1, op2;
099e5b4d
LA
14508
14509 rs = (ctx->opcode >> 21) & 0x1f;
14510 rt = (ctx->opcode >> 16) & 0x1f;
14511 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
14512
14513 op1 = MASK_SPECIAL3(ctx->opcode);
14514 switch (op1) {
c2e19f3c
AM
14515 case OPC_DIV_G_2E:
14516 case OPC_DIVU_G_2E:
14517 case OPC_MOD_G_2E:
14518 case OPC_MODU_G_2E:
14519 case OPC_MULT_G_2E:
14520 case OPC_MULTU_G_2E:
7480515f
AM
14521 /*
14522 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14523 * the same mask and op1.
14524 */
908f6be1 14525 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 14526 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 14527 switch (op2) {
099e5b4d
LA
14528 case OPC_ADDUH_QB:
14529 case OPC_ADDUH_R_QB:
14530 case OPC_ADDQH_PH:
14531 case OPC_ADDQH_R_PH:
14532 case OPC_ADDQH_W:
14533 case OPC_ADDQH_R_W:
14534 case OPC_SUBUH_QB:
14535 case OPC_SUBUH_R_QB:
14536 case OPC_SUBQH_PH:
14537 case OPC_SUBQH_R_PH:
14538 case OPC_SUBQH_W:
14539 case OPC_SUBQH_R_W:
461c08df
JL
14540 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14541 break;
099e5b4d
LA
14542 case OPC_MUL_PH:
14543 case OPC_MUL_S_PH:
14544 case OPC_MULQ_S_W:
14545 case OPC_MULQ_RS_W:
14546 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 14547 break;
461c08df 14548 default:
099e5b4d 14549 MIPS_INVAL("MASK ADDUH.QB");
3a4ef3b7 14550 gen_reserved_instruction(ctx);
461c08df
JL
14551 break;
14552 }
099e5b4d
LA
14553 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14554 gen_loongson_integer(ctx, op1, rd, rs, rt);
14555 } else {
3a4ef3b7 14556 gen_reserved_instruction(ctx);
099e5b4d
LA
14557 }
14558 break;
14559 case OPC_LX_DSP:
14560 op2 = MASK_LX(ctx->opcode);
14561 switch (op2) {
14562#if defined(TARGET_MIPS64)
14563 case OPC_LDX:
14564#endif
14565 case OPC_LBUX:
14566 case OPC_LHX:
14567 case OPC_LWX:
14568 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14569 break;
14570 default: /* Invalid */
14571 MIPS_INVAL("MASK LX");
3a4ef3b7 14572 gen_reserved_instruction(ctx);
099e5b4d
LA
14573 break;
14574 }
14575 break;
14576 case OPC_ABSQ_S_PH_DSP:
14577 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14578 switch (op2) {
14579 case OPC_ABSQ_S_QB:
14580 case OPC_ABSQ_S_PH:
14581 case OPC_ABSQ_S_W:
14582 case OPC_PRECEQ_W_PHL:
14583 case OPC_PRECEQ_W_PHR:
14584 case OPC_PRECEQU_PH_QBL:
14585 case OPC_PRECEQU_PH_QBR:
14586 case OPC_PRECEQU_PH_QBLA:
14587 case OPC_PRECEQU_PH_QBRA:
14588 case OPC_PRECEU_PH_QBL:
14589 case OPC_PRECEU_PH_QBR:
14590 case OPC_PRECEU_PH_QBLA:
14591 case OPC_PRECEU_PH_QBRA:
14592 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14593 break;
14594 case OPC_BITREV:
14595 case OPC_REPL_QB:
14596 case OPC_REPLV_QB:
14597 case OPC_REPL_PH:
14598 case OPC_REPLV_PH:
14599 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14600 break;
14601 default:
14602 MIPS_INVAL("MASK ABSQ_S.PH");
3a4ef3b7 14603 gen_reserved_instruction(ctx);
099e5b4d
LA
14604 break;
14605 }
14606 break;
14607 case OPC_ADDU_QB_DSP:
14608 op2 = MASK_ADDU_QB(ctx->opcode);
14609 switch (op2) {
14610 case OPC_ADDQ_PH:
14611 case OPC_ADDQ_S_PH:
14612 case OPC_ADDQ_S_W:
14613 case OPC_ADDU_QB:
14614 case OPC_ADDU_S_QB:
14615 case OPC_ADDU_PH:
14616 case OPC_ADDU_S_PH:
14617 case OPC_SUBQ_PH:
14618 case OPC_SUBQ_S_PH:
14619 case OPC_SUBQ_S_W:
14620 case OPC_SUBU_QB:
14621 case OPC_SUBU_S_QB:
14622 case OPC_SUBU_PH:
14623 case OPC_SUBU_S_PH:
14624 case OPC_ADDSC:
14625 case OPC_ADDWC:
14626 case OPC_MODSUB:
14627 case OPC_RADDU_W_QB:
14628 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14629 break;
14630 case OPC_MULEU_S_PH_QBL:
14631 case OPC_MULEU_S_PH_QBR:
14632 case OPC_MULQ_RS_PH:
14633 case OPC_MULEQ_S_W_PHL:
14634 case OPC_MULEQ_S_W_PHR:
14635 case OPC_MULQ_S_PH:
14636 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14637 break;
14638 default: /* Invalid */
14639 MIPS_INVAL("MASK ADDU.QB");
3a4ef3b7 14640 gen_reserved_instruction(ctx);
461c08df 14641 break;
461c08df 14642
099e5b4d
LA
14643 }
14644 break;
14645 case OPC_CMPU_EQ_QB_DSP:
14646 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14647 switch (op2) {
14648 case OPC_PRECR_SRA_PH_W:
14649 case OPC_PRECR_SRA_R_PH_W:
14650 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 14651 break;
099e5b4d
LA
14652 case OPC_PRECR_QB_PH:
14653 case OPC_PRECRQ_QB_PH:
14654 case OPC_PRECRQ_PH_W:
14655 case OPC_PRECRQ_RS_PH_W:
14656 case OPC_PRECRQU_S_QB_PH:
14657 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 14658 break;
099e5b4d
LA
14659 case OPC_CMPU_EQ_QB:
14660 case OPC_CMPU_LT_QB:
14661 case OPC_CMPU_LE_QB:
14662 case OPC_CMP_EQ_PH:
14663 case OPC_CMP_LT_PH:
14664 case OPC_CMP_LE_PH:
14665 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 14666 break;
099e5b4d
LA
14667 case OPC_CMPGU_EQ_QB:
14668 case OPC_CMPGU_LT_QB:
14669 case OPC_CMPGU_LE_QB:
14670 case OPC_CMPGDU_EQ_QB:
14671 case OPC_CMPGDU_LT_QB:
14672 case OPC_CMPGDU_LE_QB:
14673 case OPC_PICK_QB:
14674 case OPC_PICK_PH:
14675 case OPC_PACKRL_PH:
14676 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14677 break;
14678 default: /* Invalid */
14679 MIPS_INVAL("MASK CMPU.EQ.QB");
3a4ef3b7 14680 gen_reserved_instruction(ctx);
099e5b4d
LA
14681 break;
14682 }
14683 break;
14684 case OPC_SHLL_QB_DSP:
14685 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14686 break;
14687 case OPC_DPA_W_PH_DSP:
14688 op2 = MASK_DPA_W_PH(ctx->opcode);
14689 switch (op2) {
14690 case OPC_DPAU_H_QBL:
14691 case OPC_DPAU_H_QBR:
14692 case OPC_DPSU_H_QBL:
14693 case OPC_DPSU_H_QBR:
14694 case OPC_DPA_W_PH:
14695 case OPC_DPAX_W_PH:
14696 case OPC_DPAQ_S_W_PH:
14697 case OPC_DPAQX_S_W_PH:
14698 case OPC_DPAQX_SA_W_PH:
14699 case OPC_DPS_W_PH:
14700 case OPC_DPSX_W_PH:
14701 case OPC_DPSQ_S_W_PH:
14702 case OPC_DPSQX_S_W_PH:
14703 case OPC_DPSQX_SA_W_PH:
14704 case OPC_MULSAQ_S_W_PH:
14705 case OPC_DPAQ_SA_L_W:
14706 case OPC_DPSQ_SA_L_W:
14707 case OPC_MAQ_S_W_PHL:
14708 case OPC_MAQ_S_W_PHR:
14709 case OPC_MAQ_SA_W_PHL:
14710 case OPC_MAQ_SA_W_PHR:
14711 case OPC_MULSA_W_PH:
14712 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14713 break;
14714 default: /* Invalid */
14715 MIPS_INVAL("MASK DPAW.PH");
3a4ef3b7 14716 gen_reserved_instruction(ctx);
099e5b4d
LA
14717 break;
14718 }
14719 break;
14720 case OPC_INSV_DSP:
14721 op2 = MASK_INSV(ctx->opcode);
14722 switch (op2) {
14723 case OPC_INSV:
14724 check_dsp(ctx);
14725 {
14726 TCGv t0, t1;
14727
14728 if (rt == 0) {
099e5b4d
LA
14729 break;
14730 }
14731
14732 t0 = tcg_temp_new();
14733 t1 = tcg_temp_new();
14734
14735 gen_load_gpr(t0, rt);
14736 gen_load_gpr(t1, rs);
14737
14738 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14739
14740 tcg_temp_free(t0);
14741 tcg_temp_free(t1);
a22260ae
JL
14742 break;
14743 }
099e5b4d
LA
14744 default: /* Invalid */
14745 MIPS_INVAL("MASK INSV");
3a4ef3b7 14746 gen_reserved_instruction(ctx);
099e5b4d
LA
14747 break;
14748 }
14749 break;
14750 case OPC_APPEND_DSP:
14751 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14752 break;
14753 case OPC_EXTR_W_DSP:
14754 op2 = MASK_EXTR_W(ctx->opcode);
14755 switch (op2) {
14756 case OPC_EXTR_W:
14757 case OPC_EXTR_R_W:
14758 case OPC_EXTR_RS_W:
14759 case OPC_EXTR_S_H:
14760 case OPC_EXTRV_S_H:
14761 case OPC_EXTRV_W:
14762 case OPC_EXTRV_R_W:
14763 case OPC_EXTRV_RS_W:
14764 case OPC_EXTP:
14765 case OPC_EXTPV:
14766 case OPC_EXTPDP:
14767 case OPC_EXTPDPV:
14768 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14769 break;
14770 case OPC_RDDSP:
14771 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14772 break;
14773 case OPC_SHILO:
14774 case OPC_SHILOV:
14775 case OPC_MTHLIP:
14776 case OPC_WRDSP:
14777 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14778 break;
14779 default: /* Invalid */
14780 MIPS_INVAL("MASK EXTR.W");
3a4ef3b7 14781 gen_reserved_instruction(ctx);
099e5b4d
LA
14782 break;
14783 }
14784 break;
099e5b4d 14785#if defined(TARGET_MIPS64)
c2e19f3c
AM
14786 case OPC_DDIV_G_2E:
14787 case OPC_DDIVU_G_2E:
14788 case OPC_DMULT_G_2E:
14789 case OPC_DMULTU_G_2E:
14790 case OPC_DMOD_G_2E:
14791 case OPC_DMODU_G_2E:
fac5a073
LA
14792 check_insn(ctx, INSN_LOONGSON2E);
14793 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 14794 break;
099e5b4d
LA
14795 case OPC_ABSQ_S_QH_DSP:
14796 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14797 switch (op2) {
14798 case OPC_PRECEQ_L_PWL:
14799 case OPC_PRECEQ_L_PWR:
14800 case OPC_PRECEQ_PW_QHL:
14801 case OPC_PRECEQ_PW_QHR:
14802 case OPC_PRECEQ_PW_QHLA:
14803 case OPC_PRECEQ_PW_QHRA:
14804 case OPC_PRECEQU_QH_OBL:
14805 case OPC_PRECEQU_QH_OBR:
14806 case OPC_PRECEQU_QH_OBLA:
14807 case OPC_PRECEQU_QH_OBRA:
14808 case OPC_PRECEU_QH_OBL:
14809 case OPC_PRECEU_QH_OBR:
14810 case OPC_PRECEU_QH_OBLA:
14811 case OPC_PRECEU_QH_OBRA:
14812 case OPC_ABSQ_S_OB:
14813 case OPC_ABSQ_S_PW:
14814 case OPC_ABSQ_S_QH:
14815 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14816 break;
14817 case OPC_REPL_OB:
14818 case OPC_REPL_PW:
14819 case OPC_REPL_QH:
14820 case OPC_REPLV_OB:
14821 case OPC_REPLV_PW:
14822 case OPC_REPLV_QH:
14823 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14824 break;
14825 default: /* Invalid */
14826 MIPS_INVAL("MASK ABSQ_S.QH");
3a4ef3b7 14827 gen_reserved_instruction(ctx);
099e5b4d
LA
14828 break;
14829 }
14830 break;
14831 case OPC_ADDU_OB_DSP:
14832 op2 = MASK_ADDU_OB(ctx->opcode);
14833 switch (op2) {
14834 case OPC_RADDU_L_OB:
14835 case OPC_SUBQ_PW:
14836 case OPC_SUBQ_S_PW:
14837 case OPC_SUBQ_QH:
14838 case OPC_SUBQ_S_QH:
14839 case OPC_SUBU_OB:
14840 case OPC_SUBU_S_OB:
14841 case OPC_SUBU_QH:
14842 case OPC_SUBU_S_QH:
14843 case OPC_SUBUH_OB:
14844 case OPC_SUBUH_R_OB:
14845 case OPC_ADDQ_PW:
14846 case OPC_ADDQ_S_PW:
14847 case OPC_ADDQ_QH:
14848 case OPC_ADDQ_S_QH:
14849 case OPC_ADDU_OB:
14850 case OPC_ADDU_S_OB:
14851 case OPC_ADDU_QH:
14852 case OPC_ADDU_S_QH:
14853 case OPC_ADDUH_OB:
14854 case OPC_ADDUH_R_OB:
14855 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 14856 break;
099e5b4d
LA
14857 case OPC_MULEQ_S_PW_QHL:
14858 case OPC_MULEQ_S_PW_QHR:
14859 case OPC_MULEU_S_QH_OBL:
14860 case OPC_MULEU_S_QH_OBR:
14861 case OPC_MULQ_RS_QH:
14862 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 14863 break;
099e5b4d
LA
14864 default: /* Invalid */
14865 MIPS_INVAL("MASK ADDU.OB");
3a4ef3b7 14866 gen_reserved_instruction(ctx);
26690560 14867 break;
099e5b4d
LA
14868 }
14869 break;
14870 case OPC_CMPU_EQ_OB_DSP:
14871 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14872 switch (op2) {
14873 case OPC_PRECR_SRA_QH_PW:
14874 case OPC_PRECR_SRA_R_QH_PW:
14875 /* Return value is rt. */
14876 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 14877 break;
099e5b4d
LA
14878 case OPC_PRECR_OB_QH:
14879 case OPC_PRECRQ_OB_QH:
14880 case OPC_PRECRQ_PW_L:
14881 case OPC_PRECRQ_QH_PW:
14882 case OPC_PRECRQ_RS_QH_PW:
14883 case OPC_PRECRQU_S_OB_QH:
14884 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 14885 break;
099e5b4d
LA
14886 case OPC_CMPU_EQ_OB:
14887 case OPC_CMPU_LT_OB:
14888 case OPC_CMPU_LE_OB:
14889 case OPC_CMP_EQ_QH:
14890 case OPC_CMP_LT_QH:
14891 case OPC_CMP_LE_QH:
14892 case OPC_CMP_EQ_PW:
14893 case OPC_CMP_LT_PW:
14894 case OPC_CMP_LE_PW:
14895 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 14896 break;
099e5b4d
LA
14897 case OPC_CMPGDU_EQ_OB:
14898 case OPC_CMPGDU_LT_OB:
14899 case OPC_CMPGDU_LE_OB:
14900 case OPC_CMPGU_EQ_OB:
14901 case OPC_CMPGU_LT_OB:
14902 case OPC_CMPGU_LE_OB:
14903 case OPC_PACKRL_PW:
14904 case OPC_PICK_OB:
14905 case OPC_PICK_PW:
14906 case OPC_PICK_QH:
14907 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 14908 break;
099e5b4d
LA
14909 default: /* Invalid */
14910 MIPS_INVAL("MASK CMPU_EQ.OB");
3a4ef3b7 14911 gen_reserved_instruction(ctx);
161f85e6 14912 break;
099e5b4d
LA
14913 }
14914 break;
14915 case OPC_DAPPEND_DSP:
14916 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14917 break;
14918 case OPC_DEXTR_W_DSP:
14919 op2 = MASK_DEXTR_W(ctx->opcode);
14920 switch (op2) {
14921 case OPC_DEXTP:
14922 case OPC_DEXTPDP:
14923 case OPC_DEXTPDPV:
14924 case OPC_DEXTPV:
14925 case OPC_DEXTR_L:
14926 case OPC_DEXTR_R_L:
14927 case OPC_DEXTR_RS_L:
14928 case OPC_DEXTR_W:
14929 case OPC_DEXTR_R_W:
14930 case OPC_DEXTR_RS_W:
14931 case OPC_DEXTR_S_H:
14932 case OPC_DEXTRV_L:
14933 case OPC_DEXTRV_R_L:
14934 case OPC_DEXTRV_RS_L:
14935 case OPC_DEXTRV_S_H:
14936 case OPC_DEXTRV_W:
14937 case OPC_DEXTRV_R_W:
14938 case OPC_DEXTRV_RS_W:
14939 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 14940 break;
099e5b4d
LA
14941 case OPC_DMTHLIP:
14942 case OPC_DSHILO:
14943 case OPC_DSHILOV:
14944 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 14945 break;
099e5b4d
LA
14946 default: /* Invalid */
14947 MIPS_INVAL("MASK EXTR.W");
3a4ef3b7 14948 gen_reserved_instruction(ctx);
461c08df 14949 break;
099e5b4d
LA
14950 }
14951 break;
14952 case OPC_DPAQ_W_QH_DSP:
14953 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14954 switch (op2) {
14955 case OPC_DPAU_H_OBL:
14956 case OPC_DPAU_H_OBR:
14957 case OPC_DPSU_H_OBL:
14958 case OPC_DPSU_H_OBR:
14959 case OPC_DPA_W_QH:
14960 case OPC_DPAQ_S_W_QH:
14961 case OPC_DPS_W_QH:
14962 case OPC_DPSQ_S_W_QH:
14963 case OPC_MULSAQ_S_W_QH:
14964 case OPC_DPAQ_SA_L_PW:
14965 case OPC_DPSQ_SA_L_PW:
14966 case OPC_MULSAQ_S_L_PW:
14967 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14968 break;
14969 case OPC_MAQ_S_W_QHLL:
14970 case OPC_MAQ_S_W_QHLR:
14971 case OPC_MAQ_S_W_QHRL:
14972 case OPC_MAQ_S_W_QHRR:
14973 case OPC_MAQ_SA_W_QHLL:
14974 case OPC_MAQ_SA_W_QHLR:
14975 case OPC_MAQ_SA_W_QHRL:
14976 case OPC_MAQ_SA_W_QHRR:
14977 case OPC_MAQ_S_L_PWL:
14978 case OPC_MAQ_S_L_PWR:
14979 case OPC_DMADD:
14980 case OPC_DMADDU:
14981 case OPC_DMSUB:
14982 case OPC_DMSUBU:
14983 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 14984 break;
099e5b4d
LA
14985 default: /* Invalid */
14986 MIPS_INVAL("MASK DPAQ.W.QH");
3a4ef3b7 14987 gen_reserved_instruction(ctx);
b53371ed 14988 break;
099e5b4d
LA
14989 }
14990 break;
14991 case OPC_DINSV_DSP:
14992 op2 = MASK_INSV(ctx->opcode);
14993 switch (op2) {
14994 case OPC_DINSV:
14995 {
14996 TCGv t0, t1;
14997
a071578b
PMD
14998 check_dsp(ctx);
14999
099e5b4d 15000 if (rt == 0) {
a22260ae
JL
15001 break;
15002 }
1cb6686c 15003
099e5b4d
LA
15004 t0 = tcg_temp_new();
15005 t1 = tcg_temp_new();
1cb6686c 15006
099e5b4d
LA
15007 gen_load_gpr(t0, rt);
15008 gen_load_gpr(t1, rs);
1cb6686c 15009
099e5b4d 15010 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 15011
099e5b4d
LA
15012 tcg_temp_free(t0);
15013 tcg_temp_free(t1);
77c5fa8b 15014 break;
099e5b4d 15015 }
7a387fff 15016 default: /* Invalid */
099e5b4d 15017 MIPS_INVAL("MASK DINSV");
3a4ef3b7 15018 gen_reserved_instruction(ctx);
7a387fff
TS
15019 break;
15020 }
15021 break;
099e5b4d
LA
15022 case OPC_SHLL_OB_DSP:
15023 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15024 break;
15025#endif
fac5a073
LA
15026 default: /* Invalid */
15027 MIPS_INVAL("special3_legacy");
3a4ef3b7 15028 gen_reserved_instruction(ctx);
fac5a073
LA
15029 break;
15030 }
15031}
15032
37b9aae2
MM
15033
15034#if defined(TARGET_MIPS64)
15035
874b2879 15036static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
71b8a6b3 15037{
c8341e00 15038 uint32_t opc = MASK_MMI(ctx->opcode);
06de726b
FN
15039 int rs = extract32(ctx->opcode, 21, 5);
15040 int rt = extract32(ctx->opcode, 16, 5);
15041 int rd = extract32(ctx->opcode, 11, 5);
71b8a6b3
FN
15042
15043 switch (opc) {
baa609db
AM
15044 case MMI_OPC_MULT1:
15045 case MMI_OPC_MULTU1:
3b948f05
PMD
15046 case MMI_OPC_MADD:
15047 case MMI_OPC_MADDU:
a95c4c26
FN
15048 case MMI_OPC_MADD1:
15049 case MMI_OPC_MADDU1:
06de726b
FN
15050 gen_mul_txx9(ctx, opc, rd, rs, rt);
15051 break;
baa609db
AM
15052 case MMI_OPC_DIV1:
15053 case MMI_OPC_DIVU1:
c42171c3 15054 gen_div1_tx79(ctx, opc, rs, rt);
be9c42c9 15055 break;
71b8a6b3
FN
15056 default:
15057 MIPS_INVAL("TX79 MMI class");
3a4ef3b7 15058 gen_reserved_instruction(ctx);
71b8a6b3
FN
15059 break;
15060 }
15061}
15062
874b2879 15063static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
bb41e74b 15064{
3a4ef3b7 15065 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */
bb41e74b
FN
15066}
15067
15068/*
15069 * The TX79-specific instruction Store Quadword
15070 *
15071 * +--------+-------+-------+------------------------+
15072 * | 011111 | base | rt | offset | SQ
15073 * +--------+-------+-------+------------------------+
15074 * 6 5 5 16
15075 *
15076 * has the same opcode as the Read Hardware Register instruction
15077 *
15078 * +--------+-------+-------+-------+-------+--------+
15079 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
15080 * +--------+-------+-------+-------+-------+--------+
15081 * 6 5 5 5 5 6
15082 *
15083 * that is required, trapped and emulated by the Linux kernel. However, all
15084 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
15085 * offset is odd. Therefore all valid SQ instructions can execute normally.
15086 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
15087 * between SQ and RDHWR, as the Linux kernel does.
15088 */
874b2879 15089static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
bb41e74b
FN
15090{
15091 int base = extract32(ctx->opcode, 21, 5);
15092 int rt = extract32(ctx->opcode, 16, 5);
15093 int offset = extract32(ctx->opcode, 0, 16);
15094
15095#ifdef CONFIG_USER_ONLY
15096 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15097 uint32_t op2 = extract32(ctx->opcode, 6, 5);
15098
15099 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15100 int rd = extract32(ctx->opcode, 11, 5);
15101
15102 gen_rdhwr(ctx, rt, rd, 0);
15103 return;
15104 }
15105#endif
15106
874b2879 15107 gen_mmi_sq(ctx, base, rt, offset);
bb41e74b
FN
15108}
15109
37b9aae2
MM
15110#endif
15111
fac5a073
LA
15112static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15113{
15114 int rs, rt, rd, sa;
15115 uint32_t op1, op2;
76964147 15116 int16_t imm;
fac5a073
LA
15117
15118 rs = (ctx->opcode >> 21) & 0x1f;
15119 rt = (ctx->opcode >> 16) & 0x1f;
15120 rd = (ctx->opcode >> 11) & 0x1f;
15121 sa = (ctx->opcode >> 6) & 0x1f;
76964147 15122 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
15123
15124 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
15125
15126 /*
15127 * EVA loads and stores overlap Loongson 2E instructions decoded by
15128 * decode_opc_special3_legacy(), so be careful to allow their decoding when
15129 * EVA is absent.
15130 */
15131 if (ctx->eva) {
15132 switch (op1) {
c2e19f3c
AM
15133 case OPC_LWLE:
15134 case OPC_LWRE:
c2e19f3c
AM
15135 case OPC_LBUE:
15136 case OPC_LHUE:
15137 case OPC_LBE:
15138 case OPC_LHE:
15139 case OPC_LLE:
15140 case OPC_LWE:
76964147
JH
15141 check_cp0_enabled(ctx);
15142 gen_ld(ctx, op1, rt, rs, imm);
15143 return;
c2e19f3c
AM
15144 case OPC_SWLE:
15145 case OPC_SWRE:
c2e19f3c
AM
15146 case OPC_SBE:
15147 case OPC_SHE:
76964147
JH
15148 case OPC_SWE:
15149 check_cp0_enabled(ctx);
15150 gen_st(ctx, op1, rt, rs, imm);
15151 return;
15152 case OPC_SCE:
15153 check_cp0_enabled(ctx);
33a07fa2 15154 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
76964147
JH
15155 return;
15156 case OPC_CACHEE:
84c2fdc3 15157 check_eva(ctx);
76964147
JH
15158 check_cp0_enabled(ctx);
15159 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15160 gen_cache_operation(ctx, rt, rs, imm);
15161 }
76964147
JH
15162 return;
15163 case OPC_PREFE:
15164 check_cp0_enabled(ctx);
15165 /* Treat as NOP. */
15166 return;
15167 }
15168 }
15169
fac5a073
LA
15170 switch (op1) {
15171 case OPC_EXT:
15172 case OPC_INS:
7a47bae5 15173 check_insn(ctx, ISA_MIPS_R2);
fac5a073
LA
15174 gen_bitops(ctx, op1, rt, rs, sa, rd);
15175 break;
15176 case OPC_BSHFL:
fac5a073 15177 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 15178 switch (op2) {
c2e19f3c 15179 case OPC_ALIGN:
373ecd38
AM
15180 case OPC_ALIGN_1:
15181 case OPC_ALIGN_2:
15182 case OPC_ALIGN_3:
15eacb9b 15183 case OPC_BITSWAP:
2e211e0a 15184 check_insn(ctx, ISA_MIPS_R6);
15eacb9b
YK
15185 decode_opc_special3_r6(env, ctx);
15186 break;
15187 default:
7a47bae5 15188 check_insn(ctx, ISA_MIPS_R2);
15eacb9b
YK
15189 gen_bshfl(ctx, op2, rt, rd);
15190 break;
15191 }
fac5a073
LA
15192 break;
15193#if defined(TARGET_MIPS64)
c2e19f3c
AM
15194 case OPC_DEXTM:
15195 case OPC_DEXTU:
15196 case OPC_DEXT:
15197 case OPC_DINSM:
15198 case OPC_DINSU:
15199 case OPC_DINS:
7a47bae5 15200 check_insn(ctx, ISA_MIPS_R2);
fac5a073
LA
15201 check_mips_64(ctx);
15202 gen_bitops(ctx, op1, rt, rs, sa, rd);
15203 break;
15204 case OPC_DBSHFL:
fac5a073 15205 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 15206 switch (op2) {
c2e19f3c 15207 case OPC_DALIGN:
373ecd38
AM
15208 case OPC_DALIGN_1:
15209 case OPC_DALIGN_2:
15210 case OPC_DALIGN_3:
15211 case OPC_DALIGN_4:
15212 case OPC_DALIGN_5:
15213 case OPC_DALIGN_6:
15214 case OPC_DALIGN_7:
15eacb9b 15215 case OPC_DBITSWAP:
2e211e0a 15216 check_insn(ctx, ISA_MIPS_R6);
15eacb9b
YK
15217 decode_opc_special3_r6(env, ctx);
15218 break;
15219 default:
7a47bae5 15220 check_insn(ctx, ISA_MIPS_R2);
15eacb9b
YK
15221 check_mips_64(ctx);
15222 op2 = MASK_DBSHFL(ctx->opcode);
15223 gen_bshfl(ctx, op2, rt, rd);
15224 break;
15225 }
fac5a073
LA
15226 break;
15227#endif
15228 case OPC_RDHWR:
b00c7218 15229 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
15230 break;
15231 case OPC_FORK:
9affc1c5 15232 check_mt(ctx);
fac5a073
LA
15233 {
15234 TCGv t0 = tcg_temp_new();
15235 TCGv t1 = tcg_temp_new();
15236
15237 gen_load_gpr(t0, rt);
15238 gen_load_gpr(t1, rs);
15239 gen_helper_fork(t0, t1);
15240 tcg_temp_free(t0);
15241 tcg_temp_free(t1);
15242 }
15243 break;
15244 case OPC_YIELD:
9affc1c5 15245 check_mt(ctx);
fac5a073
LA
15246 {
15247 TCGv t0 = tcg_temp_new();
15248
fac5a073
LA
15249 gen_load_gpr(t0, rs);
15250 gen_helper_yield(t0, cpu_env, t0);
15251 gen_store_gpr(t0, rd);
15252 tcg_temp_free(t0);
15253 }
15254 break;
10dc65db 15255 default:
2e211e0a 15256 if (ctx->insn_flags & ISA_MIPS_R6) {
10dc65db
LA
15257 decode_opc_special3_r6(env, ctx);
15258 } else {
15259 decode_opc_special3_legacy(env, ctx);
15260 }
099e5b4d
LA
15261 }
15262}
15263
80e64a38 15264static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
4c789546 15265{
80e64a38
PMD
15266 int32_t offset;
15267 int rs, rt, rd, sa;
15268 uint32_t op, op1;
15269 int16_t imm;
4c789546 15270
80e64a38
PMD
15271 op = MASK_OP_MAJOR(ctx->opcode);
15272 rs = (ctx->opcode >> 21) & 0x1f;
15273 rt = (ctx->opcode >> 16) & 0x1f;
15274 rd = (ctx->opcode >> 11) & 0x1f;
15275 sa = (ctx->opcode >> 6) & 0x1f;
15276 imm = (int16_t)ctx->opcode;
15277 switch (op) {
15278 case OPC_SPECIAL:
15279 decode_opc_special(env, ctx);
4c789546 15280 break;
80e64a38
PMD
15281 case OPC_SPECIAL2:
15282#if defined(TARGET_MIPS64)
15283 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15284 decode_mmi(env, ctx);
4f57f43c
PMD
15285 break;
15286 }
15287#endif
c7abe00a 15288 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
22345286
PMD
15289 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15290 gen_arith(ctx, OPC_MUL, rd, rs, rt);
15291 } else {
e31b43ec 15292 decode_ase_mxu(ctx, ctx->opcode);
22345286 15293 }
4f57f43c 15294 break;
4c789546 15295 }
4f57f43c 15296 decode_opc_special2_legacy(env, ctx);
4c789546 15297 break;
80e64a38
PMD
15298 case OPC_SPECIAL3:
15299#if defined(TARGET_MIPS64)
15300 if (ctx->insn_flags & INSN_R5900) {
15301 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
15302 } else {
15303 decode_opc_special3(env, ctx);
80e71591 15304 }
80e64a38
PMD
15305#else
15306 decode_opc_special3(env, ctx);
15307#endif
80e71591 15308 break;
80e64a38
PMD
15309 case OPC_REGIMM:
15310 op1 = MASK_REGIMM(ctx->opcode);
15311 switch (op1) {
15312 case OPC_BLTZL: /* REGIMM branches */
15313 case OPC_BGEZL:
15314 case OPC_BLTZALL:
15315 case OPC_BGEZALL:
15316 check_insn(ctx, ISA_MIPS2);
15317 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15318 /* Fallthrough */
15319 case OPC_BLTZ:
15320 case OPC_BGEZ:
15321 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
2e3eddb0 15322 break;
80e64a38
PMD
15323 case OPC_BLTZAL:
15324 case OPC_BGEZAL:
15325 if (ctx->insn_flags & ISA_MIPS_R6) {
15326 if (rs == 0) {
15327 /* OPC_NAL, OPC_BAL */
15328 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15329 } else {
15330 gen_reserved_instruction(ctx);
15331 }
15332 } else {
15333 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15334 }
2e3eddb0 15335 break;
80e64a38
PMD
15336 case OPC_TGEI: /* REGIMM traps */
15337 case OPC_TGEIU:
15338 case OPC_TLTI:
15339 case OPC_TLTIU:
15340 case OPC_TEQI:
15341
15342 case OPC_TNEI:
15343 check_insn(ctx, ISA_MIPS2);
15344 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15345 gen_trap(ctx, op1, rs, -1, imm);
2e3eddb0 15346 break;
80e64a38
PMD
15347 case OPC_SIGRIE:
15348 check_insn(ctx, ISA_MIPS_R6);
15349 gen_reserved_instruction(ctx);
2e3eddb0 15350 break;
80e64a38
PMD
15351 case OPC_SYNCI:
15352 check_insn(ctx, ISA_MIPS_R2);
15353 /*
15354 * Break the TB to be able to sync copied instructions
15355 * immediately.
15356 */
15357 ctx->base.is_jmp = DISAS_STOP;
2e3eddb0 15358 break;
80e64a38
PMD
15359 case OPC_BPOSGE32: /* MIPS DSP branch */
15360#if defined(TARGET_MIPS64)
15361 case OPC_BPOSGE64:
15362#endif
15363 check_dsp(ctx);
15364 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
a44d6d14 15365 break;
80e64a38
PMD
15366#if defined(TARGET_MIPS64)
15367 case OPC_DAHI:
15368 check_insn(ctx, ISA_MIPS_R6);
15369 check_mips_64(ctx);
15370 if (rs != 0) {
15371 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15372 }
a44d6d14 15373 break;
80e64a38
PMD
15374 case OPC_DATI:
15375 check_insn(ctx, ISA_MIPS_R6);
15376 check_mips_64(ctx);
15377 if (rs != 0) {
15378 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15379 }
a44d6d14 15380 break;
80e64a38
PMD
15381#endif
15382 default: /* Invalid */
15383 MIPS_INVAL("regimm");
15384 gen_reserved_instruction(ctx);
a44d6d14
AM
15385 break;
15386 }
15387 break;
80e64a38
PMD
15388 case OPC_CP0:
15389 check_cp0_enabled(ctx);
15390 op1 = MASK_CP0(ctx->opcode);
15391 switch (op1) {
15392 case OPC_MFC0:
15393 case OPC_MTC0:
15394 case OPC_MFTR:
15395 case OPC_MTTR:
15396 case OPC_MFHC0:
15397 case OPC_MTHC0:
15398#if defined(TARGET_MIPS64)
15399 case OPC_DMFC0:
15400 case OPC_DMTC0:
15401#endif
15402#ifndef CONFIG_USER_ONLY
15403 gen_cp0(env, ctx, op1, rt, rd);
15404#endif /* !CONFIG_USER_ONLY */
7a387fff 15405 break;
c38a1d52
AR
15406 case OPC_C0:
15407 case OPC_C0_1:
15408 case OPC_C0_2:
15409 case OPC_C0_3:
15410 case OPC_C0_4:
15411 case OPC_C0_5:
15412 case OPC_C0_6:
15413 case OPC_C0_7:
15414 case OPC_C0_8:
15415 case OPC_C0_9:
15416 case OPC_C0_A:
15417 case OPC_C0_B:
15418 case OPC_C0_C:
15419 case OPC_C0_D:
15420 case OPC_C0_E:
15421 case OPC_C0_F:
f1aa6320 15422#ifndef CONFIG_USER_ONLY
932e71cd 15423 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15424#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15425 break;
15426 case OPC_MFMC0:
8706c382 15427#ifndef CONFIG_USER_ONLY
932e71cd 15428 {
099e5b4d 15429 uint32_t op2;
35fbce2c 15430 TCGv t0 = tcg_temp_new();
6c5c1e20 15431
0eaef5aa 15432 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15433 switch (op2) {
15434 case OPC_DMT:
9affc1c5 15435 check_cp0_mt(ctx);
9ed5726c 15436 gen_helper_dmt(t0);
35fbce2c 15437 gen_store_gpr(t0, rt);
6c5c1e20
TS
15438 break;
15439 case OPC_EMT:
9affc1c5 15440 check_cp0_mt(ctx);
9ed5726c 15441 gen_helper_emt(t0);
35fbce2c 15442 gen_store_gpr(t0, rt);
da80682b 15443 break;
6c5c1e20 15444 case OPC_DVPE:
9affc1c5 15445 check_cp0_mt(ctx);
895c2d04 15446 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15447 gen_store_gpr(t0, rt);
6c5c1e20
TS
15448 break;
15449 case OPC_EVPE:
9affc1c5 15450 check_cp0_mt(ctx);
895c2d04 15451 gen_helper_evpe(t0, cpu_env);
35fbce2c 15452 gen_store_gpr(t0, rt);
6c5c1e20 15453 break;
01bc435b 15454 case OPC_DVP:
2e211e0a 15455 check_insn(ctx, ISA_MIPS_R6);
01bc435b
YK
15456 if (ctx->vp) {
15457 gen_helper_dvp(t0, cpu_env);
15458 gen_store_gpr(t0, rt);
15459 }
15460 break;
15461 case OPC_EVP:
2e211e0a 15462 check_insn(ctx, ISA_MIPS_R6);
01bc435b
YK
15463 if (ctx->vp) {
15464 gen_helper_evp(t0, cpu_env);
15465 gen_store_gpr(t0, rt);
15466 }
15467 break;
6c5c1e20 15468 case OPC_DI:
7a47bae5 15469 check_insn(ctx, ISA_MIPS_R2);
867abc7e 15470 save_cpu_state(ctx, 1);
895c2d04 15471 gen_helper_di(t0, cpu_env);
35fbce2c 15472 gen_store_gpr(t0, rt);
7480515f
AM
15473 /*
15474 * Stop translation as we may have switched
15475 * the execution mode.
15476 */
eeb3bba8 15477 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
15478 break;
15479 case OPC_EI:
7a47bae5 15480 check_insn(ctx, ISA_MIPS_R2);
867abc7e 15481 save_cpu_state(ctx, 1);
895c2d04 15482 gen_helper_ei(t0, cpu_env);
35fbce2c 15483 gen_store_gpr(t0, rt);
7480515f
AM
15484 /*
15485 * DISAS_STOP isn't sufficient, we need to ensure we break
15486 * out of translated code to check for pending interrupts.
15487 */
eeb3bba8
EC
15488 gen_save_pc(ctx->base.pc_next + 4);
15489 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
15490 break;
15491 default: /* Invalid */
15492 MIPS_INVAL("mfmc0");
3a4ef3b7 15493 gen_reserved_instruction(ctx);
6c5c1e20
TS
15494 break;
15495 }
6c5c1e20 15496 tcg_temp_free(t0);
7a387fff 15497 }
0eaef5aa 15498#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15499 break;
7a387fff 15500 case OPC_RDPGPR:
7a47bae5 15501 check_insn(ctx, ISA_MIPS_R2);
be24bb4f 15502 gen_load_srsgpr(rt, rd);
ead9360e 15503 break;
7a387fff 15504 case OPC_WRPGPR:
7a47bae5 15505 check_insn(ctx, ISA_MIPS_R2);
be24bb4f 15506 gen_store_srsgpr(rt, rd);
38121543 15507 break;
6af0bf9c 15508 default:
923617a3 15509 MIPS_INVAL("cp0");
3a4ef3b7 15510 gen_reserved_instruction(ctx);
6af0bf9c
FB
15511 break;
15512 }
15513 break;
31837be3 15514 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
2e211e0a 15515 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15516 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
15517 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15518 } else {
15519 /* OPC_ADDI */
15520 /* Arithmetic with immediate opcode */
15521 gen_arith_imm(ctx, op, rt, rs, imm);
15522 }
15523 break;
324d9e32 15524 case OPC_ADDIU:
d75c135e 15525 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15526 break;
324d9e32
AJ
15527 case OPC_SLTI: /* Set on less than with immediate opcode */
15528 case OPC_SLTIU:
d75c135e 15529 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15530 break;
15531 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 15532 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
15533 case OPC_ORI:
15534 case OPC_XORI:
d75c135e 15535 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15536 break;
c2e19f3c
AM
15537 case OPC_J: /* Jump */
15538 case OPC_JAL:
7a387fff 15539 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 15540 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 15541 break;
31837be3
YK
15542 /* Branch */
15543 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
2e211e0a 15544 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3 15545 if (rt == 0) {
3a4ef3b7 15546 gen_reserved_instruction(ctx);
31837be3
YK
15547 break;
15548 }
15549 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
15550 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15551 } else {
15552 /* OPC_BLEZL */
b231c103 15553 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
15554 }
15555 break;
15556 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
2e211e0a 15557 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3 15558 if (rt == 0) {
3a4ef3b7 15559 gen_reserved_instruction(ctx);
31837be3
YK
15560 break;
15561 }
15562 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
15563 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15564 } else {
15565 /* OPC_BGTZL */
b231c103 15566 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
15567 }
15568 break;
15569 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
15570 if (rt == 0) {
15571 /* OPC_BLEZ */
b231c103 15572 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3 15573 } else {
2e211e0a 15574 check_insn(ctx, ISA_MIPS_R6);
31837be3
YK
15575 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
15576 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15577 }
15578 break;
15579 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
15580 if (rt == 0) {
15581 /* OPC_BGTZ */
b231c103 15582 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3 15583 } else {
2e211e0a 15584 check_insn(ctx, ISA_MIPS_R6);
31837be3
YK
15585 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
15586 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15587 }
15588 break;
15589 case OPC_BEQL:
15590 case OPC_BNEL:
d9224450 15591 check_insn(ctx, ISA_MIPS2);
2e211e0a 15592 check_insn_opc_removed(ctx, ISA_MIPS_R6);
d9224450 15593 /* Fallthrough */
31837be3
YK
15594 case OPC_BEQ:
15595 case OPC_BNE:
b231c103 15596 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 15597 break;
d9224450
MR
15598 case OPC_LL: /* Load and stores */
15599 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
15600 if (ctx->insn_flags & INSN_R5900) {
15601 check_insn_opc_user_only(ctx, INSN_R5900);
15602 }
d9224450
MR
15603 /* Fallthrough */
15604 case OPC_LWL:
fecd2646 15605 case OPC_LWR:
c2e19f3c
AM
15606 case OPC_LB:
15607 case OPC_LH:
15608 case OPC_LW:
15609 case OPC_LWPC:
15610 case OPC_LBU:
15611 case OPC_LHU:
d75c135e 15612 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15613 break;
fecd2646 15614 case OPC_SWL:
7a387fff 15615 case OPC_SWR:
c2e19f3c
AM
15616 case OPC_SB:
15617 case OPC_SH:
fecd2646 15618 case OPC_SW:
5c13fdfd 15619 gen_st(ctx, op, rt, rs, imm);
7a387fff 15620 break;
d66c7132 15621 case OPC_SC:
d9224450 15622 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
15623 if (ctx->insn_flags & INSN_R5900) {
15624 check_insn_opc_user_only(ctx, INSN_R5900);
15625 }
33a07fa2
LA
15626 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15627 break;
7a387fff 15628 case OPC_CACHE:
2e15497c 15629 check_cp0_enabled(ctx);
bbd5e4a2 15630 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
0d74a222
LA
15631 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15632 gen_cache_operation(ctx, rt, rs, imm);
15633 }
ead9360e 15634 /* Treat as NOP. */
34ae7b51 15635 break;
7a387fff 15636 case OPC_PREF:
2e176eaf
PMD
15637 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15638 /* Treat as NOP. */
6af0bf9c 15639 break;
4ad40f36 15640
923617a3 15641 /* Floating point (COP1). */
7a387fff
TS
15642 case OPC_LWC1:
15643 case OPC_LDC1:
15644 case OPC_SWC1:
15645 case OPC_SDC1:
5ab5c041 15646 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
15647 break;
15648
7a387fff 15649 case OPC_CP1:
5692c6e1
YK
15650 op1 = MASK_CP1(ctx->opcode);
15651
15652 switch (op1) {
15653 case OPC_MFHC1:
15654 case OPC_MTHC1:
5e755519 15655 check_cp1_enabled(ctx);
7a47bae5 15656 check_insn(ctx, ISA_MIPS_R2);
146dd620 15657 /* fall through */
5692c6e1
YK
15658 case OPC_MFC1:
15659 case OPC_CFC1:
15660 case OPC_MTC1:
15661 case OPC_CTC1:
15662 check_cp1_enabled(ctx);
15663 gen_cp1(ctx, op1, rt, rd);
15664 break;
d26bc211 15665#if defined(TARGET_MIPS64)
5692c6e1
YK
15666 case OPC_DMFC1:
15667 case OPC_DMTC1:
15668 check_cp1_enabled(ctx);
15669 check_insn(ctx, ISA_MIPS3);
d9224450 15670 check_mips_64(ctx);
5692c6e1
YK
15671 gen_cp1(ctx, op1, rt, rd);
15672 break;
e189e748 15673#endif
5692c6e1
YK
15674 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15675 check_cp1_enabled(ctx);
2e211e0a 15676 if (ctx->insn_flags & ISA_MIPS_R6) {
5692c6e1 15677 /* OPC_BC1EQZ */
31837be3 15678 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 15679 rt, imm << 2, 4);
5692c6e1
YK
15680 } else {
15681 /* OPC_BC1ANY2 */
b8aa4598 15682 check_cop1x(ctx);
d75c135e 15683 check_insn(ctx, ASE_MIPS3D);
d75c135e 15684 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15685 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
15686 }
15687 break;
15688 case OPC_BC1NEZ:
15689 check_cp1_enabled(ctx);
2e211e0a 15690 check_insn(ctx, ISA_MIPS_R6);
5692c6e1 15691 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 15692 rt, imm << 2, 4);
5692c6e1
YK
15693 break;
15694 case OPC_BC1ANY4:
15695 check_cp1_enabled(ctx);
2e211e0a 15696 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5692c6e1
YK
15697 check_cop1x(ctx);
15698 check_insn(ctx, ASE_MIPS3D);
15699 /* fall through */
15700 case OPC_BC1:
15701 check_cp1_enabled(ctx);
2e211e0a 15702 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5692c6e1
YK
15703 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15704 (rt >> 2) & 0x7, imm << 2);
15705 break;
15706 case OPC_PS_FMT:
e29c9628 15707 check_ps(ctx);
b6f3b233 15708 /* fall through */
5692c6e1
YK
15709 case OPC_S_FMT:
15710 case OPC_D_FMT:
15711 check_cp1_enabled(ctx);
15712 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15713 (imm >> 8) & 0x7);
15714 break;
15715 case OPC_W_FMT:
15716 case OPC_L_FMT:
15717 {
15718 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15719 check_cp1_enabled(ctx);
2e211e0a 15720 if (ctx->insn_flags & ISA_MIPS_R6) {
5692c6e1
YK
15721 switch (r6_op) {
15722 case R6_OPC_CMP_AF_S:
15723 case R6_OPC_CMP_UN_S:
15724 case R6_OPC_CMP_EQ_S:
15725 case R6_OPC_CMP_UEQ_S:
15726 case R6_OPC_CMP_LT_S:
15727 case R6_OPC_CMP_ULT_S:
15728 case R6_OPC_CMP_LE_S:
15729 case R6_OPC_CMP_ULE_S:
15730 case R6_OPC_CMP_SAF_S:
15731 case R6_OPC_CMP_SUN_S:
15732 case R6_OPC_CMP_SEQ_S:
15733 case R6_OPC_CMP_SEUQ_S:
15734 case R6_OPC_CMP_SLT_S:
15735 case R6_OPC_CMP_SULT_S:
15736 case R6_OPC_CMP_SLE_S:
15737 case R6_OPC_CMP_SULE_S:
15738 case R6_OPC_CMP_OR_S:
15739 case R6_OPC_CMP_UNE_S:
15740 case R6_OPC_CMP_NE_S:
15741 case R6_OPC_CMP_SOR_S:
15742 case R6_OPC_CMP_SUNE_S:
15743 case R6_OPC_CMP_SNE_S:
15744 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15745 break;
15746 case R6_OPC_CMP_AF_D:
15747 case R6_OPC_CMP_UN_D:
15748 case R6_OPC_CMP_EQ_D:
15749 case R6_OPC_CMP_UEQ_D:
15750 case R6_OPC_CMP_LT_D:
15751 case R6_OPC_CMP_ULT_D:
15752 case R6_OPC_CMP_LE_D:
15753 case R6_OPC_CMP_ULE_D:
15754 case R6_OPC_CMP_SAF_D:
15755 case R6_OPC_CMP_SUN_D:
15756 case R6_OPC_CMP_SEQ_D:
15757 case R6_OPC_CMP_SEUQ_D:
15758 case R6_OPC_CMP_SLT_D:
15759 case R6_OPC_CMP_SULT_D:
15760 case R6_OPC_CMP_SLE_D:
15761 case R6_OPC_CMP_SULE_D:
15762 case R6_OPC_CMP_OR_D:
15763 case R6_OPC_CMP_UNE_D:
15764 case R6_OPC_CMP_NE_D:
15765 case R6_OPC_CMP_SOR_D:
15766 case R6_OPC_CMP_SUNE_D:
15767 case R6_OPC_CMP_SNE_D:
15768 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15769 break;
15770 default:
d2bfa6e6
MR
15771 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15772 rt, rd, sa, (imm >> 8) & 0x7);
15773
5692c6e1 15774 break;
3f493883 15775 }
5692c6e1
YK
15776 } else {
15777 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15778 (imm >> 8) & 0x7);
36d23958 15779 }
5692c6e1
YK
15780 break;
15781 }
5692c6e1
YK
15782 default:
15783 MIPS_INVAL("cp1");
3a4ef3b7 15784 gen_reserved_instruction(ctx);
5692c6e1 15785 break;
6ea83fed 15786 }
4ad40f36
FB
15787 break;
15788
31837be3
YK
15789 /* Compact branches [R6] and COP2 [non-R6] */
15790 case OPC_BC: /* OPC_LWC2 */
15791 case OPC_BALC: /* OPC_SWC2 */
2e211e0a 15792 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15793 /* OPC_BC, OPC_BALC */
15794 gen_compute_compact_branch(ctx, op, 0, 0,
15795 sextract32(ctx->opcode << 2, 0, 28));
e10a0ca1
JY
15796 } else if (ctx->insn_flags & ASE_LEXT) {
15797 gen_loongson_lswc2(ctx, rt, rs, rd);
31837be3
YK
15798 } else {
15799 /* OPC_LWC2, OPC_SWC2 */
15800 /* COP2: Not implemented. */
15801 generate_exception_err(ctx, EXCP_CpU, 2);
15802 }
15803 break;
15804 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15805 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
2e211e0a 15806 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15807 if (rs != 0) {
15808 /* OPC_BEQZC, OPC_BNEZC */
15809 gen_compute_compact_branch(ctx, op, rs, 0,
15810 sextract32(ctx->opcode << 2, 0, 23));
15811 } else {
15812 /* OPC_JIC, OPC_JIALC */
15813 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15814 }
90e22a57
JY
15815 } else if (ctx->insn_flags & ASE_LEXT) {
15816 gen_loongson_lsdc2(ctx, rt, rs, rd);
31837be3
YK
15817 } else {
15818 /* OPC_LWC2, OPC_SWC2 */
15819 /* COP2: Not implemented. */
15820 generate_exception_err(ctx, EXCP_CpU, 2);
15821 }
4ad40f36 15822 break;
bd277fa1 15823 case OPC_CP2:
8e2d5831 15824 check_insn(ctx, ASE_LMMI);
bd277fa1
RH
15825 /* Note that these instructions use different fields. */
15826 gen_loongson_multimedia(ctx, sa, rd, rt);
15827 break;
4ad40f36 15828
7a387fff 15829 case OPC_CP3:
5ab5c041 15830 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15831 check_cp1_enabled(ctx);
36d23958
TS
15832 op1 = MASK_CP3(ctx->opcode);
15833 switch (op1) {
d9224450
MR
15834 case OPC_LUXC1:
15835 case OPC_SUXC1:
7a47bae5 15836 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
d9224450 15837 /* Fallthrough */
5a5012ec
TS
15838 case OPC_LWXC1:
15839 case OPC_LDXC1:
5a5012ec
TS
15840 case OPC_SWXC1:
15841 case OPC_SDXC1:
7a47bae5 15842 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
93b12ccc 15843 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15844 break;
e0c84da7 15845 case OPC_PREFX:
7a47bae5 15846 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
ead9360e 15847 /* Treat as NOP. */
e0c84da7 15848 break;
5a5012ec 15849 case OPC_ALNV_PS:
7a47bae5 15850 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
d9224450 15851 /* Fallthrough */
5a5012ec
TS
15852 case OPC_MADD_S:
15853 case OPC_MADD_D:
15854 case OPC_MADD_PS:
15855 case OPC_MSUB_S:
15856 case OPC_MSUB_D:
15857 case OPC_MSUB_PS:
15858 case OPC_NMADD_S:
15859 case OPC_NMADD_D:
15860 case OPC_NMADD_PS:
15861 case OPC_NMSUB_S:
15862 case OPC_NMSUB_D:
15863 case OPC_NMSUB_PS:
7a47bae5 15864 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
5a5012ec
TS
15865 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15866 break;
36d23958 15867 default:
923617a3 15868 MIPS_INVAL("cp3");
3a4ef3b7 15869 gen_reserved_instruction(ctx);
36d23958
TS
15870 break;
15871 }
15872 } else {
e397ee33 15873 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15874 }
4ad40f36
FB
15875 break;
15876
d26bc211 15877#if defined(TARGET_MIPS64)
7a387fff 15878 /* MIPS64 opcodes */
96631327 15879 case OPC_LLD:
55fc7a69
FN
15880 if (ctx->insn_flags & INSN_R5900) {
15881 check_insn_opc_user_only(ctx, INSN_R5900);
15882 }
96631327 15883 /* fall through */
c2e19f3c
AM
15884 case OPC_LDL:
15885 case OPC_LDR:
fecd2646 15886 case OPC_LWU:
7a387fff 15887 case OPC_LD:
d75c135e 15888 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15889 check_mips_64(ctx);
d75c135e 15890 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15891 break;
c2e19f3c
AM
15892 case OPC_SDL:
15893 case OPC_SDR:
7a387fff 15894 case OPC_SD:
d75c135e 15895 check_insn(ctx, ISA_MIPS3);
e189e748 15896 check_mips_64(ctx);
5c13fdfd 15897 gen_st(ctx, op, rt, rs, imm);
7a387fff 15898 break;
d66c7132 15899 case OPC_SCD:
d75c135e 15900 check_insn(ctx, ISA_MIPS3);
55fc7a69
FN
15901 if (ctx->insn_flags & INSN_R5900) {
15902 check_insn_opc_user_only(ctx, INSN_R5900);
15903 }
d66c7132 15904 check_mips_64(ctx);
33a07fa2 15905 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
d66c7132 15906 break;
31837be3 15907 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
2e211e0a 15908 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15909 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15910 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15911 } else {
15912 /* OPC_DADDI */
15913 check_insn(ctx, ISA_MIPS3);
15914 check_mips_64(ctx);
15915 gen_arith_imm(ctx, op, rt, rs, imm);
15916 }
15917 break;
324d9e32 15918 case OPC_DADDIU:
d75c135e 15919 check_insn(ctx, ISA_MIPS3);
e189e748 15920 check_mips_64(ctx);
d75c135e 15921 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15922 break;
31837be3
YK
15923#else
15924 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
2e211e0a 15925 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15926 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15927 } else {
15928 MIPS_INVAL("major opcode");
3a4ef3b7 15929 gen_reserved_instruction(ctx);
31837be3
YK
15930 }
15931 break;
6af0bf9c 15932#endif
d4ea6acd 15933 case OPC_DAUI: /* OPC_JALX */
2e211e0a 15934 if (ctx->insn_flags & ISA_MIPS_R6) {
d4ea6acd
LA
15935#if defined(TARGET_MIPS64)
15936 /* OPC_DAUI */
15937 check_mips_64(ctx);
db77d852
LA
15938 if (rs == 0) {
15939 generate_exception(ctx, EXCP_RI);
15940 } else if (rt != 0) {
d4ea6acd
LA
15941 TCGv t0 = tcg_temp_new();
15942 gen_load_gpr(t0, rs);
15943 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15944 tcg_temp_free(t0);
15945 }
d4ea6acd 15946#else
3a4ef3b7 15947 gen_reserved_instruction(ctx);
d4ea6acd
LA
15948 MIPS_INVAL("major opcode");
15949#endif
15950 } else {
15951 /* OPC_JALX */
15952 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15953 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 15954 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 15955 }
364d4831 15956 break;
aaaa82a9
PMD
15957 case OPC_MDMX:
15958 /* MDMX: Not implemented. */
d4ea6acd
LA
15959 break;
15960 case OPC_PCREL:
2e211e0a 15961 check_insn(ctx, ISA_MIPS_R6);
eeb3bba8 15962 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 15963 break;
6af0bf9c 15964 default: /* Invalid */
923617a3 15965 MIPS_INVAL("major opcode");
311edee7 15966 return false;
6af0bf9c 15967 }
311edee7
PMD
15968 return true;
15969}
15970
15971static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15972{
15973 /* make sure instructions are on a word boundary */
15974 if (ctx->base.pc_next & 0x3) {
15975 env->CP0_BadVAddr = ctx->base.pc_next;
15976 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15977 return;
15978 }
15979
15980 /* Handle blikely not taken case */
15981 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15982 TCGLabel *l1 = gen_new_label();
15983
15984 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15985 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15986 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15987 gen_set_label(l1);
15988 }
15989
96e5b4c7
PMD
15990 /* Transition to the auto-generated decoder. */
15991
4919f69c
PMD
15992 /* Vendor specific extensions */
15993 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15994 return;
15995 }
9d005392
PMD
15996 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15997 return;
15998 }
4919f69c 15999
96e5b4c7
PMD
16000 /* ISA extensions */
16001 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
16002 return;
16003 }
16004
3f7a9278
PMD
16005 /* ISA (from latest to oldest) */
16006 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
16007 return;
16008 }
16009
311edee7
PMD
16010 if (decode_opc_legacy(env, ctx)) {
16011 return;
16012 }
16013
16014 gen_reserved_instruction(ctx);
6af0bf9c
FB
16015}
16016
18f440ed 16017static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 16018{
18f440ed 16019 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 16020 CPUMIPSState *env = cs->env_ptr;
12be9258 16021
18f440ed 16022 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
16023 ctx->saved_pc = -1;
16024 ctx->insn_flags = env->insn_flags;
16025 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 16026 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
16027 ctx->CP0_Config3 = env->CP0_Config3;
16028 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
16029 ctx->btarget = 0;
16030 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
16031 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
16032 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
16033 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
16034 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
16035 ctx->PAMask = env->PAMask;
16036 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
16037 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
16038 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
16039 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
16040 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 16041 /* Restore delay slot state from the tb context. */
12be9258
EC
16042 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
16043 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16044 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 16045 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
16046 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16047 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16048 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16049 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
feafe82c 16050 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
99029be1 16051 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
12be9258 16052 restore_cpu_state(env, ctx);
932e71cd 16053#ifdef CONFIG_USER_ONLY
12be9258 16054 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 16055#else
12be9258 16056 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 16057#endif
2e211e0a 16058 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
8a805609 16059 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
190ce7fb 16060
18f440ed
EC
16061 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16062 ctx->hflags);
16063}
12be9258 16064
18f440ed
EC
16065static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16066{
16067}
b933066a 16068
18f440ed
EC
16069static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16070{
16071 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 16072
18f440ed
EC
16073 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16074 ctx->btarget);
16075}
31837be3 16076
18f440ed
EC
16077static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16078{
16079 CPUMIPSState *env = cs->env_ptr;
16080 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16081 int insn_bytes;
16082 int is_slot;
4ad40f36 16083
18f440ed 16084 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4 16085 if (ctx->insn_flags & ISA_NANOMIPS32) {
0ab8e33a 16086 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
3f178b8d 16087 insn_bytes = decode_isa_nanomips(env, ctx);
c533c0f4 16088 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
0ab8e33a 16089 ctx->opcode = translator_ldl(env, ctx->base.pc_next);
18f440ed
EC
16090 insn_bytes = 4;
16091 decode_opc(env, ctx);
16092 } else if (ctx->insn_flags & ASE_MICROMIPS) {
0ab8e33a 16093 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
bf52c45a 16094 insn_bytes = decode_isa_micromips(env, ctx);
18f440ed 16095 } else if (ctx->insn_flags & ASE_MIPS16) {
0ab8e33a 16096 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
3230bad9 16097 insn_bytes = decode_ase_mips16e(env, ctx);
18f440ed 16098 } else {
3a4ef3b7 16099 gen_reserved_instruction(ctx);
18f440ed
EC
16100 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16101 return;
16102 }
faf7aaa9 16103
18f440ed
EC
16104 if (ctx->hflags & MIPS_HFLAG_BMASK) {
16105 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16106 MIPS_HFLAG_FBNSLOT))) {
7480515f
AM
16107 /*
16108 * Force to generate branch as there is neither delay nor
16109 * forbidden slot.
16110 */
18f440ed
EC
16111 is_slot = 1;
16112 }
16113 if ((ctx->hflags & MIPS_HFLAG_M16) &&
16114 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
7480515f
AM
16115 /*
16116 * Force to generate branch as microMIPS R6 doesn't restrict
16117 * branches in the forbidden slot.
16118 */
18f440ed 16119 is_slot = 1;
eeb3bba8 16120 }
18f440ed
EC
16121 }
16122 if (is_slot) {
16123 gen_branch(ctx, insn_bytes);
16124 }
16125 ctx->base.pc_next += insn_bytes;
1b530a6d 16126
18f440ed
EC
16127 if (ctx->base.is_jmp != DISAS_NEXT) {
16128 return;
6af0bf9c 16129 }
7480515f
AM
16130 /*
16131 * Execute a branch and its delay slot as a single instruction.
16132 * This is what GDB expects and is consistent with what the
16133 * hardware does (e.g. if a delay slot instruction faults, the
16134 * reported PC is the PC of the branch).
16135 */
18f440ed
EC
16136 if (ctx->base.singlestep_enabled &&
16137 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
16138 ctx->base.is_jmp = DISAS_TOO_MANY;
16139 }
16140 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
16141 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 16142 }
18f440ed
EC
16143}
16144
16145static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16146{
16147 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16148
12be9258
EC
16149 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
16150 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 16151 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 16152 } else {
12be9258 16153 switch (ctx->base.is_jmp) {
b28425ba 16154 case DISAS_STOP:
12be9258 16155 gen_save_pc(ctx->base.pc_next);
cd314a7d 16156 tcg_gen_lookup_and_goto_ptr();
df1561e2 16157 break;
b28425ba 16158 case DISAS_NEXT:
18f440ed 16159 case DISAS_TOO_MANY:
12be9258
EC
16160 save_cpu_state(ctx, 0);
16161 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 16162 break;
b28425ba 16163 case DISAS_EXIT:
07ea28b4 16164 tcg_gen_exit_tb(NULL, 0);
16c00cb2 16165 break;
b28425ba 16166 case DISAS_NORETURN:
5a5012ec 16167 break;
18f440ed
EC
16168 default:
16169 g_assert_not_reached();
6958549d 16170 }
6af0bf9c 16171 }
18f440ed
EC
16172}
16173
16174static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16175{
16176 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16177 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16178}
16179
16180static const TranslatorOps mips_tr_ops = {
16181 .init_disas_context = mips_tr_init_disas_context,
16182 .tb_start = mips_tr_tb_start,
16183 .insn_start = mips_tr_insn_start,
18f440ed
EC
16184 .translate_insn = mips_tr_translate_insn,
16185 .tb_stop = mips_tr_tb_stop,
16186 .disas_log = mips_tr_disas_log,
16187};
16188
8b86d6d2 16189void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
18f440ed
EC
16190{
16191 DisasContext ctx;
16192
8b86d6d2 16193 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
6af0bf9c
FB
16194}
16195
959c5da2
PMD
16196void mips_tcg_init(void)
16197{
16198 int i;
16199
16200 cpu_gpr[0] = NULL;
16201 for (i = 1; i < 32; i++)
16202 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16203 offsetof(CPUMIPSState,
16204 active_tc.gpr[i]),
16205 regnames[i]);
cefd68f6
PMD
16206#if defined(TARGET_MIPS64)
16207 cpu_gpr_hi[0] = NULL;
16208
16209 for (unsigned i = 1; i < 32; i++) {
b5b63d43
PMD
16210 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16211
cefd68f6
PMD
16212 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16213 offsetof(CPUMIPSState,
16214 active_tc.gpr_hi[i]),
b5b63d43 16215 rname);
cefd68f6
PMD
16216 }
16217#endif /* !TARGET_MIPS64 */
959c5da2
PMD
16218 for (i = 0; i < 32; i++) {
16219 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
863f264d 16220
959c5da2
PMD
16221 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16222 }
16223 msa_translate_init();
e1ccc054 16224 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 16225 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 16226 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 16227 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 16228 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 16229 regnames_HI[i]);
e1ccc054 16230 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 16231 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 16232 regnames_LO[i]);
4b2eb8d2 16233 }
e1ccc054 16234 cpu_dspctrl = tcg_global_mem_new(cpu_env,
71375b59
AM
16235 offsetof(CPUMIPSState,
16236 active_tc.DSPControl),
4b2eb8d2 16237 "DSPControl");
e1ccc054 16238 bcond = tcg_global_mem_new(cpu_env,
7db13fae 16239 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 16240 btarget = tcg_global_mem_new(cpu_env,
7db13fae 16241 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 16242 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 16243 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 16244
e1ccc054 16245 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 16246 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 16247 "fcr0");
e1ccc054 16248 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 16249 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 16250 "fcr31");
33a07fa2
LA
16251 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16252 "lladdr");
16253 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16254 "llval");
a168a796 16255
fe35ea94
PMD
16256 if (TARGET_LONG_BITS == 32) {
16257 mxu_translate_init();
eb5559f6 16258 }
39454628
TS
16259}
16260
bad729e2
RH
16261void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16262 target_ulong *data)
d2856f1a 16263{
bad729e2 16264 env->active_tc.PC = data[0];
d2856f1a 16265 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 16266 env->hflags |= data[1];
4636401d
AJ
16267 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16268 case MIPS_HFLAG_BR:
16269 break;
16270 case MIPS_HFLAG_BC:
16271 case MIPS_HFLAG_BL:
16272 case MIPS_HFLAG_B:
bad729e2 16273 env->btarget = data[2];
4636401d
AJ
16274 break;
16275 }
d2856f1a 16276}