]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/tcg/translate.c
gitlab-ci: Make more custom runner jobs manual, and don't allow failure
[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
b28425ba
EC
1216#define DISAS_STOP DISAS_TARGET_0
1217#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 1218
06106772 1219static const char regnames_HI[][4] = {
d73ee8a2
RH
1220 "HI0", "HI1", "HI2", "HI3",
1221};
4b2eb8d2 1222
06106772 1223static const char regnames_LO[][4] = {
d73ee8a2
RH
1224 "LO0", "LO1", "LO2", "LO3",
1225};
4b2eb8d2 1226
8e9ade68 1227/* General purpose registers moves. */
46c9e2b3 1228void gen_load_gpr(TCGv t, int reg)
aaa9128a 1229{
1f8929d2 1230 if (reg == 0) {
8e9ade68 1231 tcg_gen_movi_tl(t, 0);
1f8929d2 1232 } else {
4b2eb8d2 1233 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1f8929d2 1234 }
aaa9128a
TS
1235}
1236
46c9e2b3 1237void gen_store_gpr(TCGv t, int reg)
aaa9128a 1238{
1f8929d2 1239 if (reg != 0) {
4b2eb8d2 1240 tcg_gen_mov_tl(cpu_gpr[reg], t);
1f8929d2 1241 }
aaa9128a
TS
1242}
1243
61f4e0ec
PMD
1244#if defined(TARGET_MIPS64)
1245void gen_load_gpr_hi(TCGv_i64 t, int reg)
1246{
1247 if (reg == 0) {
1248 tcg_gen_movi_i64(t, 0);
1249 } else {
1250 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1251 }
1252}
1253
1254void gen_store_gpr_hi(TCGv_i64 t, int reg)
1255{
1256 if (reg != 0) {
1257 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1258 }
1259}
1260#endif /* TARGET_MIPS64 */
1261
8e9ade68 1262/* Moves to/from shadow registers. */
235785e8 1263static inline void gen_load_srsgpr(int from, int to)
aaa9128a 1264{
d9bea114 1265 TCGv t0 = tcg_temp_new();
be24bb4f 1266
1f8929d2 1267 if (from == 0) {
d9bea114 1268 tcg_gen_movi_tl(t0, 0);
1f8929d2 1269 } else {
d9bea114 1270 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1271 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1272
7db13fae 1273 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1274 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1275 tcg_gen_andi_i32(t2, t2, 0xf);
1276 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1277 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1278 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1279
d9bea114 1280 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1281 tcg_temp_free_ptr(addr);
d9bea114 1282 tcg_temp_free_i32(t2);
8e9ade68 1283 }
d9bea114
AJ
1284 gen_store_gpr(t0, to);
1285 tcg_temp_free(t0);
aaa9128a
TS
1286}
1287
71375b59 1288static inline void gen_store_srsgpr(int from, int to)
aaa9128a 1289{
be24bb4f 1290 if (to != 0) {
d9bea114
AJ
1291 TCGv t0 = tcg_temp_new();
1292 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1293 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1294
d9bea114 1295 gen_load_gpr(t0, from);
7db13fae 1296 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1297 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1298 tcg_gen_andi_i32(t2, t2, 0xf);
1299 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1300 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1301 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1302
d9bea114 1303 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1304 tcg_temp_free_ptr(addr);
d9bea114
AJ
1305 tcg_temp_free_i32(t2);
1306 tcg_temp_free(t0);
8e9ade68 1307 }
aaa9128a
TS
1308}
1309
eab9944c
LA
1310/* Tests */
1311static inline void gen_save_pc(target_ulong pc)
1312{
1313 tcg_gen_movi_tl(cpu_PC, pc);
1314}
1315
1316static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1317{
1318 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
1319 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1320 gen_save_pc(ctx->base.pc_next);
1321 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
1322 }
1323 if (ctx->hflags != ctx->saved_hflags) {
1324 tcg_gen_movi_i32(hflags, ctx->hflags);
1325 ctx->saved_hflags = ctx->hflags;
1326 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1327 case MIPS_HFLAG_BR:
1328 break;
1329 case MIPS_HFLAG_BC:
1330 case MIPS_HFLAG_BL:
1331 case MIPS_HFLAG_B:
1332 tcg_gen_movi_tl(btarget, ctx->btarget);
1333 break;
1334 }
1335 }
1336}
1337
1338static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1339{
1340 ctx->saved_hflags = ctx->hflags;
1341 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1342 case MIPS_HFLAG_BR:
1343 break;
1344 case MIPS_HFLAG_BC:
1345 case MIPS_HFLAG_BL:
1346 case MIPS_HFLAG_B:
1347 ctx->btarget = env->btarget;
1348 break;
1349 }
1350}
1351
46c9e2b3 1352void generate_exception_err(DisasContext *ctx, int excp, int err)
eab9944c 1353{
eab9944c 1354 save_cpu_state(ctx, 1);
a8b18de7
PMD
1355 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1356 tcg_constant_i32(err));
eeb3bba8 1357 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
1358}
1359
46c9e2b3 1360void generate_exception(DisasContext *ctx, int excp)
eab9944c 1361{
ae71abad 1362 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
eab9944c
LA
1363}
1364
46c9e2b3 1365void generate_exception_end(DisasContext *ctx, int excp)
9c708c7f
PD
1366{
1367 generate_exception_err(ctx, excp, 0);
1368}
1369
3a4ef3b7
PMD
1370void gen_reserved_instruction(DisasContext *ctx)
1371{
1372 generate_exception_end(ctx, EXCP_RI);
1373}
1374
aaa9128a 1375/* Floating point register moves. */
8758d1b8 1376void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1377{
7c979afd
LA
1378 if (ctx->hflags & MIPS_HFLAG_FRE) {
1379 generate_exception(ctx, EXCP_RI);
1380 }
ecc7b3aa 1381 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1382}
1383
8758d1b8 1384void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1385{
7c979afd
LA
1386 TCGv_i64 t64;
1387 if (ctx->hflags & MIPS_HFLAG_FRE) {
1388 generate_exception(ctx, EXCP_RI);
1389 }
1390 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1391 tcg_gen_extu_i32_i64(t64, t);
1392 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1393 tcg_temp_free_i64(t64);
6d066274
AJ
1394}
1395
7f6613ce 1396static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1397{
7f6613ce 1398 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1399 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1400 } else {
7c979afd 1401 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1402 }
6d066274
AJ
1403}
1404
7f6613ce 1405static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1406{
7f6613ce
PJ
1407 if (ctx->hflags & MIPS_HFLAG_F64) {
1408 TCGv_i64 t64 = tcg_temp_new_i64();
1409 tcg_gen_extu_i32_i64(t64, t);
1410 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1411 tcg_temp_free_i64(t64);
1412 } else {
7c979afd 1413 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1414 }
aa0bf00b 1415}
6ea83fed 1416
8758d1b8 1417void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1418{
f364515c 1419 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1420 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1421 } else {
d73ee8a2 1422 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1423 }
1424}
6ea83fed 1425
8758d1b8 1426void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1427{
f364515c 1428 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1429 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1430 } else {
d73ee8a2
RH
1431 TCGv_i64 t0;
1432 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1433 t0 = tcg_temp_new_i64();
6d066274 1434 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1435 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1436 tcg_temp_free_i64(t0);
aa0bf00b
TS
1437 }
1438}
6ea83fed 1439
8758d1b8 1440int get_fp_bit(int cc)
a16336e4 1441{
1f8929d2 1442 if (cc) {
d94536f4 1443 return 24 + cc;
1f8929d2 1444 } else {
d94536f4 1445 return 23;
1f8929d2 1446 }
a16336e4
TS
1447}
1448
48d38ca5 1449/* Addresses computation */
46c9e2b3 1450void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1451{
941694d0 1452 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1453
1454#if defined(TARGET_MIPS64)
01f72885 1455 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1456 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1457 }
1458#endif
4ad40f36
FB
1459}
1460
bf0718c5
SM
1461static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1462 target_long ofs)
1463{
1464 tcg_gen_addi_tl(ret, base, ofs);
1465
1466#if defined(TARGET_MIPS64)
1467 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1468 tcg_gen_ext32s_i64(ret, ret);
1469 }
1470#endif
1471}
1472
31837be3
YK
1473/* Addresses computation (translation time) */
1474static target_long addr_add(DisasContext *ctx, target_long base,
1475 target_long offset)
1476{
1477 target_long sum = base + offset;
1478
1479#if defined(TARGET_MIPS64)
1480 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1481 sum = (int32_t)sum;
1482 }
1483#endif
1484 return sum;
1485}
1486
71f303cd 1487/* Sign-extract the low 32-bits to a target_long. */
46c9e2b3 1488void gen_move_low32(TCGv ret, TCGv_i64 arg)
1f1b4c00
YK
1489{
1490#if defined(TARGET_MIPS64)
71f303cd
RH
1491 tcg_gen_ext32s_i64(ret, arg);
1492#else
1493 tcg_gen_extrl_i64_i32(ret, arg);
1494#endif
1495}
1496
1497/* Sign-extract the high 32-bits to a target_long. */
46c9e2b3 1498void gen_move_high32(TCGv ret, TCGv_i64 arg)
71f303cd
RH
1499{
1500#if defined(TARGET_MIPS64)
1501 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1502#else
71f303cd 1503 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1504#endif
1505}
1506
905bdf72 1507bool check_cp0_enabled(DisasContext *ctx)
387a8fe5 1508{
1f8929d2 1509 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
11a75118 1510 generate_exception_end(ctx, EXCP_CpU);
905bdf72 1511 return false;
1f8929d2 1512 }
905bdf72 1513 return true;
387a8fe5
TS
1514}
1515
8758d1b8 1516void check_cp1_enabled(DisasContext *ctx)
5e755519 1517{
1f8929d2 1518 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
5e755519 1519 generate_exception_err(ctx, EXCP_CpU, 1);
1f8929d2 1520 }
5e755519
TS
1521}
1522
7480515f
AM
1523/*
1524 * Verify that the processor is running with COP1X instructions enabled.
1525 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1526 * opcode tables.
1527 */
8758d1b8 1528void check_cop1x(DisasContext *ctx)
b8aa4598 1529{
1f8929d2 1530 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
3a4ef3b7 1531 gen_reserved_instruction(ctx);
1f8929d2 1532 }
b8aa4598
TS
1533}
1534
7480515f
AM
1535/*
1536 * Verify that the processor is running with 64-bit floating-point
1537 * operations enabled.
1538 */
8758d1b8 1539void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1540{
1f8929d2 1541 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
3a4ef3b7 1542 gen_reserved_instruction(ctx);
1f8929d2 1543 }
5e755519
TS
1544}
1545
1546/*
1547 * Verify if floating point register is valid; an operation is not defined
1548 * if bit 0 of any register specification is set and the FR bit in the
1549 * Status register equals zero, since the register numbers specify an
1550 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1551 * in the Status register equals one, both even and odd register numbers
1552 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1553 *
1554 * Multiple 64 bit wide registers can be checked by calling
1555 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1556 */
8758d1b8 1557void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1558{
1f8929d2 1559 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
3a4ef3b7 1560 gen_reserved_instruction(ctx);
1f8929d2 1561 }
5e755519
TS
1562}
1563
7480515f
AM
1564/*
1565 * Verify that the processor is running with DSP instructions enabled.
1566 * This is enabled by CP0 Status register MX(24) bit.
853c3240 1567 */
853c3240
JL
1568static inline void check_dsp(DisasContext *ctx)
1569{
1570 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1571 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1572 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1573 } else {
3a4ef3b7 1574 gen_reserved_instruction(ctx);
ad153f15 1575 }
853c3240
JL
1576 }
1577}
1578
908f6be1 1579static inline void check_dsp_r2(DisasContext *ctx)
853c3240 1580{
908f6be1 1581 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 1582 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1583 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1584 } else {
3a4ef3b7 1585 gen_reserved_instruction(ctx);
ad153f15 1586 }
853c3240
JL
1587 }
1588}
1589
908f6be1 1590static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 1591{
908f6be1 1592 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
1593 if (ctx->insn_flags & ASE_DSP) {
1594 generate_exception_end(ctx, EXCP_DSPDIS);
1595 } else {
3a4ef3b7 1596 gen_reserved_instruction(ctx);
59e781fb
SM
1597 }
1598 }
1599}
1600
7480515f
AM
1601/*
1602 * This code generates a "reserved instruction" exception if the
1603 * CPU does not support the instruction set corresponding to flags.
1604 */
46c9e2b3 1605void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 1606{
d75c135e 1607 if (unlikely(!(ctx->insn_flags & flags))) {
3a4ef3b7 1608 gen_reserved_instruction(ctx);
d75c135e 1609 }
3a95e3a7
TS
1610}
1611
7480515f
AM
1612/*
1613 * This code generates a "reserved instruction" exception if the
1614 * CPU has corresponding flag set which indicates that the instruction
1615 * has been removed.
1616 */
f9c9cd63 1617static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
1618{
1619 if (unlikely(ctx->insn_flags & flags)) {
3a4ef3b7 1620 gen_reserved_instruction(ctx);
fecd2646
LA
1621 }
1622}
1623
96631327
FN
1624/*
1625 * The Linux kernel traps certain reserved instruction exceptions to
1626 * emulate the corresponding instructions. QEMU is the kernel in user
1627 * mode, so those traps are emulated by accepting the instructions.
1628 *
1629 * A reserved instruction exception is generated for flagged CPUs if
1630 * QEMU runs in system mode.
1631 */
1632static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1633{
1634#ifndef CONFIG_USER_ONLY
1635 check_insn_opc_removed(ctx, flags);
1636#endif
1637}
1638
7480515f
AM
1639/*
1640 * This code generates a "reserved instruction" exception if the
1641 * CPU does not support 64-bit paired-single (PS) floating point data type.
1642 */
e29c9628
YK
1643static inline void check_ps(DisasContext *ctx)
1644{
1645 if (unlikely(!ctx->ps)) {
1646 generate_exception(ctx, EXCP_RI);
1647 }
1648 check_cp1_64bitmode(ctx);
1649}
1650
7480515f 1651/*
d7efb693
PMD
1652 * This code generates a "reserved instruction" exception if cpu is not
1653 * 64-bit or 64-bit instructions are not enabled.
7480515f 1654 */
46c9e2b3 1655void check_mips_64(DisasContext *ctx)
e189e748 1656{
d7efb693 1657 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
3a4ef3b7 1658 gen_reserved_instruction(ctx);
1f8929d2 1659 }
e189e748
TS
1660}
1661
5204ea79
LA
1662#ifndef CONFIG_USER_ONLY
1663static inline void check_mvh(DisasContext *ctx)
1664{
1665 if (unlikely(!ctx->mvh)) {
1666 generate_exception(ctx, EXCP_RI);
1667 }
1668}
1669#endif
1670
0b16dcd1
AR
1671/*
1672 * This code generates a "reserved instruction" exception if the
1673 * Config5 XNP bit is set.
1674 */
1675static inline void check_xnp(DisasContext *ctx)
1676{
1677 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3a4ef3b7 1678 gen_reserved_instruction(ctx);
0b16dcd1
AR
1679 }
1680}
1681
5e31fdd5
YK
1682#ifndef CONFIG_USER_ONLY
1683/*
1684 * This code generates a "reserved instruction" exception if the
1685 * Config3 PW bit is NOT set.
1686 */
1687static inline void check_pw(DisasContext *ctx)
1688{
1689 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3a4ef3b7 1690 gen_reserved_instruction(ctx);
5e31fdd5
YK
1691 }
1692}
1693#endif
1694
9affc1c5
AR
1695/*
1696 * This code generates a "reserved instruction" exception if the
1697 * Config3 MT bit is NOT set.
1698 */
1699static inline void check_mt(DisasContext *ctx)
1700{
1701 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3a4ef3b7 1702 gen_reserved_instruction(ctx);
9affc1c5
AR
1703 }
1704}
1705
1706#ifndef CONFIG_USER_ONLY
1707/*
1708 * This code generates a "coprocessor unusable" exception if CP0 is not
1709 * available, and, if that is not the case, generates a "reserved instruction"
1710 * exception if the Config5 MT bit is NOT set. This is needed for availability
1711 * control of some of MT ASE instructions.
1712 */
1713static inline void check_cp0_mt(DisasContext *ctx)
1714{
1715 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
11a75118 1716 generate_exception_end(ctx, EXCP_CpU);
9affc1c5
AR
1717 } else {
1718 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3a4ef3b7 1719 gen_reserved_instruction(ctx);
9affc1c5
AR
1720 }
1721 }
1722}
1723#endif
1724
fb32f8c8
DN
1725/*
1726 * This code generates a "reserved instruction" exception if the
1727 * Config5 NMS bit is set.
1728 */
1729static inline void check_nms(DisasContext *ctx)
1730{
1731 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3a4ef3b7 1732 gen_reserved_instruction(ctx);
fb32f8c8
DN
1733 }
1734}
1735
d046a9ea
DN
1736/*
1737 * This code generates a "reserved instruction" exception if the
1738 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1739 * Config2 TL, and Config5 L2C are unset.
1740 */
1741static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1742{
1f8929d2
AM
1743 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1744 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1745 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1746 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1747 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1748 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3a4ef3b7 1749 gen_reserved_instruction(ctx);
d046a9ea
DN
1750 }
1751}
1752
1753/*
1754 * This code generates a "reserved instruction" exception if the
1755 * Config5 EVA bit is NOT set.
1756 */
1757static inline void check_eva(DisasContext *ctx)
1758{
1759 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3a4ef3b7 1760 gen_reserved_instruction(ctx);
d046a9ea
DN
1761 }
1762}
1763
0b16dcd1 1764
7480515f
AM
1765/*
1766 * Define small wrappers for gen_load_fpr* so that we have a uniform
1767 * calling interface for 32 and 64-bit FPRs. No sense in changing
1768 * all callers for gen_load_fpr32 when we need the CTX parameter for
1769 * this one use.
1770 */
7c979afd 1771#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1772#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1773#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1774static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1775 int ft, int fs, int cc) \
1776{ \
71375b59
AM
1777 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1778 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
8153667c
NF
1779 switch (ifmt) { \
1780 case FMT_PS: \
e29c9628 1781 check_ps(ctx); \
8153667c
NF
1782 break; \
1783 case FMT_D: \
1784 if (abs) { \
1785 check_cop1x(ctx); \
1786 } \
1787 check_cp1_registers(ctx, fs | ft); \
1788 break; \
1789 case FMT_S: \
1790 if (abs) { \
1791 check_cop1x(ctx); \
1792 } \
1793 break; \
1794 } \
71375b59
AM
1795 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1796 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
8153667c 1797 switch (n) { \
1f8929d2
AM
1798 case 0: \
1799 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1800 break; \
1801 case 1: \
1802 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1803 break; \
1804 case 2: \
1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1806 break; \
1807 case 3: \
1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1809 break; \
1810 case 4: \
1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1812 break; \
1813 case 5: \
1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1815 break; \
1816 case 6: \
1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1818 break; \
1819 case 7: \
1820 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1821 break; \
1822 case 8: \
1823 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1824 break; \
1825 case 9: \
1826 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1827 break; \
1828 case 10: \
1829 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1830 break; \
1831 case 11: \
1832 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1833 break; \
1834 case 12: \
1835 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1836 break; \
1837 case 13: \
1838 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1839 break; \
1840 case 14: \
1841 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1842 break; \
1843 case 15: \
1844 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1845 break; \
1846 default: \
1847 abort(); \
8153667c 1848 } \
71375b59
AM
1849 tcg_temp_free_i##bits(fp0); \
1850 tcg_temp_free_i##bits(fp1); \
8153667c
NF
1851}
1852
1853FOP_CONDS(, 0, d, FMT_D, 64)
1854FOP_CONDS(abs, 1, d, FMT_D, 64)
1855FOP_CONDS(, 0, s, FMT_S, 32)
1856FOP_CONDS(abs, 1, s, FMT_S, 32)
1857FOP_CONDS(, 0, ps, FMT_PS, 64)
1858FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1859#undef FOP_CONDS
3f493883
YK
1860
1861#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
71375b59 1862static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3f493883
YK
1863 int ft, int fs, int fd) \
1864{ \
1865 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1866 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1867 if (ifmt == FMT_D) { \
3f493883 1868 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1869 } \
1870 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1871 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1872 switch (n) { \
1873 case 0: \
1874 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1875 break; \
1876 case 1: \
1877 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1878 break; \
1879 case 2: \
1880 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1881 break; \
1882 case 3: \
1883 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1884 break; \
1885 case 4: \
1886 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1887 break; \
1888 case 5: \
1889 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1890 break; \
1891 case 6: \
1892 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1893 break; \
1894 case 7: \
1895 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1896 break; \
1897 case 8: \
1898 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1899 break; \
1900 case 9: \
1901 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1902 break; \
1903 case 10: \
1904 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1905 break; \
1906 case 11: \
1907 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 12: \
1910 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 13: \
1913 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 14: \
1916 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 15: \
1919 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 17: \
1922 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 18: \
1925 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 19: \
1928 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 25: \
1931 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 26: \
1934 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 27: \
1937 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 default: \
1940 abort(); \
1941 } \
1942 STORE; \
71375b59
AM
1943 tcg_temp_free_i ## bits(fp0); \
1944 tcg_temp_free_i ## bits(fp1); \
3f493883
YK
1945}
1946
1947FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 1948FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 1949#undef FOP_CONDNS
8153667c
NF
1950#undef gen_ldcmp_fpr32
1951#undef gen_ldcmp_fpr64
1952
958fb4a9 1953/* load/store instructions. */
e7139c44 1954#ifdef CONFIG_USER_ONLY
71375b59 1955#define OP_LD_ATOMIC(insn, fname) \
dd4096cd
JH
1956static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1957 DisasContext *ctx) \
d9bea114
AJ
1958{ \
1959 TCGv t0 = tcg_temp_new(); \
1960 tcg_gen_mov_tl(t0, arg1); \
1961 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
71375b59
AM
1962 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1963 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1964 tcg_temp_free(t0); \
aaa9128a 1965}
e7139c44 1966#else
71375b59 1967#define OP_LD_ATOMIC(insn, fname) \
dd4096cd
JH
1968static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1969 DisasContext *ctx) \
e7139c44 1970{ \
a1b4b060 1971 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \
e7139c44
AJ
1972}
1973#endif
71375b59 1974OP_LD_ATOMIC(ll, ld32s);
aaa9128a 1975#if defined(TARGET_MIPS64)
71375b59 1976OP_LD_ATOMIC(lld, ld64);
aaa9128a
TS
1977#endif
1978#undef OP_LD_ATOMIC
1979
46c9e2b3 1980void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
662d7485
NF
1981{
1982 if (base == 0) {
1983 tcg_gen_movi_tl(addr, offset);
1984 } else if (offset == 0) {
1985 gen_load_gpr(addr, base);
1986 } else {
1987 tcg_gen_movi_tl(addr, offset);
1988 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1989 }
1990}
1991
235785e8 1992static target_ulong pc_relative_pc(DisasContext *ctx)
364d4831 1993{
eeb3bba8 1994 target_ulong pc = ctx->base.pc_next;
364d4831
NF
1995
1996 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1997 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1998
1999 pc -= branch_bytes;
2000 }
2001
2002 pc &= ~(target_ulong)3;
2003 return pc;
2004}
2005
5c13fdfd 2006/* Load */
d75c135e 2007static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 2008 int rt, int base, int offset)
6af0bf9c 2009{
fc40787a 2010 TCGv t0, t1, t2;
dd4096cd 2011 int mem_idx = ctx->mem_idx;
afa88c3a 2012
8e2d5831
JY
2013 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2014 INSN_LOONGSON3A)) {
7480515f
AM
2015 /*
2016 * Loongson CPU uses a load to zero register for prefetch.
2017 * We emulate it as a NOP. On other CPU we must perform the
2018 * actual memory access.
2019 */
afa88c3a
AJ
2020 return;
2021 }
6af0bf9c 2022
afa88c3a 2023 t0 = tcg_temp_new();
662d7485 2024 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2025
6af0bf9c 2026 switch (opc) {
d26bc211 2027#if defined(TARGET_MIPS64)
6e473128 2028 case OPC_LWU:
dd4096cd 2029 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2030 ctx->default_tcg_memop_mask);
78723684 2031 gen_store_gpr(t0, rt);
6e473128 2032 break;
6af0bf9c 2033 case OPC_LD:
dd4096cd 2034 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2035 ctx->default_tcg_memop_mask);
78723684 2036 gen_store_gpr(t0, rt);
6af0bf9c 2037 break;
7a387fff 2038 case OPC_LLD:
bf7910c6 2039 case R6_OPC_LLD:
dd4096cd 2040 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2041 gen_store_gpr(t0, rt);
7a387fff 2042 break;
6af0bf9c 2043 case OPC_LDL:
3cee3050 2044 t1 = tcg_temp_new();
7480515f
AM
2045 /*
2046 * Do a byte access to possibly trigger a page
2047 * fault with the unaligned address.
2048 */
dd4096cd 2049 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a 2050 tcg_gen_andi_tl(t1, t0, 7);
bf78469c
PMD
2051 if (!cpu_is_bigendian(ctx)) {
2052 tcg_gen_xori_tl(t1, t1, 7);
2053 }
fc40787a
AJ
2054 tcg_gen_shli_tl(t1, t1, 3);
2055 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2056 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2057 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2058 t2 = tcg_const_tl(-1);
2059 tcg_gen_shl_tl(t2, t2, t1);
78723684 2060 gen_load_gpr(t1, rt);
eb02cc3f 2061 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2062 tcg_temp_free(t2);
2063 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2064 tcg_temp_free(t1);
fc40787a 2065 gen_store_gpr(t0, rt);
6af0bf9c 2066 break;
6af0bf9c 2067 case OPC_LDR:
3cee3050 2068 t1 = tcg_temp_new();
7480515f
AM
2069 /*
2070 * Do a byte access to possibly trigger a page
2071 * fault with the unaligned address.
2072 */
dd4096cd 2073 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a 2074 tcg_gen_andi_tl(t1, t0, 7);
bf78469c
PMD
2075 if (cpu_is_bigendian(ctx)) {
2076 tcg_gen_xori_tl(t1, t1, 7);
2077 }
fc40787a
AJ
2078 tcg_gen_shli_tl(t1, t1, 3);
2079 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2080 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2081 tcg_gen_shr_tl(t0, t0, t1);
2082 tcg_gen_xori_tl(t1, t1, 63);
2083 t2 = tcg_const_tl(0xfffffffffffffffeull);
2084 tcg_gen_shl_tl(t2, t2, t1);
78723684 2085 gen_load_gpr(t1, rt);
fc40787a
AJ
2086 tcg_gen_and_tl(t1, t1, t2);
2087 tcg_temp_free(t2);
2088 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2089 tcg_temp_free(t1);
fc40787a 2090 gen_store_gpr(t0, rt);
6af0bf9c 2091 break;
364d4831 2092 case OPC_LDPC:
3cee3050 2093 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2094 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2095 tcg_temp_free(t1);
dd4096cd 2096 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2097 gen_store_gpr(t0, rt);
2098 break;
6af0bf9c 2099#endif
364d4831 2100 case OPC_LWPC:
3cee3050 2101 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2102 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2103 tcg_temp_free(t1);
dd4096cd 2104 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2105 gen_store_gpr(t0, rt);
2106 break;
76964147
JH
2107 case OPC_LWE:
2108 mem_idx = MIPS_HFLAG_UM;
2109 /* fall through */
6af0bf9c 2110 case OPC_LW:
dd4096cd 2111 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2112 ctx->default_tcg_memop_mask);
78723684 2113 gen_store_gpr(t0, rt);
6af0bf9c 2114 break;
76964147
JH
2115 case OPC_LHE:
2116 mem_idx = MIPS_HFLAG_UM;
2117 /* fall through */
6af0bf9c 2118 case OPC_LH:
dd4096cd 2119 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2120 ctx->default_tcg_memop_mask);
78723684 2121 gen_store_gpr(t0, rt);
6af0bf9c 2122 break;
76964147
JH
2123 case OPC_LHUE:
2124 mem_idx = MIPS_HFLAG_UM;
2125 /* fall through */
6af0bf9c 2126 case OPC_LHU:
dd4096cd 2127 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2128 ctx->default_tcg_memop_mask);
78723684 2129 gen_store_gpr(t0, rt);
6af0bf9c 2130 break;
76964147
JH
2131 case OPC_LBE:
2132 mem_idx = MIPS_HFLAG_UM;
2133 /* fall through */
6af0bf9c 2134 case OPC_LB:
dd4096cd 2135 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2136 gen_store_gpr(t0, rt);
6af0bf9c 2137 break;
76964147
JH
2138 case OPC_LBUE:
2139 mem_idx = MIPS_HFLAG_UM;
2140 /* fall through */
6af0bf9c 2141 case OPC_LBU:
dd4096cd 2142 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2143 gen_store_gpr(t0, rt);
6af0bf9c 2144 break;
76964147
JH
2145 case OPC_LWLE:
2146 mem_idx = MIPS_HFLAG_UM;
2147 /* fall through */
6af0bf9c 2148 case OPC_LWL:
3cee3050 2149 t1 = tcg_temp_new();
7480515f
AM
2150 /*
2151 * Do a byte access to possibly trigger a page
2152 * fault with the unaligned address.
2153 */
dd4096cd 2154 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a 2155 tcg_gen_andi_tl(t1, t0, 3);
bf78469c
PMD
2156 if (!cpu_is_bigendian(ctx)) {
2157 tcg_gen_xori_tl(t1, t1, 3);
2158 }
fc40787a
AJ
2159 tcg_gen_shli_tl(t1, t1, 3);
2160 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2161 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2162 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2163 t2 = tcg_const_tl(-1);
2164 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2165 gen_load_gpr(t1, rt);
eb02cc3f 2166 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2167 tcg_temp_free(t2);
2168 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2169 tcg_temp_free(t1);
fc40787a
AJ
2170 tcg_gen_ext32s_tl(t0, t0);
2171 gen_store_gpr(t0, rt);
6af0bf9c 2172 break;
76964147
JH
2173 case OPC_LWRE:
2174 mem_idx = MIPS_HFLAG_UM;
2175 /* fall through */
6af0bf9c 2176 case OPC_LWR:
3cee3050 2177 t1 = tcg_temp_new();
7480515f
AM
2178 /*
2179 * Do a byte access to possibly trigger a page
2180 * fault with the unaligned address.
2181 */
dd4096cd 2182 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a 2183 tcg_gen_andi_tl(t1, t0, 3);
bf78469c
PMD
2184 if (cpu_is_bigendian(ctx)) {
2185 tcg_gen_xori_tl(t1, t1, 3);
2186 }
fc40787a
AJ
2187 tcg_gen_shli_tl(t1, t1, 3);
2188 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2189 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2190 tcg_gen_shr_tl(t0, t0, t1);
2191 tcg_gen_xori_tl(t1, t1, 31);
2192 t2 = tcg_const_tl(0xfffffffeull);
2193 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2194 gen_load_gpr(t1, rt);
fc40787a
AJ
2195 tcg_gen_and_tl(t1, t1, t2);
2196 tcg_temp_free(t2);
2197 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2198 tcg_temp_free(t1);
c728154b 2199 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2200 gen_store_gpr(t0, rt);
6af0bf9c 2201 break;
76964147
JH
2202 case OPC_LLE:
2203 mem_idx = MIPS_HFLAG_UM;
2204 /* fall through */
6af0bf9c 2205 case OPC_LL:
4368b29a 2206 case R6_OPC_LL:
dd4096cd 2207 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2208 gen_store_gpr(t0, rt);
6af0bf9c 2209 break;
d66c7132 2210 }
d66c7132 2211 tcg_temp_free(t0);
d66c7132
AJ
2212}
2213
5c13fdfd 2214/* Store */
235785e8
AM
2215static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2216 int base, int offset)
5c13fdfd 2217{
5c13fdfd
AJ
2218 TCGv t0 = tcg_temp_new();
2219 TCGv t1 = tcg_temp_new();
dd4096cd 2220 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2221
2222 gen_base_offset_addr(ctx, t0, base, offset);
2223 gen_load_gpr(t1, rt);
2224 switch (opc) {
2225#if defined(TARGET_MIPS64)
2226 case OPC_SD:
dd4096cd 2227 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2228 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2229 break;
2230 case OPC_SDL:
dd4096cd 2231 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2232 break;
2233 case OPC_SDR:
dd4096cd 2234 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2235 break;
2236#endif
76964147
JH
2237 case OPC_SWE:
2238 mem_idx = MIPS_HFLAG_UM;
2239 /* fall through */
5c13fdfd 2240 case OPC_SW:
dd4096cd 2241 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2242 ctx->default_tcg_memop_mask);
5c13fdfd 2243 break;
76964147
JH
2244 case OPC_SHE:
2245 mem_idx = MIPS_HFLAG_UM;
2246 /* fall through */
5c13fdfd 2247 case OPC_SH:
dd4096cd 2248 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2249 ctx->default_tcg_memop_mask);
5c13fdfd 2250 break;
76964147
JH
2251 case OPC_SBE:
2252 mem_idx = MIPS_HFLAG_UM;
2253 /* fall through */
5c13fdfd 2254 case OPC_SB:
dd4096cd 2255 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2256 break;
76964147
JH
2257 case OPC_SWLE:
2258 mem_idx = MIPS_HFLAG_UM;
2259 /* fall through */
5c13fdfd 2260 case OPC_SWL:
dd4096cd 2261 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2262 break;
76964147
JH
2263 case OPC_SWRE:
2264 mem_idx = MIPS_HFLAG_UM;
2265 /* fall through */
5c13fdfd 2266 case OPC_SWR:
dd4096cd 2267 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2268 break;
2269 }
5c13fdfd
AJ
2270 tcg_temp_free(t0);
2271 tcg_temp_free(t1);
2272}
2273
2274
d66c7132 2275/* Store conditional */
33a07fa2 2276static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
14776ab5 2277 MemOp tcg_mo, bool eva)
d66c7132 2278{
33a07fa2
LA
2279 TCGv addr, t0, val;
2280 TCGLabel *l1 = gen_new_label();
2281 TCGLabel *done = gen_new_label();
d66c7132 2282
2d2826b9 2283 t0 = tcg_temp_new();
33a07fa2 2284 addr = tcg_temp_new();
8cdf8869 2285 /* compare the address against that of the preceding LL */
33a07fa2
LA
2286 gen_base_offset_addr(ctx, addr, base, offset);
2287 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2288 tcg_temp_free(addr);
2289 tcg_gen_movi_tl(t0, 0);
2290 gen_store_gpr(t0, rt);
2291 tcg_gen_br(done);
2292
2293 gen_set_label(l1);
2294 /* generate cmpxchg */
2295 val = tcg_temp_new();
2296 gen_load_gpr(val, rt);
2297 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2298 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2299 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2300 gen_store_gpr(t0, rt);
2301 tcg_temp_free(val);
2302
2303 gen_set_label(done);
d66c7132 2304 tcg_temp_free(t0);
6af0bf9c
FB
2305}
2306
6ea83fed 2307/* Load and store */
235785e8
AM
2308static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2309 TCGv t0)
6ea83fed 2310{
7480515f
AM
2311 /*
2312 * Don't do NOP if destination is zero: we must perform the actual
2313 * memory access.
2314 */
6ea83fed
FB
2315 switch (opc) {
2316 case OPC_LWC1:
b6d96bed 2317 {
a7812ae4 2318 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2319 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2320 ctx->default_tcg_memop_mask);
7c979afd 2321 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2322 tcg_temp_free_i32(fp0);
b6d96bed 2323 }
6ea83fed
FB
2324 break;
2325 case OPC_SWC1:
b6d96bed 2326 {
a7812ae4 2327 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2328 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2329 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2330 ctx->default_tcg_memop_mask);
a7812ae4 2331 tcg_temp_free_i32(fp0);
b6d96bed 2332 }
6ea83fed
FB
2333 break;
2334 case OPC_LDC1:
b6d96bed 2335 {
a7812ae4 2336 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2337 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2338 ctx->default_tcg_memop_mask);
b6d96bed 2339 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2340 tcg_temp_free_i64(fp0);
b6d96bed 2341 }
6ea83fed
FB
2342 break;
2343 case OPC_SDC1:
b6d96bed 2344 {
a7812ae4 2345 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2346 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2347 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2348 ctx->default_tcg_memop_mask);
a7812ae4 2349 tcg_temp_free_i64(fp0);
b6d96bed 2350 }
6ea83fed
FB
2351 break;
2352 default:
9d68ac14 2353 MIPS_INVAL("flt_ldst");
3a4ef3b7 2354 gen_reserved_instruction(ctx);
b52d3bfa 2355 break;
6ea83fed 2356 }
6ea83fed 2357}
6ea83fed 2358
5ab5c041
AJ
2359static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2360 int rs, int16_t imm)
26ebe468 2361{
b52d3bfa
YK
2362 TCGv t0 = tcg_temp_new();
2363
5ab5c041 2364 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2365 check_cp1_enabled(ctx);
d9224450
MR
2366 switch (op) {
2367 case OPC_LDC1:
2368 case OPC_SDC1:
2369 check_insn(ctx, ISA_MIPS2);
2370 /* Fallthrough */
2371 default:
b52d3bfa
YK
2372 gen_base_offset_addr(ctx, t0, rs, imm);
2373 gen_flt_ldst(ctx, op, rt, t0);
d9224450 2374 }
26ebe468
NF
2375 } else {
2376 generate_exception_err(ctx, EXCP_CpU, 1);
2377 }
b52d3bfa 2378 tcg_temp_free(t0);
26ebe468
NF
2379}
2380
6af0bf9c 2381/* Arithmetic with immediate operand */
d75c135e 2382static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 2383 int rt, int rs, int imm)
6af0bf9c 2384{
324d9e32 2385 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2386
7a387fff 2387 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
7480515f
AM
2388 /*
2389 * If no destination, treat it as a NOP.
2390 * For addi, we must generate the overflow exception when needed.
2391 */
324d9e32 2392 return;
6af0bf9c
FB
2393 }
2394 switch (opc) {
2395 case OPC_ADDI:
48d38ca5 2396 {
324d9e32
AJ
2397 TCGv t0 = tcg_temp_local_new();
2398 TCGv t1 = tcg_temp_new();
2399 TCGv t2 = tcg_temp_new();
42a268c2 2400 TCGLabel *l1 = gen_new_label();
48d38ca5 2401
324d9e32
AJ
2402 gen_load_gpr(t1, rs);
2403 tcg_gen_addi_tl(t0, t1, uimm);
2404 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2405
324d9e32
AJ
2406 tcg_gen_xori_tl(t1, t1, ~uimm);
2407 tcg_gen_xori_tl(t2, t0, uimm);
2408 tcg_gen_and_tl(t1, t1, t2);
2409 tcg_temp_free(t2);
2410 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2411 tcg_temp_free(t1);
48d38ca5
TS
2412 /* operands of same sign, result different sign */
2413 generate_exception(ctx, EXCP_OVERFLOW);
2414 gen_set_label(l1);
78723684 2415 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2416 gen_store_gpr(t0, rt);
2417 tcg_temp_free(t0);
48d38ca5 2418 }
6af0bf9c
FB
2419 break;
2420 case OPC_ADDIU:
324d9e32
AJ
2421 if (rs != 0) {
2422 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2423 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2426 }
6af0bf9c 2427 break;
d26bc211 2428#if defined(TARGET_MIPS64)
7a387fff 2429 case OPC_DADDI:
48d38ca5 2430 {
324d9e32
AJ
2431 TCGv t0 = tcg_temp_local_new();
2432 TCGv t1 = tcg_temp_new();
2433 TCGv t2 = tcg_temp_new();
42a268c2 2434 TCGLabel *l1 = gen_new_label();
48d38ca5 2435
324d9e32
AJ
2436 gen_load_gpr(t1, rs);
2437 tcg_gen_addi_tl(t0, t1, uimm);
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);
324d9e32
AJ
2448 gen_store_gpr(t0, rt);
2449 tcg_temp_free(t0);
48d38ca5 2450 }
7a387fff
TS
2451 break;
2452 case OPC_DADDIU:
324d9e32
AJ
2453 if (rs != 0) {
2454 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2455 } else {
2456 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2457 }
7a387fff
TS
2458 break;
2459#endif
324d9e32 2460 }
324d9e32
AJ
2461}
2462
2463/* Logic with immediate operand */
d75c135e 2464static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2465 int rt, int rs, int16_t imm)
324d9e32
AJ
2466{
2467 target_ulong uimm;
324d9e32
AJ
2468
2469 if (rt == 0) {
2470 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2471 return;
2472 }
2473 uimm = (uint16_t)imm;
2474 switch (opc) {
6af0bf9c 2475 case OPC_ANDI:
1f8929d2 2476 if (likely(rs != 0)) {
324d9e32 2477 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 2478 } else {
324d9e32 2479 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1f8929d2 2480 }
6af0bf9c
FB
2481 break;
2482 case OPC_ORI:
1f8929d2 2483 if (rs != 0) {
324d9e32 2484 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 2485 } else {
324d9e32 2486 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1f8929d2 2487 }
6af0bf9c
FB
2488 break;
2489 case OPC_XORI:
1f8929d2 2490 if (likely(rs != 0)) {
324d9e32 2491 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1f8929d2 2492 } else {
324d9e32 2493 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1f8929d2 2494 }
6af0bf9c
FB
2495 break;
2496 case OPC_LUI:
2e211e0a 2497 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
d4ea6acd
LA
2498 /* OPC_AUI */
2499 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2500 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2501 } else {
2502 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2503 }
7c2c3ea3
EJ
2504 break;
2505
2506 default:
6af0bf9c 2507 break;
324d9e32 2508 }
324d9e32
AJ
2509}
2510
2511/* Set on less than with immediate operand */
d75c135e 2512static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2513 int rt, int rs, int16_t imm)
324d9e32
AJ
2514{
2515 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2516 TCGv t0;
2517
2518 if (rt == 0) {
2519 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2520 return;
2521 }
2522 t0 = tcg_temp_new();
2523 gen_load_gpr(t0, rs);
2524 switch (opc) {
2525 case OPC_SLTI:
e68dd28f 2526 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2527 break;
2528 case OPC_SLTIU:
e68dd28f 2529 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2530 break;
2531 }
324d9e32
AJ
2532 tcg_temp_free(t0);
2533}
2534
2535/* Shifts with immediate operand */
d75c135e 2536static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2537 int rt, int rs, int16_t imm)
2538{
2539 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2540 TCGv t0;
2541
2542 if (rt == 0) {
2543 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2544 return;
2545 }
2546
2547 t0 = tcg_temp_new();
2548 gen_load_gpr(t0, rs);
2549 switch (opc) {
6af0bf9c 2550 case OPC_SLL:
78723684 2551 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2552 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2553 break;
2554 case OPC_SRA:
324d9e32 2555 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2556 break;
2557 case OPC_SRL:
ea63e2c3
NF
2558 if (uimm != 0) {
2559 tcg_gen_ext32u_tl(t0, t0);
2560 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2561 } else {
2562 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2563 }
ea63e2c3
NF
2564 break;
2565 case OPC_ROTR:
2566 if (uimm != 0) {
2567 TCGv_i32 t1 = tcg_temp_new_i32();
2568
2569 tcg_gen_trunc_tl_i32(t1, t0);
2570 tcg_gen_rotri_i32(t1, t1, uimm);
2571 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2572 tcg_temp_free_i32(t1);
3399e30f
NF
2573 } else {
2574 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2575 }
7a387fff 2576 break;
d26bc211 2577#if defined(TARGET_MIPS64)
7a387fff 2578 case OPC_DSLL:
324d9e32 2579 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2580 break;
2581 case OPC_DSRA:
324d9e32 2582 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2583 break;
2584 case OPC_DSRL:
ea63e2c3 2585 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2586 break;
2587 case OPC_DROTR:
2588 if (uimm != 0) {
2589 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2590 } else {
2591 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2592 }
7a387fff
TS
2593 break;
2594 case OPC_DSLL32:
324d9e32 2595 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2596 break;
2597 case OPC_DSRA32:
324d9e32 2598 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2599 break;
2600 case OPC_DSRL32:
ea63e2c3 2601 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2602 break;
2603 case OPC_DROTR32:
2604 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2605 break;
7a387fff 2606#endif
6af0bf9c 2607 }
78723684 2608 tcg_temp_free(t0);
6af0bf9c
FB
2609}
2610
2611/* Arithmetic */
d75c135e
AJ
2612static void gen_arith(DisasContext *ctx, uint32_t opc,
2613 int rd, int rs, int rt)
6af0bf9c 2614{
7a387fff
TS
2615 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2616 && opc != OPC_DADD && opc != OPC_DSUB) {
7480515f
AM
2617 /*
2618 * If no destination, treat it as a NOP.
2619 * For add & sub, we must generate the overflow exception when needed.
2620 */
460f00c4 2621 return;
185f0762 2622 }
460f00c4 2623
6af0bf9c
FB
2624 switch (opc) {
2625 case OPC_ADD:
48d38ca5 2626 {
460f00c4
AJ
2627 TCGv t0 = tcg_temp_local_new();
2628 TCGv t1 = tcg_temp_new();
2629 TCGv t2 = tcg_temp_new();
42a268c2 2630 TCGLabel *l1 = gen_new_label();
48d38ca5 2631
460f00c4
AJ
2632 gen_load_gpr(t1, rs);
2633 gen_load_gpr(t2, rt);
2634 tcg_gen_add_tl(t0, t1, t2);
2635 tcg_gen_ext32s_tl(t0, t0);
2636 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2637 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2638 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2639 tcg_temp_free(t2);
2640 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2641 tcg_temp_free(t1);
48d38ca5
TS
2642 /* operands of same sign, result different sign */
2643 generate_exception(ctx, EXCP_OVERFLOW);
2644 gen_set_label(l1);
460f00c4
AJ
2645 gen_store_gpr(t0, rd);
2646 tcg_temp_free(t0);
48d38ca5 2647 }
6af0bf9c
FB
2648 break;
2649 case OPC_ADDU:
460f00c4
AJ
2650 if (rs != 0 && rt != 0) {
2651 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2652 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2653 } else if (rs == 0 && rt != 0) {
2654 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2655 } else if (rs != 0 && rt == 0) {
2656 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2657 } else {
2658 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2659 }
6af0bf9c
FB
2660 break;
2661 case OPC_SUB:
48d38ca5 2662 {
460f00c4
AJ
2663 TCGv t0 = tcg_temp_local_new();
2664 TCGv t1 = tcg_temp_new();
2665 TCGv t2 = tcg_temp_new();
42a268c2 2666 TCGLabel *l1 = gen_new_label();
48d38ca5 2667
460f00c4
AJ
2668 gen_load_gpr(t1, rs);
2669 gen_load_gpr(t2, rt);
2670 tcg_gen_sub_tl(t0, t1, t2);
2671 tcg_gen_ext32s_tl(t0, t0);
2672 tcg_gen_xor_tl(t2, t1, t2);
2673 tcg_gen_xor_tl(t1, t0, t1);
2674 tcg_gen_and_tl(t1, t1, t2);
2675 tcg_temp_free(t2);
2676 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2677 tcg_temp_free(t1);
7480515f
AM
2678 /*
2679 * operands of different sign, first operand and the result
2680 * of different sign
2681 */
48d38ca5
TS
2682 generate_exception(ctx, EXCP_OVERFLOW);
2683 gen_set_label(l1);
460f00c4
AJ
2684 gen_store_gpr(t0, rd);
2685 tcg_temp_free(t0);
48d38ca5 2686 }
6af0bf9c
FB
2687 break;
2688 case OPC_SUBU:
460f00c4
AJ
2689 if (rs != 0 && rt != 0) {
2690 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2691 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2692 } else if (rs == 0 && rt != 0) {
2693 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2694 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2695 } else if (rs != 0 && rt == 0) {
2696 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2697 } else {
2698 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2699 }
6af0bf9c 2700 break;
d26bc211 2701#if defined(TARGET_MIPS64)
7a387fff 2702 case OPC_DADD:
48d38ca5 2703 {
460f00c4
AJ
2704 TCGv t0 = tcg_temp_local_new();
2705 TCGv t1 = tcg_temp_new();
2706 TCGv t2 = tcg_temp_new();
42a268c2 2707 TCGLabel *l1 = gen_new_label();
48d38ca5 2708
460f00c4
AJ
2709 gen_load_gpr(t1, rs);
2710 gen_load_gpr(t2, rt);
2711 tcg_gen_add_tl(t0, t1, t2);
2712 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2713 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2714 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2715 tcg_temp_free(t2);
2716 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2717 tcg_temp_free(t1);
48d38ca5
TS
2718 /* operands of same sign, result different sign */
2719 generate_exception(ctx, EXCP_OVERFLOW);
2720 gen_set_label(l1);
460f00c4
AJ
2721 gen_store_gpr(t0, rd);
2722 tcg_temp_free(t0);
48d38ca5 2723 }
7a387fff
TS
2724 break;
2725 case OPC_DADDU:
460f00c4
AJ
2726 if (rs != 0 && rt != 0) {
2727 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2728 } else if (rs == 0 && rt != 0) {
2729 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2730 } else if (rs != 0 && rt == 0) {
2731 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2732 } else {
2733 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2734 }
7a387fff
TS
2735 break;
2736 case OPC_DSUB:
48d38ca5 2737 {
460f00c4
AJ
2738 TCGv t0 = tcg_temp_local_new();
2739 TCGv t1 = tcg_temp_new();
2740 TCGv t2 = tcg_temp_new();
42a268c2 2741 TCGLabel *l1 = gen_new_label();
48d38ca5 2742
460f00c4
AJ
2743 gen_load_gpr(t1, rs);
2744 gen_load_gpr(t2, rt);
2745 tcg_gen_sub_tl(t0, t1, t2);
2746 tcg_gen_xor_tl(t2, t1, t2);
2747 tcg_gen_xor_tl(t1, t0, t1);
2748 tcg_gen_and_tl(t1, t1, t2);
2749 tcg_temp_free(t2);
2750 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2751 tcg_temp_free(t1);
71375b59
AM
2752 /*
2753 * Operands of different sign, first operand and result different
2754 * sign.
2755 */
48d38ca5
TS
2756 generate_exception(ctx, EXCP_OVERFLOW);
2757 gen_set_label(l1);
460f00c4
AJ
2758 gen_store_gpr(t0, rd);
2759 tcg_temp_free(t0);
48d38ca5 2760 }
7a387fff
TS
2761 break;
2762 case OPC_DSUBU:
460f00c4
AJ
2763 if (rs != 0 && rt != 0) {
2764 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2765 } else if (rs == 0 && rt != 0) {
2766 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2767 } else if (rs != 0 && rt == 0) {
2768 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2769 } else {
2770 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2771 }
7a387fff
TS
2772 break;
2773#endif
460f00c4
AJ
2774 case OPC_MUL:
2775 if (likely(rs != 0 && rt != 0)) {
2776 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2777 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2778 } else {
2779 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780 }
6af0bf9c 2781 break;
460f00c4 2782 }
460f00c4
AJ
2783}
2784
2785/* Conditional move */
d75c135e 2786static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2787 int rd, int rs, int rt)
460f00c4 2788{
acf12465 2789 TCGv t0, t1, t2;
460f00c4
AJ
2790
2791 if (rd == 0) {
acf12465 2792 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2793 return;
2794 }
2795
acf12465
AJ
2796 t0 = tcg_temp_new();
2797 gen_load_gpr(t0, rt);
2798 t1 = tcg_const_tl(0);
2799 t2 = tcg_temp_new();
2800 gen_load_gpr(t2, rs);
460f00c4
AJ
2801 switch (opc) {
2802 case OPC_MOVN:
acf12465 2803 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2804 break;
460f00c4 2805 case OPC_MOVZ:
acf12465 2806 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2807 break;
b691d9d2
LA
2808 case OPC_SELNEZ:
2809 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2810 break;
2811 case OPC_SELEQZ:
2812 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2813 break;
460f00c4 2814 }
acf12465
AJ
2815 tcg_temp_free(t2);
2816 tcg_temp_free(t1);
2817 tcg_temp_free(t0);
460f00c4
AJ
2818}
2819
2820/* Logic */
d75c135e 2821static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2822 int rd, int rs, int rt)
460f00c4 2823{
460f00c4
AJ
2824 if (rd == 0) {
2825 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2826 return;
2827 }
2828
2829 switch (opc) {
6af0bf9c 2830 case OPC_AND:
460f00c4
AJ
2831 if (likely(rs != 0 && rt != 0)) {
2832 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2833 } else {
2834 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2835 }
6af0bf9c
FB
2836 break;
2837 case OPC_NOR:
460f00c4
AJ
2838 if (rs != 0 && rt != 0) {
2839 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2840 } else if (rs == 0 && rt != 0) {
2841 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2842 } else if (rs != 0 && rt == 0) {
2843 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2844 } else {
2845 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2846 }
6af0bf9c
FB
2847 break;
2848 case OPC_OR:
460f00c4
AJ
2849 if (likely(rs != 0 && rt != 0)) {
2850 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2851 } else if (rs == 0 && rt != 0) {
2852 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2853 } else if (rs != 0 && rt == 0) {
2854 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2855 } else {
2856 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2857 }
6af0bf9c
FB
2858 break;
2859 case OPC_XOR:
460f00c4
AJ
2860 if (likely(rs != 0 && rt != 0)) {
2861 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2862 } else if (rs == 0 && rt != 0) {
2863 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2864 } else if (rs != 0 && rt == 0) {
2865 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2866 } else {
2867 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2868 }
6af0bf9c 2869 break;
460f00c4 2870 }
460f00c4
AJ
2871}
2872
2873/* Set on lower than */
d75c135e 2874static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2875 int rd, int rs, int rt)
460f00c4 2876{
460f00c4
AJ
2877 TCGv t0, t1;
2878
2879 if (rd == 0) {
2880 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2881 return;
2882 }
2883
2884 t0 = tcg_temp_new();
2885 t1 = tcg_temp_new();
2886 gen_load_gpr(t0, rs);
2887 gen_load_gpr(t1, rt);
2888 switch (opc) {
2889 case OPC_SLT:
e68dd28f 2890 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 2891 break;
460f00c4 2892 case OPC_SLTU:
e68dd28f 2893 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2894 break;
2895 }
460f00c4
AJ
2896 tcg_temp_free(t0);
2897 tcg_temp_free(t1);
2898}
20c4c97c 2899
460f00c4 2900/* Shifts */
d75c135e
AJ
2901static void gen_shift(DisasContext *ctx, uint32_t opc,
2902 int rd, int rs, int rt)
460f00c4 2903{
460f00c4 2904 TCGv t0, t1;
20c4c97c 2905
460f00c4 2906 if (rd == 0) {
7480515f
AM
2907 /*
2908 * If no destination, treat it as a NOP.
2909 * For add & sub, we must generate the overflow exception when needed.
2910 */
460f00c4
AJ
2911 return;
2912 }
2913
2914 t0 = tcg_temp_new();
2915 t1 = tcg_temp_new();
2916 gen_load_gpr(t0, rs);
2917 gen_load_gpr(t1, rt);
2918 switch (opc) {
6af0bf9c 2919 case OPC_SLLV:
78723684
TS
2920 tcg_gen_andi_tl(t0, t0, 0x1f);
2921 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2922 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2923 break;
2924 case OPC_SRAV:
78723684 2925 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2926 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2927 break;
2928 case OPC_SRLV:
ea63e2c3
NF
2929 tcg_gen_ext32u_tl(t1, t1);
2930 tcg_gen_andi_tl(t0, t0, 0x1f);
2931 tcg_gen_shr_tl(t0, t1, t0);
2932 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
2933 break;
2934 case OPC_ROTRV:
2935 {
2936 TCGv_i32 t2 = tcg_temp_new_i32();
2937 TCGv_i32 t3 = tcg_temp_new_i32();
2938
2939 tcg_gen_trunc_tl_i32(t2, t0);
2940 tcg_gen_trunc_tl_i32(t3, t1);
2941 tcg_gen_andi_i32(t2, t2, 0x1f);
2942 tcg_gen_rotr_i32(t2, t3, t2);
2943 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2944 tcg_temp_free_i32(t2);
2945 tcg_temp_free_i32(t3);
5a63bcb2 2946 }
7a387fff 2947 break;
d26bc211 2948#if defined(TARGET_MIPS64)
7a387fff 2949 case OPC_DSLLV:
78723684 2950 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2951 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2952 break;
2953 case OPC_DSRAV:
78723684 2954 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2955 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2956 break;
2957 case OPC_DSRLV:
ea63e2c3
NF
2958 tcg_gen_andi_tl(t0, t0, 0x3f);
2959 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
2960 break;
2961 case OPC_DROTRV:
2962 tcg_gen_andi_tl(t0, t0, 0x3f);
2963 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 2964 break;
7a387fff 2965#endif
6af0bf9c 2966 }
78723684
TS
2967 tcg_temp_free(t0);
2968 tcg_temp_free(t1);
6af0bf9c
FB
2969}
2970
2971/* Arithmetic on HI/LO registers */
26135ead 2972static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2973{
86efbfb6 2974 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2975 /* Treat as NOP. */
a1f6684d 2976 return;
6af0bf9c 2977 }
4133498f 2978
4133498f 2979 if (acc != 0) {
86efbfb6 2980 check_dsp(ctx);
4133498f
JL
2981 }
2982
6af0bf9c
FB
2983 switch (opc) {
2984 case OPC_MFHI:
4133498f
JL
2985#if defined(TARGET_MIPS64)
2986 if (acc != 0) {
2987 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2988 } else
2989#endif
2990 {
2991 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2992 }
6af0bf9c
FB
2993 break;
2994 case OPC_MFLO:
4133498f
JL
2995#if defined(TARGET_MIPS64)
2996 if (acc != 0) {
2997 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2998 } else
2999#endif
3000 {
3001 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3002 }
6af0bf9c
FB
3003 break;
3004 case OPC_MTHI:
4133498f
JL
3005 if (reg != 0) {
3006#if defined(TARGET_MIPS64)
3007 if (acc != 0) {
3008 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3009 } else
3010#endif
3011 {
3012 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3013 }
3014 } else {
3015 tcg_gen_movi_tl(cpu_HI[acc], 0);
3016 }
6af0bf9c
FB
3017 break;
3018 case OPC_MTLO:
4133498f
JL
3019 if (reg != 0) {
3020#if defined(TARGET_MIPS64)
3021 if (acc != 0) {
3022 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3023 } else
3024#endif
3025 {
3026 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3027 }
3028 } else {
3029 tcg_gen_movi_tl(cpu_LO[acc], 0);
3030 }
6af0bf9c 3031 break;
6af0bf9c 3032 }
6af0bf9c
FB
3033}
3034
d4ea6acd 3035static inline void gen_r6_ld(target_long addr, int reg, int memidx,
14776ab5 3036 MemOp memop)
d4ea6acd
LA
3037{
3038 TCGv t0 = tcg_const_tl(addr);
3039 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3040 gen_store_gpr(t0, reg);
3041 tcg_temp_free(t0);
3042}
3043
ab39ee45
YK
3044static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3045 int rs)
d4ea6acd
LA
3046{
3047 target_long offset;
3048 target_long addr;
3049
ab39ee45 3050 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3051 case OPC_ADDIUPC:
3052 if (rs != 0) {
3053 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3054 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3055 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3056 }
3057 break;
3058 case R6_OPC_LWPC:
3059 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3060 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3061 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3062 break;
3063#if defined(TARGET_MIPS64)
3064 case OPC_LWUPC:
3065 check_mips_64(ctx);
3066 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3067 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3068 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3069 break;
3070#endif
3071 default:
ab39ee45 3072 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3073 case OPC_AUIPC:
3074 if (rs != 0) {
ab39ee45
YK
3075 offset = sextract32(ctx->opcode, 0, 16) << 16;
3076 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3077 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3078 }
3079 break;
3080 case OPC_ALUIPC:
3081 if (rs != 0) {
ab39ee45
YK
3082 offset = sextract32(ctx->opcode, 0, 16) << 16;
3083 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3084 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3085 }
3086 break;
3087#if defined(TARGET_MIPS64)
3088 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3089 case R6_OPC_LDPC + (1 << 16):
3090 case R6_OPC_LDPC + (2 << 16):
3091 case R6_OPC_LDPC + (3 << 16):
3092 check_mips_64(ctx);
3093 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3094 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3095 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3096 break;
3097#endif
3098 default:
3099 MIPS_INVAL("OPC_PCREL");
3a4ef3b7 3100 gen_reserved_instruction(ctx);
d4ea6acd
LA
3101 break;
3102 }
3103 break;
3104 }
3105}
3106
b42ee5e1
LA
3107static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3108{
b42ee5e1
LA
3109 TCGv t0, t1;
3110
3111 if (rd == 0) {
3112 /* Treat as NOP. */
b42ee5e1
LA
3113 return;
3114 }
3115
3116 t0 = tcg_temp_new();
3117 t1 = tcg_temp_new();
3118
3119 gen_load_gpr(t0, rs);
3120 gen_load_gpr(t1, rt);
3121
3122 switch (opc) {
3123 case R6_OPC_DIV:
3124 {
3125 TCGv t2 = tcg_temp_new();
3126 TCGv t3 = tcg_temp_new();
3127 tcg_gen_ext32s_tl(t0, t0);
3128 tcg_gen_ext32s_tl(t1, t1);
3129 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3130 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3131 tcg_gen_and_tl(t2, t2, t3);
3132 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3133 tcg_gen_or_tl(t2, t2, t3);
3134 tcg_gen_movi_tl(t3, 0);
3135 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3136 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3137 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3138 tcg_temp_free(t3);
3139 tcg_temp_free(t2);
3140 }
b42ee5e1
LA
3141 break;
3142 case R6_OPC_MOD:
3143 {
3144 TCGv t2 = tcg_temp_new();
3145 TCGv t3 = tcg_temp_new();
3146 tcg_gen_ext32s_tl(t0, t0);
3147 tcg_gen_ext32s_tl(t1, t1);
3148 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3149 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3150 tcg_gen_and_tl(t2, t2, t3);
3151 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3152 tcg_gen_or_tl(t2, t2, t3);
3153 tcg_gen_movi_tl(t3, 0);
3154 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3155 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3156 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3157 tcg_temp_free(t3);
3158 tcg_temp_free(t2);
3159 }
b42ee5e1
LA
3160 break;
3161 case R6_OPC_DIVU:
3162 {
3163 TCGv t2 = tcg_const_tl(0);
3164 TCGv t3 = tcg_const_tl(1);
3165 tcg_gen_ext32u_tl(t0, t0);
3166 tcg_gen_ext32u_tl(t1, t1);
3167 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3168 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3169 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3170 tcg_temp_free(t3);
3171 tcg_temp_free(t2);
3172 }
b42ee5e1
LA
3173 break;
3174 case R6_OPC_MODU:
3175 {
3176 TCGv t2 = tcg_const_tl(0);
3177 TCGv t3 = tcg_const_tl(1);
3178 tcg_gen_ext32u_tl(t0, t0);
3179 tcg_gen_ext32u_tl(t1, t1);
3180 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3181 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3182 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3183 tcg_temp_free(t3);
3184 tcg_temp_free(t2);
3185 }
b42ee5e1
LA
3186 break;
3187 case R6_OPC_MUL:
3188 {
3189 TCGv_i32 t2 = tcg_temp_new_i32();
3190 TCGv_i32 t3 = tcg_temp_new_i32();
3191 tcg_gen_trunc_tl_i32(t2, t0);
3192 tcg_gen_trunc_tl_i32(t3, t1);
3193 tcg_gen_mul_i32(t2, t2, t3);
3194 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3195 tcg_temp_free_i32(t2);
3196 tcg_temp_free_i32(t3);
3197 }
b42ee5e1
LA
3198 break;
3199 case R6_OPC_MUH:
3200 {
3201 TCGv_i32 t2 = tcg_temp_new_i32();
3202 TCGv_i32 t3 = tcg_temp_new_i32();
3203 tcg_gen_trunc_tl_i32(t2, t0);
3204 tcg_gen_trunc_tl_i32(t3, t1);
3205 tcg_gen_muls2_i32(t2, t3, t2, t3);
3206 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3207 tcg_temp_free_i32(t2);
3208 tcg_temp_free_i32(t3);
3209 }
b42ee5e1
LA
3210 break;
3211 case R6_OPC_MULU:
3212 {
3213 TCGv_i32 t2 = tcg_temp_new_i32();
3214 TCGv_i32 t3 = tcg_temp_new_i32();
3215 tcg_gen_trunc_tl_i32(t2, t0);
3216 tcg_gen_trunc_tl_i32(t3, t1);
3217 tcg_gen_mul_i32(t2, t2, t3);
3218 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3219 tcg_temp_free_i32(t2);
3220 tcg_temp_free_i32(t3);
3221 }
b42ee5e1
LA
3222 break;
3223 case R6_OPC_MUHU:
3224 {
3225 TCGv_i32 t2 = tcg_temp_new_i32();
3226 TCGv_i32 t3 = tcg_temp_new_i32();
3227 tcg_gen_trunc_tl_i32(t2, t0);
3228 tcg_gen_trunc_tl_i32(t3, t1);
3229 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3230 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3231 tcg_temp_free_i32(t2);
3232 tcg_temp_free_i32(t3);
3233 }
b42ee5e1
LA
3234 break;
3235#if defined(TARGET_MIPS64)
3236 case R6_OPC_DDIV:
3237 {
3238 TCGv t2 = tcg_temp_new();
3239 TCGv t3 = tcg_temp_new();
3240 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3241 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3242 tcg_gen_and_tl(t2, t2, t3);
3243 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3244 tcg_gen_or_tl(t2, t2, t3);
3245 tcg_gen_movi_tl(t3, 0);
3246 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3247 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3248 tcg_temp_free(t3);
3249 tcg_temp_free(t2);
3250 }
b42ee5e1
LA
3251 break;
3252 case R6_OPC_DMOD:
3253 {
3254 TCGv t2 = tcg_temp_new();
3255 TCGv t3 = tcg_temp_new();
3256 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3257 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3258 tcg_gen_and_tl(t2, t2, t3);
3259 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3260 tcg_gen_or_tl(t2, t2, t3);
3261 tcg_gen_movi_tl(t3, 0);
3262 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3263 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3264 tcg_temp_free(t3);
3265 tcg_temp_free(t2);
3266 }
b42ee5e1
LA
3267 break;
3268 case R6_OPC_DDIVU:
3269 {
3270 TCGv t2 = tcg_const_tl(0);
3271 TCGv t3 = tcg_const_tl(1);
3272 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3273 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3274 tcg_temp_free(t3);
3275 tcg_temp_free(t2);
3276 }
b42ee5e1
LA
3277 break;
3278 case R6_OPC_DMODU:
3279 {
3280 TCGv t2 = tcg_const_tl(0);
3281 TCGv t3 = tcg_const_tl(1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3284 tcg_temp_free(t3);
3285 tcg_temp_free(t2);
3286 }
b42ee5e1
LA
3287 break;
3288 case R6_OPC_DMUL:
3289 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3290 break;
3291 case R6_OPC_DMUH:
3292 {
3293 TCGv t2 = tcg_temp_new();
3294 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3295 tcg_temp_free(t2);
3296 }
b42ee5e1
LA
3297 break;
3298 case R6_OPC_DMULU:
3299 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3300 break;
3301 case R6_OPC_DMUHU:
3302 {
3303 TCGv t2 = tcg_temp_new();
3304 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3305 tcg_temp_free(t2);
3306 }
b42ee5e1
LA
3307 break;
3308#endif
3309 default:
9d68ac14 3310 MIPS_INVAL("r6 mul/div");
3a4ef3b7 3311 gen_reserved_instruction(ctx);
b42ee5e1
LA
3312 goto out;
3313 }
b42ee5e1
LA
3314 out:
3315 tcg_temp_free(t0);
3316 tcg_temp_free(t1);
3317}
3318
37b9aae2 3319#if defined(TARGET_MIPS64)
c42171c3
FN
3320static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3321{
3322 TCGv t0, t1;
3323
3324 t0 = tcg_temp_new();
3325 t1 = tcg_temp_new();
3326
3327 gen_load_gpr(t0, rs);
3328 gen_load_gpr(t1, rt);
3329
3330 switch (opc) {
baa609db 3331 case MMI_OPC_DIV1:
c42171c3
FN
3332 {
3333 TCGv t2 = tcg_temp_new();
3334 TCGv t3 = tcg_temp_new();
3335 tcg_gen_ext32s_tl(t0, t0);
3336 tcg_gen_ext32s_tl(t1, t1);
3337 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3338 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3339 tcg_gen_and_tl(t2, t2, t3);
3340 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3341 tcg_gen_or_tl(t2, t2, t3);
3342 tcg_gen_movi_tl(t3, 0);
3343 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3344 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3345 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3346 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3347 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3348 tcg_temp_free(t3);
3349 tcg_temp_free(t2);
3350 }
3351 break;
baa609db 3352 case MMI_OPC_DIVU1:
c42171c3
FN
3353 {
3354 TCGv t2 = tcg_const_tl(0);
3355 TCGv t3 = tcg_const_tl(1);
3356 tcg_gen_ext32u_tl(t0, t0);
3357 tcg_gen_ext32u_tl(t1, t1);
3358 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3359 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3360 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3361 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3362 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3363 tcg_temp_free(t3);
3364 tcg_temp_free(t2);
3365 }
3366 break;
3367 default:
3368 MIPS_INVAL("div1 TX79");
3a4ef3b7 3369 gen_reserved_instruction(ctx);
c42171c3
FN
3370 goto out;
3371 }
3372 out:
3373 tcg_temp_free(t0);
3374 tcg_temp_free(t1);
3375}
37b9aae2 3376#endif
c42171c3 3377
26135ead
RS
3378static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3379 int acc, int rs, int rt)
6af0bf9c 3380{
d45f89f4
AJ
3381 TCGv t0, t1;
3382
51127181
AJ
3383 t0 = tcg_temp_new();
3384 t1 = tcg_temp_new();
6af0bf9c 3385
78723684
TS
3386 gen_load_gpr(t0, rs);
3387 gen_load_gpr(t1, rt);
51127181 3388
26135ead 3389 if (acc != 0) {
c42171c3 3390 check_dsp(ctx);
26135ead
RS
3391 }
3392
6af0bf9c
FB
3393 switch (opc) {
3394 case OPC_DIV:
48d38ca5 3395 {
51127181
AJ
3396 TCGv t2 = tcg_temp_new();
3397 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3398 tcg_gen_ext32s_tl(t0, t0);
3399 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3400 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3401 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3402 tcg_gen_and_tl(t2, t2, t3);
3403 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3404 tcg_gen_or_tl(t2, t2, t3);
3405 tcg_gen_movi_tl(t3, 0);
3406 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3407 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3408 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3409 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3410 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3411 tcg_temp_free(t3);
3412 tcg_temp_free(t2);
48d38ca5 3413 }
6af0bf9c
FB
3414 break;
3415 case OPC_DIVU:
48d38ca5 3416 {
51127181
AJ
3417 TCGv t2 = tcg_const_tl(0);
3418 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3419 tcg_gen_ext32u_tl(t0, t0);
3420 tcg_gen_ext32u_tl(t1, t1);
51127181 3421 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3422 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3423 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3424 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3425 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3426 tcg_temp_free(t3);
3427 tcg_temp_free(t2);
48d38ca5 3428 }
6af0bf9c
FB
3429 break;
3430 case OPC_MULT:
214c465f 3431 {
ce1dd5d1
RH
3432 TCGv_i32 t2 = tcg_temp_new_i32();
3433 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3434 tcg_gen_trunc_tl_i32(t2, t0);
3435 tcg_gen_trunc_tl_i32(t3, t1);
3436 tcg_gen_muls2_i32(t2, t3, t2, t3);
3437 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3438 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3439 tcg_temp_free_i32(t2);
3440 tcg_temp_free_i32(t3);
214c465f 3441 }
6af0bf9c
FB
3442 break;
3443 case OPC_MULTU:
214c465f 3444 {
ce1dd5d1
RH
3445 TCGv_i32 t2 = tcg_temp_new_i32();
3446 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3447 tcg_gen_trunc_tl_i32(t2, t0);
3448 tcg_gen_trunc_tl_i32(t3, t1);
3449 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3450 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3451 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3452 tcg_temp_free_i32(t2);
3453 tcg_temp_free_i32(t3);
214c465f 3454 }
6af0bf9c 3455 break;
d26bc211 3456#if defined(TARGET_MIPS64)
7a387fff 3457 case OPC_DDIV:
48d38ca5 3458 {
51127181
AJ
3459 TCGv t2 = tcg_temp_new();
3460 TCGv t3 = tcg_temp_new();
3461 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3462 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3463 tcg_gen_and_tl(t2, t2, t3);
3464 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3465 tcg_gen_or_tl(t2, t2, t3);
3466 tcg_gen_movi_tl(t3, 0);
3467 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3468 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3469 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3470 tcg_temp_free(t3);
3471 tcg_temp_free(t2);
48d38ca5 3472 }
7a387fff
TS
3473 break;
3474 case OPC_DDIVU:
48d38ca5 3475 {
51127181
AJ
3476 TCGv t2 = tcg_const_tl(0);
3477 TCGv t3 = tcg_const_tl(1);
3478 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3479 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3480 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3481 tcg_temp_free(t3);
3482 tcg_temp_free(t2);
48d38ca5 3483 }
7a387fff
TS
3484 break;
3485 case OPC_DMULT:
26135ead 3486 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3487 break;
3488 case OPC_DMULTU:
26135ead 3489 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3490 break;
3491#endif
6af0bf9c 3492 case OPC_MADD:
214c465f 3493 {
d45f89f4
AJ
3494 TCGv_i64 t2 = tcg_temp_new_i64();
3495 TCGv_i64 t3 = tcg_temp_new_i64();
3496
3497 tcg_gen_ext_tl_i64(t2, t0);
3498 tcg_gen_ext_tl_i64(t3, t1);
3499 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3500 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3501 tcg_gen_add_i64(t2, t2, t3);
3502 tcg_temp_free_i64(t3);
71f303cd
RH
3503 gen_move_low32(cpu_LO[acc], t2);
3504 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3505 tcg_temp_free_i64(t2);
214c465f 3506 }
6af0bf9c
FB
3507 break;
3508 case OPC_MADDU:
4133498f 3509 {
d45f89f4
AJ
3510 TCGv_i64 t2 = tcg_temp_new_i64();
3511 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3512
78723684
TS
3513 tcg_gen_ext32u_tl(t0, t0);
3514 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3515 tcg_gen_extu_tl_i64(t2, t0);
3516 tcg_gen_extu_tl_i64(t3, t1);
3517 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3518 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3519 tcg_gen_add_i64(t2, t2, t3);
3520 tcg_temp_free_i64(t3);
71f303cd
RH
3521 gen_move_low32(cpu_LO[acc], t2);
3522 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3523 tcg_temp_free_i64(t2);
214c465f 3524 }
6af0bf9c
FB
3525 break;
3526 case OPC_MSUB:
214c465f 3527 {
d45f89f4
AJ
3528 TCGv_i64 t2 = tcg_temp_new_i64();
3529 TCGv_i64 t3 = tcg_temp_new_i64();
3530
3531 tcg_gen_ext_tl_i64(t2, t0);
3532 tcg_gen_ext_tl_i64(t3, t1);
3533 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3534 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3535 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3536 tcg_temp_free_i64(t3);
71f303cd
RH
3537 gen_move_low32(cpu_LO[acc], t2);
3538 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3539 tcg_temp_free_i64(t2);
214c465f 3540 }
6af0bf9c
FB
3541 break;
3542 case OPC_MSUBU:
214c465f 3543 {
d45f89f4
AJ
3544 TCGv_i64 t2 = tcg_temp_new_i64();
3545 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3546
78723684
TS
3547 tcg_gen_ext32u_tl(t0, t0);
3548 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3549 tcg_gen_extu_tl_i64(t2, t0);
3550 tcg_gen_extu_tl_i64(t3, t1);
3551 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3552 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3553 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3554 tcg_temp_free_i64(t3);
71f303cd
RH
3555 gen_move_low32(cpu_LO[acc], t2);
3556 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3557 tcg_temp_free_i64(t2);
214c465f 3558 }
6af0bf9c
FB
3559 break;
3560 default:
9d68ac14 3561 MIPS_INVAL("mul/div");
3a4ef3b7 3562 gen_reserved_instruction(ctx);
78723684 3563 goto out;
6af0bf9c 3564 }
78723684
TS
3565 out:
3566 tcg_temp_free(t0);
3567 tcg_temp_free(t1);
6af0bf9c
FB
3568}
3569
21e8e8b2 3570/*
3b948f05
PMD
3571 * These MULT[U] and MADD[U] instructions implemented in for example
3572 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
21e8e8b2
FN
3573 * architectures are special three-operand variants with the syntax
3574 *
06de726b 3575 * MULT[U][1] rd, rs, rt
21e8e8b2
FN
3576 *
3577 * such that
3578 *
3579 * (rd, LO, HI) <- rs * rt
3580 *
3b948f05
PMD
3581 * and
3582 *
a95c4c26 3583 * MADD[U][1] rd, rs, rt
3b948f05
PMD
3584 *
3585 * such that
3586 *
3587 * (rd, LO, HI) <- (LO, HI) + rs * rt
3588 *
21e8e8b2
FN
3589 * where the low-order 32-bits of the result is placed into both the
3590 * GPR rd and the special register LO. The high-order 32-bits of the
3591 * result is placed into the special register HI.
3592 *
3593 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3594 * which is the zero register that always reads as 0.
3595 */
3596static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3597 int rd, int rs, int rt)
3598{
3599 TCGv t0 = tcg_temp_new();
3600 TCGv t1 = tcg_temp_new();
3601 int acc = 0;
3602
3603 gen_load_gpr(t0, rs);
3604 gen_load_gpr(t1, rt);
3605
3606 switch (opc) {
baa609db 3607 case MMI_OPC_MULT1:
06de726b
FN
3608 acc = 1;
3609 /* Fall through */
21e8e8b2
FN
3610 case OPC_MULT:
3611 {
3612 TCGv_i32 t2 = tcg_temp_new_i32();
3613 TCGv_i32 t3 = tcg_temp_new_i32();
3614 tcg_gen_trunc_tl_i32(t2, t0);
3615 tcg_gen_trunc_tl_i32(t3, t1);
3616 tcg_gen_muls2_i32(t2, t3, t2, t3);
3617 if (rd) {
3618 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3619 }
3620 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3621 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3622 tcg_temp_free_i32(t2);
3623 tcg_temp_free_i32(t3);
3624 }
3625 break;
baa609db 3626 case MMI_OPC_MULTU1:
06de726b
FN
3627 acc = 1;
3628 /* Fall through */
21e8e8b2
FN
3629 case OPC_MULTU:
3630 {
3631 TCGv_i32 t2 = tcg_temp_new_i32();
3632 TCGv_i32 t3 = tcg_temp_new_i32();
3633 tcg_gen_trunc_tl_i32(t2, t0);
3634 tcg_gen_trunc_tl_i32(t3, t1);
3635 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3636 if (rd) {
3637 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3638 }
3639 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3640 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3641 tcg_temp_free_i32(t2);
3642 tcg_temp_free_i32(t3);
3643 }
3644 break;
a95c4c26
FN
3645 case MMI_OPC_MADD1:
3646 acc = 1;
3647 /* Fall through */
3b948f05
PMD
3648 case MMI_OPC_MADD:
3649 {
3650 TCGv_i64 t2 = tcg_temp_new_i64();
3651 TCGv_i64 t3 = tcg_temp_new_i64();
3652
3653 tcg_gen_ext_tl_i64(t2, t0);
3654 tcg_gen_ext_tl_i64(t3, t1);
3655 tcg_gen_mul_i64(t2, t2, t3);
3656 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3657 tcg_gen_add_i64(t2, t2, t3);
3658 tcg_temp_free_i64(t3);
3659 gen_move_low32(cpu_LO[acc], t2);
3660 gen_move_high32(cpu_HI[acc], t2);
3661 if (rd) {
3662 gen_move_low32(cpu_gpr[rd], t2);
3663 }
3664 tcg_temp_free_i64(t2);
3665 }
3666 break;
a95c4c26
FN
3667 case MMI_OPC_MADDU1:
3668 acc = 1;
3669 /* Fall through */
3b948f05
PMD
3670 case MMI_OPC_MADDU:
3671 {
3672 TCGv_i64 t2 = tcg_temp_new_i64();
3673 TCGv_i64 t3 = tcg_temp_new_i64();
3674
3675 tcg_gen_ext32u_tl(t0, t0);
3676 tcg_gen_ext32u_tl(t1, t1);
3677 tcg_gen_extu_tl_i64(t2, t0);
3678 tcg_gen_extu_tl_i64(t3, t1);
3679 tcg_gen_mul_i64(t2, t2, t3);
3680 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3681 tcg_gen_add_i64(t2, t2, t3);
3682 tcg_temp_free_i64(t3);
3683 gen_move_low32(cpu_LO[acc], t2);
3684 gen_move_high32(cpu_HI[acc], t2);
3685 if (rd) {
3686 gen_move_low32(cpu_gpr[rd], t2);
3687 }
3688 tcg_temp_free_i64(t2);
3689 }
3690 break;
21e8e8b2 3691 default:
3b948f05 3692 MIPS_INVAL("mul/madd TXx9");
3a4ef3b7 3693 gen_reserved_instruction(ctx);
21e8e8b2
FN
3694 goto out;
3695 }
3696
3697 out:
3698 tcg_temp_free(t0);
3699 tcg_temp_free(t1);
3700}
3701
235785e8
AM
3702static void gen_cl(DisasContext *ctx, uint32_t opc,
3703 int rd, int rs)
6af0bf9c 3704{
20e1fb52 3705 TCGv t0;
6c5c1e20 3706
6af0bf9c 3707 if (rd == 0) {
ead9360e 3708 /* Treat as NOP. */
20e1fb52 3709 return;
6af0bf9c 3710 }
1a0196c5 3711 t0 = cpu_gpr[rd];
6c5c1e20 3712 gen_load_gpr(t0, rs);
1a0196c5 3713
6af0bf9c
FB
3714 switch (opc) {
3715 case OPC_CLO:
4267d3e6 3716 case R6_OPC_CLO:
1a0196c5
RH
3717#if defined(TARGET_MIPS64)
3718 case OPC_DCLO:
3719 case R6_OPC_DCLO:
3720#endif
3721 tcg_gen_not_tl(t0, t0);
6af0bf9c 3722 break;
1a0196c5
RH
3723 }
3724
3725 switch (opc) {
3726 case OPC_CLO:
3727 case R6_OPC_CLO:
6af0bf9c 3728 case OPC_CLZ:
4267d3e6 3729 case R6_OPC_CLZ:
1a0196c5
RH
3730 tcg_gen_ext32u_tl(t0, t0);
3731 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3732 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3733 break;
d26bc211 3734#if defined(TARGET_MIPS64)
7a387fff 3735 case OPC_DCLO:
4267d3e6 3736 case R6_OPC_DCLO:
7a387fff 3737 case OPC_DCLZ:
4267d3e6 3738 case R6_OPC_DCLZ:
1a0196c5 3739 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3740 break;
3741#endif
6af0bf9c 3742 }
6af0bf9c
FB
3743}
3744
161f85e6 3745/* Godson integer instructions */
bd277fa1
RH
3746static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3747 int rd, int rs, int rt)
161f85e6 3748{
161f85e6
AJ
3749 TCGv t0, t1;
3750
3751 if (rd == 0) {
3752 /* Treat as NOP. */
161f85e6
AJ
3753 return;
3754 }
3755
3756 switch (opc) {
3757 case OPC_MULT_G_2E:
3758 case OPC_MULT_G_2F:
3759 case OPC_MULTU_G_2E:
3760 case OPC_MULTU_G_2F:
3761#if defined(TARGET_MIPS64)
3762 case OPC_DMULT_G_2E:
3763 case OPC_DMULT_G_2F:
3764 case OPC_DMULTU_G_2E:
3765 case OPC_DMULTU_G_2F:
3766#endif
3767 t0 = tcg_temp_new();
3768 t1 = tcg_temp_new();
3769 break;
3770 default:
3771 t0 = tcg_temp_local_new();
3772 t1 = tcg_temp_local_new();
3773 break;
3774 }
3775
3776 gen_load_gpr(t0, rs);
3777 gen_load_gpr(t1, rt);
3778
3779 switch (opc) {
3780 case OPC_MULT_G_2E:
3781 case OPC_MULT_G_2F:
3782 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3783 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3784 break;
3785 case OPC_MULTU_G_2E:
3786 case OPC_MULTU_G_2F:
3787 tcg_gen_ext32u_tl(t0, t0);
3788 tcg_gen_ext32u_tl(t1, t1);
3789 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3790 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3791 break;
3792 case OPC_DIV_G_2E:
3793 case OPC_DIV_G_2F:
3794 {
42a268c2
RH
3795 TCGLabel *l1 = gen_new_label();
3796 TCGLabel *l2 = gen_new_label();
3797 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3798 tcg_gen_ext32s_tl(t0, t0);
3799 tcg_gen_ext32s_tl(t1, t1);
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3801 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3802 tcg_gen_br(l3);
3803 gen_set_label(l1);
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3805 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3806 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3807 tcg_gen_br(l3);
3808 gen_set_label(l2);
3809 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3810 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3811 gen_set_label(l3);
3812 }
161f85e6
AJ
3813 break;
3814 case OPC_DIVU_G_2E:
3815 case OPC_DIVU_G_2F:
3816 {
42a268c2
RH
3817 TCGLabel *l1 = gen_new_label();
3818 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3819 tcg_gen_ext32u_tl(t0, t0);
3820 tcg_gen_ext32u_tl(t1, t1);
3821 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3822 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3823 tcg_gen_br(l2);
3824 gen_set_label(l1);
3825 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3826 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3827 gen_set_label(l2);
3828 }
161f85e6
AJ
3829 break;
3830 case OPC_MOD_G_2E:
3831 case OPC_MOD_G_2F:
3832 {
42a268c2
RH
3833 TCGLabel *l1 = gen_new_label();
3834 TCGLabel *l2 = gen_new_label();
3835 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3836 tcg_gen_ext32u_tl(t0, t0);
3837 tcg_gen_ext32u_tl(t1, t1);
3838 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3839 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3840 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3841 gen_set_label(l1);
3842 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3843 tcg_gen_br(l3);
3844 gen_set_label(l2);
3845 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3846 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3847 gen_set_label(l3);
3848 }
161f85e6
AJ
3849 break;
3850 case OPC_MODU_G_2E:
3851 case OPC_MODU_G_2F:
3852 {
42a268c2
RH
3853 TCGLabel *l1 = gen_new_label();
3854 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3855 tcg_gen_ext32u_tl(t0, t0);
3856 tcg_gen_ext32u_tl(t1, t1);
3857 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3858 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3859 tcg_gen_br(l2);
3860 gen_set_label(l1);
3861 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3862 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3863 gen_set_label(l2);
3864 }
161f85e6
AJ
3865 break;
3866#if defined(TARGET_MIPS64)
3867 case OPC_DMULT_G_2E:
3868 case OPC_DMULT_G_2F:
3869 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3870 break;
3871 case OPC_DMULTU_G_2E:
3872 case OPC_DMULTU_G_2F:
3873 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3874 break;
3875 case OPC_DDIV_G_2E:
3876 case OPC_DDIV_G_2F:
3877 {
42a268c2
RH
3878 TCGLabel *l1 = gen_new_label();
3879 TCGLabel *l2 = gen_new_label();
3880 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3881 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3882 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3883 tcg_gen_br(l3);
3884 gen_set_label(l1);
3885 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3886 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3887 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3888 tcg_gen_br(l3);
3889 gen_set_label(l2);
3890 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3891 gen_set_label(l3);
3892 }
161f85e6
AJ
3893 break;
3894 case OPC_DDIVU_G_2E:
3895 case OPC_DDIVU_G_2F:
3896 {
42a268c2
RH
3897 TCGLabel *l1 = gen_new_label();
3898 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3899 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3901 tcg_gen_br(l2);
3902 gen_set_label(l1);
3903 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3904 gen_set_label(l2);
3905 }
161f85e6
AJ
3906 break;
3907 case OPC_DMOD_G_2E:
3908 case OPC_DMOD_G_2F:
3909 {
42a268c2
RH
3910 TCGLabel *l1 = gen_new_label();
3911 TCGLabel *l2 = gen_new_label();
3912 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3913 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3915 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3916 gen_set_label(l1);
3917 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3918 tcg_gen_br(l3);
3919 gen_set_label(l2);
3920 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3921 gen_set_label(l3);
3922 }
161f85e6
AJ
3923 break;
3924 case OPC_DMODU_G_2E:
3925 case OPC_DMODU_G_2F:
3926 {
42a268c2
RH
3927 TCGLabel *l1 = gen_new_label();
3928 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3929 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3930 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3931 tcg_gen_br(l2);
3932 gen_set_label(l1);
3933 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3934 gen_set_label(l2);
3935 }
161f85e6
AJ
3936 break;
3937#endif
3938 }
3939
161f85e6
AJ
3940 tcg_temp_free(t0);
3941 tcg_temp_free(t1);
3942}
3943
bd277fa1
RH
3944/* Loongson multimedia instructions */
3945static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3946{
bd277fa1
RH
3947 uint32_t opc, shift_max;
3948 TCGv_i64 t0, t1;
84878f4c 3949 TCGCond cond;
bd277fa1 3950
8e2d5831 3951 opc = MASK_LMMI(ctx->opcode);
bd277fa1
RH
3952 switch (opc) {
3953 case OPC_ADD_CP2:
3954 case OPC_SUB_CP2:
3955 case OPC_DADD_CP2:
3956 case OPC_DSUB_CP2:
3957 t0 = tcg_temp_local_new_i64();
3958 t1 = tcg_temp_local_new_i64();
3959 break;
3960 default:
3961 t0 = tcg_temp_new_i64();
3962 t1 = tcg_temp_new_i64();
3963 break;
3964 }
3965
b5a587b6 3966 check_cp1_enabled(ctx);
bd277fa1
RH
3967 gen_load_fpr64(ctx, t0, rs);
3968 gen_load_fpr64(ctx, t1, rt);
3969
bd277fa1 3970 switch (opc) {
b1cf82f0
AM
3971 case OPC_PADDSH:
3972 gen_helper_paddsh(t0, t0, t1);
3973 break;
3974 case OPC_PADDUSH:
3975 gen_helper_paddush(t0, t0, t1);
3976 break;
3977 case OPC_PADDH:
3978 gen_helper_paddh(t0, t0, t1);
3979 break;
3980 case OPC_PADDW:
3981 gen_helper_paddw(t0, t0, t1);
3982 break;
3983 case OPC_PADDSB:
3984 gen_helper_paddsb(t0, t0, t1);
3985 break;
3986 case OPC_PADDUSB:
3987 gen_helper_paddusb(t0, t0, t1);
3988 break;
3989 case OPC_PADDB:
3990 gen_helper_paddb(t0, t0, t1);
3991 break;
3992
3993 case OPC_PSUBSH:
3994 gen_helper_psubsh(t0, t0, t1);
3995 break;
3996 case OPC_PSUBUSH:
3997 gen_helper_psubush(t0, t0, t1);
3998 break;
3999 case OPC_PSUBH:
4000 gen_helper_psubh(t0, t0, t1);
4001 break;
4002 case OPC_PSUBW:
4003 gen_helper_psubw(t0, t0, t1);
4004 break;
4005 case OPC_PSUBSB:
4006 gen_helper_psubsb(t0, t0, t1);
4007 break;
4008 case OPC_PSUBUSB:
4009 gen_helper_psubusb(t0, t0, t1);
4010 break;
4011 case OPC_PSUBB:
4012 gen_helper_psubb(t0, t0, t1);
4013 break;
4014
4015 case OPC_PSHUFH:
4016 gen_helper_pshufh(t0, t0, t1);
4017 break;
4018 case OPC_PACKSSWH:
4019 gen_helper_packsswh(t0, t0, t1);
4020 break;
4021 case OPC_PACKSSHB:
4022 gen_helper_packsshb(t0, t0, t1);
4023 break;
4024 case OPC_PACKUSHB:
4025 gen_helper_packushb(t0, t0, t1);
4026 break;
4027
4028 case OPC_PUNPCKLHW:
4029 gen_helper_punpcklhw(t0, t0, t1);
4030 break;
4031 case OPC_PUNPCKHHW:
4032 gen_helper_punpckhhw(t0, t0, t1);
4033 break;
4034 case OPC_PUNPCKLBH:
4035 gen_helper_punpcklbh(t0, t0, t1);
4036 break;
4037 case OPC_PUNPCKHBH:
4038 gen_helper_punpckhbh(t0, t0, t1);
4039 break;
4040 case OPC_PUNPCKLWD:
4041 gen_helper_punpcklwd(t0, t0, t1);
4042 break;
4043 case OPC_PUNPCKHWD:
4044 gen_helper_punpckhwd(t0, t0, t1);
4045 break;
4046
4047 case OPC_PAVGH:
4048 gen_helper_pavgh(t0, t0, t1);
4049 break;
4050 case OPC_PAVGB:
4051 gen_helper_pavgb(t0, t0, t1);
4052 break;
4053 case OPC_PMAXSH:
4054 gen_helper_pmaxsh(t0, t0, t1);
4055 break;
4056 case OPC_PMINSH:
4057 gen_helper_pminsh(t0, t0, t1);
4058 break;
4059 case OPC_PMAXUB:
4060 gen_helper_pmaxub(t0, t0, t1);
4061 break;
4062 case OPC_PMINUB:
4063 gen_helper_pminub(t0, t0, t1);
4064 break;
4065
4066 case OPC_PCMPEQW:
4067 gen_helper_pcmpeqw(t0, t0, t1);
4068 break;
4069 case OPC_PCMPGTW:
4070 gen_helper_pcmpgtw(t0, t0, t1);
4071 break;
4072 case OPC_PCMPEQH:
4073 gen_helper_pcmpeqh(t0, t0, t1);
4074 break;
4075 case OPC_PCMPGTH:
4076 gen_helper_pcmpgth(t0, t0, t1);
4077 break;
4078 case OPC_PCMPEQB:
4079 gen_helper_pcmpeqb(t0, t0, t1);
4080 break;
4081 case OPC_PCMPGTB:
4082 gen_helper_pcmpgtb(t0, t0, t1);
4083 break;
4084
4085 case OPC_PSLLW:
4086 gen_helper_psllw(t0, t0, t1);
4087 break;
4088 case OPC_PSLLH:
4089 gen_helper_psllh(t0, t0, t1);
4090 break;
4091 case OPC_PSRLW:
4092 gen_helper_psrlw(t0, t0, t1);
4093 break;
4094 case OPC_PSRLH:
4095 gen_helper_psrlh(t0, t0, t1);
4096 break;
4097 case OPC_PSRAW:
4098 gen_helper_psraw(t0, t0, t1);
4099 break;
4100 case OPC_PSRAH:
4101 gen_helper_psrah(t0, t0, t1);
4102 break;
4103
4104 case OPC_PMULLH:
4105 gen_helper_pmullh(t0, t0, t1);
4106 break;
4107 case OPC_PMULHH:
4108 gen_helper_pmulhh(t0, t0, t1);
4109 break;
4110 case OPC_PMULHUH:
4111 gen_helper_pmulhuh(t0, t0, t1);
4112 break;
4113 case OPC_PMADDHW:
4114 gen_helper_pmaddhw(t0, t0, t1);
4115 break;
4116
4117 case OPC_PASUBUB:
4118 gen_helper_pasubub(t0, t0, t1);
4119 break;
4120 case OPC_BIADD:
4121 gen_helper_biadd(t0, t0);
4122 break;
4123 case OPC_PMOVMSKB:
4124 gen_helper_pmovmskb(t0, t0);
4125 break;
4126
4127 case OPC_PADDD:
4128 tcg_gen_add_i64(t0, t0, t1);
4129 break;
4130 case OPC_PSUBD:
4131 tcg_gen_sub_i64(t0, t0, t1);
4132 break;
4133 case OPC_XOR_CP2:
4134 tcg_gen_xor_i64(t0, t0, t1);
4135 break;
4136 case OPC_NOR_CP2:
4137 tcg_gen_nor_i64(t0, t0, t1);
4138 break;
4139 case OPC_AND_CP2:
4140 tcg_gen_and_i64(t0, t0, t1);
4141 break;
4142 case OPC_OR_CP2:
4143 tcg_gen_or_i64(t0, t0, t1);
4144 break;
bd277fa1 4145
9099a36b
H
4146 case OPC_PANDN:
4147 tcg_gen_andc_i64(t0, t1, t0);
4148 break;
4149
bd277fa1
RH
4150 case OPC_PINSRH_0:
4151 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4152 break;
4153 case OPC_PINSRH_1:
4154 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4155 break;
4156 case OPC_PINSRH_2:
4157 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4158 break;
4159 case OPC_PINSRH_3:
4160 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4161 break;
4162
4163 case OPC_PEXTRH:
4164 tcg_gen_andi_i64(t1, t1, 3);
4165 tcg_gen_shli_i64(t1, t1, 4);
4166 tcg_gen_shr_i64(t0, t0, t1);
4167 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4168 break;
4169
4170 case OPC_ADDU_CP2:
4171 tcg_gen_add_i64(t0, t0, t1);
4172 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4173 break;
4174 case OPC_SUBU_CP2:
4175 tcg_gen_sub_i64(t0, t0, t1);
4176 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4177 break;
4178
4179 case OPC_SLL_CP2:
bd277fa1
RH
4180 shift_max = 32;
4181 goto do_shift;
4182 case OPC_SRL_CP2:
bd277fa1
RH
4183 shift_max = 32;
4184 goto do_shift;
4185 case OPC_SRA_CP2:
bd277fa1
RH
4186 shift_max = 32;
4187 goto do_shift;
4188 case OPC_DSLL_CP2:
bd277fa1
RH
4189 shift_max = 64;
4190 goto do_shift;
4191 case OPC_DSRL_CP2:
bd277fa1
RH
4192 shift_max = 64;
4193 goto do_shift;
4194 case OPC_DSRA_CP2:
bd277fa1
RH
4195 shift_max = 64;
4196 goto do_shift;
4197 do_shift:
4198 /* Make sure shift count isn't TCG undefined behaviour. */
4199 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4200
4201 switch (opc) {
4202 case OPC_SLL_CP2:
4203 case OPC_DSLL_CP2:
4204 tcg_gen_shl_i64(t0, t0, t1);
4205 break;
4206 case OPC_SRA_CP2:
4207 case OPC_DSRA_CP2:
7480515f
AM
4208 /*
4209 * Since SRA is UndefinedResult without sign-extended inputs,
4210 * we can treat SRA and DSRA the same.
4211 */
bd277fa1
RH
4212 tcg_gen_sar_i64(t0, t0, t1);
4213 break;
4214 case OPC_SRL_CP2:
4215 /* We want to shift in zeros for SRL; zero-extend first. */
4216 tcg_gen_ext32u_i64(t0, t0);
4217 /* FALLTHRU */
4218 case OPC_DSRL_CP2:
4219 tcg_gen_shr_i64(t0, t0, t1);
4220 break;
4221 }
4222
4223 if (shift_max == 32) {
4224 tcg_gen_ext32s_i64(t0, t0);
4225 }
4226
4227 /* Shifts larger than MAX produce zero. */
4228 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4229 tcg_gen_neg_i64(t1, t1);
4230 tcg_gen_and_i64(t0, t0, t1);
4231 break;
4232
4233 case OPC_ADD_CP2:
4234 case OPC_DADD_CP2:
4235 {
4236 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4237 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4238
4239 tcg_gen_mov_i64(t2, t0);
4240 tcg_gen_add_i64(t0, t1, t2);
4241 if (opc == OPC_ADD_CP2) {
4242 tcg_gen_ext32s_i64(t0, t0);
4243 }
4244 tcg_gen_xor_i64(t1, t1, t2);
4245 tcg_gen_xor_i64(t2, t2, t0);
4246 tcg_gen_andc_i64(t1, t2, t1);
4247 tcg_temp_free_i64(t2);
4248 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4249 generate_exception(ctx, EXCP_OVERFLOW);
4250 gen_set_label(lab);
bd277fa1
RH
4251 break;
4252 }
4253
4254 case OPC_SUB_CP2:
4255 case OPC_DSUB_CP2:
4256 {
4257 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4258 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4259
4260 tcg_gen_mov_i64(t2, t0);
4261 tcg_gen_sub_i64(t0, t1, t2);
4262 if (opc == OPC_SUB_CP2) {
4263 tcg_gen_ext32s_i64(t0, t0);
4264 }
4265 tcg_gen_xor_i64(t1, t1, t2);
4266 tcg_gen_xor_i64(t2, t2, t0);
4267 tcg_gen_and_i64(t1, t1, t2);
4268 tcg_temp_free_i64(t2);
4269 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4270 generate_exception(ctx, EXCP_OVERFLOW);
4271 gen_set_label(lab);
bd277fa1
RH
4272 break;
4273 }
4274
4275 case OPC_PMULUW:
4276 tcg_gen_ext32u_i64(t0, t0);
4277 tcg_gen_ext32u_i64(t1, t1);
4278 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4279 break;
4280
4281 case OPC_SEQU_CP2:
4282 case OPC_SEQ_CP2:
84878f4c
JY
4283 cond = TCG_COND_EQ;
4284 goto do_cc_cond;
4285 break;
bd277fa1 4286 case OPC_SLTU_CP2:
84878f4c
JY
4287 cond = TCG_COND_LTU;
4288 goto do_cc_cond;
4289 break;
bd277fa1 4290 case OPC_SLT_CP2:
84878f4c
JY
4291 cond = TCG_COND_LT;
4292 goto do_cc_cond;
4293 break;
bd277fa1 4294 case OPC_SLEU_CP2:
84878f4c
JY
4295 cond = TCG_COND_LEU;
4296 goto do_cc_cond;
4297 break;
bd277fa1 4298 case OPC_SLE_CP2:
84878f4c
JY
4299 cond = TCG_COND_LE;
4300 do_cc_cond:
4301 {
4302 int cc = (ctx->opcode >> 8) & 0x7;
4303 TCGv_i64 t64 = tcg_temp_new_i64();
4304 TCGv_i32 t32 = tcg_temp_new_i32();
4305
4306 tcg_gen_setcond_i64(cond, t64, t0, t1);
4307 tcg_gen_extrl_i64_i32(t32, t64);
4308 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4309 get_fp_bit(cc), 1);
4310
4311 tcg_temp_free_i32(t32);
4312 tcg_temp_free_i64(t64);
4313 }
4314 goto no_rd;
4315 break;
bd277fa1 4316 default:
9d68ac14 4317 MIPS_INVAL("loongson_cp2");
3a4ef3b7 4318 gen_reserved_instruction(ctx);
bd277fa1
RH
4319 return;
4320 }
4321
bd277fa1
RH
4322 gen_store_fpr64(ctx, t0, rd);
4323
84878f4c 4324no_rd:
bd277fa1
RH
4325 tcg_temp_free_i64(t0);
4326 tcg_temp_free_i64(t1);
4327}
4328
e10a0ca1
JY
4329static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4330 int rs, int rd)
4331{
fd723105
JY
4332 TCGv t0, t1, t2;
4333 TCGv_i32 fp0;
e10a0ca1 4334#if defined(TARGET_MIPS64)
e10a0ca1
JY
4335 int lsq_rt1 = ctx->opcode & 0x1f;
4336 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4337#endif
fd723105 4338 int shf_offset = sextract32(ctx->opcode, 6, 8);
e10a0ca1
JY
4339
4340 t0 = tcg_temp_new();
4341
4342 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4343#if defined(TARGET_MIPS64)
4344 case OPC_GSLQ:
4345 t1 = tcg_temp_new();
4346 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4347 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4348 ctx->default_tcg_memop_mask);
4349 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4350 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4351 ctx->default_tcg_memop_mask);
4352 gen_store_gpr(t1, rt);
4353 gen_store_gpr(t0, lsq_rt1);
4354 tcg_temp_free(t1);
4355 break;
4356 case OPC_GSLQC1:
4357 check_cp1_enabled(ctx);
4358 t1 = tcg_temp_new();
4359 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4360 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4361 ctx->default_tcg_memop_mask);
4362 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4363 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4364 ctx->default_tcg_memop_mask);
4365 gen_store_fpr64(ctx, t1, rt);
4366 gen_store_fpr64(ctx, t0, lsq_rt1);
4367 tcg_temp_free(t1);
4368 break;
4369 case OPC_GSSQ:
4370 t1 = tcg_temp_new();
4371 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4372 gen_load_gpr(t1, rt);
4373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4374 ctx->default_tcg_memop_mask);
4375 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4376 gen_load_gpr(t1, lsq_rt1);
4377 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4378 ctx->default_tcg_memop_mask);
4379 tcg_temp_free(t1);
4380 break;
4381 case OPC_GSSQC1:
4382 check_cp1_enabled(ctx);
4383 t1 = tcg_temp_new();
4384 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4385 gen_load_fpr64(ctx, t1, rt);
4386 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4387 ctx->default_tcg_memop_mask);
4388 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4389 gen_load_fpr64(ctx, t1, lsq_rt1);
4390 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4391 ctx->default_tcg_memop_mask);
4392 tcg_temp_free(t1);
4393 break;
4394#endif
fd723105
JY
4395 case OPC_GSSHFL:
4396 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4397 case OPC_GSLWLC1:
4398 check_cp1_enabled(ctx);
4399 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4400 t1 = tcg_temp_new();
4401 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4402 tcg_gen_andi_tl(t1, t0, 3);
bf78469c
PMD
4403 if (!cpu_is_bigendian(ctx)) {
4404 tcg_gen_xori_tl(t1, t1, 3);
4405 }
fd723105
JY
4406 tcg_gen_shli_tl(t1, t1, 3);
4407 tcg_gen_andi_tl(t0, t0, ~3);
4408 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4409 tcg_gen_shl_tl(t0, t0, t1);
4410 t2 = tcg_const_tl(-1);
4411 tcg_gen_shl_tl(t2, t2, t1);
4412 fp0 = tcg_temp_new_i32();
4413 gen_load_fpr32(ctx, fp0, rt);
4414 tcg_gen_ext_i32_tl(t1, fp0);
4415 tcg_gen_andc_tl(t1, t1, t2);
4416 tcg_temp_free(t2);
4417 tcg_gen_or_tl(t0, t0, t1);
4418 tcg_temp_free(t1);
4419#if defined(TARGET_MIPS64)
4420 tcg_gen_extrl_i64_i32(fp0, t0);
4421#else
4422 tcg_gen_ext32s_tl(fp0, t0);
4423#endif
4424 gen_store_fpr32(ctx, fp0, rt);
4425 tcg_temp_free_i32(fp0);
4426 break;
4427 case OPC_GSLWRC1:
4428 check_cp1_enabled(ctx);
4429 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4430 t1 = tcg_temp_new();
4431 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4432 tcg_gen_andi_tl(t1, t0, 3);
bf78469c
PMD
4433 if (cpu_is_bigendian(ctx)) {
4434 tcg_gen_xori_tl(t1, t1, 3);
4435 }
fd723105
JY
4436 tcg_gen_shli_tl(t1, t1, 3);
4437 tcg_gen_andi_tl(t0, t0, ~3);
4438 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4439 tcg_gen_shr_tl(t0, t0, t1);
4440 tcg_gen_xori_tl(t1, t1, 31);
4441 t2 = tcg_const_tl(0xfffffffeull);
4442 tcg_gen_shl_tl(t2, t2, t1);
4443 fp0 = tcg_temp_new_i32();
4444 gen_load_fpr32(ctx, fp0, rt);
4445 tcg_gen_ext_i32_tl(t1, fp0);
4446 tcg_gen_and_tl(t1, t1, t2);
4447 tcg_temp_free(t2);
4448 tcg_gen_or_tl(t0, t0, t1);
4449 tcg_temp_free(t1);
4450#if defined(TARGET_MIPS64)
4451 tcg_gen_extrl_i64_i32(fp0, t0);
4452#else
4453 tcg_gen_ext32s_tl(fp0, t0);
4454#endif
4455 gen_store_fpr32(ctx, fp0, rt);
4456 tcg_temp_free_i32(fp0);
4457 break;
4458#if defined(TARGET_MIPS64)
4459 case OPC_GSLDLC1:
4460 check_cp1_enabled(ctx);
4461 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4462 t1 = tcg_temp_new();
4463 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4464 tcg_gen_andi_tl(t1, t0, 7);
bf78469c
PMD
4465 if (!cpu_is_bigendian(ctx)) {
4466 tcg_gen_xori_tl(t1, t1, 7);
4467 }
fd723105
JY
4468 tcg_gen_shli_tl(t1, t1, 3);
4469 tcg_gen_andi_tl(t0, t0, ~7);
4470 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4471 tcg_gen_shl_tl(t0, t0, t1);
4472 t2 = tcg_const_tl(-1);
4473 tcg_gen_shl_tl(t2, t2, t1);
4474 gen_load_fpr64(ctx, t1, rt);
4475 tcg_gen_andc_tl(t1, t1, t2);
4476 tcg_temp_free(t2);
4477 tcg_gen_or_tl(t0, t0, t1);
4478 tcg_temp_free(t1);
4479 gen_store_fpr64(ctx, t0, rt);
4480 break;
4481 case OPC_GSLDRC1:
4482 check_cp1_enabled(ctx);
4483 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4484 t1 = tcg_temp_new();
4485 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4486 tcg_gen_andi_tl(t1, t0, 7);
bf78469c
PMD
4487 if (cpu_is_bigendian(ctx)) {
4488 tcg_gen_xori_tl(t1, t1, 7);
4489 }
fd723105
JY
4490 tcg_gen_shli_tl(t1, t1, 3);
4491 tcg_gen_andi_tl(t0, t0, ~7);
4492 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4493 tcg_gen_shr_tl(t0, t0, t1);
4494 tcg_gen_xori_tl(t1, t1, 63);
4495 t2 = tcg_const_tl(0xfffffffffffffffeull);
4496 tcg_gen_shl_tl(t2, t2, t1);
4497 gen_load_fpr64(ctx, t1, rt);
4498 tcg_gen_and_tl(t1, t1, t2);
4499 tcg_temp_free(t2);
4500 tcg_gen_or_tl(t0, t0, t1);
4501 tcg_temp_free(t1);
4502 gen_store_fpr64(ctx, t0, rt);
4503 break;
4504#endif
4505 default:
4506 MIPS_INVAL("loongson_gsshfl");
3a4ef3b7 4507 gen_reserved_instruction(ctx);
fd723105
JY
4508 break;
4509 }
4510 break;
4511 case OPC_GSSHFS:
4512 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4513 case OPC_GSSWLC1:
4514 check_cp1_enabled(ctx);
4515 t1 = tcg_temp_new();
4516 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4517 fp0 = tcg_temp_new_i32();
4518 gen_load_fpr32(ctx, fp0, rt);
4519 tcg_gen_ext_i32_tl(t1, fp0);
4520 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4521 tcg_temp_free_i32(fp0);
4522 tcg_temp_free(t1);
4523 break;
4524 case OPC_GSSWRC1:
4525 check_cp1_enabled(ctx);
4526 t1 = tcg_temp_new();
4527 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4528 fp0 = tcg_temp_new_i32();
4529 gen_load_fpr32(ctx, fp0, rt);
4530 tcg_gen_ext_i32_tl(t1, fp0);
4531 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4532 tcg_temp_free_i32(fp0);
4533 tcg_temp_free(t1);
4534 break;
4535#if defined(TARGET_MIPS64)
4536 case OPC_GSSDLC1:
4537 check_cp1_enabled(ctx);
4538 t1 = tcg_temp_new();
4539 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4540 gen_load_fpr64(ctx, t1, rt);
4541 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4542 tcg_temp_free(t1);
4543 break;
4544 case OPC_GSSDRC1:
4545 check_cp1_enabled(ctx);
4546 t1 = tcg_temp_new();
4547 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4548 gen_load_fpr64(ctx, t1, rt);
4549 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4550 tcg_temp_free(t1);
4551 break;
4552#endif
4553 default:
4554 MIPS_INVAL("loongson_gsshfs");
3a4ef3b7 4555 gen_reserved_instruction(ctx);
fd723105
JY
4556 break;
4557 }
4558 break;
e10a0ca1
JY
4559 default:
4560 MIPS_INVAL("loongson_gslsq");
3a4ef3b7 4561 gen_reserved_instruction(ctx);
e10a0ca1
JY
4562 break;
4563 }
4564 tcg_temp_free(t0);
4565}
4566
90e22a57
JY
4567/* Loongson EXT LDC2/SDC2 */
4568static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4569 int rs, int rd)
4570{
4571 int offset = sextract32(ctx->opcode, 3, 8);
4572 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4573 TCGv t0, t1;
4574 TCGv_i32 fp0;
4575
4576 /* Pre-conditions */
4577 switch (opc) {
4578 case OPC_GSLBX:
4579 case OPC_GSLHX:
4580 case OPC_GSLWX:
4581 case OPC_GSLDX:
4582 /* prefetch, implement as NOP */
4583 if (rt == 0) {
4584 return;
4585 }
4586 break;
4587 case OPC_GSSBX:
4588 case OPC_GSSHX:
4589 case OPC_GSSWX:
4590 case OPC_GSSDX:
4591 break;
4592 case OPC_GSLWXC1:
4593#if defined(TARGET_MIPS64)
4594 case OPC_GSLDXC1:
4595#endif
4596 check_cp1_enabled(ctx);
4597 /* prefetch, implement as NOP */
4598 if (rt == 0) {
4599 return;
4600 }
4601 break;
4602 case OPC_GSSWXC1:
4603#if defined(TARGET_MIPS64)
4604 case OPC_GSSDXC1:
4605#endif
4606 check_cp1_enabled(ctx);
4607 break;
4608 default:
4609 MIPS_INVAL("loongson_lsdc2");
3a4ef3b7 4610 gen_reserved_instruction(ctx);
90e22a57
JY
4611 return;
4612 break;
4613 }
4614
4615 t0 = tcg_temp_new();
4616
4617 gen_base_offset_addr(ctx, t0, rs, offset);
4618 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4619
4620 switch (opc) {
4621 case OPC_GSLBX:
4622 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4623 gen_store_gpr(t0, rt);
4624 break;
4625 case OPC_GSLHX:
4626 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4627 ctx->default_tcg_memop_mask);
4628 gen_store_gpr(t0, rt);
4629 break;
4630 case OPC_GSLWX:
4631 gen_base_offset_addr(ctx, t0, rs, offset);
4632 if (rd) {
4633 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4634 }
4635 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4636 ctx->default_tcg_memop_mask);
4637 gen_store_gpr(t0, rt);
4638 break;
4639#if defined(TARGET_MIPS64)
4640 case OPC_GSLDX:
4641 gen_base_offset_addr(ctx, t0, rs, offset);
4642 if (rd) {
4643 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4644 }
4645 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4646 ctx->default_tcg_memop_mask);
4647 gen_store_gpr(t0, rt);
4648 break;
4649#endif
4650 case OPC_GSLWXC1:
90e22a57
JY
4651 gen_base_offset_addr(ctx, t0, rs, offset);
4652 if (rd) {
4653 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4654 }
4655 fp0 = tcg_temp_new_i32();
4656 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4657 ctx->default_tcg_memop_mask);
4658 gen_store_fpr32(ctx, fp0, rt);
4659 tcg_temp_free_i32(fp0);
4660 break;
4661#if defined(TARGET_MIPS64)
4662 case OPC_GSLDXC1:
90e22a57
JY
4663 gen_base_offset_addr(ctx, t0, rs, offset);
4664 if (rd) {
4665 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4666 }
4667 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4668 ctx->default_tcg_memop_mask);
4669 gen_store_fpr64(ctx, t0, rt);
4670 break;
4671#endif
4672 case OPC_GSSBX:
4673 t1 = tcg_temp_new();
4674 gen_load_gpr(t1, rt);
4675 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4676 tcg_temp_free(t1);
4677 break;
4678 case OPC_GSSHX:
4679 t1 = tcg_temp_new();
4680 gen_load_gpr(t1, rt);
4681 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4682 ctx->default_tcg_memop_mask);
4683 tcg_temp_free(t1);
4684 break;
4685 case OPC_GSSWX:
4686 t1 = tcg_temp_new();
4687 gen_load_gpr(t1, rt);
4688 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4689 ctx->default_tcg_memop_mask);
4690 tcg_temp_free(t1);
4691 break;
4692#if defined(TARGET_MIPS64)
4693 case OPC_GSSDX:
4694 t1 = tcg_temp_new();
4695 gen_load_gpr(t1, rt);
4696 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4697 ctx->default_tcg_memop_mask);
4698 tcg_temp_free(t1);
4699 break;
4700#endif
4701 case OPC_GSSWXC1:
4702 fp0 = tcg_temp_new_i32();
4703 gen_load_fpr32(ctx, fp0, rt);
4704 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4705 ctx->default_tcg_memop_mask);
4706 tcg_temp_free_i32(fp0);
4707 break;
4708#if defined(TARGET_MIPS64)
4709 case OPC_GSSDXC1:
4710 t1 = tcg_temp_new();
4711 gen_load_fpr64(ctx, t1, rt);
4712 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
4713 ctx->default_tcg_memop_mask);
4714 tcg_temp_free(t1);
4715 break;
4716#endif
4717 default:
4718 break;
4719 }
4720
4721 tcg_temp_free(t0);
4722}
4723
6af0bf9c 4724/* Traps */
71375b59
AM
4725static void gen_trap(DisasContext *ctx, uint32_t opc,
4726 int rs, int rt, int16_t imm)
6af0bf9c
FB
4727{
4728 int cond;
cdc0faa6 4729 TCGv t0 = tcg_temp_new();
1ba74fb8 4730 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4731
4732 cond = 0;
4733 /* Load needed operands */
4734 switch (opc) {
4735 case OPC_TEQ:
4736 case OPC_TGE:
4737 case OPC_TGEU:
4738 case OPC_TLT:
4739 case OPC_TLTU:
4740 case OPC_TNE:
4741 /* Compare two registers */
4742 if (rs != rt) {
be24bb4f
TS
4743 gen_load_gpr(t0, rs);
4744 gen_load_gpr(t1, rt);
6af0bf9c
FB
4745 cond = 1;
4746 }
179e32bb 4747 break;
6af0bf9c
FB
4748 case OPC_TEQI:
4749 case OPC_TGEI:
4750 case OPC_TGEIU:
4751 case OPC_TLTI:
4752 case OPC_TLTIU:
4753 case OPC_TNEI:
4754 /* Compare register to immediate */
4755 if (rs != 0 || imm != 0) {
be24bb4f
TS
4756 gen_load_gpr(t0, rs);
4757 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4758 cond = 1;
4759 }
4760 break;
4761 }
4762 if (cond == 0) {
4763 switch (opc) {
4764 case OPC_TEQ: /* rs == rs */
4765 case OPC_TEQI: /* r0 == 0 */
4766 case OPC_TGE: /* rs >= rs */
4767 case OPC_TGEI: /* r0 >= 0 */
4768 case OPC_TGEU: /* rs >= rs unsigned */
4769 case OPC_TGEIU: /* r0 >= 0 unsigned */
4770 /* Always trap */
9c708c7f 4771 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4772 break;
4773 case OPC_TLT: /* rs < rs */
4774 case OPC_TLTI: /* r0 < 0 */
4775 case OPC_TLTU: /* rs < rs unsigned */
4776 case OPC_TLTIU: /* r0 < 0 unsigned */
4777 case OPC_TNE: /* rs != rs */
4778 case OPC_TNEI: /* r0 != 0 */
ead9360e 4779 /* Never trap: treat as NOP. */
cdc0faa6 4780 break;
6af0bf9c
FB
4781 }
4782 } else {
42a268c2 4783 TCGLabel *l1 = gen_new_label();
cdc0faa6 4784
6af0bf9c
FB
4785 switch (opc) {
4786 case OPC_TEQ:
4787 case OPC_TEQI:
cdc0faa6 4788 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4789 break;
4790 case OPC_TGE:
4791 case OPC_TGEI:
cdc0faa6 4792 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4793 break;
4794 case OPC_TGEU:
4795 case OPC_TGEIU:
cdc0faa6 4796 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4797 break;
4798 case OPC_TLT:
4799 case OPC_TLTI:
cdc0faa6 4800 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4801 break;
4802 case OPC_TLTU:
4803 case OPC_TLTIU:
cdc0faa6 4804 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4805 break;
4806 case OPC_TNE:
4807 case OPC_TNEI:
cdc0faa6 4808 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4809 break;
6af0bf9c 4810 }
cdc0faa6 4811 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4812 gen_set_label(l1);
4813 }
be24bb4f
TS
4814 tcg_temp_free(t0);
4815 tcg_temp_free(t1);
6af0bf9c
FB
4816}
4817
97eea3c1 4818static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
90aa39a1 4819{
97eea3c1 4820 if (translator_use_goto_tb(&ctx->base, dest)) {
57fec1fe 4821 tcg_gen_goto_tb(n);
9b9e4393 4822 gen_save_pc(dest);
07ea28b4 4823 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 4824 } else {
9b9e4393 4825 gen_save_pc(dest);
eeb3bba8 4826 if (ctx->base.singlestep_enabled) {
7b270ef2 4827 save_cpu_state(ctx, 0);
9c708c7f 4828 gen_helper_raise_exception_debug(cpu_env);
34f5e75a
RH
4829 } else {
4830 tcg_gen_lookup_and_goto_ptr();
7b270ef2 4831 }
6e256c93 4832 }
c53be334
FB
4833}
4834
6af0bf9c 4835/* Branches (before delay slot) */
71375b59
AM
4836static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4837 int insn_bytes,
4838 int rs, int rt, int32_t offset,
4839 int delayslot_size)
6af0bf9c 4840{
d077b6f7 4841 target_ulong btgt = -1;
3ad4bb2d 4842 int blink = 0;
2fdbad25 4843 int bcond_compute = 0;
1ba74fb8
AJ
4844 TCGv t0 = tcg_temp_new();
4845 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4846
4847 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4848#ifdef MIPS_DEBUG_DISAS
339cd2a8 4849 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 4850 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 4851#endif
3a4ef3b7 4852 gen_reserved_instruction(ctx);
6c5c1e20 4853 goto out;
3ad4bb2d 4854 }
6af0bf9c 4855
6af0bf9c
FB
4856 /* Load needed operands */
4857 switch (opc) {
4858 case OPC_BEQ:
4859 case OPC_BEQL:
4860 case OPC_BNE:
4861 case OPC_BNEL:
4862 /* Compare two registers */
4863 if (rs != rt) {
6c5c1e20
TS
4864 gen_load_gpr(t0, rs);
4865 gen_load_gpr(t1, rt);
2fdbad25 4866 bcond_compute = 1;
6af0bf9c 4867 }
eeb3bba8 4868 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
4869 break;
4870 case OPC_BGEZ:
4871 case OPC_BGEZAL:
4872 case OPC_BGEZALL:
4873 case OPC_BGEZL:
4874 case OPC_BGTZ:
4875 case OPC_BGTZL:
4876 case OPC_BLEZ:
4877 case OPC_BLEZL:
4878 case OPC_BLTZ:
4879 case OPC_BLTZAL:
4880 case OPC_BLTZALL:
4881 case OPC_BLTZL:
4882 /* Compare to zero */
4883 if (rs != 0) {
6c5c1e20 4884 gen_load_gpr(t0, rs);
2fdbad25 4885 bcond_compute = 1;
6af0bf9c 4886 }
eeb3bba8 4887 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 4888 break;
e45a93e2
JL
4889 case OPC_BPOSGE32:
4890#if defined(TARGET_MIPS64)
4891 case OPC_BPOSGE64:
4892 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4893#else
4894 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4895#endif
4896 bcond_compute = 1;
eeb3bba8 4897 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 4898 break;
6af0bf9c
FB
4899 case OPC_J:
4900 case OPC_JAL:
364d4831 4901 case OPC_JALX:
6af0bf9c 4902 /* Jump to immediate */
eeb3bba8
EC
4903 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4904 (uint32_t)offset;
6af0bf9c
FB
4905 break;
4906 case OPC_JR:
4907 case OPC_JALR:
4908 /* Jump to register */
7a387fff 4909 if (offset != 0 && offset != 16) {
7480515f
AM
4910 /*
4911 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4912 * others are reserved.
4913 */
923617a3 4914 MIPS_INVAL("jump hint");
3a4ef3b7 4915 gen_reserved_instruction(ctx);
6c5c1e20 4916 goto out;
6af0bf9c 4917 }
d077b6f7 4918 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4919 break;
4920 default:
4921 MIPS_INVAL("branch/jump");
3a4ef3b7 4922 gen_reserved_instruction(ctx);
6c5c1e20 4923 goto out;
6af0bf9c 4924 }
2fdbad25 4925 if (bcond_compute == 0) {
6af0bf9c
FB
4926 /* No condition to be computed */
4927 switch (opc) {
4928 case OPC_BEQ: /* rx == rx */
4929 case OPC_BEQL: /* rx == rx likely */
4930 case OPC_BGEZ: /* 0 >= 0 */
4931 case OPC_BGEZL: /* 0 >= 0 likely */
4932 case OPC_BLEZ: /* 0 <= 0 */
4933 case OPC_BLEZL: /* 0 <= 0 likely */
4934 /* Always take */
4ad40f36 4935 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4936 break;
4937 case OPC_BGEZAL: /* 0 >= 0 */
4938 case OPC_BGEZALL: /* 0 >= 0 likely */
4939 /* Always take and link */
4940 blink = 31;
4ad40f36 4941 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4942 break;
4943 case OPC_BNE: /* rx != rx */
4944 case OPC_BGTZ: /* 0 > 0 */
4945 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4946 /* Treat as NOP. */
6c5c1e20 4947 goto out;
eeef26cd 4948 case OPC_BLTZAL: /* 0 < 0 */
7480515f
AM
4949 /*
4950 * Handle as an unconditional branch to get correct delay
4951 * slot checking.
4952 */
3c824109 4953 blink = 31;
eeb3bba8 4954 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 4955 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4956 break;
eeef26cd 4957 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 4958 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 4959 /* Skip the instruction in the delay slot */
eeb3bba8 4960 ctx->base.pc_next += 4;
6c5c1e20 4961 goto out;
6af0bf9c
FB
4962 case OPC_BNEL: /* rx != rx likely */
4963 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4964 case OPC_BLTZL: /* 0 < 0 likely */
4965 /* Skip the instruction in the delay slot */
eeb3bba8 4966 ctx->base.pc_next += 4;
6c5c1e20 4967 goto out;
6af0bf9c 4968 case OPC_J:
4ad40f36 4969 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4970 break;
364d4831
NF
4971 case OPC_JALX:
4972 ctx->hflags |= MIPS_HFLAG_BX;
4973 /* Fallthrough */
6af0bf9c
FB
4974 case OPC_JAL:
4975 blink = 31;
4ad40f36 4976 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4977 break;
4978 case OPC_JR:
4ad40f36 4979 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4980 break;
4981 case OPC_JALR:
4982 blink = rt;
4ad40f36 4983 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4984 break;
4985 default:
4986 MIPS_INVAL("branch/jump");
3a4ef3b7 4987 gen_reserved_instruction(ctx);
6c5c1e20 4988 goto out;
6af0bf9c
FB
4989 }
4990 } else {
4991 switch (opc) {
4992 case OPC_BEQ:
e68dd28f 4993 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4994 goto not_likely;
4995 case OPC_BEQL:
e68dd28f 4996 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4997 goto likely;
4998 case OPC_BNE:
e68dd28f 4999 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5000 goto not_likely;
5001 case OPC_BNEL:
e68dd28f 5002 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5003 goto likely;
5004 case OPC_BGEZ:
e68dd28f 5005 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5006 goto not_likely;
5007 case OPC_BGEZL:
e68dd28f 5008 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5009 goto likely;
5010 case OPC_BGEZAL:
e68dd28f 5011 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5012 blink = 31;
5013 goto not_likely;
5014 case OPC_BGEZALL:
e68dd28f 5015 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 5016 blink = 31;
6af0bf9c
FB
5017 goto likely;
5018 case OPC_BGTZ:
e68dd28f 5019 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5020 goto not_likely;
5021 case OPC_BGTZL:
e68dd28f 5022 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5023 goto likely;
5024 case OPC_BLEZ:
e68dd28f 5025 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5026 goto not_likely;
5027 case OPC_BLEZL:
e68dd28f 5028 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5029 goto likely;
5030 case OPC_BLTZ:
e68dd28f 5031 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
5032 goto not_likely;
5033 case OPC_BLTZL:
e68dd28f 5034 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5035 goto likely;
e45a93e2
JL
5036 case OPC_BPOSGE32:
5037 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
5038 goto not_likely;
5039#if defined(TARGET_MIPS64)
5040 case OPC_BPOSGE64:
5041 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
5042 goto not_likely;
5043#endif
6af0bf9c 5044 case OPC_BLTZAL:
e68dd28f 5045 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5046 blink = 31;
6af0bf9c 5047 not_likely:
4ad40f36 5048 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
5049 break;
5050 case OPC_BLTZALL:
e68dd28f 5051 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5052 blink = 31;
6af0bf9c 5053 likely:
4ad40f36 5054 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 5055 break;
c53f4a62
TS
5056 default:
5057 MIPS_INVAL("conditional branch/jump");
3a4ef3b7 5058 gen_reserved_instruction(ctx);
6c5c1e20 5059 goto out;
6af0bf9c 5060 }
6af0bf9c 5061 }
9b9e4393 5062
d077b6f7 5063 ctx->btarget = btgt;
b231c103
YK
5064
5065 switch (delayslot_size) {
5066 case 2:
5067 ctx->hflags |= MIPS_HFLAG_BDS16;
5068 break;
5069 case 4:
5070 ctx->hflags |= MIPS_HFLAG_BDS32;
5071 break;
5072 }
5073
6af0bf9c 5074 if (blink > 0) {
b231c103 5075 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
5076 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5077
eeb3bba8
EC
5078 tcg_gen_movi_tl(cpu_gpr[blink],
5079 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 5080 }
6c5c1e20
TS
5081
5082 out:
1f8929d2 5083 if (insn_bytes == 2) {
364d4831 5084 ctx->hflags |= MIPS_HFLAG_B16;
1f8929d2 5085 }
6c5c1e20
TS
5086 tcg_temp_free(t0);
5087 tcg_temp_free(t1);
6af0bf9c
FB
5088}
5089
764371d2 5090
7a387fff 5091/* special3 bitfield operations */
235785e8
AM
5092static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5093 int rs, int lsb, int msb)
7a387fff 5094{
a7812ae4
PB
5095 TCGv t0 = tcg_temp_new();
5096 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
5097
5098 gen_load_gpr(t1, rs);
7a387fff
TS
5099 switch (opc) {
5100 case OPC_EXT:
b7f26e52 5101 if (lsb + msb > 31) {
7a387fff 5102 goto fail;
b7f26e52 5103 }
505ad7c2 5104 if (msb != 31) {
6eebb7a4 5105 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 5106 } else {
7480515f
AM
5107 /*
5108 * The two checks together imply that lsb == 0,
5109 * so this is a simple sign-extension.
5110 */
6eebb7a4 5111 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 5112 }
7a387fff 5113 break;
c6d6dd7c 5114#if defined(TARGET_MIPS64)
7a387fff 5115 case OPC_DEXTU:
b7f26e52
RH
5116 lsb += 32;
5117 goto do_dext;
5118 case OPC_DEXTM:
5119 msb += 32;
5120 goto do_dext;
7a387fff 5121 case OPC_DEXT:
b7f26e52
RH
5122 do_dext:
5123 if (lsb + msb > 63) {
5124 goto fail;
5125 }
6eebb7a4 5126 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 5127 break;
c6d6dd7c 5128#endif
7a387fff 5129 case OPC_INS:
b7f26e52 5130 if (lsb > msb) {
7a387fff 5131 goto fail;
b7f26e52 5132 }
6c5c1e20 5133 gen_load_gpr(t0, rt);
e0d002f1 5134 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 5135 tcg_gen_ext32s_tl(t0, t0);
7a387fff 5136 break;
c6d6dd7c 5137#if defined(TARGET_MIPS64)
7a387fff 5138 case OPC_DINSU:
b7f26e52
RH
5139 lsb += 32;
5140 /* FALLTHRU */
5141 case OPC_DINSM:
5142 msb += 32;
5143 /* FALLTHRU */
7a387fff 5144 case OPC_DINS:
b7f26e52
RH
5145 if (lsb > msb) {
5146 goto fail;
5147 }
6c5c1e20 5148 gen_load_gpr(t0, rt);
e0d002f1 5149 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 5150 break;
c6d6dd7c 5151#endif
7a387fff
TS
5152 default:
5153fail:
5154 MIPS_INVAL("bitops");
3a4ef3b7 5155 gen_reserved_instruction(ctx);
6c5c1e20
TS
5156 tcg_temp_free(t0);
5157 tcg_temp_free(t1);
7a387fff
TS
5158 return;
5159 }
6c5c1e20
TS
5160 gen_store_gpr(t0, rt);
5161 tcg_temp_free(t0);
5162 tcg_temp_free(t1);
7a387fff
TS
5163}
5164
235785e8 5165static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
49bcf33c 5166{
3a55fa47 5167 TCGv t0;
49bcf33c 5168
3a55fa47
AJ
5169 if (rd == 0) {
5170 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
5171 return;
5172 }
5173
5174 t0 = tcg_temp_new();
5175 gen_load_gpr(t0, rt);
49bcf33c
AJ
5176 switch (op2) {
5177 case OPC_WSBH:
3a55fa47
AJ
5178 {
5179 TCGv t1 = tcg_temp_new();
06a57e5c 5180 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
5181
5182 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5183 tcg_gen_and_tl(t1, t1, t2);
5184 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5185 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5186 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 5187 tcg_temp_free(t2);
3a55fa47
AJ
5188 tcg_temp_free(t1);
5189 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5190 }
49bcf33c
AJ
5191 break;
5192 case OPC_SEB:
3a55fa47 5193 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5194 break;
5195 case OPC_SEH:
3a55fa47 5196 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
5197 break;
5198#if defined(TARGET_MIPS64)
5199 case OPC_DSBH:
3a55fa47
AJ
5200 {
5201 TCGv t1 = tcg_temp_new();
06a57e5c 5202 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
5203
5204 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
5205 tcg_gen_and_tl(t1, t1, t2);
5206 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5207 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 5208 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5209 tcg_temp_free(t2);
3a55fa47
AJ
5210 tcg_temp_free(t1);
5211 }
49bcf33c
AJ
5212 break;
5213 case OPC_DSHD:
3a55fa47
AJ
5214 {
5215 TCGv t1 = tcg_temp_new();
06a57e5c 5216 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
5217
5218 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
5219 tcg_gen_and_tl(t1, t1, t2);
5220 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 5221 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
5222 tcg_gen_or_tl(t0, t0, t1);
5223 tcg_gen_shri_tl(t1, t0, 32);
5224 tcg_gen_shli_tl(t0, t0, 32);
5225 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 5226 tcg_temp_free(t2);
3a55fa47
AJ
5227 tcg_temp_free(t1);
5228 }
49bcf33c
AJ
5229 break;
5230#endif
5231 default:
5232 MIPS_INVAL("bsfhl");
3a4ef3b7 5233 gen_reserved_instruction(ctx);
49bcf33c 5234 tcg_temp_free(t0);
49bcf33c
AJ
5235 return;
5236 }
49bcf33c 5237 tcg_temp_free(t0);
49bcf33c
AJ
5238}
5239
821f2008
JH
5240static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5241 int rt, int bits)
284b731a 5242{
1f1b4c00
YK
5243 TCGv t0;
5244 if (rd == 0) {
5245 /* Treat as NOP. */
5246 return;
5247 }
5248 t0 = tcg_temp_new();
821f2008
JH
5249 if (bits == 0 || bits == wordsz) {
5250 if (bits == 0) {
5251 gen_load_gpr(t0, rt);
5252 } else {
5253 gen_load_gpr(t0, rs);
5254 }
5255 switch (wordsz) {
5256 case 32:
51243852
MD
5257 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5258 break;
5259#if defined(TARGET_MIPS64)
821f2008 5260 case 64:
51243852
MD
5261 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5262 break;
5263#endif
5264 }
1f1b4c00
YK
5265 } else {
5266 TCGv t1 = tcg_temp_new();
821f2008 5267 gen_load_gpr(t0, rt);
1f1b4c00 5268 gen_load_gpr(t1, rs);
821f2008
JH
5269 switch (wordsz) {
5270 case 32:
1f1b4c00
YK
5271 {
5272 TCGv_i64 t2 = tcg_temp_new_i64();
5273 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 5274 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
5275 gen_move_low32(cpu_gpr[rd], t2);
5276 tcg_temp_free_i64(t2);
5277 }
5278 break;
284b731a 5279#if defined(TARGET_MIPS64)
821f2008
JH
5280 case 64:
5281 tcg_gen_shli_tl(t0, t0, bits);
5282 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
5283 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5284 break;
284b731a 5285#endif
1f1b4c00
YK
5286 }
5287 tcg_temp_free(t1);
5288 }
5289
5290 tcg_temp_free(t0);
5291}
5292
d5076631 5293void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
821f2008
JH
5294{
5295 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5296}
5297
1f1b4c00
YK
5298static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5299{
5300 TCGv t0;
5301 if (rd == 0) {
5302 /* Treat as NOP. */
5303 return;
5304 }
5305 t0 = tcg_temp_new();
5306 gen_load_gpr(t0, rt);
5307 switch (opc) {
5308 case OPC_BITSWAP:
5309 gen_helper_bitswap(cpu_gpr[rd], t0);
5310 break;
5311#if defined(TARGET_MIPS64)
5312 case OPC_DBITSWAP:
5313 gen_helper_dbitswap(cpu_gpr[rd], t0);
5314 break;
5315#endif
5316 }
5317 tcg_temp_free(t0);
284b731a
LA
5318}
5319
1f1b4c00
YK
5320#ifndef CONFIG_USER_ONLY
5321/* CP0 (MMU and control) */
5204ea79
LA
5322static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5323{
5324 TCGv_i64 t0 = tcg_temp_new_i64();
5325 TCGv_i64 t1 = tcg_temp_new_i64();
5326
5327 tcg_gen_ext_tl_i64(t0, arg);
5328 tcg_gen_ld_i64(t1, cpu_env, off);
5329#if defined(TARGET_MIPS64)
5330 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5331#else
5332 tcg_gen_concat32_i64(t1, t1, t0);
5333#endif
5334 tcg_gen_st_i64(t1, cpu_env, off);
5335 tcg_temp_free_i64(t1);
5336 tcg_temp_free_i64(t0);
5337}
5338
5339static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5340{
5341 TCGv_i64 t0 = tcg_temp_new_i64();
5342 TCGv_i64 t1 = tcg_temp_new_i64();
5343
5344 tcg_gen_ext_tl_i64(t0, arg);
5345 tcg_gen_ld_i64(t1, cpu_env, off);
5346 tcg_gen_concat32_i64(t1, t1, t0);
5347 tcg_gen_st_i64(t1, cpu_env, off);
5348 tcg_temp_free_i64(t1);
5349 tcg_temp_free_i64(t0);
5350}
5351
5352static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5353{
5354 TCGv_i64 t0 = tcg_temp_new_i64();
5355
5356 tcg_gen_ld_i64(t0, cpu_env, off);
5357#if defined(TARGET_MIPS64)
5358 tcg_gen_shri_i64(t0, t0, 30);
5359#else
5360 tcg_gen_shri_i64(t0, t0, 32);
5361#endif
5362 gen_move_low32(arg, t0);
5363 tcg_temp_free_i64(t0);
5364}
5365
5366static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5367{
5368 TCGv_i64 t0 = tcg_temp_new_i64();
5369
5370 tcg_gen_ld_i64(t0, cpu_env, off);
5371 tcg_gen_shri_i64(t0, t0, 32 + shift);
5372 gen_move_low32(arg, t0);
5373 tcg_temp_free_i64(t0);
5374}
5375
235785e8 5376static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4f57689a 5377{
d9bea114 5378 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 5379
d9bea114
AJ
5380 tcg_gen_ld_i32(t0, cpu_env, off);
5381 tcg_gen_ext_i32_tl(arg, t0);
5382 tcg_temp_free_i32(t0);
4f57689a
TS
5383}
5384
235785e8 5385static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4f57689a 5386{
d9bea114
AJ
5387 tcg_gen_ld_tl(arg, cpu_env, off);
5388 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
5389}
5390
235785e8 5391static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
f1aa6320 5392{
d9bea114 5393 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 5394
d9bea114
AJ
5395 tcg_gen_trunc_tl_i32(t0, arg);
5396 tcg_gen_st_i32(t0, cpu_env, off);
5397 tcg_temp_free_i32(t0);
f1aa6320
TS
5398}
5399
c98d3d79
YK
5400#define CP0_CHECK(c) \
5401 do { \
5402 if (!(c)) { \
5403 goto cp0_unimplemented; \
5404 } \
5405 } while (0)
5406
5204ea79
LA
5407static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5408{
294fc2ea 5409 const char *register_name = "invalid";
5204ea79 5410
5204ea79 5411 switch (reg) {
04992c8c 5412 case CP0_REGISTER_02:
5204ea79
LA
5413 switch (sel) {
5414 case 0:
59488dda 5415 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79 5416 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 5417 register_name = "EntryLo0";
5204ea79
LA
5418 break;
5419 default:
c98d3d79 5420 goto cp0_unimplemented;
5204ea79
LA
5421 }
5422 break;
04992c8c 5423 case CP0_REGISTER_03:
5204ea79 5424 switch (sel) {
acd37316 5425 case CP0_REG03__ENTRYLO1:
59488dda 5426 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79 5427 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 5428 register_name = "EntryLo1";
5204ea79
LA
5429 break;
5430 default:
c98d3d79 5431 goto cp0_unimplemented;
5204ea79
LA
5432 }
5433 break;
04992c8c 5434 case CP0_REGISTER_09:
5fb2dcd1 5435 switch (sel) {
e5a98a72 5436 case CP0_REG09__SAAR:
5fb2dcd1
YK
5437 CP0_CHECK(ctx->saar);
5438 gen_helper_mfhc0_saar(arg, cpu_env);
294fc2ea 5439 register_name = "SAAR";
5fb2dcd1
YK
5440 break;
5441 default:
5442 goto cp0_unimplemented;
5443 }
5444 break;
04992c8c 5445 case CP0_REGISTER_17:
5204ea79 5446 switch (sel) {
706ce142 5447 case CP0_REG17__LLADDR:
c7c7e1e9 5448 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5204ea79 5449 ctx->CP0_LLAddr_shift);
294fc2ea 5450 register_name = "LLAddr";
5204ea79 5451 break;
706ce142 5452 case CP0_REG17__MAAR:
f6d4dd81
YK
5453 CP0_CHECK(ctx->mrp);
5454 gen_helper_mfhc0_maar(arg, cpu_env);
294fc2ea 5455 register_name = "MAAR";
f6d4dd81 5456 break;
5204ea79 5457 default:
c98d3d79 5458 goto cp0_unimplemented;
5204ea79
LA
5459 }
5460 break;
feafe82c
YK
5461 case CP0_REGISTER_19:
5462 switch (sel) {
5463 case CP0_REG19__WATCHHI0:
5464 case CP0_REG19__WATCHHI1:
5465 case CP0_REG19__WATCHHI2:
5466 case CP0_REG19__WATCHHI3:
5467 case CP0_REG19__WATCHHI4:
5468 case CP0_REG19__WATCHHI5:
5469 case CP0_REG19__WATCHHI6:
5470 case CP0_REG19__WATCHHI7:
5471 /* upper 32 bits are only available when Config5MI != 0 */
5472 CP0_CHECK(ctx->mi);
5473 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5474 register_name = "WatchHi";
5475 break;
5476 default:
5477 goto cp0_unimplemented;
5478 }
5479 break;
04992c8c 5480 case CP0_REGISTER_28:
5204ea79
LA
5481 switch (sel) {
5482 case 0:
5483 case 2:
5484 case 4:
5485 case 6:
5486 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
294fc2ea 5487 register_name = "TagLo";
5204ea79
LA
5488 break;
5489 default:
c98d3d79 5490 goto cp0_unimplemented;
5204ea79
LA
5491 }
5492 break;
5493 default:
c98d3d79 5494 goto cp0_unimplemented;
5204ea79 5495 }
294fc2ea 5496 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5204ea79
LA
5497 return;
5498
c98d3d79 5499cp0_unimplemented:
294fc2ea
AM
5500 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5501 register_name, reg, sel);
5204ea79
LA
5502 tcg_gen_movi_tl(arg, 0);
5503}
5504
5505static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5506{
294fc2ea 5507 const char *register_name = "invalid";
5204ea79
LA
5508 uint64_t mask = ctx->PAMask >> 36;
5509
5204ea79 5510 switch (reg) {
04992c8c 5511 case CP0_REGISTER_02:
5204ea79
LA
5512 switch (sel) {
5513 case 0:
59488dda 5514 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5515 tcg_gen_andi_tl(arg, arg, mask);
5516 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 5517 register_name = "EntryLo0";
5204ea79
LA
5518 break;
5519 default:
c98d3d79 5520 goto cp0_unimplemented;
5204ea79
LA
5521 }
5522 break;
04992c8c 5523 case CP0_REGISTER_03:
5204ea79 5524 switch (sel) {
acd37316 5525 case CP0_REG03__ENTRYLO1:
59488dda 5526 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5527 tcg_gen_andi_tl(arg, arg, mask);
5528 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 5529 register_name = "EntryLo1";
5204ea79
LA
5530 break;
5531 default:
c98d3d79 5532 goto cp0_unimplemented;
5204ea79
LA
5533 }
5534 break;
04992c8c 5535 case CP0_REGISTER_09:
5fb2dcd1 5536 switch (sel) {
e5a98a72 5537 case CP0_REG09__SAAR:
5fb2dcd1
YK
5538 CP0_CHECK(ctx->saar);
5539 gen_helper_mthc0_saar(cpu_env, arg);
294fc2ea 5540 register_name = "SAAR";
5fb2dcd1
YK
5541 break;
5542 default:
5543 goto cp0_unimplemented;
5544 }
ab8c3410 5545 break;
04992c8c 5546 case CP0_REGISTER_17:
5204ea79 5547 switch (sel) {
706ce142 5548 case CP0_REG17__LLADDR:
7480515f
AM
5549 /*
5550 * LLAddr is read-only (the only exception is bit 0 if LLB is
5551 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5552 * relevant for modern MIPS cores supporting MTHC0, therefore
5553 * treating MTHC0 to LLAddr as NOP.
5554 */
294fc2ea 5555 register_name = "LLAddr";
5204ea79 5556 break;
706ce142 5557 case CP0_REG17__MAAR:
f6d4dd81
YK
5558 CP0_CHECK(ctx->mrp);
5559 gen_helper_mthc0_maar(cpu_env, arg);
294fc2ea 5560 register_name = "MAAR";
f6d4dd81 5561 break;
5204ea79 5562 default:
c98d3d79 5563 goto cp0_unimplemented;
5204ea79
LA
5564 }
5565 break;
feafe82c
YK
5566 case CP0_REGISTER_19:
5567 switch (sel) {
5568 case CP0_REG19__WATCHHI0:
5569 case CP0_REG19__WATCHHI1:
5570 case CP0_REG19__WATCHHI2:
5571 case CP0_REG19__WATCHHI3:
5572 case CP0_REG19__WATCHHI4:
5573 case CP0_REG19__WATCHHI5:
5574 case CP0_REG19__WATCHHI6:
5575 case CP0_REG19__WATCHHI7:
5576 /* upper 32 bits are only available when Config5MI != 0 */
5577 CP0_CHECK(ctx->mi);
5578 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5579 register_name = "WatchHi";
5580 break;
5581 default:
5582 goto cp0_unimplemented;
5583 }
5584 break;
04992c8c 5585 case CP0_REGISTER_28:
5204ea79
LA
5586 switch (sel) {
5587 case 0:
5588 case 2:
5589 case 4:
5590 case 6:
5591 tcg_gen_andi_tl(arg, arg, mask);
5592 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
294fc2ea 5593 register_name = "TagLo";
5204ea79
LA
5594 break;
5595 default:
c98d3d79 5596 goto cp0_unimplemented;
5204ea79
LA
5597 }
5598 break;
5599 default:
c98d3d79 5600 goto cp0_unimplemented;
5204ea79 5601 }
294fc2ea 5602 trace_mips_translate_c0("mthc0", register_name, reg, sel);
bc2eb5ea 5603 return;
5204ea79 5604
c98d3d79 5605cp0_unimplemented:
294fc2ea
AM
5606 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5607 register_name, reg, sel);
5204ea79
LA
5608}
5609
e98c0d17
LA
5610static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5611{
2e211e0a 5612 if (ctx->insn_flags & ISA_MIPS_R6) {
e98c0d17
LA
5613 tcg_gen_movi_tl(arg, 0);
5614 } else {
5615 tcg_gen_movi_tl(arg, ~0);
5616 }
5617}
5618
d75c135e 5619static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5620{
294fc2ea 5621 const char *register_name = "invalid";
873eb012 5622
1f8929d2 5623 if (sel != 0) {
bbd5e4a2 5624 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 5625 }
e189e748 5626
873eb012 5627 switch (reg) {
04992c8c 5628 case CP0_REGISTER_00:
7a387fff 5629 switch (sel) {
1b142da5 5630 case CP0_REG00__INDEX:
7db13fae 5631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
294fc2ea 5632 register_name = "Index";
7a387fff 5633 break;
1b142da5 5634 case CP0_REG00__MVPCONTROL:
f31b035a 5635 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5636 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
294fc2ea 5637 register_name = "MVPControl";
ead9360e 5638 break;
1b142da5 5639 case CP0_REG00__MVPCONF0:
f31b035a 5640 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5641 gen_helper_mfc0_mvpconf0(arg, cpu_env);
294fc2ea 5642 register_name = "MVPConf0";
ead9360e 5643 break;
1b142da5 5644 case CP0_REG00__MVPCONF1:
f31b035a 5645 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5646 gen_helper_mfc0_mvpconf1(arg, cpu_env);
294fc2ea 5647 register_name = "MVPConf1";
ead9360e 5648 break;
1b142da5 5649 case CP0_REG00__VPCONTROL:
01bc435b
YK
5650 CP0_CHECK(ctx->vp);
5651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
294fc2ea 5652 register_name = "VPControl";
01bc435b 5653 break;
7a387fff 5654 default:
f31b035a 5655 goto cp0_unimplemented;
7a387fff 5656 }
873eb012 5657 break;
04992c8c 5658 case CP0_REGISTER_01:
7a387fff 5659 switch (sel) {
30deb460 5660 case CP0_REG01__RANDOM:
2e211e0a 5661 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
895c2d04 5662 gen_helper_mfc0_random(arg, cpu_env);
294fc2ea 5663 register_name = "Random";
2423f660 5664 break;
30deb460 5665 case CP0_REG01__VPECONTROL:
f31b035a 5666 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5667 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
294fc2ea 5668 register_name = "VPEControl";
ead9360e 5669 break;
30deb460 5670 case CP0_REG01__VPECONF0:
f31b035a 5671 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
294fc2ea 5673 register_name = "VPEConf0";
ead9360e 5674 break;
30deb460 5675 case CP0_REG01__VPECONF1:
f31b035a 5676 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
294fc2ea 5678 register_name = "VPEConf1";
ead9360e 5679 break;
30deb460 5680 case CP0_REG01__YQMASK:
f31b035a 5681 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5682 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
294fc2ea 5683 register_name = "YQMask";
ead9360e 5684 break;
30deb460 5685 case CP0_REG01__VPESCHEDULE:
f31b035a 5686 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5687 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 5688 register_name = "VPESchedule";
ead9360e 5689 break;
30deb460 5690 case CP0_REG01__VPESCHEFBACK:
f31b035a 5691 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5692 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 5693 register_name = "VPEScheFBack";
ead9360e 5694 break;
30deb460 5695 case CP0_REG01__VPEOPT:
f31b035a 5696 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5697 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
294fc2ea 5698 register_name = "VPEOpt";
ead9360e 5699 break;
7a387fff 5700 default:
f31b035a 5701 goto cp0_unimplemented;
7a387fff 5702 }
873eb012 5703 break;
04992c8c 5704 case CP0_REGISTER_02:
7a387fff 5705 switch (sel) {
6d27d5bd 5706 case CP0_REG02__ENTRYLO0:
284b731a
LA
5707 {
5708 TCGv_i64 tmp = tcg_temp_new_i64();
5709 tcg_gen_ld_i64(tmp, cpu_env,
5710 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5711#if defined(TARGET_MIPS64)
284b731a
LA
5712 if (ctx->rxi) {
5713 /* Move RI/XI fields to bits 31:30 */
5714 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5715 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5716 }
7207c7f9 5717#endif
284b731a
LA
5718 gen_move_low32(arg, tmp);
5719 tcg_temp_free_i64(tmp);
5720 }
294fc2ea 5721 register_name = "EntryLo0";
2423f660 5722 break;
6d27d5bd 5723 case CP0_REG02__TCSTATUS:
f31b035a 5724 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5725 gen_helper_mfc0_tcstatus(arg, cpu_env);
294fc2ea 5726 register_name = "TCStatus";
ead9360e 5727 break;
6d27d5bd 5728 case CP0_REG02__TCBIND:
f31b035a 5729 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5730 gen_helper_mfc0_tcbind(arg, cpu_env);
294fc2ea 5731 register_name = "TCBind";
ead9360e 5732 break;
6d27d5bd 5733 case CP0_REG02__TCRESTART:
f31b035a 5734 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5735 gen_helper_mfc0_tcrestart(arg, cpu_env);
294fc2ea 5736 register_name = "TCRestart";
ead9360e 5737 break;
6d27d5bd 5738 case CP0_REG02__TCHALT:
f31b035a 5739 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5740 gen_helper_mfc0_tchalt(arg, cpu_env);
294fc2ea 5741 register_name = "TCHalt";
ead9360e 5742 break;
6d27d5bd 5743 case CP0_REG02__TCCONTEXT:
f31b035a 5744 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5745 gen_helper_mfc0_tccontext(arg, cpu_env);
294fc2ea 5746 register_name = "TCContext";
ead9360e 5747 break;
6d27d5bd 5748 case CP0_REG02__TCSCHEDULE:
f31b035a 5749 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5750 gen_helper_mfc0_tcschedule(arg, cpu_env);
294fc2ea 5751 register_name = "TCSchedule";
ead9360e 5752 break;
6d27d5bd 5753 case CP0_REG02__TCSCHEFBACK:
f31b035a 5754 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5755 gen_helper_mfc0_tcschefback(arg, cpu_env);
294fc2ea 5756 register_name = "TCScheFBack";
ead9360e 5757 break;
7a387fff 5758 default:
f31b035a 5759 goto cp0_unimplemented;
7a387fff 5760 }
873eb012 5761 break;
04992c8c 5762 case CP0_REGISTER_03:
7a387fff 5763 switch (sel) {
acd37316 5764 case CP0_REG03__ENTRYLO1:
284b731a
LA
5765 {
5766 TCGv_i64 tmp = tcg_temp_new_i64();
5767 tcg_gen_ld_i64(tmp, cpu_env,
5768 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5769#if defined(TARGET_MIPS64)
284b731a
LA
5770 if (ctx->rxi) {
5771 /* Move RI/XI fields to bits 31:30 */
5772 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5773 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5774 }
7207c7f9 5775#endif
284b731a
LA
5776 gen_move_low32(arg, tmp);
5777 tcg_temp_free_i64(tmp);
5778 }
294fc2ea 5779 register_name = "EntryLo1";
2423f660 5780 break;
acd37316 5781 case CP0_REG03__GLOBALNUM:
01bc435b
YK
5782 CP0_CHECK(ctx->vp);
5783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
294fc2ea 5784 register_name = "GlobalNumber";
01bc435b 5785 break;
7a387fff 5786 default:
f31b035a 5787 goto cp0_unimplemented;
1579a72e 5788 }
873eb012 5789 break;
04992c8c 5790 case CP0_REGISTER_04:
7a387fff 5791 switch (sel) {
020fe379 5792 case CP0_REG04__CONTEXT:
7db13fae 5793 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5794 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5795 register_name = "Context";
2423f660 5796 break;
020fe379
AM
5797 case CP0_REG04__CONTEXTCONFIG:
5798 /* SmartMIPS ASE */
5799 /* gen_helper_mfc0_contextconfig(arg); */
294fc2ea 5800 register_name = "ContextConfig";
f31b035a 5801 goto cp0_unimplemented;
020fe379 5802 case CP0_REG04__USERLOCAL:
f31b035a 5803 CP0_CHECK(ctx->ulri);
e40df9a8
JH
5804 tcg_gen_ld_tl(arg, cpu_env,
5805 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5806 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5807 register_name = "UserLocal";
d279279e 5808 break;
99029be1
YK
5809 case CP0_REG04__MMID:
5810 CP0_CHECK(ctx->mi);
5811 gen_helper_mtc0_memorymapid(cpu_env, arg);
5812 register_name = "MMID";
5813 break;
7a387fff 5814 default:
f31b035a 5815 goto cp0_unimplemented;
1579a72e 5816 }
873eb012 5817 break;
04992c8c 5818 case CP0_REGISTER_05:
7a387fff 5819 switch (sel) {
a1e76353 5820 case CP0_REG05__PAGEMASK:
7db13fae 5821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
294fc2ea 5822 register_name = "PageMask";
2423f660 5823 break;
a1e76353 5824 case CP0_REG05__PAGEGRAIN:
7a47bae5 5825 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5826 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
294fc2ea 5827 register_name = "PageGrain";
2423f660 5828 break;
a1e76353 5829 case CP0_REG05__SEGCTL0:
cec56a73
JH
5830 CP0_CHECK(ctx->sc);
5831 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5832 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5833 register_name = "SegCtl0";
cec56a73 5834 break;
a1e76353 5835 case CP0_REG05__SEGCTL1:
cec56a73
JH
5836 CP0_CHECK(ctx->sc);
5837 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5838 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5839 register_name = "SegCtl1";
cec56a73 5840 break;
a1e76353 5841 case CP0_REG05__SEGCTL2:
cec56a73
JH
5842 CP0_CHECK(ctx->sc);
5843 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5844 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5845 register_name = "SegCtl2";
cec56a73 5846 break;
a1e76353 5847 case CP0_REG05__PWBASE:
5e31fdd5
YK
5848 check_pw(ctx);
5849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 5850 register_name = "PWBase";
5e31fdd5 5851 break;
a1e76353 5852 case CP0_REG05__PWFIELD:
fa75ad14
YK
5853 check_pw(ctx);
5854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
294fc2ea 5855 register_name = "PWField";
fa75ad14 5856 break;
a1e76353 5857 case CP0_REG05__PWSIZE:
20b28ebc
YK
5858 check_pw(ctx);
5859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
294fc2ea 5860 register_name = "PWSize";
20b28ebc 5861 break;
7a387fff 5862 default:
f31b035a 5863 goto cp0_unimplemented;
1579a72e 5864 }
873eb012 5865 break;
04992c8c 5866 case CP0_REGISTER_06:
7a387fff 5867 switch (sel) {
9023594b 5868 case CP0_REG06__WIRED:
7db13fae 5869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
294fc2ea 5870 register_name = "Wired";
2423f660 5871 break;
9023594b 5872 case CP0_REG06__SRSCONF0:
7a47bae5 5873 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5874 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
294fc2ea 5875 register_name = "SRSConf0";
ead9360e 5876 break;
9023594b 5877 case CP0_REG06__SRSCONF1:
7a47bae5 5878 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5879 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
294fc2ea 5880 register_name = "SRSConf1";
ead9360e 5881 break;
9023594b 5882 case CP0_REG06__SRSCONF2:
7a47bae5 5883 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5884 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
294fc2ea 5885 register_name = "SRSConf2";
ead9360e 5886 break;
9023594b 5887 case CP0_REG06__SRSCONF3:
7a47bae5 5888 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5889 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
294fc2ea 5890 register_name = "SRSConf3";
ead9360e 5891 break;
9023594b 5892 case CP0_REG06__SRSCONF4:
7a47bae5 5893 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
294fc2ea 5895 register_name = "SRSConf4";
ead9360e 5896 break;
9023594b 5897 case CP0_REG06__PWCTL:
103be64c
YK
5898 check_pw(ctx);
5899 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
294fc2ea 5900 register_name = "PWCtl";
103be64c 5901 break;
7a387fff 5902 default:
f31b035a 5903 goto cp0_unimplemented;
1579a72e 5904 }
873eb012 5905 break;
04992c8c 5906 case CP0_REGISTER_07:
7a387fff 5907 switch (sel) {
143a9875 5908 case CP0_REG07__HWRENA:
7a47bae5 5909 check_insn(ctx, ISA_MIPS_R2);
7db13fae 5910 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
294fc2ea 5911 register_name = "HWREna";
2423f660 5912 break;
7a387fff 5913 default:
f31b035a 5914 goto cp0_unimplemented;
1579a72e 5915 }
8c0fdd85 5916 break;
04992c8c 5917 case CP0_REGISTER_08:
7a387fff 5918 switch (sel) {
67d167d2 5919 case CP0_REG08__BADVADDR:
7db13fae 5920 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5921 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5922 register_name = "BadVAddr";
2423f660 5923 break;
67d167d2 5924 case CP0_REG08__BADINSTR:
f31b035a
LA
5925 CP0_CHECK(ctx->bi);
5926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
294fc2ea 5927 register_name = "BadInstr";
aea14095 5928 break;
67d167d2 5929 case CP0_REG08__BADINSTRP:
f31b035a
LA
5930 CP0_CHECK(ctx->bp);
5931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
294fc2ea 5932 register_name = "BadInstrP";
aea14095 5933 break;
67d167d2 5934 case CP0_REG08__BADINSTRX:
25beba9b
SM
5935 CP0_CHECK(ctx->bi);
5936 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5937 tcg_gen_andi_tl(arg, arg, ~0xffff);
294fc2ea 5938 register_name = "BadInstrX";
25beba9b 5939 break;
05aa7e93 5940 default:
f31b035a 5941 goto cp0_unimplemented;
aea14095 5942 }
873eb012 5943 break;
04992c8c 5944 case CP0_REGISTER_09:
7a387fff 5945 switch (sel) {
e5a98a72 5946 case CP0_REG09__COUNT:
2e70f6ef 5947 /* Mark as an IO operation because we read the time. */
eeb3bba8 5948 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5949 gen_io_start();
7d37435b 5950 }
895c2d04 5951 gen_helper_mfc0_count(arg, cpu_env);
7480515f
AM
5952 /*
5953 * Break the TB to be able to take timer interrupts immediately
5954 * after reading count. DISAS_STOP isn't sufficient, we need to
5955 * ensure we break completely out of translated code.
5956 */
eeb3bba8
EC
5957 gen_save_pc(ctx->base.pc_next + 4);
5958 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 5959 register_name = "Count";
2423f660 5960 break;
e5a98a72 5961 case CP0_REG09__SAARI:
5fb2dcd1
YK
5962 CP0_CHECK(ctx->saar);
5963 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
294fc2ea 5964 register_name = "SAARI";
5fb2dcd1 5965 break;
e5a98a72 5966 case CP0_REG09__SAAR:
5fb2dcd1
YK
5967 CP0_CHECK(ctx->saar);
5968 gen_helper_mfc0_saar(arg, cpu_env);
294fc2ea 5969 register_name = "SAAR";
5fb2dcd1 5970 break;
7a387fff 5971 default:
f31b035a 5972 goto cp0_unimplemented;
2423f660 5973 }
873eb012 5974 break;
04992c8c 5975 case CP0_REGISTER_10:
7a387fff 5976 switch (sel) {
860ffef0 5977 case CP0_REG10__ENTRYHI:
7db13fae 5978 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5979 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 5980 register_name = "EntryHi";
2423f660 5981 break;
7a387fff 5982 default:
f31b035a 5983 goto cp0_unimplemented;
1579a72e 5984 }
873eb012 5985 break;
04992c8c 5986 case CP0_REGISTER_11:
7a387fff 5987 switch (sel) {
f5f3834f 5988 case CP0_REG11__COMPARE:
7db13fae 5989 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
294fc2ea 5990 register_name = "Compare";
2423f660
TS
5991 break;
5992 /* 6,7 are implementation dependent */
7a387fff 5993 default:
f31b035a 5994 goto cp0_unimplemented;
2423f660 5995 }
873eb012 5996 break;
04992c8c 5997 case CP0_REGISTER_12:
7a387fff 5998 switch (sel) {
2b084867 5999 case CP0_REG12__STATUS:
7db13fae 6000 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
294fc2ea 6001 register_name = "Status";
2423f660 6002 break;
2b084867 6003 case CP0_REG12__INTCTL:
7a47bae5 6004 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
294fc2ea 6006 register_name = "IntCtl";
2423f660 6007 break;
2b084867 6008 case CP0_REG12__SRSCTL:
7a47bae5 6009 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
294fc2ea 6011 register_name = "SRSCtl";
2423f660 6012 break;
2b084867 6013 case CP0_REG12__SRSMAP:
7a47bae5 6014 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
294fc2ea 6016 register_name = "SRSMap";
fd88b6ab 6017 break;
7a387fff 6018 default:
f31b035a 6019 goto cp0_unimplemented;
7a387fff 6020 }
873eb012 6021 break;
04992c8c 6022 case CP0_REGISTER_13:
7a387fff 6023 switch (sel) {
e3c7559d 6024 case CP0_REG13__CAUSE:
7db13fae 6025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
294fc2ea 6026 register_name = "Cause";
2423f660 6027 break;
7a387fff 6028 default:
f31b035a 6029 goto cp0_unimplemented;
7a387fff 6030 }
873eb012 6031 break;
04992c8c 6032 case CP0_REGISTER_14:
7a387fff 6033 switch (sel) {
35e4b54d 6034 case CP0_REG14__EPC:
7db13fae 6035 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 6036 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6037 register_name = "EPC";
2423f660 6038 break;
7a387fff 6039 default:
f31b035a 6040 goto cp0_unimplemented;
1579a72e 6041 }
873eb012 6042 break;
04992c8c 6043 case CP0_REGISTER_15:
7a387fff 6044 switch (sel) {
4466cd49 6045 case CP0_REG15__PRID:
7db13fae 6046 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
294fc2ea 6047 register_name = "PRid";
2423f660 6048 break;
4466cd49 6049 case CP0_REG15__EBASE:
7a47bae5 6050 check_insn(ctx, ISA_MIPS_R2);
74dbf824
JH
6051 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6052 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6053 register_name = "EBase";
2423f660 6054 break;
4466cd49 6055 case CP0_REG15__CMGCRBASE:
7a47bae5 6056 check_insn(ctx, ISA_MIPS_R2);
c870e3f5
YK
6057 CP0_CHECK(ctx->cmgcr);
6058 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6059 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6060 register_name = "CMGCRBase";
c870e3f5 6061 break;
7a387fff 6062 default:
f31b035a 6063 goto cp0_unimplemented;
7a387fff 6064 }
873eb012 6065 break;
04992c8c 6066 case CP0_REGISTER_16:
873eb012 6067 switch (sel) {
433efb4c 6068 case CP0_REG16__CONFIG:
7db13fae 6069 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
294fc2ea 6070 register_name = "Config";
873eb012 6071 break;
433efb4c 6072 case CP0_REG16__CONFIG1:
7db13fae 6073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
294fc2ea 6074 register_name = "Config1";
873eb012 6075 break;
433efb4c 6076 case CP0_REG16__CONFIG2:
7db13fae 6077 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
294fc2ea 6078 register_name = "Config2";
7a387fff 6079 break;
433efb4c 6080 case CP0_REG16__CONFIG3:
7db13fae 6081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
294fc2ea 6082 register_name = "Config3";
7a387fff 6083 break;
433efb4c 6084 case CP0_REG16__CONFIG4:
b4160af1 6085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
294fc2ea 6086 register_name = "Config4";
b4160af1 6087 break;
433efb4c 6088 case CP0_REG16__CONFIG5:
b4dd99a3 6089 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
294fc2ea 6090 register_name = "Config5";
b4dd99a3 6091 break;
e397ee33 6092 /* 6,7 are implementation dependent */
433efb4c 6093 case CP0_REG16__CONFIG6:
7db13fae 6094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
294fc2ea 6095 register_name = "Config6";
e397ee33 6096 break;
433efb4c 6097 case CP0_REG16__CONFIG7:
7db13fae 6098 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
294fc2ea 6099 register_name = "Config7";
e397ee33 6100 break;
873eb012 6101 default:
f31b035a 6102 goto cp0_unimplemented;
873eb012
TS
6103 }
6104 break;
04992c8c 6105 case CP0_REGISTER_17:
7a387fff 6106 switch (sel) {
706ce142 6107 case CP0_REG17__LLADDR:
895c2d04 6108 gen_helper_mfc0_lladdr(arg, cpu_env);
294fc2ea 6109 register_name = "LLAddr";
2423f660 6110 break;
706ce142 6111 case CP0_REG17__MAAR:
f6d4dd81
YK
6112 CP0_CHECK(ctx->mrp);
6113 gen_helper_mfc0_maar(arg, cpu_env);
294fc2ea 6114 register_name = "MAAR";
f6d4dd81 6115 break;
706ce142 6116 case CP0_REG17__MAARI:
f6d4dd81
YK
6117 CP0_CHECK(ctx->mrp);
6118 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
294fc2ea 6119 register_name = "MAARI";
f6d4dd81 6120 break;
7a387fff 6121 default:
f31b035a 6122 goto cp0_unimplemented;
7a387fff 6123 }
873eb012 6124 break;
04992c8c 6125 case CP0_REGISTER_18:
7a387fff 6126 switch (sel) {
e8dcfe82
AM
6127 case CP0_REG18__WATCHLO0:
6128 case CP0_REG18__WATCHLO1:
6129 case CP0_REG18__WATCHLO2:
6130 case CP0_REG18__WATCHLO3:
6131 case CP0_REG18__WATCHLO4:
6132 case CP0_REG18__WATCHLO5:
6133 case CP0_REG18__WATCHLO6:
6134 case CP0_REG18__WATCHLO7:
fa192d49 6135 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6136 gen_helper_1e0i(mfc0_watchlo, arg, sel);
294fc2ea 6137 register_name = "WatchLo";
2423f660 6138 break;
7a387fff 6139 default:
f31b035a 6140 goto cp0_unimplemented;
7a387fff 6141 }
873eb012 6142 break;
04992c8c 6143 case CP0_REGISTER_19:
7a387fff 6144 switch (sel) {
be274dc1
AM
6145 case CP0_REG19__WATCHHI0:
6146 case CP0_REG19__WATCHHI1:
6147 case CP0_REG19__WATCHHI2:
6148 case CP0_REG19__WATCHHI3:
6149 case CP0_REG19__WATCHHI4:
6150 case CP0_REG19__WATCHHI5:
6151 case CP0_REG19__WATCHHI6:
6152 case CP0_REG19__WATCHHI7:
fa192d49 6153 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6154 gen_helper_1e0i(mfc0_watchhi, arg, sel);
294fc2ea 6155 register_name = "WatchHi";
2423f660 6156 break;
7a387fff 6157 default:
f31b035a 6158 goto cp0_unimplemented;
7a387fff 6159 }
873eb012 6160 break;
04992c8c 6161 case CP0_REGISTER_20:
7a387fff 6162 switch (sel) {
14f92b0b 6163 case CP0_REG20__XCONTEXT:
d26bc211 6164#if defined(TARGET_MIPS64)
d75c135e 6165 check_insn(ctx, ISA_MIPS3);
7db13fae 6166 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 6167 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6168 register_name = "XContext";
2423f660 6169 break;
703eaf37 6170#endif
7a387fff 6171 default:
f31b035a 6172 goto cp0_unimplemented;
7a387fff 6173 }
8c0fdd85 6174 break;
04992c8c 6175 case CP0_REGISTER_21:
7a387fff 6176 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 6177 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7a387fff
TS
6178 switch (sel) {
6179 case 0:
7db13fae 6180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
294fc2ea 6181 register_name = "Framemask";
2423f660 6182 break;
7a387fff 6183 default:
f31b035a 6184 goto cp0_unimplemented;
7a387fff 6185 }
8c0fdd85 6186 break;
04992c8c 6187 case CP0_REGISTER_22:
d9bea114 6188 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 6189 register_name = "'Diagnostic"; /* implementation dependent */
2423f660 6190 break;
04992c8c 6191 case CP0_REGISTER_23:
7a387fff 6192 switch (sel) {
4cbf4b6d 6193 case CP0_REG23__DEBUG:
895c2d04 6194 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
294fc2ea 6195 register_name = "Debug";
2423f660 6196 break;
4cbf4b6d
AM
6197 case CP0_REG23__TRACECONTROL:
6198 /* PDtrace support */
6199 /* gen_helper_mfc0_tracecontrol(arg); */
294fc2ea 6200 register_name = "TraceControl";
3570d7f6 6201 goto cp0_unimplemented;
4cbf4b6d
AM
6202 case CP0_REG23__TRACECONTROL2:
6203 /* PDtrace support */
6204 /* gen_helper_mfc0_tracecontrol2(arg); */
294fc2ea 6205 register_name = "TraceControl2";
3570d7f6 6206 goto cp0_unimplemented;
4cbf4b6d
AM
6207 case CP0_REG23__USERTRACEDATA1:
6208 /* PDtrace support */
6209 /* gen_helper_mfc0_usertracedata1(arg);*/
6210 register_name = "UserTraceData1";
3570d7f6 6211 goto cp0_unimplemented;
4cbf4b6d
AM
6212 case CP0_REG23__TRACEIBPC:
6213 /* PDtrace support */
6214 /* gen_helper_mfc0_traceibpc(arg); */
6215 register_name = "TraceIBPC";
6216 goto cp0_unimplemented;
6217 case CP0_REG23__TRACEDBPC:
6218 /* PDtrace support */
6219 /* gen_helper_mfc0_tracedbpc(arg); */
6220 register_name = "TraceDBPC";
3570d7f6 6221 goto cp0_unimplemented;
7a387fff 6222 default:
f31b035a 6223 goto cp0_unimplemented;
7a387fff 6224 }
873eb012 6225 break;
04992c8c 6226 case CP0_REGISTER_24:
7a387fff 6227 switch (sel) {
8d7b4b6e 6228 case CP0_REG24__DEPC:
f0b3f3ae 6229 /* EJTAG support */
7db13fae 6230 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 6231 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6232 register_name = "DEPC";
2423f660 6233 break;
7a387fff 6234 default:
f31b035a 6235 goto cp0_unimplemented;
7a387fff 6236 }
873eb012 6237 break;
04992c8c 6238 case CP0_REGISTER_25:
7a387fff 6239 switch (sel) {
1176b328 6240 case CP0_REG25__PERFCTL0:
7db13fae 6241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
294fc2ea 6242 register_name = "Performance0";
7a387fff 6243 break;
1176b328 6244 case CP0_REG25__PERFCNT0:
7480515f 6245 /* gen_helper_mfc0_performance1(arg); */
294fc2ea 6246 register_name = "Performance1";
3570d7f6 6247 goto cp0_unimplemented;
1176b328 6248 case CP0_REG25__PERFCTL1:
7480515f 6249 /* gen_helper_mfc0_performance2(arg); */
294fc2ea 6250 register_name = "Performance2";
3570d7f6 6251 goto cp0_unimplemented;
1176b328 6252 case CP0_REG25__PERFCNT1:
7480515f 6253 /* gen_helper_mfc0_performance3(arg); */
294fc2ea 6254 register_name = "Performance3";
3570d7f6 6255 goto cp0_unimplemented;
1176b328 6256 case CP0_REG25__PERFCTL2:
7480515f 6257 /* gen_helper_mfc0_performance4(arg); */
294fc2ea 6258 register_name = "Performance4";
3570d7f6 6259 goto cp0_unimplemented;
1176b328 6260 case CP0_REG25__PERFCNT2:
7480515f 6261 /* gen_helper_mfc0_performance5(arg); */
294fc2ea 6262 register_name = "Performance5";
3570d7f6 6263 goto cp0_unimplemented;
1176b328 6264 case CP0_REG25__PERFCTL3:
7480515f 6265 /* gen_helper_mfc0_performance6(arg); */
294fc2ea 6266 register_name = "Performance6";
3570d7f6 6267 goto cp0_unimplemented;
1176b328 6268 case CP0_REG25__PERFCNT3:
7480515f 6269 /* gen_helper_mfc0_performance7(arg); */
294fc2ea 6270 register_name = "Performance7";
3570d7f6 6271 goto cp0_unimplemented;
7a387fff 6272 default:
f31b035a 6273 goto cp0_unimplemented;
7a387fff 6274 }
8c0fdd85 6275 break;
04992c8c 6276 case CP0_REGISTER_26:
0d74a222 6277 switch (sel) {
dbbf08b2 6278 case CP0_REG26__ERRCTL:
0d74a222 6279 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
294fc2ea 6280 register_name = "ErrCtl";
0d74a222
LA
6281 break;
6282 default:
6283 goto cp0_unimplemented;
6284 }
da80682b 6285 break;
04992c8c 6286 case CP0_REGISTER_27:
7a387fff 6287 switch (sel) {
5a10873d 6288 case CP0_REG27__CACHERR:
d9bea114 6289 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 6290 register_name = "CacheErr";
2423f660 6291 break;
7a387fff 6292 default:
f31b035a 6293 goto cp0_unimplemented;
7a387fff 6294 }
8c0fdd85 6295 break;
04992c8c 6296 case CP0_REGISTER_28:
873eb012 6297 switch (sel) {
a30e2f21
AM
6298 case CP0_REG28__TAGLO:
6299 case CP0_REG28__TAGLO1:
6300 case CP0_REG28__TAGLO2:
6301 case CP0_REG28__TAGLO3:
284b731a
LA
6302 {
6303 TCGv_i64 tmp = tcg_temp_new_i64();
6304 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6305 gen_move_low32(arg, tmp);
6306 tcg_temp_free_i64(tmp);
6307 }
294fc2ea 6308 register_name = "TagLo";
873eb012 6309 break;
a30e2f21
AM
6310 case CP0_REG28__DATALO:
6311 case CP0_REG28__DATALO1:
6312 case CP0_REG28__DATALO2:
6313 case CP0_REG28__DATALO3:
7db13fae 6314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
294fc2ea 6315 register_name = "DataLo";
873eb012
TS
6316 break;
6317 default:
f31b035a 6318 goto cp0_unimplemented;
873eb012
TS
6319 }
6320 break;
04992c8c 6321 case CP0_REGISTER_29:
7a387fff 6322 switch (sel) {
af4bb6da
AM
6323 case CP0_REG29__TAGHI:
6324 case CP0_REG29__TAGHI1:
6325 case CP0_REG29__TAGHI2:
6326 case CP0_REG29__TAGHI3:
7db13fae 6327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
294fc2ea 6328 register_name = "TagHi";
7a387fff 6329 break;
af4bb6da
AM
6330 case CP0_REG29__DATAHI:
6331 case CP0_REG29__DATAHI1:
6332 case CP0_REG29__DATAHI2:
6333 case CP0_REG29__DATAHI3:
7db13fae 6334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
294fc2ea 6335 register_name = "DataHi";
7a387fff
TS
6336 break;
6337 default:
f31b035a 6338 goto cp0_unimplemented;
7a387fff 6339 }
8c0fdd85 6340 break;
04992c8c 6341 case CP0_REGISTER_30:
7a387fff 6342 switch (sel) {
4bcf121e 6343 case CP0_REG30__ERROREPC:
7db13fae 6344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 6345 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6346 register_name = "ErrorEPC";
2423f660 6347 break;
7a387fff 6348 default:
f31b035a 6349 goto cp0_unimplemented;
7a387fff 6350 }
873eb012 6351 break;
04992c8c 6352 case CP0_REGISTER_31:
7a387fff 6353 switch (sel) {
14d92efd 6354 case CP0_REG31__DESAVE:
f0b3f3ae 6355 /* EJTAG support */
7db13fae 6356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 6357 register_name = "DESAVE";
2423f660 6358 break;
14d92efd
AM
6359 case CP0_REG31__KSCRATCH1:
6360 case CP0_REG31__KSCRATCH2:
6361 case CP0_REG31__KSCRATCH3:
6362 case CP0_REG31__KSCRATCH4:
6363 case CP0_REG31__KSCRATCH5:
6364 case CP0_REG31__KSCRATCH6:
f31b035a
LA
6365 CP0_CHECK(ctx->kscrexist & (1 << sel));
6366 tcg_gen_ld_tl(arg, cpu_env,
05aa7e93 6367 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
f31b035a 6368 tcg_gen_ext32s_tl(arg, arg);
294fc2ea 6369 register_name = "KScratch";
e98c0d17 6370 break;
7a387fff 6371 default:
f31b035a 6372 goto cp0_unimplemented;
7a387fff 6373 }
873eb012
TS
6374 break;
6375 default:
f31b035a 6376 goto cp0_unimplemented;
873eb012 6377 }
294fc2ea 6378 trace_mips_translate_c0("mfc0", register_name, reg, sel);
873eb012
TS
6379 return;
6380
f31b035a 6381cp0_unimplemented:
294fc2ea
AM
6382 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6383 register_name, reg, sel);
f31b035a 6384 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
6385}
6386
d75c135e 6387static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 6388{
294fc2ea 6389 const char *register_name = "invalid";
7a387fff 6390
1f8929d2 6391 if (sel != 0) {
bbd5e4a2 6392 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 6393 }
e189e748 6394
eeb3bba8 6395 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6396 gen_io_start();
bd79255d 6397 }
2e70f6ef 6398
8c0fdd85 6399 switch (reg) {
04992c8c 6400 case CP0_REGISTER_00:
7a387fff 6401 switch (sel) {
1b142da5 6402 case CP0_REG00__INDEX:
895c2d04 6403 gen_helper_mtc0_index(cpu_env, arg);
294fc2ea 6404 register_name = "Index";
7a387fff 6405 break;
1b142da5 6406 case CP0_REG00__MVPCONTROL:
f31b035a 6407 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6408 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
294fc2ea 6409 register_name = "MVPControl";
ead9360e 6410 break;
1b142da5 6411 case CP0_REG00__MVPCONF0:
f31b035a 6412 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6413 /* ignored */
294fc2ea 6414 register_name = "MVPConf0";
ead9360e 6415 break;
1b142da5 6416 case CP0_REG00__MVPCONF1:
f31b035a 6417 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 6418 /* ignored */
294fc2ea 6419 register_name = "MVPConf1";
ead9360e 6420 break;
1b142da5 6421 case CP0_REG00__VPCONTROL:
01bc435b
YK
6422 CP0_CHECK(ctx->vp);
6423 /* ignored */
294fc2ea 6424 register_name = "VPControl";
01bc435b 6425 break;
7a387fff 6426 default:
f31b035a 6427 goto cp0_unimplemented;
7a387fff 6428 }
8c0fdd85 6429 break;
04992c8c 6430 case CP0_REGISTER_01:
7a387fff 6431 switch (sel) {
30deb460 6432 case CP0_REG01__RANDOM:
2423f660 6433 /* ignored */
294fc2ea 6434 register_name = "Random";
2423f660 6435 break;
30deb460 6436 case CP0_REG01__VPECONTROL:
f31b035a 6437 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6438 gen_helper_mtc0_vpecontrol(cpu_env, arg);
294fc2ea 6439 register_name = "VPEControl";
ead9360e 6440 break;
30deb460 6441 case CP0_REG01__VPECONF0:
f31b035a 6442 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6443 gen_helper_mtc0_vpeconf0(cpu_env, arg);
294fc2ea 6444 register_name = "VPEConf0";
ead9360e 6445 break;
30deb460 6446 case CP0_REG01__VPECONF1:
f31b035a 6447 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6448 gen_helper_mtc0_vpeconf1(cpu_env, arg);
294fc2ea 6449 register_name = "VPEConf1";
ead9360e 6450 break;
30deb460 6451 case CP0_REG01__YQMASK:
f31b035a 6452 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6453 gen_helper_mtc0_yqmask(cpu_env, arg);
294fc2ea 6454 register_name = "YQMask";
ead9360e 6455 break;
30deb460 6456 case CP0_REG01__VPESCHEDULE:
f31b035a 6457 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
6458 tcg_gen_st_tl(arg, cpu_env,
6459 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 6460 register_name = "VPESchedule";
ead9360e 6461 break;
30deb460 6462 case CP0_REG01__VPESCHEFBACK:
f31b035a 6463 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
6464 tcg_gen_st_tl(arg, cpu_env,
6465 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 6466 register_name = "VPEScheFBack";
ead9360e 6467 break;
30deb460 6468 case CP0_REG01__VPEOPT:
f31b035a 6469 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6470 gen_helper_mtc0_vpeopt(cpu_env, arg);
294fc2ea 6471 register_name = "VPEOpt";
ead9360e 6472 break;
7a387fff 6473 default:
f31b035a 6474 goto cp0_unimplemented;
7a387fff 6475 }
8c0fdd85 6476 break;
04992c8c 6477 case CP0_REGISTER_02:
7a387fff 6478 switch (sel) {
6d27d5bd 6479 case CP0_REG02__ENTRYLO0:
895c2d04 6480 gen_helper_mtc0_entrylo0(cpu_env, arg);
294fc2ea 6481 register_name = "EntryLo0";
2423f660 6482 break;
6d27d5bd 6483 case CP0_REG02__TCSTATUS:
f31b035a 6484 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6485 gen_helper_mtc0_tcstatus(cpu_env, arg);
294fc2ea 6486 register_name = "TCStatus";
ead9360e 6487 break;
6d27d5bd 6488 case CP0_REG02__TCBIND:
f31b035a 6489 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6490 gen_helper_mtc0_tcbind(cpu_env, arg);
294fc2ea 6491 register_name = "TCBind";
ead9360e 6492 break;
6d27d5bd 6493 case CP0_REG02__TCRESTART:
f31b035a 6494 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6495 gen_helper_mtc0_tcrestart(cpu_env, arg);
294fc2ea 6496 register_name = "TCRestart";
ead9360e 6497 break;
6d27d5bd 6498 case CP0_REG02__TCHALT:
f31b035a 6499 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6500 gen_helper_mtc0_tchalt(cpu_env, arg);
294fc2ea 6501 register_name = "TCHalt";
ead9360e 6502 break;
6d27d5bd 6503 case CP0_REG02__TCCONTEXT:
f31b035a 6504 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6505 gen_helper_mtc0_tccontext(cpu_env, arg);
294fc2ea 6506 register_name = "TCContext";
ead9360e 6507 break;
6d27d5bd 6508 case CP0_REG02__TCSCHEDULE:
f31b035a 6509 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6510 gen_helper_mtc0_tcschedule(cpu_env, arg);
294fc2ea 6511 register_name = "TCSchedule";
ead9360e 6512 break;
6d27d5bd 6513 case CP0_REG02__TCSCHEFBACK:
f31b035a 6514 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6515 gen_helper_mtc0_tcschefback(cpu_env, arg);
294fc2ea 6516 register_name = "TCScheFBack";
ead9360e 6517 break;
7a387fff 6518 default:
f31b035a 6519 goto cp0_unimplemented;
7a387fff 6520 }
8c0fdd85 6521 break;
04992c8c 6522 case CP0_REGISTER_03:
7a387fff 6523 switch (sel) {
acd37316 6524 case CP0_REG03__ENTRYLO1:
895c2d04 6525 gen_helper_mtc0_entrylo1(cpu_env, arg);
294fc2ea 6526 register_name = "EntryLo1";
2423f660 6527 break;
acd37316 6528 case CP0_REG03__GLOBALNUM:
01bc435b
YK
6529 CP0_CHECK(ctx->vp);
6530 /* ignored */
294fc2ea 6531 register_name = "GlobalNumber";
01bc435b 6532 break;
7a387fff 6533 default:
f31b035a 6534 goto cp0_unimplemented;
876d4b07 6535 }
8c0fdd85 6536 break;
04992c8c 6537 case CP0_REGISTER_04:
7a387fff 6538 switch (sel) {
020fe379 6539 case CP0_REG04__CONTEXT:
895c2d04 6540 gen_helper_mtc0_context(cpu_env, arg);
294fc2ea 6541 register_name = "Context";
2423f660 6542 break;
020fe379
AM
6543 case CP0_REG04__CONTEXTCONFIG:
6544 /* SmartMIPS ASE */
6545 /* gen_helper_mtc0_contextconfig(arg); */
294fc2ea 6546 register_name = "ContextConfig";
f31b035a 6547 goto cp0_unimplemented;
020fe379 6548 case CP0_REG04__USERLOCAL:
f31b035a
LA
6549 CP0_CHECK(ctx->ulri);
6550 tcg_gen_st_tl(arg, cpu_env,
6551 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 6552 register_name = "UserLocal";
d279279e 6553 break;
99029be1
YK
6554 case CP0_REG04__MMID:
6555 CP0_CHECK(ctx->mi);
6556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6557 register_name = "MMID";
6558 break;
7a387fff 6559 default:
f31b035a 6560 goto cp0_unimplemented;
876d4b07 6561 }
8c0fdd85 6562 break;
04992c8c 6563 case CP0_REGISTER_05:
7a387fff 6564 switch (sel) {
a1e76353 6565 case CP0_REG05__PAGEMASK:
895c2d04 6566 gen_helper_mtc0_pagemask(cpu_env, arg);
294fc2ea 6567 register_name = "PageMask";
2423f660 6568 break;
a1e76353 6569 case CP0_REG05__PAGEGRAIN:
7a47bae5 6570 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6571 gen_helper_mtc0_pagegrain(cpu_env, arg);
294fc2ea 6572 register_name = "PageGrain";
eeb3bba8 6573 ctx->base.is_jmp = DISAS_STOP;
2423f660 6574 break;
a1e76353 6575 case CP0_REG05__SEGCTL0:
cec56a73
JH
6576 CP0_CHECK(ctx->sc);
6577 gen_helper_mtc0_segctl0(cpu_env, arg);
294fc2ea 6578 register_name = "SegCtl0";
cec56a73 6579 break;
a1e76353 6580 case CP0_REG05__SEGCTL1:
cec56a73
JH
6581 CP0_CHECK(ctx->sc);
6582 gen_helper_mtc0_segctl1(cpu_env, arg);
294fc2ea 6583 register_name = "SegCtl1";
cec56a73 6584 break;
a1e76353 6585 case CP0_REG05__SEGCTL2:
cec56a73
JH
6586 CP0_CHECK(ctx->sc);
6587 gen_helper_mtc0_segctl2(cpu_env, arg);
294fc2ea 6588 register_name = "SegCtl2";
cec56a73 6589 break;
a1e76353 6590 case CP0_REG05__PWBASE:
5e31fdd5
YK
6591 check_pw(ctx);
6592 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 6593 register_name = "PWBase";
5e31fdd5 6594 break;
a1e76353 6595 case CP0_REG05__PWFIELD:
fa75ad14
YK
6596 check_pw(ctx);
6597 gen_helper_mtc0_pwfield(cpu_env, arg);
294fc2ea 6598 register_name = "PWField";
fa75ad14 6599 break;
a1e76353 6600 case CP0_REG05__PWSIZE:
20b28ebc
YK
6601 check_pw(ctx);
6602 gen_helper_mtc0_pwsize(cpu_env, arg);
294fc2ea 6603 register_name = "PWSize";
20b28ebc 6604 break;
7a387fff 6605 default:
f31b035a 6606 goto cp0_unimplemented;
876d4b07 6607 }
8c0fdd85 6608 break;
04992c8c 6609 case CP0_REGISTER_06:
7a387fff 6610 switch (sel) {
9023594b 6611 case CP0_REG06__WIRED:
895c2d04 6612 gen_helper_mtc0_wired(cpu_env, arg);
294fc2ea 6613 register_name = "Wired";
2423f660 6614 break;
9023594b 6615 case CP0_REG06__SRSCONF0:
7a47bae5 6616 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6617 gen_helper_mtc0_srsconf0(cpu_env, arg);
294fc2ea 6618 register_name = "SRSConf0";
ead9360e 6619 break;
9023594b 6620 case CP0_REG06__SRSCONF1:
7a47bae5 6621 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6622 gen_helper_mtc0_srsconf1(cpu_env, arg);
294fc2ea 6623 register_name = "SRSConf1";
ead9360e 6624 break;
9023594b 6625 case CP0_REG06__SRSCONF2:
7a47bae5 6626 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6627 gen_helper_mtc0_srsconf2(cpu_env, arg);
294fc2ea 6628 register_name = "SRSConf2";
ead9360e 6629 break;
9023594b 6630 case CP0_REG06__SRSCONF3:
7a47bae5 6631 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6632 gen_helper_mtc0_srsconf3(cpu_env, arg);
294fc2ea 6633 register_name = "SRSConf3";
ead9360e 6634 break;
9023594b 6635 case CP0_REG06__SRSCONF4:
7a47bae5 6636 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6637 gen_helper_mtc0_srsconf4(cpu_env, arg);
294fc2ea 6638 register_name = "SRSConf4";
ead9360e 6639 break;
9023594b 6640 case CP0_REG06__PWCTL:
103be64c
YK
6641 check_pw(ctx);
6642 gen_helper_mtc0_pwctl(cpu_env, arg);
294fc2ea 6643 register_name = "PWCtl";
103be64c 6644 break;
7a387fff 6645 default:
f31b035a 6646 goto cp0_unimplemented;
876d4b07 6647 }
8c0fdd85 6648 break;
04992c8c 6649 case CP0_REGISTER_07:
7a387fff 6650 switch (sel) {
143a9875 6651 case CP0_REG07__HWRENA:
7a47bae5 6652 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6653 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 6654 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6655 register_name = "HWREna";
2423f660 6656 break;
7a387fff 6657 default:
f31b035a 6658 goto cp0_unimplemented;
876d4b07 6659 }
8c0fdd85 6660 break;
04992c8c 6661 case CP0_REGISTER_08:
aea14095 6662 switch (sel) {
67d167d2 6663 case CP0_REG08__BADVADDR:
aea14095 6664 /* ignored */
294fc2ea 6665 register_name = "BadVAddr";
aea14095 6666 break;
67d167d2 6667 case CP0_REG08__BADINSTR:
aea14095 6668 /* ignored */
294fc2ea 6669 register_name = "BadInstr";
aea14095 6670 break;
67d167d2 6671 case CP0_REG08__BADINSTRP:
aea14095 6672 /* ignored */
294fc2ea 6673 register_name = "BadInstrP";
aea14095 6674 break;
67d167d2 6675 case CP0_REG08__BADINSTRX:
25beba9b 6676 /* ignored */
294fc2ea 6677 register_name = "BadInstrX";
25beba9b 6678 break;
aea14095 6679 default:
f31b035a 6680 goto cp0_unimplemented;
aea14095 6681 }
8c0fdd85 6682 break;
04992c8c 6683 case CP0_REGISTER_09:
7a387fff 6684 switch (sel) {
e5a98a72 6685 case CP0_REG09__COUNT:
895c2d04 6686 gen_helper_mtc0_count(cpu_env, arg);
294fc2ea 6687 register_name = "Count";
2423f660 6688 break;
e5a98a72 6689 case CP0_REG09__SAARI:
5fb2dcd1
YK
6690 CP0_CHECK(ctx->saar);
6691 gen_helper_mtc0_saari(cpu_env, arg);
294fc2ea 6692 register_name = "SAARI";
5fb2dcd1 6693 break;
e5a98a72 6694 case CP0_REG09__SAAR:
5fb2dcd1
YK
6695 CP0_CHECK(ctx->saar);
6696 gen_helper_mtc0_saar(cpu_env, arg);
294fc2ea 6697 register_name = "SAAR";
5fb2dcd1 6698 break;
7a387fff 6699 default:
f31b035a 6700 goto cp0_unimplemented;
876d4b07 6701 }
8c0fdd85 6702 break;
04992c8c 6703 case CP0_REGISTER_10:
7a387fff 6704 switch (sel) {
860ffef0 6705 case CP0_REG10__ENTRYHI:
895c2d04 6706 gen_helper_mtc0_entryhi(cpu_env, arg);
294fc2ea 6707 register_name = "EntryHi";
2423f660 6708 break;
7a387fff 6709 default:
f31b035a 6710 goto cp0_unimplemented;
876d4b07 6711 }
8c0fdd85 6712 break;
04992c8c 6713 case CP0_REGISTER_11:
7a387fff 6714 switch (sel) {
f5f3834f 6715 case CP0_REG11__COMPARE:
895c2d04 6716 gen_helper_mtc0_compare(cpu_env, arg);
294fc2ea 6717 register_name = "Compare";
2423f660
TS
6718 break;
6719 /* 6,7 are implementation dependent */
7a387fff 6720 default:
f31b035a 6721 goto cp0_unimplemented;
876d4b07 6722 }
8c0fdd85 6723 break;
04992c8c 6724 case CP0_REGISTER_12:
7a387fff 6725 switch (sel) {
2b084867 6726 case CP0_REG12__STATUS:
867abc7e 6727 save_cpu_state(ctx, 1);
895c2d04 6728 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6729 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6730 gen_save_pc(ctx->base.pc_next + 4);
6731 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 6732 register_name = "Status";
2423f660 6733 break;
2b084867 6734 case CP0_REG12__INTCTL:
7a47bae5 6735 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6736 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6737 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6738 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6739 register_name = "IntCtl";
2423f660 6740 break;
2b084867 6741 case CP0_REG12__SRSCTL:
7a47bae5 6742 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6743 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6744 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6745 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6746 register_name = "SRSCtl";
2423f660 6747 break;
2b084867 6748 case CP0_REG12__SRSMAP:
7a47bae5 6749 check_insn(ctx, ISA_MIPS_R2);
7db13fae 6750 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6751 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6752 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 6753 register_name = "SRSMap";
fd88b6ab 6754 break;
7a387fff 6755 default:
f31b035a 6756 goto cp0_unimplemented;
876d4b07 6757 }
8c0fdd85 6758 break;
04992c8c 6759 case CP0_REGISTER_13:
7a387fff 6760 switch (sel) {
e3c7559d 6761 case CP0_REG13__CAUSE:
867abc7e 6762 save_cpu_state(ctx, 1);
895c2d04 6763 gen_helper_mtc0_cause(cpu_env, arg);
7480515f
AM
6764 /*
6765 * Stop translation as we may have triggered an interrupt.
b28425ba 6766 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7480515f
AM
6767 * translated code to check for pending interrupts.
6768 */
eeb3bba8
EC
6769 gen_save_pc(ctx->base.pc_next + 4);
6770 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 6771 register_name = "Cause";
2423f660 6772 break;
7a387fff 6773 default:
f31b035a 6774 goto cp0_unimplemented;
876d4b07 6775 }
8c0fdd85 6776 break;
04992c8c 6777 case CP0_REGISTER_14:
7a387fff 6778 switch (sel) {
35e4b54d 6779 case CP0_REG14__EPC:
d54a299b 6780 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 6781 register_name = "EPC";
2423f660 6782 break;
7a387fff 6783 default:
f31b035a 6784 goto cp0_unimplemented;
876d4b07 6785 }
8c0fdd85 6786 break;
04992c8c 6787 case CP0_REGISTER_15:
7a387fff 6788 switch (sel) {
4466cd49 6789 case CP0_REG15__PRID:
2423f660 6790 /* ignored */
294fc2ea 6791 register_name = "PRid";
2423f660 6792 break;
4466cd49 6793 case CP0_REG15__EBASE:
7a47bae5 6794 check_insn(ctx, ISA_MIPS_R2);
895c2d04 6795 gen_helper_mtc0_ebase(cpu_env, arg);
294fc2ea 6796 register_name = "EBase";
2423f660 6797 break;
7a387fff 6798 default:
f31b035a 6799 goto cp0_unimplemented;
1579a72e 6800 }
8c0fdd85 6801 break;
04992c8c 6802 case CP0_REGISTER_16:
8c0fdd85 6803 switch (sel) {
433efb4c 6804 case CP0_REG16__CONFIG:
895c2d04 6805 gen_helper_mtc0_config0(cpu_env, arg);
294fc2ea 6806 register_name = "Config";
2423f660 6807 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6808 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6809 break;
433efb4c 6810 case CP0_REG16__CONFIG1:
e397ee33 6811 /* ignored, read only */
294fc2ea 6812 register_name = "Config1";
7a387fff 6813 break;
433efb4c 6814 case CP0_REG16__CONFIG2:
895c2d04 6815 gen_helper_mtc0_config2(cpu_env, arg);
294fc2ea 6816 register_name = "Config2";
2423f660 6817 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6818 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6819 break;
433efb4c 6820 case CP0_REG16__CONFIG3:
90f12d73 6821 gen_helper_mtc0_config3(cpu_env, arg);
294fc2ea 6822 register_name = "Config3";
90f12d73 6823 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6824 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6825 break;
433efb4c 6826 case CP0_REG16__CONFIG4:
b4160af1 6827 gen_helper_mtc0_config4(cpu_env, arg);
294fc2ea 6828 register_name = "Config4";
eeb3bba8 6829 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6830 break;
433efb4c 6831 case CP0_REG16__CONFIG5:
b4dd99a3 6832 gen_helper_mtc0_config5(cpu_env, arg);
294fc2ea 6833 register_name = "Config5";
b4dd99a3 6834 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6835 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6836 break;
e397ee33 6837 /* 6,7 are implementation dependent */
433efb4c 6838 case CP0_REG16__CONFIG6:
e397ee33 6839 /* ignored */
294fc2ea 6840 register_name = "Config6";
e397ee33 6841 break;
433efb4c 6842 case CP0_REG16__CONFIG7:
e397ee33 6843 /* ignored */
294fc2ea 6844 register_name = "Config7";
e397ee33 6845 break;
8c0fdd85 6846 default:
294fc2ea 6847 register_name = "Invalid config selector";
f31b035a 6848 goto cp0_unimplemented;
8c0fdd85
TS
6849 }
6850 break;
04992c8c 6851 case CP0_REGISTER_17:
7a387fff 6852 switch (sel) {
706ce142 6853 case CP0_REG17__LLADDR:
895c2d04 6854 gen_helper_mtc0_lladdr(cpu_env, arg);
294fc2ea 6855 register_name = "LLAddr";
2423f660 6856 break;
706ce142 6857 case CP0_REG17__MAAR:
f6d4dd81
YK
6858 CP0_CHECK(ctx->mrp);
6859 gen_helper_mtc0_maar(cpu_env, arg);
294fc2ea 6860 register_name = "MAAR";
f6d4dd81 6861 break;
706ce142 6862 case CP0_REG17__MAARI:
f6d4dd81
YK
6863 CP0_CHECK(ctx->mrp);
6864 gen_helper_mtc0_maari(cpu_env, arg);
294fc2ea 6865 register_name = "MAARI";
f6d4dd81 6866 break;
7a387fff 6867 default:
f31b035a 6868 goto cp0_unimplemented;
7a387fff 6869 }
8c0fdd85 6870 break;
04992c8c 6871 case CP0_REGISTER_18:
7a387fff 6872 switch (sel) {
e8dcfe82
AM
6873 case CP0_REG18__WATCHLO0:
6874 case CP0_REG18__WATCHLO1:
6875 case CP0_REG18__WATCHLO2:
6876 case CP0_REG18__WATCHLO3:
6877 case CP0_REG18__WATCHLO4:
6878 case CP0_REG18__WATCHLO5:
6879 case CP0_REG18__WATCHLO6:
6880 case CP0_REG18__WATCHLO7:
fa192d49 6881 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6882 gen_helper_0e1i(mtc0_watchlo, arg, sel);
294fc2ea 6883 register_name = "WatchLo";
2423f660 6884 break;
7a387fff 6885 default:
f31b035a 6886 goto cp0_unimplemented;
7a387fff 6887 }
8c0fdd85 6888 break;
04992c8c 6889 case CP0_REGISTER_19:
7a387fff 6890 switch (sel) {
be274dc1
AM
6891 case CP0_REG19__WATCHHI0:
6892 case CP0_REG19__WATCHHI1:
6893 case CP0_REG19__WATCHHI2:
6894 case CP0_REG19__WATCHHI3:
6895 case CP0_REG19__WATCHHI4:
6896 case CP0_REG19__WATCHHI5:
6897 case CP0_REG19__WATCHHI6:
6898 case CP0_REG19__WATCHHI7:
fa192d49 6899 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6900 gen_helper_0e1i(mtc0_watchhi, arg, sel);
294fc2ea 6901 register_name = "WatchHi";
2423f660 6902 break;
7a387fff 6903 default:
f31b035a 6904 goto cp0_unimplemented;
7a387fff 6905 }
8c0fdd85 6906 break;
04992c8c 6907 case CP0_REGISTER_20:
7a387fff 6908 switch (sel) {
14f92b0b 6909 case CP0_REG20__XCONTEXT:
d26bc211 6910#if defined(TARGET_MIPS64)
d75c135e 6911 check_insn(ctx, ISA_MIPS3);
895c2d04 6912 gen_helper_mtc0_xcontext(cpu_env, arg);
294fc2ea 6913 register_name = "XContext";
2423f660 6914 break;
703eaf37 6915#endif
7a387fff 6916 default:
f31b035a 6917 goto cp0_unimplemented;
7a387fff 6918 }
8c0fdd85 6919 break;
04992c8c 6920 case CP0_REGISTER_21:
7a387fff 6921 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 6922 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7a387fff
TS
6923 switch (sel) {
6924 case 0:
895c2d04 6925 gen_helper_mtc0_framemask(cpu_env, arg);
294fc2ea 6926 register_name = "Framemask";
2423f660 6927 break;
7a387fff 6928 default:
f31b035a 6929 goto cp0_unimplemented;
7a387fff
TS
6930 }
6931 break;
04992c8c 6932 case CP0_REGISTER_22:
7a387fff 6933 /* ignored */
294fc2ea 6934 register_name = "Diagnostic"; /* implementation dependent */
2423f660 6935 break;
04992c8c 6936 case CP0_REGISTER_23:
7a387fff 6937 switch (sel) {
4cbf4b6d 6938 case CP0_REG23__DEBUG:
895c2d04 6939 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6940 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6941 gen_save_pc(ctx->base.pc_next + 4);
6942 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 6943 register_name = "Debug";
2423f660 6944 break;
4cbf4b6d
AM
6945 case CP0_REG23__TRACECONTROL:
6946 /* PDtrace support */
6947 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
294fc2ea 6948 register_name = "TraceControl";
8487327a 6949 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6950 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6951 goto cp0_unimplemented;
4cbf4b6d
AM
6952 case CP0_REG23__TRACECONTROL2:
6953 /* PDtrace support */
6954 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
294fc2ea 6955 register_name = "TraceControl2";
8487327a 6956 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6957 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6958 goto cp0_unimplemented;
4cbf4b6d 6959 case CP0_REG23__USERTRACEDATA1:
8487327a 6960 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6961 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d
AM
6962 /* PDtrace support */
6963 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
294fc2ea 6964 register_name = "UserTraceData";
8487327a 6965 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6966 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6967 goto cp0_unimplemented;
4cbf4b6d
AM
6968 case CP0_REG23__TRACEIBPC:
6969 /* PDtrace support */
6970 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8487327a 6971 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6972 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d
AM
6973 register_name = "TraceIBPC";
6974 goto cp0_unimplemented;
6975 case CP0_REG23__TRACEDBPC:
6976 /* PDtrace support */
6977 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
6978 /* Stop translation as we may have switched the execution mode */
6979 ctx->base.is_jmp = DISAS_STOP;
6980 register_name = "TraceDBPC";
3570d7f6 6981 goto cp0_unimplemented;
7a387fff 6982 default:
f31b035a 6983 goto cp0_unimplemented;
7a387fff 6984 }
8c0fdd85 6985 break;
04992c8c 6986 case CP0_REGISTER_24:
7a387fff 6987 switch (sel) {
8d7b4b6e 6988 case CP0_REG24__DEPC:
f1aa6320 6989 /* EJTAG support */
d54a299b 6990 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 6991 register_name = "DEPC";
2423f660 6992 break;
7a387fff 6993 default:
f31b035a 6994 goto cp0_unimplemented;
7a387fff 6995 }
8c0fdd85 6996 break;
04992c8c 6997 case CP0_REGISTER_25:
7a387fff 6998 switch (sel) {
1176b328 6999 case CP0_REG25__PERFCTL0:
895c2d04 7000 gen_helper_mtc0_performance0(cpu_env, arg);
294fc2ea 7001 register_name = "Performance0";
2423f660 7002 break;
1176b328 7003 case CP0_REG25__PERFCNT0:
7480515f 7004 /* gen_helper_mtc0_performance1(arg); */
294fc2ea 7005 register_name = "Performance1";
3570d7f6 7006 goto cp0_unimplemented;
1176b328 7007 case CP0_REG25__PERFCTL1:
7480515f 7008 /* gen_helper_mtc0_performance2(arg); */
294fc2ea 7009 register_name = "Performance2";
3570d7f6 7010 goto cp0_unimplemented;
1176b328 7011 case CP0_REG25__PERFCNT1:
7480515f 7012 /* gen_helper_mtc0_performance3(arg); */
294fc2ea 7013 register_name = "Performance3";
3570d7f6 7014 goto cp0_unimplemented;
1176b328 7015 case CP0_REG25__PERFCTL2:
7480515f 7016 /* gen_helper_mtc0_performance4(arg); */
294fc2ea 7017 register_name = "Performance4";
3570d7f6 7018 goto cp0_unimplemented;
1176b328 7019 case CP0_REG25__PERFCNT2:
7480515f 7020 /* gen_helper_mtc0_performance5(arg); */
294fc2ea 7021 register_name = "Performance5";
3570d7f6 7022 goto cp0_unimplemented;
1176b328 7023 case CP0_REG25__PERFCTL3:
7480515f 7024 /* gen_helper_mtc0_performance6(arg); */
294fc2ea 7025 register_name = "Performance6";
3570d7f6 7026 goto cp0_unimplemented;
1176b328 7027 case CP0_REG25__PERFCNT3:
7480515f 7028 /* gen_helper_mtc0_performance7(arg); */
294fc2ea 7029 register_name = "Performance7";
3570d7f6 7030 goto cp0_unimplemented;
7a387fff 7031 default:
f31b035a 7032 goto cp0_unimplemented;
7a387fff 7033 }
8c0fdd85 7034 break;
04992c8c 7035 case CP0_REGISTER_26:
0d74a222 7036 switch (sel) {
dbbf08b2 7037 case CP0_REG26__ERRCTL:
0d74a222 7038 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7039 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 7040 register_name = "ErrCtl";
0d74a222
LA
7041 break;
7042 default:
7043 goto cp0_unimplemented;
7044 }
2423f660 7045 break;
04992c8c 7046 case CP0_REGISTER_27:
7a387fff 7047 switch (sel) {
5a10873d 7048 case CP0_REG27__CACHERR:
2423f660 7049 /* ignored */
294fc2ea 7050 register_name = "CacheErr";
2423f660 7051 break;
7a387fff 7052 default:
f31b035a 7053 goto cp0_unimplemented;
7a387fff 7054 }
8c0fdd85 7055 break;
04992c8c 7056 case CP0_REGISTER_28:
8c0fdd85 7057 switch (sel) {
a30e2f21
AM
7058 case CP0_REG28__TAGLO:
7059 case CP0_REG28__TAGLO1:
7060 case CP0_REG28__TAGLO2:
7061 case CP0_REG28__TAGLO3:
895c2d04 7062 gen_helper_mtc0_taglo(cpu_env, arg);
294fc2ea 7063 register_name = "TagLo";
8c0fdd85 7064 break;
a30e2f21
AM
7065 case CP0_REG28__DATALO:
7066 case CP0_REG28__DATALO1:
7067 case CP0_REG28__DATALO2:
7068 case CP0_REG28__DATALO3:
895c2d04 7069 gen_helper_mtc0_datalo(cpu_env, arg);
294fc2ea 7070 register_name = "DataLo";
7a387fff 7071 break;
8c0fdd85 7072 default:
f31b035a 7073 goto cp0_unimplemented;
8c0fdd85
TS
7074 }
7075 break;
04992c8c 7076 case CP0_REGISTER_29:
7a387fff 7077 switch (sel) {
af4bb6da
AM
7078 case CP0_REG29__TAGHI:
7079 case CP0_REG29__TAGHI1:
7080 case CP0_REG29__TAGHI2:
7081 case CP0_REG29__TAGHI3:
895c2d04 7082 gen_helper_mtc0_taghi(cpu_env, arg);
294fc2ea 7083 register_name = "TagHi";
7a387fff 7084 break;
af4bb6da
AM
7085 case CP0_REG29__DATAHI:
7086 case CP0_REG29__DATAHI1:
7087 case CP0_REG29__DATAHI2:
7088 case CP0_REG29__DATAHI3:
895c2d04 7089 gen_helper_mtc0_datahi(cpu_env, arg);
294fc2ea 7090 register_name = "DataHi";
7a387fff
TS
7091 break;
7092 default:
294fc2ea 7093 register_name = "invalid sel";
f31b035a 7094 goto cp0_unimplemented;
7a387fff 7095 }
8c0fdd85 7096 break;
04992c8c 7097 case CP0_REGISTER_30:
7a387fff 7098 switch (sel) {
4bcf121e 7099 case CP0_REG30__ERROREPC:
d54a299b 7100 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 7101 register_name = "ErrorEPC";
2423f660 7102 break;
7a387fff 7103 default:
f31b035a 7104 goto cp0_unimplemented;
7a387fff 7105 }
8c0fdd85 7106 break;
04992c8c 7107 case CP0_REGISTER_31:
7a387fff 7108 switch (sel) {
14d92efd 7109 case CP0_REG31__DESAVE:
f1aa6320 7110 /* EJTAG support */
7db13fae 7111 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 7112 register_name = "DESAVE";
2423f660 7113 break;
14d92efd
AM
7114 case CP0_REG31__KSCRATCH1:
7115 case CP0_REG31__KSCRATCH2:
7116 case CP0_REG31__KSCRATCH3:
7117 case CP0_REG31__KSCRATCH4:
7118 case CP0_REG31__KSCRATCH5:
7119 case CP0_REG31__KSCRATCH6:
f31b035a
LA
7120 CP0_CHECK(ctx->kscrexist & (1 << sel));
7121 tcg_gen_st_tl(arg, cpu_env,
05aa7e93 7122 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 7123 register_name = "KScratch";
e98c0d17 7124 break;
7a387fff 7125 default:
f31b035a 7126 goto cp0_unimplemented;
7a387fff 7127 }
8c0fdd85
TS
7128 break;
7129 default:
f31b035a 7130 goto cp0_unimplemented;
8c0fdd85 7131 }
294fc2ea 7132 trace_mips_translate_c0("mtc0", register_name, reg, sel);
b44a7fb1 7133
bf20dc07 7134 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7135 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480515f
AM
7136 /*
7137 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7138 * translated code to check for pending interrupts.
7139 */
eeb3bba8
EC
7140 gen_save_pc(ctx->base.pc_next + 4);
7141 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7142 }
8c0fdd85
TS
7143 return;
7144
f31b035a 7145cp0_unimplemented:
294fc2ea
AM
7146 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7147 register_name, reg, sel);
8c0fdd85
TS
7148}
7149
d26bc211 7150#if defined(TARGET_MIPS64)
d75c135e 7151static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8 7152{
294fc2ea 7153 const char *register_name = "invalid";
9c2149c8 7154
1f8929d2 7155 if (sel != 0) {
bbd5e4a2 7156 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 7157 }
e189e748 7158
9c2149c8 7159 switch (reg) {
04992c8c 7160 case CP0_REGISTER_00:
9c2149c8 7161 switch (sel) {
1b142da5 7162 case CP0_REG00__INDEX:
7db13fae 7163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
294fc2ea 7164 register_name = "Index";
9c2149c8 7165 break;
1b142da5 7166 case CP0_REG00__MVPCONTROL:
f31b035a 7167 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7168 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
294fc2ea 7169 register_name = "MVPControl";
ead9360e 7170 break;
1b142da5 7171 case CP0_REG00__MVPCONF0:
f31b035a 7172 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7173 gen_helper_mfc0_mvpconf0(arg, cpu_env);
294fc2ea 7174 register_name = "MVPConf0";
ead9360e 7175 break;
1b142da5 7176 case CP0_REG00__MVPCONF1:
f31b035a 7177 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7178 gen_helper_mfc0_mvpconf1(arg, cpu_env);
294fc2ea 7179 register_name = "MVPConf1";
ead9360e 7180 break;
1b142da5 7181 case CP0_REG00__VPCONTROL:
01bc435b
YK
7182 CP0_CHECK(ctx->vp);
7183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
294fc2ea 7184 register_name = "VPControl";
01bc435b 7185 break;
9c2149c8 7186 default:
f31b035a 7187 goto cp0_unimplemented;
9c2149c8
TS
7188 }
7189 break;
04992c8c 7190 case CP0_REGISTER_01:
9c2149c8 7191 switch (sel) {
30deb460 7192 case CP0_REG01__RANDOM:
2e211e0a 7193 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
895c2d04 7194 gen_helper_mfc0_random(arg, cpu_env);
294fc2ea 7195 register_name = "Random";
2423f660 7196 break;
30deb460 7197 case CP0_REG01__VPECONTROL:
f31b035a 7198 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
294fc2ea 7200 register_name = "VPEControl";
ead9360e 7201 break;
30deb460 7202 case CP0_REG01__VPECONF0:
f31b035a 7203 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
294fc2ea 7205 register_name = "VPEConf0";
ead9360e 7206 break;
30deb460 7207 case CP0_REG01__VPECONF1:
f31b035a 7208 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7209 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
294fc2ea 7210 register_name = "VPEConf1";
ead9360e 7211 break;
30deb460 7212 case CP0_REG01__YQMASK:
f31b035a 7213 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7214 tcg_gen_ld_tl(arg, cpu_env,
7215 offsetof(CPUMIPSState, CP0_YQMask));
294fc2ea 7216 register_name = "YQMask";
ead9360e 7217 break;
30deb460 7218 case CP0_REG01__VPESCHEDULE:
f31b035a 7219 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7220 tcg_gen_ld_tl(arg, cpu_env,
7221 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 7222 register_name = "VPESchedule";
ead9360e 7223 break;
30deb460 7224 case CP0_REG01__VPESCHEFBACK:
f31b035a 7225 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7226 tcg_gen_ld_tl(arg, cpu_env,
7227 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 7228 register_name = "VPEScheFBack";
ead9360e 7229 break;
30deb460 7230 case CP0_REG01__VPEOPT:
f31b035a 7231 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
294fc2ea 7233 register_name = "VPEOpt";
ead9360e 7234 break;
9c2149c8 7235 default:
f31b035a 7236 goto cp0_unimplemented;
9c2149c8
TS
7237 }
7238 break;
04992c8c 7239 case CP0_REGISTER_02:
9c2149c8 7240 switch (sel) {
6d27d5bd 7241 case CP0_REG02__ENTRYLO0:
05aa7e93
AM
7242 tcg_gen_ld_tl(arg, cpu_env,
7243 offsetof(CPUMIPSState, CP0_EntryLo0));
294fc2ea 7244 register_name = "EntryLo0";
2423f660 7245 break;
6d27d5bd 7246 case CP0_REG02__TCSTATUS:
f31b035a 7247 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7248 gen_helper_mfc0_tcstatus(arg, cpu_env);
294fc2ea 7249 register_name = "TCStatus";
ead9360e 7250 break;
6d27d5bd 7251 case CP0_REG02__TCBIND:
f31b035a 7252 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7253 gen_helper_mfc0_tcbind(arg, cpu_env);
294fc2ea 7254 register_name = "TCBind";
ead9360e 7255 break;
6d27d5bd 7256 case CP0_REG02__TCRESTART:
f31b035a 7257 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7258 gen_helper_dmfc0_tcrestart(arg, cpu_env);
294fc2ea 7259 register_name = "TCRestart";
ead9360e 7260 break;
6d27d5bd 7261 case CP0_REG02__TCHALT:
f31b035a 7262 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7263 gen_helper_dmfc0_tchalt(arg, cpu_env);
294fc2ea 7264 register_name = "TCHalt";
ead9360e 7265 break;
6d27d5bd 7266 case CP0_REG02__TCCONTEXT:
f31b035a 7267 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7268 gen_helper_dmfc0_tccontext(arg, cpu_env);
294fc2ea 7269 register_name = "TCContext";
ead9360e 7270 break;
6d27d5bd 7271 case CP0_REG02__TCSCHEDULE:
f31b035a 7272 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7273 gen_helper_dmfc0_tcschedule(arg, cpu_env);
294fc2ea 7274 register_name = "TCSchedule";
ead9360e 7275 break;
6d27d5bd 7276 case CP0_REG02__TCSCHEFBACK:
f31b035a 7277 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7278 gen_helper_dmfc0_tcschefback(arg, cpu_env);
294fc2ea 7279 register_name = "TCScheFBack";
ead9360e 7280 break;
9c2149c8 7281 default:
f31b035a 7282 goto cp0_unimplemented;
9c2149c8
TS
7283 }
7284 break;
04992c8c 7285 case CP0_REGISTER_03:
9c2149c8 7286 switch (sel) {
acd37316 7287 case CP0_REG03__ENTRYLO1:
7db13fae 7288 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
294fc2ea 7289 register_name = "EntryLo1";
2423f660 7290 break;
acd37316 7291 case CP0_REG03__GLOBALNUM:
01bc435b
YK
7292 CP0_CHECK(ctx->vp);
7293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
294fc2ea 7294 register_name = "GlobalNumber";
01bc435b 7295 break;
9c2149c8 7296 default:
f31b035a 7297 goto cp0_unimplemented;
1579a72e 7298 }
9c2149c8 7299 break;
04992c8c 7300 case CP0_REGISTER_04:
9c2149c8 7301 switch (sel) {
020fe379 7302 case CP0_REG04__CONTEXT:
7db13fae 7303 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
294fc2ea 7304 register_name = "Context";
2423f660 7305 break;
020fe379
AM
7306 case CP0_REG04__CONTEXTCONFIG:
7307 /* SmartMIPS ASE */
7308 /* gen_helper_dmfc0_contextconfig(arg); */
294fc2ea 7309 register_name = "ContextConfig";
f31b035a 7310 goto cp0_unimplemented;
020fe379 7311 case CP0_REG04__USERLOCAL:
f31b035a
LA
7312 CP0_CHECK(ctx->ulri);
7313 tcg_gen_ld_tl(arg, cpu_env,
7314 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 7315 register_name = "UserLocal";
d279279e 7316 break;
99029be1
YK
7317 case CP0_REG04__MMID:
7318 CP0_CHECK(ctx->mi);
7319 gen_helper_mtc0_memorymapid(cpu_env, arg);
7320 register_name = "MMID";
7321 break;
9c2149c8 7322 default:
f31b035a 7323 goto cp0_unimplemented;
876d4b07 7324 }
9c2149c8 7325 break;
04992c8c 7326 case CP0_REGISTER_05:
9c2149c8 7327 switch (sel) {
a1e76353 7328 case CP0_REG05__PAGEMASK:
7db13fae 7329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
294fc2ea 7330 register_name = "PageMask";
2423f660 7331 break;
a1e76353 7332 case CP0_REG05__PAGEGRAIN:
7a47bae5 7333 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
294fc2ea 7335 register_name = "PageGrain";
2423f660 7336 break;
a1e76353 7337 case CP0_REG05__SEGCTL0:
cec56a73
JH
7338 CP0_CHECK(ctx->sc);
7339 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
294fc2ea 7340 register_name = "SegCtl0";
cec56a73 7341 break;
a1e76353 7342 case CP0_REG05__SEGCTL1:
cec56a73
JH
7343 CP0_CHECK(ctx->sc);
7344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
294fc2ea 7345 register_name = "SegCtl1";
cec56a73 7346 break;
a1e76353 7347 case CP0_REG05__SEGCTL2:
cec56a73
JH
7348 CP0_CHECK(ctx->sc);
7349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
294fc2ea 7350 register_name = "SegCtl2";
cec56a73 7351 break;
a1e76353 7352 case CP0_REG05__PWBASE:
5e31fdd5
YK
7353 check_pw(ctx);
7354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 7355 register_name = "PWBase";
5e31fdd5 7356 break;
a1e76353 7357 case CP0_REG05__PWFIELD:
fa75ad14
YK
7358 check_pw(ctx);
7359 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
294fc2ea 7360 register_name = "PWField";
fa75ad14 7361 break;
a1e76353 7362 case CP0_REG05__PWSIZE:
20b28ebc
YK
7363 check_pw(ctx);
7364 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
294fc2ea 7365 register_name = "PWSize";
20b28ebc 7366 break;
9c2149c8 7367 default:
f31b035a 7368 goto cp0_unimplemented;
876d4b07 7369 }
9c2149c8 7370 break;
04992c8c 7371 case CP0_REGISTER_06:
9c2149c8 7372 switch (sel) {
9023594b 7373 case CP0_REG06__WIRED:
7db13fae 7374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
294fc2ea 7375 register_name = "Wired";
2423f660 7376 break;
9023594b 7377 case CP0_REG06__SRSCONF0:
7a47bae5 7378 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
294fc2ea 7380 register_name = "SRSConf0";
ead9360e 7381 break;
9023594b 7382 case CP0_REG06__SRSCONF1:
7a47bae5 7383 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
294fc2ea 7385 register_name = "SRSConf1";
ead9360e 7386 break;
9023594b 7387 case CP0_REG06__SRSCONF2:
7a47bae5 7388 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
294fc2ea 7390 register_name = "SRSConf2";
ead9360e 7391 break;
9023594b 7392 case CP0_REG06__SRSCONF3:
7a47bae5 7393 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
294fc2ea 7395 register_name = "SRSConf3";
ead9360e 7396 break;
9023594b 7397 case CP0_REG06__SRSCONF4:
7a47bae5 7398 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
294fc2ea 7400 register_name = "SRSConf4";
ead9360e 7401 break;
9023594b 7402 case CP0_REG06__PWCTL:
103be64c
YK
7403 check_pw(ctx);
7404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
294fc2ea 7405 register_name = "PWCtl";
103be64c 7406 break;
9c2149c8 7407 default:
f31b035a 7408 goto cp0_unimplemented;
876d4b07 7409 }
9c2149c8 7410 break;
04992c8c 7411 case CP0_REGISTER_07:
9c2149c8 7412 switch (sel) {
143a9875 7413 case CP0_REG07__HWRENA:
7a47bae5 7414 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7415 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
294fc2ea 7416 register_name = "HWREna";
2423f660 7417 break;
9c2149c8 7418 default:
f31b035a 7419 goto cp0_unimplemented;
876d4b07 7420 }
9c2149c8 7421 break;
04992c8c 7422 case CP0_REGISTER_08:
9c2149c8 7423 switch (sel) {
67d167d2 7424 case CP0_REG08__BADVADDR:
7db13fae 7425 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
294fc2ea 7426 register_name = "BadVAddr";
2423f660 7427 break;
67d167d2 7428 case CP0_REG08__BADINSTR:
f31b035a
LA
7429 CP0_CHECK(ctx->bi);
7430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
294fc2ea 7431 register_name = "BadInstr";
aea14095 7432 break;
67d167d2 7433 case CP0_REG08__BADINSTRP:
f31b035a
LA
7434 CP0_CHECK(ctx->bp);
7435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
294fc2ea 7436 register_name = "BadInstrP";
aea14095 7437 break;
67d167d2 7438 case CP0_REG08__BADINSTRX:
25beba9b
SM
7439 CP0_CHECK(ctx->bi);
7440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7441 tcg_gen_andi_tl(arg, arg, ~0xffff);
294fc2ea 7442 register_name = "BadInstrX";
25beba9b 7443 break;
9c2149c8 7444 default:
f31b035a 7445 goto cp0_unimplemented;
876d4b07 7446 }
9c2149c8 7447 break;
04992c8c 7448 case CP0_REGISTER_09:
9c2149c8 7449 switch (sel) {
e5a98a72 7450 case CP0_REG09__COUNT:
2e70f6ef 7451 /* Mark as an IO operation because we read the time. */
eeb3bba8 7452 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7453 gen_io_start();
bd79255d 7454 }
895c2d04 7455 gen_helper_mfc0_count(arg, cpu_env);
7480515f
AM
7456 /*
7457 * Break the TB to be able to take timer interrupts immediately
7458 * after reading count. DISAS_STOP isn't sufficient, we need to
7459 * ensure we break completely out of translated code.
7460 */
eeb3bba8
EC
7461 gen_save_pc(ctx->base.pc_next + 4);
7462 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 7463 register_name = "Count";
2423f660 7464 break;
e5a98a72 7465 case CP0_REG09__SAARI:
5fb2dcd1
YK
7466 CP0_CHECK(ctx->saar);
7467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
294fc2ea 7468 register_name = "SAARI";
5fb2dcd1 7469 break;
e5a98a72 7470 case CP0_REG09__SAAR:
5fb2dcd1
YK
7471 CP0_CHECK(ctx->saar);
7472 gen_helper_dmfc0_saar(arg, cpu_env);
294fc2ea 7473 register_name = "SAAR";
5fb2dcd1 7474 break;
9c2149c8 7475 default:
f31b035a 7476 goto cp0_unimplemented;
876d4b07 7477 }
9c2149c8 7478 break;
04992c8c 7479 case CP0_REGISTER_10:
9c2149c8 7480 switch (sel) {
860ffef0 7481 case CP0_REG10__ENTRYHI:
7db13fae 7482 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
294fc2ea 7483 register_name = "EntryHi";
2423f660 7484 break;
9c2149c8 7485 default:
f31b035a 7486 goto cp0_unimplemented;
876d4b07 7487 }
9c2149c8 7488 break;
04992c8c 7489 case CP0_REGISTER_11:
9c2149c8 7490 switch (sel) {
f5f3834f 7491 case CP0_REG11__COMPARE:
7db13fae 7492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
294fc2ea 7493 register_name = "Compare";
2423f660 7494 break;
876d4b07 7495 /* 6,7 are implementation dependent */
9c2149c8 7496 default:
f31b035a 7497 goto cp0_unimplemented;
876d4b07 7498 }
9c2149c8 7499 break;
04992c8c 7500 case CP0_REGISTER_12:
9c2149c8 7501 switch (sel) {
2b084867 7502 case CP0_REG12__STATUS:
7db13fae 7503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
294fc2ea 7504 register_name = "Status";
2423f660 7505 break;
2b084867 7506 case CP0_REG12__INTCTL:
7a47bae5 7507 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
294fc2ea 7509 register_name = "IntCtl";
2423f660 7510 break;
2b084867 7511 case CP0_REG12__SRSCTL:
7a47bae5 7512 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
294fc2ea 7514 register_name = "SRSCtl";
2423f660 7515 break;
2b084867 7516 case CP0_REG12__SRSMAP:
7a47bae5 7517 check_insn(ctx, ISA_MIPS_R2);
7db13fae 7518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
294fc2ea 7519 register_name = "SRSMap";
2423f660 7520 break;
9c2149c8 7521 default:
f31b035a 7522 goto cp0_unimplemented;
876d4b07 7523 }
9c2149c8 7524 break;
04992c8c 7525 case CP0_REGISTER_13:
9c2149c8 7526 switch (sel) {
e3c7559d 7527 case CP0_REG13__CAUSE:
7db13fae 7528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
294fc2ea 7529 register_name = "Cause";
2423f660 7530 break;
9c2149c8 7531 default:
f31b035a 7532 goto cp0_unimplemented;
876d4b07 7533 }
9c2149c8 7534 break;
04992c8c 7535 case CP0_REGISTER_14:
9c2149c8 7536 switch (sel) {
35e4b54d 7537 case CP0_REG14__EPC:
7db13fae 7538 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 7539 register_name = "EPC";
2423f660 7540 break;
9c2149c8 7541 default:
f31b035a 7542 goto cp0_unimplemented;
876d4b07 7543 }
9c2149c8 7544 break;
04992c8c 7545 case CP0_REGISTER_15:
9c2149c8 7546 switch (sel) {
4466cd49 7547 case CP0_REG15__PRID:
7db13fae 7548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
294fc2ea 7549 register_name = "PRid";
2423f660 7550 break;
4466cd49 7551 case CP0_REG15__EBASE:
7a47bae5 7552 check_insn(ctx, ISA_MIPS_R2);
74dbf824 7553 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
294fc2ea 7554 register_name = "EBase";
2423f660 7555 break;
4466cd49 7556 case CP0_REG15__CMGCRBASE:
7a47bae5 7557 check_insn(ctx, ISA_MIPS_R2);
c870e3f5
YK
7558 CP0_CHECK(ctx->cmgcr);
7559 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
294fc2ea 7560 register_name = "CMGCRBase";
c870e3f5 7561 break;
9c2149c8 7562 default:
f31b035a 7563 goto cp0_unimplemented;
876d4b07 7564 }
9c2149c8 7565 break;
04992c8c 7566 case CP0_REGISTER_16:
9c2149c8 7567 switch (sel) {
433efb4c 7568 case CP0_REG16__CONFIG:
7db13fae 7569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
294fc2ea 7570 register_name = "Config";
9c2149c8 7571 break;
433efb4c 7572 case CP0_REG16__CONFIG1:
7db13fae 7573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
294fc2ea 7574 register_name = "Config1";
9c2149c8 7575 break;
433efb4c 7576 case CP0_REG16__CONFIG2:
7db13fae 7577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
294fc2ea 7578 register_name = "Config2";
9c2149c8 7579 break;
433efb4c 7580 case CP0_REG16__CONFIG3:
7db13fae 7581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
294fc2ea 7582 register_name = "Config3";
9c2149c8 7583 break;
433efb4c 7584 case CP0_REG16__CONFIG4:
faf1f68b 7585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
294fc2ea 7586 register_name = "Config4";
faf1f68b 7587 break;
433efb4c 7588 case CP0_REG16__CONFIG5:
faf1f68b 7589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
294fc2ea 7590 register_name = "Config5";
faf1f68b 7591 break;
05aa7e93 7592 /* 6,7 are implementation dependent */
433efb4c 7593 case CP0_REG16__CONFIG6:
7db13fae 7594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
294fc2ea 7595 register_name = "Config6";
f0b3f3ae 7596 break;
433efb4c 7597 case CP0_REG16__CONFIG7:
7db13fae 7598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
294fc2ea 7599 register_name = "Config7";
f0b3f3ae 7600 break;
9c2149c8 7601 default:
f31b035a 7602 goto cp0_unimplemented;
9c2149c8
TS
7603 }
7604 break;
04992c8c 7605 case CP0_REGISTER_17:
9c2149c8 7606 switch (sel) {
706ce142 7607 case CP0_REG17__LLADDR:
895c2d04 7608 gen_helper_dmfc0_lladdr(arg, cpu_env);
294fc2ea 7609 register_name = "LLAddr";
2423f660 7610 break;
706ce142 7611 case CP0_REG17__MAAR:
f6d4dd81
YK
7612 CP0_CHECK(ctx->mrp);
7613 gen_helper_dmfc0_maar(arg, cpu_env);
294fc2ea 7614 register_name = "MAAR";
f6d4dd81 7615 break;
706ce142 7616 case CP0_REG17__MAARI:
f6d4dd81
YK
7617 CP0_CHECK(ctx->mrp);
7618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
294fc2ea 7619 register_name = "MAARI";
f6d4dd81 7620 break;
9c2149c8 7621 default:
f31b035a 7622 goto cp0_unimplemented;
9c2149c8
TS
7623 }
7624 break;
04992c8c 7625 case CP0_REGISTER_18:
9c2149c8 7626 switch (sel) {
e8dcfe82
AM
7627 case CP0_REG18__WATCHLO0:
7628 case CP0_REG18__WATCHLO1:
7629 case CP0_REG18__WATCHLO2:
7630 case CP0_REG18__WATCHLO3:
7631 case CP0_REG18__WATCHLO4:
7632 case CP0_REG18__WATCHLO5:
7633 case CP0_REG18__WATCHLO6:
7634 case CP0_REG18__WATCHLO7:
fa192d49 7635 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7636 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
294fc2ea 7637 register_name = "WatchLo";
2423f660 7638 break;
9c2149c8 7639 default:
f31b035a 7640 goto cp0_unimplemented;
9c2149c8
TS
7641 }
7642 break;
04992c8c 7643 case CP0_REGISTER_19:
9c2149c8 7644 switch (sel) {
be274dc1
AM
7645 case CP0_REG19__WATCHHI0:
7646 case CP0_REG19__WATCHHI1:
7647 case CP0_REG19__WATCHHI2:
7648 case CP0_REG19__WATCHHI3:
7649 case CP0_REG19__WATCHHI4:
7650 case CP0_REG19__WATCHHI5:
7651 case CP0_REG19__WATCHHI6:
7652 case CP0_REG19__WATCHHI7:
fa192d49 7653 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
feafe82c 7654 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
294fc2ea 7655 register_name = "WatchHi";
2423f660 7656 break;
9c2149c8 7657 default:
f31b035a 7658 goto cp0_unimplemented;
9c2149c8
TS
7659 }
7660 break;
04992c8c 7661 case CP0_REGISTER_20:
9c2149c8 7662 switch (sel) {
14f92b0b 7663 case CP0_REG20__XCONTEXT:
d75c135e 7664 check_insn(ctx, ISA_MIPS3);
7db13fae 7665 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
294fc2ea 7666 register_name = "XContext";
2423f660 7667 break;
9c2149c8 7668 default:
f31b035a 7669 goto cp0_unimplemented;
9c2149c8
TS
7670 }
7671 break;
04992c8c 7672 case CP0_REGISTER_21:
05aa7e93 7673 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 7674 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
9c2149c8
TS
7675 switch (sel) {
7676 case 0:
7db13fae 7677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
294fc2ea 7678 register_name = "Framemask";
2423f660 7679 break;
9c2149c8 7680 default:
f31b035a 7681 goto cp0_unimplemented;
9c2149c8
TS
7682 }
7683 break;
04992c8c 7684 case CP0_REGISTER_22:
d9bea114 7685 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 7686 register_name = "'Diagnostic"; /* implementation dependent */
2423f660 7687 break;
04992c8c 7688 case CP0_REGISTER_23:
9c2149c8 7689 switch (sel) {
4cbf4b6d 7690 case CP0_REG23__DEBUG:
895c2d04 7691 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
294fc2ea 7692 register_name = "Debug";
2423f660 7693 break;
4cbf4b6d
AM
7694 case CP0_REG23__TRACECONTROL:
7695 /* PDtrace support */
7696 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
294fc2ea 7697 register_name = "TraceControl";
3570d7f6 7698 goto cp0_unimplemented;
4cbf4b6d
AM
7699 case CP0_REG23__TRACECONTROL2:
7700 /* PDtrace support */
7701 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
294fc2ea 7702 register_name = "TraceControl2";
3570d7f6 7703 goto cp0_unimplemented;
4cbf4b6d
AM
7704 case CP0_REG23__USERTRACEDATA1:
7705 /* PDtrace support */
7706 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7707 register_name = "UserTraceData1";
3570d7f6 7708 goto cp0_unimplemented;
4cbf4b6d
AM
7709 case CP0_REG23__TRACEIBPC:
7710 /* PDtrace support */
7711 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
7712 register_name = "TraceIBPC";
7713 goto cp0_unimplemented;
7714 case CP0_REG23__TRACEDBPC:
7715 /* PDtrace support */
7716 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
7717 register_name = "TraceDBPC";
3570d7f6 7718 goto cp0_unimplemented;
9c2149c8 7719 default:
f31b035a 7720 goto cp0_unimplemented;
9c2149c8
TS
7721 }
7722 break;
04992c8c 7723 case CP0_REGISTER_24:
9c2149c8 7724 switch (sel) {
8d7b4b6e 7725 case CP0_REG24__DEPC:
f0b3f3ae 7726 /* EJTAG support */
7db13fae 7727 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 7728 register_name = "DEPC";
2423f660 7729 break;
9c2149c8 7730 default:
f31b035a 7731 goto cp0_unimplemented;
9c2149c8
TS
7732 }
7733 break;
04992c8c 7734 case CP0_REGISTER_25:
9c2149c8 7735 switch (sel) {
1176b328 7736 case CP0_REG25__PERFCTL0:
7db13fae 7737 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
294fc2ea 7738 register_name = "Performance0";
9c2149c8 7739 break;
1176b328 7740 case CP0_REG25__PERFCNT0:
7480515f 7741 /* gen_helper_dmfc0_performance1(arg); */
294fc2ea 7742 register_name = "Performance1";
3570d7f6 7743 goto cp0_unimplemented;
1176b328 7744 case CP0_REG25__PERFCTL1:
7480515f 7745 /* gen_helper_dmfc0_performance2(arg); */
294fc2ea 7746 register_name = "Performance2";
3570d7f6 7747 goto cp0_unimplemented;
1176b328 7748 case CP0_REG25__PERFCNT1:
7480515f 7749 /* gen_helper_dmfc0_performance3(arg); */
294fc2ea 7750 register_name = "Performance3";
3570d7f6 7751 goto cp0_unimplemented;
1176b328 7752 case CP0_REG25__PERFCTL2:
7480515f 7753 /* gen_helper_dmfc0_performance4(arg); */
294fc2ea 7754 register_name = "Performance4";
3570d7f6 7755 goto cp0_unimplemented;
1176b328 7756 case CP0_REG25__PERFCNT2:
7480515f 7757 /* gen_helper_dmfc0_performance5(arg); */
294fc2ea 7758 register_name = "Performance5";
3570d7f6 7759 goto cp0_unimplemented;
1176b328 7760 case CP0_REG25__PERFCTL3:
7480515f 7761 /* gen_helper_dmfc0_performance6(arg); */
294fc2ea 7762 register_name = "Performance6";
3570d7f6 7763 goto cp0_unimplemented;
1176b328 7764 case CP0_REG25__PERFCNT3:
7480515f 7765 /* gen_helper_dmfc0_performance7(arg); */
294fc2ea 7766 register_name = "Performance7";
3570d7f6 7767 goto cp0_unimplemented;
9c2149c8 7768 default:
f31b035a 7769 goto cp0_unimplemented;
9c2149c8
TS
7770 }
7771 break;
04992c8c 7772 case CP0_REGISTER_26:
0d74a222 7773 switch (sel) {
dbbf08b2 7774 case CP0_REG26__ERRCTL:
0d74a222 7775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
294fc2ea 7776 register_name = "ErrCtl";
0d74a222
LA
7777 break;
7778 default:
7779 goto cp0_unimplemented;
7780 }
da80682b 7781 break;
04992c8c 7782 case CP0_REGISTER_27:
9c2149c8
TS
7783 switch (sel) {
7784 /* ignored */
5a10873d 7785 case CP0_REG27__CACHERR:
d9bea114 7786 tcg_gen_movi_tl(arg, 0); /* unimplemented */
294fc2ea 7787 register_name = "CacheErr";
2423f660 7788 break;
9c2149c8 7789 default:
f31b035a 7790 goto cp0_unimplemented;
9c2149c8
TS
7791 }
7792 break;
04992c8c 7793 case CP0_REGISTER_28:
9c2149c8 7794 switch (sel) {
a30e2f21
AM
7795 case CP0_REG28__TAGLO:
7796 case CP0_REG28__TAGLO1:
7797 case CP0_REG28__TAGLO2:
7798 case CP0_REG28__TAGLO3:
7db13fae 7799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
294fc2ea 7800 register_name = "TagLo";
9c2149c8 7801 break;
a30e2f21
AM
7802 case CP0_REG28__DATALO:
7803 case CP0_REG28__DATALO1:
7804 case CP0_REG28__DATALO2:
7805 case CP0_REG28__DATALO3:
7db13fae 7806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
294fc2ea 7807 register_name = "DataLo";
9c2149c8
TS
7808 break;
7809 default:
f31b035a 7810 goto cp0_unimplemented;
9c2149c8
TS
7811 }
7812 break;
04992c8c 7813 case CP0_REGISTER_29:
9c2149c8 7814 switch (sel) {
af4bb6da
AM
7815 case CP0_REG29__TAGHI:
7816 case CP0_REG29__TAGHI1:
7817 case CP0_REG29__TAGHI2:
7818 case CP0_REG29__TAGHI3:
7db13fae 7819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
294fc2ea 7820 register_name = "TagHi";
9c2149c8 7821 break;
af4bb6da
AM
7822 case CP0_REG29__DATAHI:
7823 case CP0_REG29__DATAHI1:
7824 case CP0_REG29__DATAHI2:
7825 case CP0_REG29__DATAHI3:
7db13fae 7826 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
294fc2ea 7827 register_name = "DataHi";
9c2149c8
TS
7828 break;
7829 default:
f31b035a 7830 goto cp0_unimplemented;
9c2149c8
TS
7831 }
7832 break;
04992c8c 7833 case CP0_REGISTER_30:
9c2149c8 7834 switch (sel) {
4bcf121e 7835 case CP0_REG30__ERROREPC:
7db13fae 7836 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 7837 register_name = "ErrorEPC";
2423f660 7838 break;
9c2149c8 7839 default:
f31b035a 7840 goto cp0_unimplemented;
9c2149c8
TS
7841 }
7842 break;
04992c8c 7843 case CP0_REGISTER_31:
9c2149c8 7844 switch (sel) {
14d92efd 7845 case CP0_REG31__DESAVE:
f0b3f3ae 7846 /* EJTAG support */
7db13fae 7847 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 7848 register_name = "DESAVE";
2423f660 7849 break;
14d92efd
AM
7850 case CP0_REG31__KSCRATCH1:
7851 case CP0_REG31__KSCRATCH2:
7852 case CP0_REG31__KSCRATCH3:
7853 case CP0_REG31__KSCRATCH4:
7854 case CP0_REG31__KSCRATCH5:
7855 case CP0_REG31__KSCRATCH6:
f31b035a
LA
7856 CP0_CHECK(ctx->kscrexist & (1 << sel));
7857 tcg_gen_ld_tl(arg, cpu_env,
05aa7e93 7858 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 7859 register_name = "KScratch";
e98c0d17 7860 break;
9c2149c8 7861 default:
f31b035a 7862 goto cp0_unimplemented;
9c2149c8
TS
7863 }
7864 break;
7865 default:
f31b035a 7866 goto cp0_unimplemented;
9c2149c8 7867 }
294fc2ea 7868 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9c2149c8
TS
7869 return;
7870
f31b035a 7871cp0_unimplemented:
294fc2ea
AM
7872 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7873 register_name, reg, sel);
f31b035a 7874 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7875}
7876
d75c135e 7877static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8 7878{
294fc2ea 7879 const char *register_name = "invalid";
9c2149c8 7880
1f8929d2 7881 if (sel != 0) {
bbd5e4a2 7882 check_insn(ctx, ISA_MIPS_R1);
1f8929d2 7883 }
e189e748 7884
eeb3bba8 7885 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7886 gen_io_start();
bd79255d 7887 }
2e70f6ef 7888
9c2149c8 7889 switch (reg) {
04992c8c 7890 case CP0_REGISTER_00:
9c2149c8 7891 switch (sel) {
1b142da5 7892 case CP0_REG00__INDEX:
895c2d04 7893 gen_helper_mtc0_index(cpu_env, arg);
294fc2ea 7894 register_name = "Index";
9c2149c8 7895 break;
1b142da5 7896 case CP0_REG00__MVPCONTROL:
f31b035a 7897 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7898 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
294fc2ea 7899 register_name = "MVPControl";
ead9360e 7900 break;
1b142da5 7901 case CP0_REG00__MVPCONF0:
f31b035a 7902 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7903 /* ignored */
294fc2ea 7904 register_name = "MVPConf0";
ead9360e 7905 break;
1b142da5 7906 case CP0_REG00__MVPCONF1:
f31b035a 7907 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7908 /* ignored */
294fc2ea 7909 register_name = "MVPConf1";
ead9360e 7910 break;
1b142da5 7911 case CP0_REG00__VPCONTROL:
01bc435b
YK
7912 CP0_CHECK(ctx->vp);
7913 /* ignored */
294fc2ea 7914 register_name = "VPControl";
01bc435b 7915 break;
9c2149c8 7916 default:
f31b035a 7917 goto cp0_unimplemented;
9c2149c8
TS
7918 }
7919 break;
04992c8c 7920 case CP0_REGISTER_01:
9c2149c8 7921 switch (sel) {
30deb460 7922 case CP0_REG01__RANDOM:
2423f660 7923 /* ignored */
294fc2ea 7924 register_name = "Random";
2423f660 7925 break;
30deb460 7926 case CP0_REG01__VPECONTROL:
f31b035a 7927 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7928 gen_helper_mtc0_vpecontrol(cpu_env, arg);
294fc2ea 7929 register_name = "VPEControl";
ead9360e 7930 break;
30deb460 7931 case CP0_REG01__VPECONF0:
f31b035a 7932 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7933 gen_helper_mtc0_vpeconf0(cpu_env, arg);
294fc2ea 7934 register_name = "VPEConf0";
ead9360e 7935 break;
30deb460 7936 case CP0_REG01__VPECONF1:
f31b035a 7937 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7938 gen_helper_mtc0_vpeconf1(cpu_env, arg);
294fc2ea 7939 register_name = "VPEConf1";
ead9360e 7940 break;
30deb460 7941 case CP0_REG01__YQMASK:
f31b035a 7942 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7943 gen_helper_mtc0_yqmask(cpu_env, arg);
294fc2ea 7944 register_name = "YQMask";
ead9360e 7945 break;
30deb460 7946 case CP0_REG01__VPESCHEDULE:
f31b035a 7947 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7948 tcg_gen_st_tl(arg, cpu_env,
7949 offsetof(CPUMIPSState, CP0_VPESchedule));
294fc2ea 7950 register_name = "VPESchedule";
ead9360e 7951 break;
30deb460 7952 case CP0_REG01__VPESCHEFBACK:
f31b035a 7953 CP0_CHECK(ctx->insn_flags & ASE_MT);
05aa7e93
AM
7954 tcg_gen_st_tl(arg, cpu_env,
7955 offsetof(CPUMIPSState, CP0_VPEScheFBack));
294fc2ea 7956 register_name = "VPEScheFBack";
ead9360e 7957 break;
30deb460 7958 case CP0_REG01__VPEOPT:
f31b035a 7959 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7960 gen_helper_mtc0_vpeopt(cpu_env, arg);
294fc2ea 7961 register_name = "VPEOpt";
ead9360e 7962 break;
9c2149c8 7963 default:
f31b035a 7964 goto cp0_unimplemented;
9c2149c8
TS
7965 }
7966 break;
04992c8c 7967 case CP0_REGISTER_02:
9c2149c8 7968 switch (sel) {
6d27d5bd 7969 case CP0_REG02__ENTRYLO0:
7207c7f9 7970 gen_helper_dmtc0_entrylo0(cpu_env, arg);
294fc2ea 7971 register_name = "EntryLo0";
2423f660 7972 break;
6d27d5bd 7973 case CP0_REG02__TCSTATUS:
f31b035a 7974 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7975 gen_helper_mtc0_tcstatus(cpu_env, arg);
294fc2ea 7976 register_name = "TCStatus";
ead9360e 7977 break;
6d27d5bd 7978 case CP0_REG02__TCBIND:
f31b035a 7979 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7980 gen_helper_mtc0_tcbind(cpu_env, arg);
294fc2ea 7981 register_name = "TCBind";
ead9360e 7982 break;
6d27d5bd 7983 case CP0_REG02__TCRESTART:
f31b035a 7984 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7985 gen_helper_mtc0_tcrestart(cpu_env, arg);
294fc2ea 7986 register_name = "TCRestart";
ead9360e 7987 break;
6d27d5bd 7988 case CP0_REG02__TCHALT:
f31b035a 7989 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7990 gen_helper_mtc0_tchalt(cpu_env, arg);
294fc2ea 7991 register_name = "TCHalt";
ead9360e 7992 break;
6d27d5bd 7993 case CP0_REG02__TCCONTEXT:
f31b035a 7994 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7995 gen_helper_mtc0_tccontext(cpu_env, arg);
294fc2ea 7996 register_name = "TCContext";
ead9360e 7997 break;
6d27d5bd 7998 case CP0_REG02__TCSCHEDULE:
f31b035a 7999 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8000 gen_helper_mtc0_tcschedule(cpu_env, arg);
294fc2ea 8001 register_name = "TCSchedule";
ead9360e 8002 break;
6d27d5bd 8003 case CP0_REG02__TCSCHEFBACK:
f31b035a 8004 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8005 gen_helper_mtc0_tcschefback(cpu_env, arg);
294fc2ea 8006 register_name = "TCScheFBack";
ead9360e 8007 break;
9c2149c8 8008 default:
f31b035a 8009 goto cp0_unimplemented;
9c2149c8
TS
8010 }
8011 break;
04992c8c 8012 case CP0_REGISTER_03:
9c2149c8 8013 switch (sel) {
acd37316 8014 case CP0_REG03__ENTRYLO1:
7207c7f9 8015 gen_helper_dmtc0_entrylo1(cpu_env, arg);
294fc2ea 8016 register_name = "EntryLo1";
2423f660 8017 break;
acd37316 8018 case CP0_REG03__GLOBALNUM:
01bc435b
YK
8019 CP0_CHECK(ctx->vp);
8020 /* ignored */
294fc2ea 8021 register_name = "GlobalNumber";
01bc435b 8022 break;
9c2149c8 8023 default:
f31b035a 8024 goto cp0_unimplemented;
876d4b07 8025 }
9c2149c8 8026 break;
04992c8c 8027 case CP0_REGISTER_04:
9c2149c8 8028 switch (sel) {
020fe379 8029 case CP0_REG04__CONTEXT:
895c2d04 8030 gen_helper_mtc0_context(cpu_env, arg);
294fc2ea 8031 register_name = "Context";
2423f660 8032 break;
020fe379
AM
8033 case CP0_REG04__CONTEXTCONFIG:
8034 /* SmartMIPS ASE */
8035 /* gen_helper_dmtc0_contextconfig(arg); */
294fc2ea 8036 register_name = "ContextConfig";
f31b035a 8037 goto cp0_unimplemented;
020fe379 8038 case CP0_REG04__USERLOCAL:
f31b035a
LA
8039 CP0_CHECK(ctx->ulri);
8040 tcg_gen_st_tl(arg, cpu_env,
8041 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
294fc2ea 8042 register_name = "UserLocal";
d279279e 8043 break;
99029be1
YK
8044 case CP0_REG04__MMID:
8045 CP0_CHECK(ctx->mi);
8046 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8047 register_name = "MMID";
8048 break;
9c2149c8 8049 default:
f31b035a 8050 goto cp0_unimplemented;
876d4b07 8051 }
9c2149c8 8052 break;
04992c8c 8053 case CP0_REGISTER_05:
9c2149c8 8054 switch (sel) {
a1e76353 8055 case CP0_REG05__PAGEMASK:
895c2d04 8056 gen_helper_mtc0_pagemask(cpu_env, arg);
294fc2ea 8057 register_name = "PageMask";
2423f660 8058 break;
a1e76353 8059 case CP0_REG05__PAGEGRAIN:
7a47bae5 8060 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8061 gen_helper_mtc0_pagegrain(cpu_env, arg);
294fc2ea 8062 register_name = "PageGrain";
2423f660 8063 break;
a1e76353 8064 case CP0_REG05__SEGCTL0:
cec56a73
JH
8065 CP0_CHECK(ctx->sc);
8066 gen_helper_mtc0_segctl0(cpu_env, arg);
294fc2ea 8067 register_name = "SegCtl0";
cec56a73 8068 break;
a1e76353 8069 case CP0_REG05__SEGCTL1:
cec56a73
JH
8070 CP0_CHECK(ctx->sc);
8071 gen_helper_mtc0_segctl1(cpu_env, arg);
294fc2ea 8072 register_name = "SegCtl1";
cec56a73 8073 break;
a1e76353 8074 case CP0_REG05__SEGCTL2:
cec56a73
JH
8075 CP0_CHECK(ctx->sc);
8076 gen_helper_mtc0_segctl2(cpu_env, arg);
294fc2ea 8077 register_name = "SegCtl2";
cec56a73 8078 break;
a1e76353 8079 case CP0_REG05__PWBASE:
5e31fdd5
YK
8080 check_pw(ctx);
8081 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
294fc2ea 8082 register_name = "PWBase";
5e31fdd5 8083 break;
a1e76353 8084 case CP0_REG05__PWFIELD:
fa75ad14
YK
8085 check_pw(ctx);
8086 gen_helper_mtc0_pwfield(cpu_env, arg);
294fc2ea 8087 register_name = "PWField";
fa75ad14 8088 break;
a1e76353 8089 case CP0_REG05__PWSIZE:
20b28ebc
YK
8090 check_pw(ctx);
8091 gen_helper_mtc0_pwsize(cpu_env, arg);
294fc2ea 8092 register_name = "PWSize";
20b28ebc 8093 break;
9c2149c8 8094 default:
f31b035a 8095 goto cp0_unimplemented;
876d4b07 8096 }
9c2149c8 8097 break;
04992c8c 8098 case CP0_REGISTER_06:
9c2149c8 8099 switch (sel) {
9023594b 8100 case CP0_REG06__WIRED:
895c2d04 8101 gen_helper_mtc0_wired(cpu_env, arg);
294fc2ea 8102 register_name = "Wired";
2423f660 8103 break;
9023594b 8104 case CP0_REG06__SRSCONF0:
7a47bae5 8105 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8106 gen_helper_mtc0_srsconf0(cpu_env, arg);
294fc2ea 8107 register_name = "SRSConf0";
ead9360e 8108 break;
9023594b 8109 case CP0_REG06__SRSCONF1:
7a47bae5 8110 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8111 gen_helper_mtc0_srsconf1(cpu_env, arg);
294fc2ea 8112 register_name = "SRSConf1";
ead9360e 8113 break;
9023594b 8114 case CP0_REG06__SRSCONF2:
7a47bae5 8115 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8116 gen_helper_mtc0_srsconf2(cpu_env, arg);
294fc2ea 8117 register_name = "SRSConf2";
ead9360e 8118 break;
9023594b 8119 case CP0_REG06__SRSCONF3:
7a47bae5 8120 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8121 gen_helper_mtc0_srsconf3(cpu_env, arg);
294fc2ea 8122 register_name = "SRSConf3";
ead9360e 8123 break;
9023594b 8124 case CP0_REG06__SRSCONF4:
7a47bae5 8125 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8126 gen_helper_mtc0_srsconf4(cpu_env, arg);
294fc2ea 8127 register_name = "SRSConf4";
ead9360e 8128 break;
9023594b 8129 case CP0_REG06__PWCTL:
103be64c
YK
8130 check_pw(ctx);
8131 gen_helper_mtc0_pwctl(cpu_env, arg);
294fc2ea 8132 register_name = "PWCtl";
103be64c 8133 break;
9c2149c8 8134 default:
f31b035a 8135 goto cp0_unimplemented;
876d4b07 8136 }
9c2149c8 8137 break;
04992c8c 8138 case CP0_REGISTER_07:
9c2149c8 8139 switch (sel) {
143a9875 8140 case CP0_REG07__HWRENA:
7a47bae5 8141 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8142 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 8143 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8144 register_name = "HWREna";
2423f660 8145 break;
9c2149c8 8146 default:
f31b035a 8147 goto cp0_unimplemented;
876d4b07 8148 }
9c2149c8 8149 break;
04992c8c 8150 case CP0_REGISTER_08:
aea14095 8151 switch (sel) {
67d167d2 8152 case CP0_REG08__BADVADDR:
aea14095 8153 /* ignored */
294fc2ea 8154 register_name = "BadVAddr";
aea14095 8155 break;
67d167d2 8156 case CP0_REG08__BADINSTR:
aea14095 8157 /* ignored */
294fc2ea 8158 register_name = "BadInstr";
aea14095 8159 break;
67d167d2 8160 case CP0_REG08__BADINSTRP:
aea14095 8161 /* ignored */
294fc2ea 8162 register_name = "BadInstrP";
aea14095 8163 break;
67d167d2 8164 case CP0_REG08__BADINSTRX:
25beba9b 8165 /* ignored */
294fc2ea 8166 register_name = "BadInstrX";
25beba9b 8167 break;
aea14095 8168 default:
f31b035a 8169 goto cp0_unimplemented;
aea14095 8170 }
9c2149c8 8171 break;
04992c8c 8172 case CP0_REGISTER_09:
9c2149c8 8173 switch (sel) {
e5a98a72 8174 case CP0_REG09__COUNT:
895c2d04 8175 gen_helper_mtc0_count(cpu_env, arg);
294fc2ea 8176 register_name = "Count";
2423f660 8177 break;
e5a98a72 8178 case CP0_REG09__SAARI:
5fb2dcd1
YK
8179 CP0_CHECK(ctx->saar);
8180 gen_helper_mtc0_saari(cpu_env, arg);
294fc2ea 8181 register_name = "SAARI";
5fb2dcd1 8182 break;
e5a98a72 8183 case CP0_REG09__SAAR:
5fb2dcd1
YK
8184 CP0_CHECK(ctx->saar);
8185 gen_helper_mtc0_saar(cpu_env, arg);
294fc2ea 8186 register_name = "SAAR";
5fb2dcd1 8187 break;
9c2149c8 8188 default:
f31b035a 8189 goto cp0_unimplemented;
876d4b07
TS
8190 }
8191 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8192 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8193 break;
04992c8c 8194 case CP0_REGISTER_10:
9c2149c8 8195 switch (sel) {
860ffef0 8196 case CP0_REG10__ENTRYHI:
895c2d04 8197 gen_helper_mtc0_entryhi(cpu_env, arg);
294fc2ea 8198 register_name = "EntryHi";
2423f660 8199 break;
9c2149c8 8200 default:
f31b035a 8201 goto cp0_unimplemented;
876d4b07 8202 }
9c2149c8 8203 break;
04992c8c 8204 case CP0_REGISTER_11:
9c2149c8 8205 switch (sel) {
f5f3834f 8206 case CP0_REG11__COMPARE:
895c2d04 8207 gen_helper_mtc0_compare(cpu_env, arg);
294fc2ea 8208 register_name = "Compare";
2423f660 8209 break;
876d4b07 8210 /* 6,7 are implementation dependent */
9c2149c8 8211 default:
f31b035a 8212 goto cp0_unimplemented;
876d4b07 8213 }
de9a95f0 8214 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8215 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8216 break;
04992c8c 8217 case CP0_REGISTER_12:
9c2149c8 8218 switch (sel) {
2b084867 8219 case CP0_REG12__STATUS:
867abc7e 8220 save_cpu_state(ctx, 1);
895c2d04 8221 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 8222 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8223 gen_save_pc(ctx->base.pc_next + 4);
8224 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8225 register_name = "Status";
2423f660 8226 break;
2b084867 8227 case CP0_REG12__INTCTL:
7a47bae5 8228 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8229 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 8230 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8231 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8232 register_name = "IntCtl";
2423f660 8233 break;
2b084867 8234 case CP0_REG12__SRSCTL:
7a47bae5 8235 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8236 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 8237 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8238 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8239 register_name = "SRSCtl";
2423f660 8240 break;
2b084867 8241 case CP0_REG12__SRSMAP:
7a47bae5 8242 check_insn(ctx, ISA_MIPS_R2);
7db13fae 8243 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 8244 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8245 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8246 register_name = "SRSMap";
2423f660
TS
8247 break;
8248 default:
f31b035a 8249 goto cp0_unimplemented;
876d4b07 8250 }
9c2149c8 8251 break;
04992c8c 8252 case CP0_REGISTER_13:
9c2149c8 8253 switch (sel) {
e3c7559d 8254 case CP0_REG13__CAUSE:
867abc7e 8255 save_cpu_state(ctx, 1);
895c2d04 8256 gen_helper_mtc0_cause(cpu_env, arg);
7480515f
AM
8257 /*
8258 * Stop translation as we may have triggered an interrupt.
b28425ba 8259 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7480515f
AM
8260 * translated code to check for pending interrupts.
8261 */
eeb3bba8
EC
8262 gen_save_pc(ctx->base.pc_next + 4);
8263 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8264 register_name = "Cause";
2423f660 8265 break;
9c2149c8 8266 default:
f31b035a 8267 goto cp0_unimplemented;
876d4b07 8268 }
9c2149c8 8269 break;
04992c8c 8270 case CP0_REGISTER_14:
9c2149c8 8271 switch (sel) {
35e4b54d 8272 case CP0_REG14__EPC:
7db13fae 8273 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
294fc2ea 8274 register_name = "EPC";
2423f660 8275 break;
9c2149c8 8276 default:
f31b035a 8277 goto cp0_unimplemented;
876d4b07 8278 }
9c2149c8 8279 break;
04992c8c 8280 case CP0_REGISTER_15:
9c2149c8 8281 switch (sel) {
4466cd49 8282 case CP0_REG15__PRID:
2423f660 8283 /* ignored */
294fc2ea 8284 register_name = "PRid";
2423f660 8285 break;
4466cd49 8286 case CP0_REG15__EBASE:
7a47bae5 8287 check_insn(ctx, ISA_MIPS_R2);
895c2d04 8288 gen_helper_mtc0_ebase(cpu_env, arg);
294fc2ea 8289 register_name = "EBase";
2423f660 8290 break;
9c2149c8 8291 default:
f31b035a 8292 goto cp0_unimplemented;
876d4b07 8293 }
9c2149c8 8294 break;
04992c8c 8295 case CP0_REGISTER_16:
9c2149c8 8296 switch (sel) {
433efb4c 8297 case CP0_REG16__CONFIG:
895c2d04 8298 gen_helper_mtc0_config0(cpu_env, arg);
294fc2ea 8299 register_name = "Config";
2423f660 8300 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8301 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8302 break;
433efb4c 8303 case CP0_REG16__CONFIG1:
1fc7bf6e 8304 /* ignored, read only */
294fc2ea 8305 register_name = "Config1";
9c2149c8 8306 break;
433efb4c 8307 case CP0_REG16__CONFIG2:
895c2d04 8308 gen_helper_mtc0_config2(cpu_env, arg);
294fc2ea 8309 register_name = "Config2";
2423f660 8310 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8311 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8312 break;
433efb4c 8313 case CP0_REG16__CONFIG3:
90f12d73 8314 gen_helper_mtc0_config3(cpu_env, arg);
294fc2ea 8315 register_name = "Config3";
90f12d73 8316 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8317 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 8318 break;
433efb4c 8319 case CP0_REG16__CONFIG4:
faf1f68b 8320 /* currently ignored */
294fc2ea 8321 register_name = "Config4";
faf1f68b 8322 break;
433efb4c 8323 case CP0_REG16__CONFIG5:
faf1f68b 8324 gen_helper_mtc0_config5(cpu_env, arg);
294fc2ea 8325 register_name = "Config5";
faf1f68b 8326 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8327 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 8328 break;
9c2149c8
TS
8329 /* 6,7 are implementation dependent */
8330 default:
294fc2ea 8331 register_name = "Invalid config selector";
f31b035a 8332 goto cp0_unimplemented;
9c2149c8 8333 }
9c2149c8 8334 break;
04992c8c 8335 case CP0_REGISTER_17:
9c2149c8 8336 switch (sel) {
706ce142 8337 case CP0_REG17__LLADDR:
895c2d04 8338 gen_helper_mtc0_lladdr(cpu_env, arg);
294fc2ea 8339 register_name = "LLAddr";
2423f660 8340 break;
706ce142 8341 case CP0_REG17__MAAR:
f6d4dd81
YK
8342 CP0_CHECK(ctx->mrp);
8343 gen_helper_mtc0_maar(cpu_env, arg);
294fc2ea 8344 register_name = "MAAR";
f6d4dd81 8345 break;
706ce142 8346 case CP0_REG17__MAARI:
f6d4dd81
YK
8347 CP0_CHECK(ctx->mrp);
8348 gen_helper_mtc0_maari(cpu_env, arg);
294fc2ea 8349 register_name = "MAARI";
f6d4dd81 8350 break;
9c2149c8 8351 default:
f31b035a 8352 goto cp0_unimplemented;
9c2149c8
TS
8353 }
8354 break;
04992c8c 8355 case CP0_REGISTER_18:
9c2149c8 8356 switch (sel) {
e8dcfe82
AM
8357 case CP0_REG18__WATCHLO0:
8358 case CP0_REG18__WATCHLO1:
8359 case CP0_REG18__WATCHLO2:
8360 case CP0_REG18__WATCHLO3:
8361 case CP0_REG18__WATCHLO4:
8362 case CP0_REG18__WATCHLO5:
8363 case CP0_REG18__WATCHLO6:
8364 case CP0_REG18__WATCHLO7:
fa192d49 8365 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8366 gen_helper_0e1i(mtc0_watchlo, arg, sel);
294fc2ea 8367 register_name = "WatchLo";
2423f660 8368 break;
9c2149c8 8369 default:
f31b035a 8370 goto cp0_unimplemented;
9c2149c8
TS
8371 }
8372 break;
04992c8c 8373 case CP0_REGISTER_19:
9c2149c8 8374 switch (sel) {
be274dc1
AM
8375 case CP0_REG19__WATCHHI0:
8376 case CP0_REG19__WATCHHI1:
8377 case CP0_REG19__WATCHHI2:
8378 case CP0_REG19__WATCHHI3:
8379 case CP0_REG19__WATCHHI4:
8380 case CP0_REG19__WATCHHI5:
8381 case CP0_REG19__WATCHHI6:
8382 case CP0_REG19__WATCHHI7:
fa192d49 8383 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8384 gen_helper_0e1i(mtc0_watchhi, arg, sel);
294fc2ea 8385 register_name = "WatchHi";
2423f660 8386 break;
9c2149c8 8387 default:
f31b035a 8388 goto cp0_unimplemented;
9c2149c8
TS
8389 }
8390 break;
04992c8c 8391 case CP0_REGISTER_20:
9c2149c8 8392 switch (sel) {
14f92b0b 8393 case CP0_REG20__XCONTEXT:
d75c135e 8394 check_insn(ctx, ISA_MIPS3);
895c2d04 8395 gen_helper_mtc0_xcontext(cpu_env, arg);
294fc2ea 8396 register_name = "XContext";
2423f660 8397 break;
9c2149c8 8398 default:
f31b035a 8399 goto cp0_unimplemented;
9c2149c8
TS
8400 }
8401 break;
04992c8c 8402 case CP0_REGISTER_21:
9c2149c8 8403 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2e211e0a 8404 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
9c2149c8
TS
8405 switch (sel) {
8406 case 0:
895c2d04 8407 gen_helper_mtc0_framemask(cpu_env, arg);
294fc2ea 8408 register_name = "Framemask";
2423f660 8409 break;
9c2149c8 8410 default:
f31b035a 8411 goto cp0_unimplemented;
9c2149c8
TS
8412 }
8413 break;
04992c8c 8414 case CP0_REGISTER_22:
9c2149c8 8415 /* ignored */
294fc2ea 8416 register_name = "Diagnostic"; /* implementation dependent */
876d4b07 8417 break;
04992c8c 8418 case CP0_REGISTER_23:
9c2149c8 8419 switch (sel) {
4cbf4b6d 8420 case CP0_REG23__DEBUG:
895c2d04 8421 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 8422 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8423 gen_save_pc(ctx->base.pc_next + 4);
8424 ctx->base.is_jmp = DISAS_EXIT;
294fc2ea 8425 register_name = "Debug";
2423f660 8426 break;
4cbf4b6d
AM
8427 case CP0_REG23__TRACECONTROL:
8428 /* PDtrace support */
8429 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8487327a 8430 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8431 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8432 register_name = "TraceControl";
3570d7f6 8433 goto cp0_unimplemented;
4cbf4b6d
AM
8434 case CP0_REG23__TRACECONTROL2:
8435 /* PDtrace support */
8436 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8487327a 8437 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8438 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8439 register_name = "TraceControl2";
3570d7f6 8440 goto cp0_unimplemented;
4cbf4b6d
AM
8441 case CP0_REG23__USERTRACEDATA1:
8442 /* PDtrace support */
8443 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8487327a 8444 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8445 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d 8446 register_name = "UserTraceData1";
3570d7f6 8447 goto cp0_unimplemented;
4cbf4b6d
AM
8448 case CP0_REG23__TRACEIBPC:
8449 /* PDtrace support */
8450 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8451 /* Stop translation as we may have switched the execution mode */
8452 ctx->base.is_jmp = DISAS_STOP;
8453 register_name = "TraceIBPC";
8454 goto cp0_unimplemented;
8455 case CP0_REG23__TRACEDBPC:
8456 /* PDtrace support */
8457 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8487327a 8458 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8459 ctx->base.is_jmp = DISAS_STOP;
4cbf4b6d 8460 register_name = "TraceDBPC";
3570d7f6 8461 goto cp0_unimplemented;
9c2149c8 8462 default:
f31b035a 8463 goto cp0_unimplemented;
9c2149c8 8464 }
9c2149c8 8465 break;
04992c8c 8466 case CP0_REGISTER_24:
9c2149c8 8467 switch (sel) {
8d7b4b6e 8468 case CP0_REG24__DEPC:
f1aa6320 8469 /* EJTAG support */
7db13fae 8470 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
294fc2ea 8471 register_name = "DEPC";
2423f660 8472 break;
9c2149c8 8473 default:
f31b035a 8474 goto cp0_unimplemented;
9c2149c8
TS
8475 }
8476 break;
04992c8c 8477 case CP0_REGISTER_25:
9c2149c8 8478 switch (sel) {
1176b328 8479 case CP0_REG25__PERFCTL0:
895c2d04 8480 gen_helper_mtc0_performance0(cpu_env, arg);
294fc2ea 8481 register_name = "Performance0";
2423f660 8482 break;
1176b328 8483 case CP0_REG25__PERFCNT0:
7480515f 8484 /* gen_helper_mtc0_performance1(cpu_env, arg); */
294fc2ea 8485 register_name = "Performance1";
3570d7f6 8486 goto cp0_unimplemented;
1176b328 8487 case CP0_REG25__PERFCTL1:
7480515f 8488 /* gen_helper_mtc0_performance2(cpu_env, arg); */
294fc2ea 8489 register_name = "Performance2";
3570d7f6 8490 goto cp0_unimplemented;
1176b328 8491 case CP0_REG25__PERFCNT1:
7480515f 8492 /* gen_helper_mtc0_performance3(cpu_env, arg); */
294fc2ea 8493 register_name = "Performance3";
3570d7f6 8494 goto cp0_unimplemented;
1176b328 8495 case CP0_REG25__PERFCTL2:
7480515f 8496 /* gen_helper_mtc0_performance4(cpu_env, arg); */
294fc2ea 8497 register_name = "Performance4";
3570d7f6 8498 goto cp0_unimplemented;
1176b328 8499 case CP0_REG25__PERFCNT2:
7480515f 8500 /* gen_helper_mtc0_performance5(cpu_env, arg); */
294fc2ea 8501 register_name = "Performance5";
3570d7f6 8502 goto cp0_unimplemented;
1176b328 8503 case CP0_REG25__PERFCTL3:
7480515f 8504 /* gen_helper_mtc0_performance6(cpu_env, arg); */
294fc2ea 8505 register_name = "Performance6";
3570d7f6 8506 goto cp0_unimplemented;
1176b328 8507 case CP0_REG25__PERFCNT3:
7480515f 8508 /* gen_helper_mtc0_performance7(cpu_env, arg); */
294fc2ea 8509 register_name = "Performance7";
3570d7f6 8510 goto cp0_unimplemented;
9c2149c8 8511 default:
f31b035a 8512 goto cp0_unimplemented;
9c2149c8 8513 }
876d4b07 8514 break;
04992c8c 8515 case CP0_REGISTER_26:
0d74a222 8516 switch (sel) {
dbbf08b2 8517 case CP0_REG26__ERRCTL:
0d74a222 8518 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 8519 ctx->base.is_jmp = DISAS_STOP;
294fc2ea 8520 register_name = "ErrCtl";
0d74a222
LA
8521 break;
8522 default:
8523 goto cp0_unimplemented;
8524 }
876d4b07 8525 break;
04992c8c 8526 case CP0_REGISTER_27:
9c2149c8 8527 switch (sel) {
5a10873d 8528 case CP0_REG27__CACHERR:
2423f660 8529 /* ignored */
294fc2ea 8530 register_name = "CacheErr";
2423f660 8531 break;
9c2149c8 8532 default:
f31b035a 8533 goto cp0_unimplemented;
9c2149c8 8534 }
876d4b07 8535 break;
04992c8c 8536 case CP0_REGISTER_28:
9c2149c8 8537 switch (sel) {
a30e2f21
AM
8538 case CP0_REG28__TAGLO:
8539 case CP0_REG28__TAGLO1:
8540 case CP0_REG28__TAGLO2:
8541 case CP0_REG28__TAGLO3:
895c2d04 8542 gen_helper_mtc0_taglo(cpu_env, arg);
294fc2ea 8543 register_name = "TagLo";
9c2149c8 8544 break;
a30e2f21
AM
8545 case CP0_REG28__DATALO:
8546 case CP0_REG28__DATALO1:
8547 case CP0_REG28__DATALO2:
8548 case CP0_REG28__DATALO3:
895c2d04 8549 gen_helper_mtc0_datalo(cpu_env, arg);
294fc2ea 8550 register_name = "DataLo";
9c2149c8
TS
8551 break;
8552 default:
f31b035a 8553 goto cp0_unimplemented;
9c2149c8
TS
8554 }
8555 break;
04992c8c 8556 case CP0_REGISTER_29:
9c2149c8 8557 switch (sel) {
af4bb6da
AM
8558 case CP0_REG29__TAGHI:
8559 case CP0_REG29__TAGHI1:
8560 case CP0_REG29__TAGHI2:
8561 case CP0_REG29__TAGHI3:
895c2d04 8562 gen_helper_mtc0_taghi(cpu_env, arg);
294fc2ea 8563 register_name = "TagHi";
9c2149c8 8564 break;
af4bb6da
AM
8565 case CP0_REG29__DATAHI:
8566 case CP0_REG29__DATAHI1:
8567 case CP0_REG29__DATAHI2:
8568 case CP0_REG29__DATAHI3:
895c2d04 8569 gen_helper_mtc0_datahi(cpu_env, arg);
294fc2ea 8570 register_name = "DataHi";
9c2149c8
TS
8571 break;
8572 default:
294fc2ea 8573 register_name = "invalid sel";
f31b035a 8574 goto cp0_unimplemented;
9c2149c8 8575 }
876d4b07 8576 break;
04992c8c 8577 case CP0_REGISTER_30:
9c2149c8 8578 switch (sel) {
4bcf121e 8579 case CP0_REG30__ERROREPC:
7db13fae 8580 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
294fc2ea 8581 register_name = "ErrorEPC";
2423f660 8582 break;
9c2149c8 8583 default:
f31b035a 8584 goto cp0_unimplemented;
9c2149c8
TS
8585 }
8586 break;
04992c8c 8587 case CP0_REGISTER_31:
9c2149c8 8588 switch (sel) {
14d92efd 8589 case CP0_REG31__DESAVE:
f1aa6320 8590 /* EJTAG support */
7db13fae 8591 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
294fc2ea 8592 register_name = "DESAVE";
2423f660 8593 break;
14d92efd
AM
8594 case CP0_REG31__KSCRATCH1:
8595 case CP0_REG31__KSCRATCH2:
8596 case CP0_REG31__KSCRATCH3:
8597 case CP0_REG31__KSCRATCH4:
8598 case CP0_REG31__KSCRATCH5:
8599 case CP0_REG31__KSCRATCH6:
f31b035a
LA
8600 CP0_CHECK(ctx->kscrexist & (1 << sel));
8601 tcg_gen_st_tl(arg, cpu_env,
71375b59 8602 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
294fc2ea 8603 register_name = "KScratch";
e98c0d17 8604 break;
9c2149c8 8605 default:
f31b035a 8606 goto cp0_unimplemented;
9c2149c8 8607 }
9c2149c8
TS
8608 break;
8609 default:
f31b035a 8610 goto cp0_unimplemented;
9c2149c8 8611 }
294fc2ea 8612 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
b44a7fb1 8613
bf20dc07 8614 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 8615 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480515f
AM
8616 /*
8617 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8618 * translated code to check for pending interrupts.
8619 */
eeb3bba8
EC
8620 gen_save_pc(ctx->base.pc_next + 4);
8621 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 8622 }
9c2149c8
TS
8623 return;
8624
f31b035a 8625cp0_unimplemented:
294fc2ea
AM
8626 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8627 register_name, reg, sel);
9c2149c8 8628}
d26bc211 8629#endif /* TARGET_MIPS64 */
9c2149c8 8630
7db13fae 8631static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
8632 int u, int sel, int h)
8633{
8634 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8635 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
8636
8637 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732 8638 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
1f8929d2 8639 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
1a3fd9c3 8640 tcg_gen_movi_tl(t0, -1);
1f8929d2
AM
8641 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8642 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
1a3fd9c3 8643 tcg_gen_movi_tl(t0, -1);
1f8929d2 8644 } else if (u == 0) {
ead9360e 8645 switch (rt) {
5a25ce94
EI
8646 case 1:
8647 switch (sel) {
8648 case 1:
895c2d04 8649 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
8650 break;
8651 case 2:
895c2d04 8652 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
8653 break;
8654 default:
8655 goto die;
8656 break;
8657 }
8658 break;
ead9360e
TS
8659 case 2:
8660 switch (sel) {
8661 case 1:
895c2d04 8662 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
8663 break;
8664 case 2:
895c2d04 8665 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
8666 break;
8667 case 3:
895c2d04 8668 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
8669 break;
8670 case 4:
895c2d04 8671 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
8672 break;
8673 case 5:
895c2d04 8674 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
8675 break;
8676 case 6:
895c2d04 8677 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
8678 break;
8679 case 7:
895c2d04 8680 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
8681 break;
8682 default:
d75c135e 8683 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8684 break;
8685 }
8686 break;
8687 case 10:
8688 switch (sel) {
8689 case 0:
895c2d04 8690 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
8691 break;
8692 default:
d75c135e 8693 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8694 break;
8695 }
f1fadbb2 8696 break;
ead9360e
TS
8697 case 12:
8698 switch (sel) {
8699 case 0:
895c2d04 8700 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
8701 break;
8702 default:
d75c135e 8703 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8704 break;
8705 }
f1fadbb2 8706 break;
5a25ce94
EI
8707 case 13:
8708 switch (sel) {
8709 case 0:
895c2d04 8710 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
8711 break;
8712 default:
8713 goto die;
8714 break;
8715 }
8716 break;
8717 case 14:
8718 switch (sel) {
8719 case 0:
895c2d04 8720 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
8721 break;
8722 default:
8723 goto die;
8724 break;
8725 }
8726 break;
8727 case 15:
8728 switch (sel) {
8729 case 1:
895c2d04 8730 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
8731 break;
8732 default:
8733 goto die;
8734 break;
8735 }
8736 break;
8737 case 16:
8738 switch (sel) {
c2e19f3c
AM
8739 case 0:
8740 case 1:
8741 case 2:
8742 case 3:
8743 case 4:
8744 case 5:
8745 case 6:
8746 case 7:
895c2d04 8747 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
8748 break;
8749 default:
8750 goto die;
8751 break;
8752 }
8753 break;
ead9360e
TS
8754 case 23:
8755 switch (sel) {
8756 case 0:
895c2d04 8757 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
8758 break;
8759 default:
d75c135e 8760 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8761 break;
8762 }
8763 break;
8764 default:
d75c135e 8765 gen_mfc0(ctx, t0, rt, sel);
ead9360e 8766 }
71375b59
AM
8767 } else {
8768 switch (sel) {
8769 /* GPR registers. */
ead9360e 8770 case 0:
71375b59 8771 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e 8772 break;
71375b59 8773 /* Auxiliary CPU registers */
ead9360e 8774 case 1:
71375b59
AM
8775 switch (rt) {
8776 case 0:
8777 gen_helper_1e0i(mftlo, t0, 0);
8778 break;
8779 case 1:
8780 gen_helper_1e0i(mfthi, t0, 0);
8781 break;
8782 case 2:
8783 gen_helper_1e0i(mftacx, t0, 0);
8784 break;
8785 case 4:
8786 gen_helper_1e0i(mftlo, t0, 1);
8787 break;
8788 case 5:
8789 gen_helper_1e0i(mfthi, t0, 1);
8790 break;
8791 case 6:
8792 gen_helper_1e0i(mftacx, t0, 1);
8793 break;
8794 case 8:
8795 gen_helper_1e0i(mftlo, t0, 2);
8796 break;
8797 case 9:
8798 gen_helper_1e0i(mfthi, t0, 2);
8799 break;
8800 case 10:
8801 gen_helper_1e0i(mftacx, t0, 2);
8802 break;
8803 case 12:
8804 gen_helper_1e0i(mftlo, t0, 3);
8805 break;
8806 case 13:
8807 gen_helper_1e0i(mfthi, t0, 3);
8808 break;
8809 case 14:
8810 gen_helper_1e0i(mftacx, t0, 3);
8811 break;
8812 case 16:
8813 gen_helper_mftdsp(t0, cpu_env);
8814 break;
8815 default:
8816 goto die;
8817 }
ead9360e 8818 break;
71375b59 8819 /* Floating point (COP1). */
ead9360e 8820 case 2:
71375b59
AM
8821 /* XXX: For now we support only a single FPU context. */
8822 if (h == 0) {
8823 TCGv_i32 fp0 = tcg_temp_new_i32();
8824
8825 gen_load_fpr32(ctx, fp0, rt);
8826 tcg_gen_ext_i32_tl(t0, fp0);
8827 tcg_temp_free_i32(fp0);
8828 } else {
8829 TCGv_i32 fp0 = tcg_temp_new_i32();
8830
8831 gen_load_fpr32h(ctx, fp0, rt);
8832 tcg_gen_ext_i32_tl(t0, fp0);
8833 tcg_temp_free_i32(fp0);
8834 }
ead9360e 8835 break;
71375b59
AM
8836 case 3:
8837 /* XXX: For now we support only a single FPU context. */
8838 gen_helper_1e0i(cfc1, t0, rt);
ead9360e 8839 break;
71375b59
AM
8840 /* COP2: Not implemented. */
8841 case 4:
ead9360e 8842 case 5:
71375b59 8843 /* fall through */
ead9360e
TS
8844 default:
8845 goto die;
8846 }
ead9360e 8847 }
b44a7fb1 8848 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8849 gen_store_gpr(t0, rd);
8850 tcg_temp_free(t0);
ead9360e
TS
8851 return;
8852
8853die:
1a3fd9c3 8854 tcg_temp_free(t0);
d12d51d5 8855 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
3a4ef3b7 8856 gen_reserved_instruction(ctx);
ead9360e
TS
8857}
8858
7db13fae 8859static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8860 int u, int sel, int h)
8861{
8862 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8863 TCGv t0 = tcg_temp_local_new();
ead9360e 8864
1a3fd9c3 8865 gen_load_gpr(t0, rt);
ead9360e 8866 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732 8867 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
1f8929d2 8868 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
7480515f
AM
8869 /* NOP */
8870 ;
1f8929d2
AM
8871 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8872 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
7480515f
AM
8873 /* NOP */
8874 ;
1f8929d2 8875 } else if (u == 0) {
ead9360e 8876 switch (rd) {
5a25ce94
EI
8877 case 1:
8878 switch (sel) {
8879 case 1:
895c2d04 8880 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8881 break;
8882 case 2:
895c2d04 8883 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8884 break;
8885 default:
8886 goto die;
8887 break;
8888 }
8889 break;
ead9360e
TS
8890 case 2:
8891 switch (sel) {
8892 case 1:
895c2d04 8893 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8894 break;
8895 case 2:
895c2d04 8896 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8897 break;
8898 case 3:
895c2d04 8899 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8900 break;
8901 case 4:
895c2d04 8902 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8903 break;
8904 case 5:
895c2d04 8905 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8906 break;
8907 case 6:
895c2d04 8908 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8909 break;
8910 case 7:
895c2d04 8911 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8912 break;
8913 default:
d75c135e 8914 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8915 break;
8916 }
8917 break;
8918 case 10:
8919 switch (sel) {
8920 case 0:
895c2d04 8921 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8922 break;
8923 default:
d75c135e 8924 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8925 break;
8926 }
0d0304f2 8927 break;
ead9360e
TS
8928 case 12:
8929 switch (sel) {
8930 case 0:
895c2d04 8931 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8932 break;
8933 default:
d75c135e 8934 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8935 break;
8936 }
0d0304f2 8937 break;
5a25ce94
EI
8938 case 13:
8939 switch (sel) {
8940 case 0:
895c2d04 8941 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8942 break;
8943 default:
8944 goto die;
8945 break;
8946 }
8947 break;
8948 case 15:
8949 switch (sel) {
8950 case 1:
895c2d04 8951 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8952 break;
8953 default:
8954 goto die;
8955 break;
8956 }
8957 break;
ead9360e
TS
8958 case 23:
8959 switch (sel) {
8960 case 0:
895c2d04 8961 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8962 break;
8963 default:
d75c135e 8964 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8965 break;
8966 }
8967 break;
8968 default:
d75c135e 8969 gen_mtc0(ctx, t0, rd, sel);
ead9360e 8970 }
71375b59
AM
8971 } else {
8972 switch (sel) {
8973 /* GPR registers. */
ead9360e 8974 case 0:
71375b59 8975 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e 8976 break;
71375b59 8977 /* Auxiliary CPU registers */
ead9360e 8978 case 1:
71375b59
AM
8979 switch (rd) {
8980 case 0:
8981 gen_helper_0e1i(mttlo, t0, 0);
8982 break;
8983 case 1:
8984 gen_helper_0e1i(mtthi, t0, 0);
8985 break;
8986 case 2:
8987 gen_helper_0e1i(mttacx, t0, 0);
8988 break;
8989 case 4:
8990 gen_helper_0e1i(mttlo, t0, 1);
8991 break;
8992 case 5:
8993 gen_helper_0e1i(mtthi, t0, 1);
8994 break;
8995 case 6:
8996 gen_helper_0e1i(mttacx, t0, 1);
8997 break;
8998 case 8:
8999 gen_helper_0e1i(mttlo, t0, 2);
9000 break;
9001 case 9:
9002 gen_helper_0e1i(mtthi, t0, 2);
9003 break;
9004 case 10:
9005 gen_helper_0e1i(mttacx, t0, 2);
9006 break;
9007 case 12:
9008 gen_helper_0e1i(mttlo, t0, 3);
9009 break;
9010 case 13:
9011 gen_helper_0e1i(mtthi, t0, 3);
9012 break;
9013 case 14:
9014 gen_helper_0e1i(mttacx, t0, 3);
9015 break;
9016 case 16:
9017 gen_helper_mttdsp(cpu_env, t0);
9018 break;
9019 default:
9020 goto die;
9021 }
ead9360e 9022 break;
71375b59 9023 /* Floating point (COP1). */
ead9360e 9024 case 2:
71375b59
AM
9025 /* XXX: For now we support only a single FPU context. */
9026 if (h == 0) {
9027 TCGv_i32 fp0 = tcg_temp_new_i32();
9028
9029 tcg_gen_trunc_tl_i32(fp0, t0);
9030 gen_store_fpr32(ctx, fp0, rd);
9031 tcg_temp_free_i32(fp0);
9032 } else {
9033 TCGv_i32 fp0 = tcg_temp_new_i32();
9034
9035 tcg_gen_trunc_tl_i32(fp0, t0);
9036 gen_store_fpr32h(ctx, fp0, rd);
9037 tcg_temp_free_i32(fp0);
9038 }
ead9360e 9039 break;
71375b59
AM
9040 case 3:
9041 /* XXX: For now we support only a single FPU context. */
78bdd388 9042 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
71375b59
AM
9043 /* Stop translation as we may have changed hflags */
9044 ctx->base.is_jmp = DISAS_STOP;
ead9360e 9045 break;
71375b59
AM
9046 /* COP2: Not implemented. */
9047 case 4:
ead9360e 9048 case 5:
71375b59 9049 /* fall through */
ead9360e
TS
9050 default:
9051 goto die;
9052 }
ead9360e 9053 }
b44a7fb1 9054 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 9055 tcg_temp_free(t0);
ead9360e
TS
9056 return;
9057
9058die:
1a3fd9c3 9059 tcg_temp_free(t0);
d12d51d5 9060 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
3a4ef3b7 9061 gen_reserved_instruction(ctx);
ead9360e
TS
9062}
9063
235785e8
AM
9064static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9065 int rt, int rd)
6af0bf9c 9066{
287c4b84 9067 const char *opn = "ldst";
6af0bf9c 9068
2e15497c 9069 check_cp0_enabled(ctx);
6af0bf9c
FB
9070 switch (opc) {
9071 case OPC_MFC0:
9072 if (rt == 0) {
ead9360e 9073 /* Treat as NOP. */
6af0bf9c
FB
9074 return;
9075 }
d75c135e 9076 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
9077 opn = "mfc0";
9078 break;
9079 case OPC_MTC0:
1a3fd9c3 9080 {
1fc7bf6e 9081 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9082
9083 gen_load_gpr(t0, rt);
d75c135e 9084 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9085 tcg_temp_free(t0);
9086 }
6af0bf9c
FB
9087 opn = "mtc0";
9088 break;
d26bc211 9089#if defined(TARGET_MIPS64)
9c2149c8 9090 case OPC_DMFC0:
d75c135e 9091 check_insn(ctx, ISA_MIPS3);
9c2149c8 9092 if (rt == 0) {
ead9360e 9093 /* Treat as NOP. */
9c2149c8
TS
9094 return;
9095 }
d75c135e 9096 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
9097 opn = "dmfc0";
9098 break;
9099 case OPC_DMTC0:
d75c135e 9100 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 9101 {
1fc7bf6e 9102 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9103
9104 gen_load_gpr(t0, rt);
d75c135e 9105 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9106 tcg_temp_free(t0);
9107 }
9c2149c8
TS
9108 opn = "dmtc0";
9109 break;
534ce69f 9110#endif
5204ea79
LA
9111 case OPC_MFHC0:
9112 check_mvh(ctx);
9113 if (rt == 0) {
9114 /* Treat as NOP. */
9115 return;
9116 }
9117 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9118 opn = "mfhc0";
9119 break;
9120 case OPC_MTHC0:
9121 check_mvh(ctx);
9122 {
9123 TCGv t0 = tcg_temp_new();
9124 gen_load_gpr(t0, rt);
9125 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9126 tcg_temp_free(t0);
9127 }
9128 opn = "mthc0";
9129 break;
ead9360e 9130 case OPC_MFTR:
9affc1c5 9131 check_cp0_enabled(ctx);
ead9360e
TS
9132 if (rd == 0) {
9133 /* Treat as NOP. */
9134 return;
9135 }
6c5c1e20 9136 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 9137 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
9138 opn = "mftr";
9139 break;
9140 case OPC_MTTR:
9affc1c5 9141 check_cp0_enabled(ctx);
6c5c1e20 9142 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
9143 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9144 opn = "mttr";
9145 break;
6af0bf9c 9146 case OPC_TLBWI:
6af0bf9c 9147 opn = "tlbwi";
1f8929d2 9148 if (!env->tlb->helper_tlbwi) {
29929e34 9149 goto die;
1f8929d2 9150 }
895c2d04 9151 gen_helper_tlbwi(cpu_env);
6af0bf9c 9152 break;
9456c2fb
LA
9153 case OPC_TLBINV:
9154 opn = "tlbinv";
9155 if (ctx->ie >= 2) {
9156 if (!env->tlb->helper_tlbinv) {
9157 goto die;
9158 }
9159 gen_helper_tlbinv(cpu_env);
9160 } /* treat as nop if TLBINV not supported */
9161 break;
9162 case OPC_TLBINVF:
9163 opn = "tlbinvf";
9164 if (ctx->ie >= 2) {
9165 if (!env->tlb->helper_tlbinvf) {
9166 goto die;
9167 }
9168 gen_helper_tlbinvf(cpu_env);
9169 } /* treat as nop if TLBINV not supported */
9170 break;
6af0bf9c 9171 case OPC_TLBWR:
6af0bf9c 9172 opn = "tlbwr";
1f8929d2 9173 if (!env->tlb->helper_tlbwr) {
29929e34 9174 goto die;
1f8929d2 9175 }
895c2d04 9176 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
9177 break;
9178 case OPC_TLBP:
6af0bf9c 9179 opn = "tlbp";
1f8929d2 9180 if (!env->tlb->helper_tlbp) {
29929e34 9181 goto die;
1f8929d2 9182 }
895c2d04 9183 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
9184 break;
9185 case OPC_TLBR:
6af0bf9c 9186 opn = "tlbr";
1f8929d2 9187 if (!env->tlb->helper_tlbr) {
29929e34 9188 goto die;
1f8929d2 9189 }
895c2d04 9190 gen_helper_tlbr(cpu_env);
6af0bf9c 9191 break;
ce9782f4 9192 case OPC_ERET: /* OPC_ERETNC */
2e211e0a 9193 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 9194 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 9195 goto die;
ce9782f4
LA
9196 } else {
9197 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9198 if (ctx->opcode & (1 << bit_shift)) {
9199 /* OPC_ERETNC */
9200 opn = "eretnc";
5f89ce4f 9201 check_insn(ctx, ISA_MIPS_R5);
ce9782f4
LA
9202 gen_helper_eretnc(cpu_env);
9203 } else {
9204 /* OPC_ERET */
9205 opn = "eret";
9206 check_insn(ctx, ISA_MIPS2);
9207 gen_helper_eret(cpu_env);
9208 }
eeb3bba8 9209 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 9210 }
6af0bf9c
FB
9211 break;
9212 case OPC_DERET:
9213 opn = "deret";
bbd5e4a2 9214 check_insn(ctx, ISA_MIPS_R1);
2e211e0a 9215 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 9216 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9217 goto die;
9218 }
6af0bf9c 9219 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 9220 MIPS_INVAL(opn);
3a4ef3b7 9221 gen_reserved_instruction(ctx);
6af0bf9c 9222 } else {
895c2d04 9223 gen_helper_deret(cpu_env);
eeb3bba8 9224 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
9225 }
9226 break;
4ad40f36
FB
9227 case OPC_WAIT:
9228 opn = "wait";
bbd5e4a2 9229 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
2e211e0a 9230 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 9231 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9232 goto die;
9233 }
4ad40f36 9234 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 9235 ctx->base.pc_next += 4;
4ad40f36 9236 save_cpu_state(ctx, 1);
eeb3bba8 9237 ctx->base.pc_next -= 4;
895c2d04 9238 gen_helper_wait(cpu_env);
eeb3bba8 9239 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 9240 break;
6af0bf9c 9241 default:
29929e34 9242 die:
923617a3 9243 MIPS_INVAL(opn);
3a4ef3b7 9244 gen_reserved_instruction(ctx);
6af0bf9c
FB
9245 return;
9246 }
2abf314d 9247 (void)opn; /* avoid a compiler warning */
6af0bf9c 9248}
f1aa6320 9249#endif /* !CONFIG_USER_ONLY */
6af0bf9c 9250
6ea83fed 9251/* CP1 Branches (before delay slot) */
d75c135e
AJ
9252static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9253 int32_t cc, int32_t offset)
6ea83fed
FB
9254{
9255 target_ulong btarget;
a7812ae4 9256 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 9257
2e211e0a 9258 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 9259 gen_reserved_instruction(ctx);
339cd2a8
LA
9260 goto out;
9261 }
9262
1f8929d2 9263 if (cc != 0) {
bbd5e4a2 9264 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
1f8929d2 9265 }
e189e748 9266
eeb3bba8 9267 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 9268
7a387fff
TS
9269 switch (op) {
9270 case OPC_BC1F:
d94536f4
AJ
9271 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9272 tcg_gen_not_i32(t0, t0);
9273 tcg_gen_andi_i32(t0, t0, 1);
9274 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9275 goto not_likely;
7a387fff 9276 case OPC_BC1FL:
d94536f4
AJ
9277 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9278 tcg_gen_not_i32(t0, t0);
9279 tcg_gen_andi_i32(t0, t0, 1);
9280 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9281 goto likely;
7a387fff 9282 case OPC_BC1T:
d94536f4
AJ
9283 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9284 tcg_gen_andi_i32(t0, t0, 1);
9285 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 9286 goto not_likely;
7a387fff 9287 case OPC_BC1TL:
d94536f4
AJ
9288 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9289 tcg_gen_andi_i32(t0, t0, 1);
9290 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
9291 likely:
9292 ctx->hflags |= MIPS_HFLAG_BL;
9293 break;
5a5012ec 9294 case OPC_BC1FANY2:
a16336e4 9295 {
d94536f4
AJ
9296 TCGv_i32 t1 = tcg_temp_new_i32();
9297 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9298 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d7f66b52 9299 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9300 tcg_temp_free_i32(t1);
d94536f4
AJ
9301 tcg_gen_andi_i32(t0, t0, 1);
9302 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9303 }
5a5012ec
TS
9304 goto not_likely;
9305 case OPC_BC1TANY2:
a16336e4 9306 {
d94536f4
AJ
9307 TCGv_i32 t1 = tcg_temp_new_i32();
9308 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9309 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d94536f4
AJ
9310 tcg_gen_or_i32(t0, t0, t1);
9311 tcg_temp_free_i32(t1);
9312 tcg_gen_andi_i32(t0, t0, 1);
9313 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9314 }
5a5012ec
TS
9315 goto not_likely;
9316 case OPC_BC1FANY4:
a16336e4 9317 {
d94536f4
AJ
9318 TCGv_i32 t1 = tcg_temp_new_i32();
9319 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9320 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d7f66b52 9321 tcg_gen_and_i32(t0, t0, t1);
71375b59 9322 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
d7f66b52 9323 tcg_gen_and_i32(t0, t0, t1);
71375b59 9324 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
d7f66b52 9325 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 9326 tcg_temp_free_i32(t1);
d94536f4
AJ
9327 tcg_gen_andi_i32(t0, t0, 1);
9328 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9329 }
5a5012ec
TS
9330 goto not_likely;
9331 case OPC_BC1TANY4:
a16336e4 9332 {
d94536f4
AJ
9333 TCGv_i32 t1 = tcg_temp_new_i32();
9334 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
71375b59 9335 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
d94536f4 9336 tcg_gen_or_i32(t0, t0, t1);
71375b59 9337 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
d94536f4 9338 tcg_gen_or_i32(t0, t0, t1);
71375b59 9339 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
d94536f4
AJ
9340 tcg_gen_or_i32(t0, t0, t1);
9341 tcg_temp_free_i32(t1);
9342 tcg_gen_andi_i32(t0, t0, 1);
9343 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 9344 }
5a5012ec
TS
9345 not_likely:
9346 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
9347 break;
9348 default:
9d68ac14 9349 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 9350 gen_reserved_instruction(ctx);
6c5c1e20 9351 goto out;
6ea83fed 9352 }
6ea83fed 9353 ctx->btarget = btarget;
b231c103 9354 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 9355 out:
a7812ae4 9356 tcg_temp_free_i32(t0);
6ea83fed
FB
9357}
9358
31837be3
YK
9359/* R6 CP1 Branches */
9360static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
9361 int32_t ft, int32_t offset,
9362 int delayslot_size)
31837be3
YK
9363{
9364 target_ulong btarget;
31837be3
YK
9365 TCGv_i64 t0 = tcg_temp_new_i64();
9366
9367 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9368#ifdef MIPS_DEBUG_DISAS
339cd2a8 9369 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 9370 "\n", ctx->base.pc_next);
31837be3 9371#endif
3a4ef3b7 9372 gen_reserved_instruction(ctx);
31837be3
YK
9373 goto out;
9374 }
9375
9376 gen_load_fpr64(ctx, t0, ft);
9377 tcg_gen_andi_i64(t0, t0, 1);
9378
eeb3bba8 9379 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
9380
9381 switch (op) {
9382 case OPC_BC1EQZ:
9383 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
9384 ctx->hflags |= MIPS_HFLAG_BC;
9385 break;
9386 case OPC_BC1NEZ:
9387 /* t0 already set */
31837be3
YK
9388 ctx->hflags |= MIPS_HFLAG_BC;
9389 break;
9390 default:
9d68ac14 9391 MIPS_INVAL("cp1 cond branch");
3a4ef3b7 9392 gen_reserved_instruction(ctx);
31837be3
YK
9393 goto out;
9394 }
9395
9396 tcg_gen_trunc_i64_tl(bcond, t0);
9397
31837be3 9398 ctx->btarget = btarget;
65935f07
YK
9399
9400 switch (delayslot_size) {
9401 case 2:
9402 ctx->hflags |= MIPS_HFLAG_BDS16;
9403 break;
9404 case 4:
9405 ctx->hflags |= MIPS_HFLAG_BDS32;
9406 break;
9407 }
31837be3
YK
9408
9409out:
9410 tcg_temp_free_i64(t0);
9411}
9412
6af0bf9c 9413/* Coprocessor 1 (FPU) */
5a5012ec 9414
5a5012ec
TS
9415#define FOP(func, fmt) (((fmt) << 21) | (func))
9416
bf4120ad
NF
9417enum fopcode {
9418 OPC_ADD_S = FOP(0, FMT_S),
9419 OPC_SUB_S = FOP(1, FMT_S),
9420 OPC_MUL_S = FOP(2, FMT_S),
9421 OPC_DIV_S = FOP(3, FMT_S),
9422 OPC_SQRT_S = FOP(4, FMT_S),
9423 OPC_ABS_S = FOP(5, FMT_S),
9424 OPC_MOV_S = FOP(6, FMT_S),
9425 OPC_NEG_S = FOP(7, FMT_S),
9426 OPC_ROUND_L_S = FOP(8, FMT_S),
9427 OPC_TRUNC_L_S = FOP(9, FMT_S),
9428 OPC_CEIL_L_S = FOP(10, FMT_S),
9429 OPC_FLOOR_L_S = FOP(11, FMT_S),
9430 OPC_ROUND_W_S = FOP(12, FMT_S),
9431 OPC_TRUNC_W_S = FOP(13, FMT_S),
9432 OPC_CEIL_W_S = FOP(14, FMT_S),
9433 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 9434 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
9435 OPC_MOVCF_S = FOP(17, FMT_S),
9436 OPC_MOVZ_S = FOP(18, FMT_S),
9437 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 9438 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
9439 OPC_RECIP_S = FOP(21, FMT_S),
9440 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
9441 OPC_SELNEZ_S = FOP(23, FMT_S),
9442 OPC_MADDF_S = FOP(24, FMT_S),
9443 OPC_MSUBF_S = FOP(25, FMT_S),
9444 OPC_RINT_S = FOP(26, FMT_S),
9445 OPC_CLASS_S = FOP(27, FMT_S),
9446 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 9447 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 9448 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 9449 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 9450 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 9451 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 9452 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
9453 OPC_RSQRT2_S = FOP(31, FMT_S),
9454 OPC_CVT_D_S = FOP(33, FMT_S),
9455 OPC_CVT_W_S = FOP(36, FMT_S),
9456 OPC_CVT_L_S = FOP(37, FMT_S),
9457 OPC_CVT_PS_S = FOP(38, FMT_S),
235785e8
AM
9458 OPC_CMP_F_S = FOP(48, FMT_S),
9459 OPC_CMP_UN_S = FOP(49, FMT_S),
9460 OPC_CMP_EQ_S = FOP(50, FMT_S),
9461 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9462 OPC_CMP_OLT_S = FOP(52, FMT_S),
9463 OPC_CMP_ULT_S = FOP(53, FMT_S),
9464 OPC_CMP_OLE_S = FOP(54, FMT_S),
9465 OPC_CMP_ULE_S = FOP(55, FMT_S),
9466 OPC_CMP_SF_S = FOP(56, FMT_S),
9467 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9468 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9469 OPC_CMP_NGL_S = FOP(59, FMT_S),
9470 OPC_CMP_LT_S = FOP(60, FMT_S),
9471 OPC_CMP_NGE_S = FOP(61, FMT_S),
9472 OPC_CMP_LE_S = FOP(62, FMT_S),
9473 OPC_CMP_NGT_S = FOP(63, FMT_S),
bf4120ad
NF
9474
9475 OPC_ADD_D = FOP(0, FMT_D),
9476 OPC_SUB_D = FOP(1, FMT_D),
9477 OPC_MUL_D = FOP(2, FMT_D),
9478 OPC_DIV_D = FOP(3, FMT_D),
9479 OPC_SQRT_D = FOP(4, FMT_D),
9480 OPC_ABS_D = FOP(5, FMT_D),
9481 OPC_MOV_D = FOP(6, FMT_D),
9482 OPC_NEG_D = FOP(7, FMT_D),
9483 OPC_ROUND_L_D = FOP(8, FMT_D),
9484 OPC_TRUNC_L_D = FOP(9, FMT_D),
9485 OPC_CEIL_L_D = FOP(10, FMT_D),
9486 OPC_FLOOR_L_D = FOP(11, FMT_D),
9487 OPC_ROUND_W_D = FOP(12, FMT_D),
9488 OPC_TRUNC_W_D = FOP(13, FMT_D),
9489 OPC_CEIL_W_D = FOP(14, FMT_D),
9490 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 9491 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
9492 OPC_MOVCF_D = FOP(17, FMT_D),
9493 OPC_MOVZ_D = FOP(18, FMT_D),
9494 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 9495 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
9496 OPC_RECIP_D = FOP(21, FMT_D),
9497 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
9498 OPC_SELNEZ_D = FOP(23, FMT_D),
9499 OPC_MADDF_D = FOP(24, FMT_D),
9500 OPC_MSUBF_D = FOP(25, FMT_D),
9501 OPC_RINT_D = FOP(26, FMT_D),
9502 OPC_CLASS_D = FOP(27, FMT_D),
9503 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 9504 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 9505 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 9506 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 9507 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 9508 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 9509 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
9510 OPC_RSQRT2_D = FOP(31, FMT_D),
9511 OPC_CVT_S_D = FOP(32, FMT_D),
9512 OPC_CVT_W_D = FOP(36, FMT_D),
9513 OPC_CVT_L_D = FOP(37, FMT_D),
235785e8
AM
9514 OPC_CMP_F_D = FOP(48, FMT_D),
9515 OPC_CMP_UN_D = FOP(49, FMT_D),
9516 OPC_CMP_EQ_D = FOP(50, FMT_D),
9517 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9518 OPC_CMP_OLT_D = FOP(52, FMT_D),
9519 OPC_CMP_ULT_D = FOP(53, FMT_D),
9520 OPC_CMP_OLE_D = FOP(54, FMT_D),
9521 OPC_CMP_ULE_D = FOP(55, FMT_D),
9522 OPC_CMP_SF_D = FOP(56, FMT_D),
9523 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9524 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9525 OPC_CMP_NGL_D = FOP(59, FMT_D),
9526 OPC_CMP_LT_D = FOP(60, FMT_D),
9527 OPC_CMP_NGE_D = FOP(61, FMT_D),
9528 OPC_CMP_LE_D = FOP(62, FMT_D),
9529 OPC_CMP_NGT_D = FOP(63, FMT_D),
bf4120ad
NF
9530
9531 OPC_CVT_S_W = FOP(32, FMT_W),
9532 OPC_CVT_D_W = FOP(33, FMT_W),
9533 OPC_CVT_S_L = FOP(32, FMT_L),
9534 OPC_CVT_D_L = FOP(33, FMT_L),
9535 OPC_CVT_PS_PW = FOP(38, FMT_W),
9536
9537 OPC_ADD_PS = FOP(0, FMT_PS),
9538 OPC_SUB_PS = FOP(1, FMT_PS),
9539 OPC_MUL_PS = FOP(2, FMT_PS),
9540 OPC_DIV_PS = FOP(3, FMT_PS),
9541 OPC_ABS_PS = FOP(5, FMT_PS),
9542 OPC_MOV_PS = FOP(6, FMT_PS),
9543 OPC_NEG_PS = FOP(7, FMT_PS),
9544 OPC_MOVCF_PS = FOP(17, FMT_PS),
9545 OPC_MOVZ_PS = FOP(18, FMT_PS),
9546 OPC_MOVN_PS = FOP(19, FMT_PS),
9547 OPC_ADDR_PS = FOP(24, FMT_PS),
9548 OPC_MULR_PS = FOP(26, FMT_PS),
9549 OPC_RECIP2_PS = FOP(28, FMT_PS),
9550 OPC_RECIP1_PS = FOP(29, FMT_PS),
9551 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9552 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9553
9554 OPC_CVT_S_PU = FOP(32, FMT_PS),
9555 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9556 OPC_CVT_S_PL = FOP(40, FMT_PS),
9557 OPC_PLL_PS = FOP(44, FMT_PS),
9558 OPC_PLU_PS = FOP(45, FMT_PS),
9559 OPC_PUL_PS = FOP(46, FMT_PS),
9560 OPC_PUU_PS = FOP(47, FMT_PS),
235785e8
AM
9561 OPC_CMP_F_PS = FOP(48, FMT_PS),
9562 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9563 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9564 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9565 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9566 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9567 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9568 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9569 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9570 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9571 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9572 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9573 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9574 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9575 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9576 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
bf4120ad
NF
9577};
9578
3f493883
YK
9579enum r6_f_cmp_op {
9580 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9581 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9582 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9583 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9584 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9585 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9586 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9587 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9588 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9589 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9590 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9591 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9592 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9593 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9594 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9595 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9596 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9597 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9598 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9599 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9600 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9601 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9602
9603 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9604 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9605 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9606 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9607 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9608 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9609 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9610 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9611 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9612 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9613 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9614 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9615 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9616 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9617 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9618 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9619 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9620 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9621 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9622 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9623 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9624 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9625};
235785e8
AM
9626
9627static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 9628{
72c3a3ee 9629 TCGv t0 = tcg_temp_new();
6ea83fed
FB
9630
9631 switch (opc) {
9632 case OPC_MFC1:
b6d96bed 9633 {
a7812ae4 9634 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9635
7c979afd 9636 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 9637 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9638 tcg_temp_free_i32(fp0);
6958549d 9639 }
6c5c1e20 9640 gen_store_gpr(t0, rt);
6ea83fed
FB
9641 break;
9642 case OPC_MTC1:
6c5c1e20 9643 gen_load_gpr(t0, rt);
b6d96bed 9644 {
a7812ae4 9645 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9646
9647 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9648 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 9649 tcg_temp_free_i32(fp0);
6958549d 9650 }
6ea83fed
FB
9651 break;
9652 case OPC_CFC1:
895c2d04 9653 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 9654 gen_store_gpr(t0, rt);
6ea83fed
FB
9655 break;
9656 case OPC_CTC1:
6c5c1e20 9657 gen_load_gpr(t0, rt);
9c708c7f 9658 save_cpu_state(ctx, 0);
78bdd388 9659 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
4cf8a45f 9660 /* Stop translation as we may have changed hflags */
eeb3bba8 9661 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 9662 break;
72c3a3ee 9663#if defined(TARGET_MIPS64)
9c2149c8 9664 case OPC_DMFC1:
72c3a3ee 9665 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 9666 gen_store_gpr(t0, rt);
5a5012ec 9667 break;
9c2149c8 9668 case OPC_DMTC1:
6c5c1e20 9669 gen_load_gpr(t0, rt);
72c3a3ee 9670 gen_store_fpr64(ctx, t0, fs);
5a5012ec 9671 break;
72c3a3ee 9672#endif
5a5012ec 9673 case OPC_MFHC1:
b6d96bed 9674 {
a7812ae4 9675 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9676
7f6613ce 9677 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 9678 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9679 tcg_temp_free_i32(fp0);
6958549d 9680 }
6c5c1e20 9681 gen_store_gpr(t0, rt);
5a5012ec
TS
9682 break;
9683 case OPC_MTHC1:
6c5c1e20 9684 gen_load_gpr(t0, rt);
b6d96bed 9685 {
a7812ae4 9686 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9687
9688 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9689 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 9690 tcg_temp_free_i32(fp0);
6958549d 9691 }
5a5012ec 9692 break;
6ea83fed 9693 default:
9d68ac14 9694 MIPS_INVAL("cp1 move");
3a4ef3b7 9695 gen_reserved_instruction(ctx);
6c5c1e20 9696 goto out;
6ea83fed 9697 }
6c5c1e20
TS
9698
9699 out:
9700 tcg_temp_free(t0);
6ea83fed
FB
9701}
9702
235785e8 9703static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
5a5012ec 9704{
42a268c2 9705 TCGLabel *l1;
e214b9bb 9706 TCGCond cond;
af58f9ca
AJ
9707 TCGv_i32 t0;
9708
9709 if (rd == 0) {
9710 /* Treat as NOP. */
9711 return;
9712 }
6ea83fed 9713
1f8929d2 9714 if (tf) {
e214b9bb 9715 cond = TCG_COND_EQ;
1f8929d2 9716 } else {
27848470 9717 cond = TCG_COND_NE;
1f8929d2 9718 }
27848470 9719
af58f9ca
AJ
9720 l1 = gen_new_label();
9721 t0 = tcg_temp_new_i32();
fa31af0e 9722 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 9723 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9724 tcg_temp_free_i32(t0);
c27b4579 9725 gen_load_gpr(cpu_gpr[rd], rs);
e214b9bb 9726 gen_set_label(l1);
5a5012ec
TS
9727}
9728
7c979afd
LA
9729static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9730 int tf)
a16336e4 9731{
a16336e4 9732 int cond;
cbc37b28 9733 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 9734 TCGLabel *l1 = gen_new_label();
a16336e4 9735
1f8929d2 9736 if (tf) {
a16336e4 9737 cond = TCG_COND_EQ;
1f8929d2 9738 } else {
a16336e4 9739 cond = TCG_COND_NE;
1f8929d2 9740 }
a16336e4 9741
fa31af0e 9742 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9743 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9744 gen_load_fpr32(ctx, t0, fs);
9745 gen_store_fpr32(ctx, t0, fd);
a16336e4 9746 gen_set_label(l1);
cbc37b28 9747 tcg_temp_free_i32(t0);
5a5012ec 9748}
a16336e4 9749
235785e8
AM
9750static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9751 int tf)
a16336e4 9752{
a16336e4 9753 int cond;
cbc37b28
AJ
9754 TCGv_i32 t0 = tcg_temp_new_i32();
9755 TCGv_i64 fp0;
42a268c2 9756 TCGLabel *l1 = gen_new_label();
a16336e4 9757
1f8929d2 9758 if (tf) {
a16336e4 9759 cond = TCG_COND_EQ;
1f8929d2 9760 } else {
a16336e4 9761 cond = TCG_COND_NE;
1f8929d2 9762 }
a16336e4 9763
fa31af0e 9764 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9765 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9766 tcg_temp_free_i32(t0);
11f94258 9767 fp0 = tcg_temp_new_i64();
9bf3eb2c 9768 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 9769 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9770 tcg_temp_free_i64(fp0);
cbc37b28 9771 gen_set_label(l1);
a16336e4
TS
9772}
9773
7f6613ce
PJ
9774static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9775 int cc, int tf)
a16336e4
TS
9776{
9777 int cond;
cbc37b28 9778 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
9779 TCGLabel *l1 = gen_new_label();
9780 TCGLabel *l2 = gen_new_label();
a16336e4 9781
1f8929d2 9782 if (tf) {
a16336e4 9783 cond = TCG_COND_EQ;
1f8929d2 9784 } else {
a16336e4 9785 cond = TCG_COND_NE;
1f8929d2 9786 }
a16336e4 9787
fa31af0e 9788 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9789 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9790 gen_load_fpr32(ctx, t0, fs);
9791 gen_store_fpr32(ctx, t0, fd);
a16336e4 9792 gen_set_label(l1);
9bf3eb2c 9793
71375b59 9794 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
cbc37b28 9795 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
9796 gen_load_fpr32h(ctx, t0, fs);
9797 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 9798 tcg_temp_free_i32(t0);
a16336e4 9799 gen_set_label(l2);
a16336e4
TS
9800}
9801
e7f16abb
LA
9802static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9803 int fs)
9804{
9805 TCGv_i32 t1 = tcg_const_i32(0);
9806 TCGv_i32 fp0 = tcg_temp_new_i32();
9807 TCGv_i32 fp1 = tcg_temp_new_i32();
9808 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9809 gen_load_fpr32(ctx, fp0, fd);
9810 gen_load_fpr32(ctx, fp1, ft);
9811 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9812
9813 switch (op1) {
9814 case OPC_SEL_S:
9815 tcg_gen_andi_i32(fp0, fp0, 1);
9816 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9817 break;
9818 case OPC_SELEQZ_S:
9819 tcg_gen_andi_i32(fp1, fp1, 1);
9820 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9821 break;
9822 case OPC_SELNEZ_S:
9823 tcg_gen_andi_i32(fp1, fp1, 1);
9824 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9825 break;
9826 default:
9827 MIPS_INVAL("gen_sel_s");
3a4ef3b7 9828 gen_reserved_instruction(ctx);
e7f16abb
LA
9829 break;
9830 }
9831
7c979afd 9832 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9833 tcg_temp_free_i32(fp2);
9834 tcg_temp_free_i32(fp1);
9835 tcg_temp_free_i32(fp0);
9836 tcg_temp_free_i32(t1);
9837}
9838
9839static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9840 int fs)
9841{
9842 TCGv_i64 t1 = tcg_const_i64(0);
9843 TCGv_i64 fp0 = tcg_temp_new_i64();
9844 TCGv_i64 fp1 = tcg_temp_new_i64();
9845 TCGv_i64 fp2 = tcg_temp_new_i64();
9846 gen_load_fpr64(ctx, fp0, fd);
9847 gen_load_fpr64(ctx, fp1, ft);
9848 gen_load_fpr64(ctx, fp2, fs);
9849
9850 switch (op1) {
9851 case OPC_SEL_D:
9852 tcg_gen_andi_i64(fp0, fp0, 1);
9853 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9854 break;
9855 case OPC_SELEQZ_D:
9856 tcg_gen_andi_i64(fp1, fp1, 1);
9857 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9858 break;
9859 case OPC_SELNEZ_D:
9860 tcg_gen_andi_i64(fp1, fp1, 1);
9861 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9862 break;
9863 default:
9864 MIPS_INVAL("gen_sel_d");
3a4ef3b7 9865 gen_reserved_instruction(ctx);
e7f16abb
LA
9866 break;
9867 }
9868
9869 gen_store_fpr64(ctx, fp0, fd);
9870 tcg_temp_free_i64(fp2);
9871 tcg_temp_free_i64(fp1);
9872 tcg_temp_free_i64(fp0);
9873 tcg_temp_free_i64(t1);
9874}
6ea83fed 9875
235785e8
AM
9876static void gen_farith(DisasContext *ctx, enum fopcode op1,
9877 int ft, int fs, int fd, int cc)
6ea83fed 9878{
7a387fff 9879 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9880 switch (op1) {
9881 case OPC_ADD_S:
b6d96bed 9882 {
a7812ae4
PB
9883 TCGv_i32 fp0 = tcg_temp_new_i32();
9884 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9885
7c979afd
LA
9886 gen_load_fpr32(ctx, fp0, fs);
9887 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9888 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9889 tcg_temp_free_i32(fp1);
7c979afd 9890 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9891 tcg_temp_free_i32(fp0);
b6d96bed 9892 }
5a5012ec 9893 break;
bf4120ad 9894 case OPC_SUB_S:
b6d96bed 9895 {
a7812ae4
PB
9896 TCGv_i32 fp0 = tcg_temp_new_i32();
9897 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9898
7c979afd
LA
9899 gen_load_fpr32(ctx, fp0, fs);
9900 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9901 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9902 tcg_temp_free_i32(fp1);
7c979afd 9903 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9904 tcg_temp_free_i32(fp0);
b6d96bed 9905 }
5a5012ec 9906 break;
bf4120ad 9907 case OPC_MUL_S:
b6d96bed 9908 {
a7812ae4
PB
9909 TCGv_i32 fp0 = tcg_temp_new_i32();
9910 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9911
7c979afd
LA
9912 gen_load_fpr32(ctx, fp0, fs);
9913 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9914 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9915 tcg_temp_free_i32(fp1);
7c979afd 9916 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9917 tcg_temp_free_i32(fp0);
b6d96bed 9918 }
5a5012ec 9919 break;
bf4120ad 9920 case OPC_DIV_S:
b6d96bed 9921 {
a7812ae4
PB
9922 TCGv_i32 fp0 = tcg_temp_new_i32();
9923 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9924
7c979afd
LA
9925 gen_load_fpr32(ctx, fp0, fs);
9926 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9927 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9928 tcg_temp_free_i32(fp1);
7c979afd 9929 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9930 tcg_temp_free_i32(fp0);
b6d96bed 9931 }
5a5012ec 9932 break;
bf4120ad 9933 case OPC_SQRT_S:
b6d96bed 9934 {
a7812ae4 9935 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9936
7c979afd 9937 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9938 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9939 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9940 tcg_temp_free_i32(fp0);
b6d96bed 9941 }
5a5012ec 9942 break;
bf4120ad 9943 case OPC_ABS_S:
b6d96bed 9944 {
a7812ae4 9945 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9946
7c979afd 9947 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9948 if (ctx->abs2008) {
9949 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9950 } else {
9951 gen_helper_float_abs_s(fp0, fp0);
9952 }
7c979afd 9953 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9954 tcg_temp_free_i32(fp0);
b6d96bed 9955 }
5a5012ec 9956 break;
bf4120ad 9957 case OPC_MOV_S:
b6d96bed 9958 {
a7812ae4 9959 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9960
7c979afd
LA
9961 gen_load_fpr32(ctx, fp0, fs);
9962 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9963 tcg_temp_free_i32(fp0);
b6d96bed 9964 }
5a5012ec 9965 break;
bf4120ad 9966 case OPC_NEG_S:
b6d96bed 9967 {
a7812ae4 9968 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9969
7c979afd 9970 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9971 if (ctx->abs2008) {
9972 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9973 } else {
9974 gen_helper_float_chs_s(fp0, fp0);
9975 }
7c979afd 9976 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9977 tcg_temp_free_i32(fp0);
b6d96bed 9978 }
5a5012ec 9979 break;
bf4120ad 9980 case OPC_ROUND_L_S:
5e755519 9981 check_cp1_64bitmode(ctx);
b6d96bed 9982 {
a7812ae4
PB
9983 TCGv_i32 fp32 = tcg_temp_new_i32();
9984 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9985
7c979afd 9986 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9987 if (ctx->nan2008) {
9988 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9989 } else {
9990 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9991 }
a7812ae4 9992 tcg_temp_free_i32(fp32);
b6d96bed 9993 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9994 tcg_temp_free_i64(fp64);
b6d96bed 9995 }
5a5012ec 9996 break;
bf4120ad 9997 case OPC_TRUNC_L_S:
5e755519 9998 check_cp1_64bitmode(ctx);
b6d96bed 9999 {
a7812ae4
PB
10000 TCGv_i32 fp32 = tcg_temp_new_i32();
10001 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10002
7c979afd 10003 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10004 if (ctx->nan2008) {
10005 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10006 } else {
10007 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10008 }
a7812ae4 10009 tcg_temp_free_i32(fp32);
b6d96bed 10010 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10011 tcg_temp_free_i64(fp64);
b6d96bed 10012 }
5a5012ec 10013 break;
bf4120ad 10014 case OPC_CEIL_L_S:
5e755519 10015 check_cp1_64bitmode(ctx);
b6d96bed 10016 {
a7812ae4
PB
10017 TCGv_i32 fp32 = tcg_temp_new_i32();
10018 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10019
7c979afd 10020 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10021 if (ctx->nan2008) {
10022 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10023 } else {
10024 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10025 }
a7812ae4 10026 tcg_temp_free_i32(fp32);
b6d96bed 10027 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10028 tcg_temp_free_i64(fp64);
b6d96bed 10029 }
5a5012ec 10030 break;
bf4120ad 10031 case OPC_FLOOR_L_S:
5e755519 10032 check_cp1_64bitmode(ctx);
b6d96bed 10033 {
a7812ae4
PB
10034 TCGv_i32 fp32 = tcg_temp_new_i32();
10035 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10036
7c979afd 10037 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10038 if (ctx->nan2008) {
10039 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10040 } else {
10041 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10042 }
a7812ae4 10043 tcg_temp_free_i32(fp32);
b6d96bed 10044 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10045 tcg_temp_free_i64(fp64);
b6d96bed 10046 }
5a5012ec 10047 break;
bf4120ad 10048 case OPC_ROUND_W_S:
b6d96bed 10049 {
a7812ae4 10050 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10051
7c979afd 10052 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10053 if (ctx->nan2008) {
10054 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10055 } else {
10056 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10057 }
7c979afd 10058 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10059 tcg_temp_free_i32(fp0);
b6d96bed 10060 }
5a5012ec 10061 break;
bf4120ad 10062 case OPC_TRUNC_W_S:
b6d96bed 10063 {
a7812ae4 10064 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10065
7c979afd 10066 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10067 if (ctx->nan2008) {
10068 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10069 } else {
10070 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10071 }
7c979afd 10072 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10073 tcg_temp_free_i32(fp0);
b6d96bed 10074 }
5a5012ec 10075 break;
bf4120ad 10076 case OPC_CEIL_W_S:
b6d96bed 10077 {
a7812ae4 10078 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10079
7c979afd 10080 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10081 if (ctx->nan2008) {
10082 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10083 } else {
10084 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10085 }
7c979afd 10086 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10087 tcg_temp_free_i32(fp0);
b6d96bed 10088 }
5a5012ec 10089 break;
bf4120ad 10090 case OPC_FLOOR_W_S:
b6d96bed 10091 {
a7812ae4 10092 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10093
7c979afd 10094 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10095 if (ctx->nan2008) {
10096 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10097 } else {
10098 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10099 }
7c979afd 10100 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10101 tcg_temp_free_i32(fp0);
b6d96bed 10102 }
5a5012ec 10103 break;
e7f16abb 10104 case OPC_SEL_S:
2e211e0a 10105 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10106 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10107 break;
10108 case OPC_SELEQZ_S:
2e211e0a 10109 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10110 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10111 break;
10112 case OPC_SELNEZ_S:
2e211e0a 10113 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10114 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 10115 break;
bf4120ad 10116 case OPC_MOVCF_S:
2e211e0a 10117 check_insn_opc_removed(ctx, ISA_MIPS_R6);
7c979afd 10118 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 10119 break;
bf4120ad 10120 case OPC_MOVZ_S:
2e211e0a 10121 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10122 {
42a268c2 10123 TCGLabel *l1 = gen_new_label();
c9297f4d 10124 TCGv_i32 fp0;
a16336e4 10125
c9297f4d
AJ
10126 if (ft != 0) {
10127 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10128 }
10129 fp0 = tcg_temp_new_i32();
7c979afd
LA
10130 gen_load_fpr32(ctx, fp0, fs);
10131 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10132 tcg_temp_free_i32(fp0);
a16336e4
TS
10133 gen_set_label(l1);
10134 }
5a5012ec 10135 break;
bf4120ad 10136 case OPC_MOVN_S:
2e211e0a 10137 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10138 {
42a268c2 10139 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10140 TCGv_i32 fp0;
10141
10142 if (ft != 0) {
10143 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10144 fp0 = tcg_temp_new_i32();
7c979afd
LA
10145 gen_load_fpr32(ctx, fp0, fs);
10146 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
10147 tcg_temp_free_i32(fp0);
10148 gen_set_label(l1);
10149 }
a16336e4 10150 }
5a5012ec 10151 break;
bf4120ad 10152 case OPC_RECIP_S:
b6d96bed 10153 {
a7812ae4 10154 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10155
7c979afd 10156 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10157 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 10158 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10159 tcg_temp_free_i32(fp0);
b6d96bed 10160 }
57fa1fb3 10161 break;
bf4120ad 10162 case OPC_RSQRT_S:
b6d96bed 10163 {
a7812ae4 10164 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10165
7c979afd 10166 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10167 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 10168 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10169 tcg_temp_free_i32(fp0);
b6d96bed 10170 }
57fa1fb3 10171 break;
e7f16abb 10172 case OPC_MADDF_S:
2e211e0a 10173 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10174 {
a7812ae4
PB
10175 TCGv_i32 fp0 = tcg_temp_new_i32();
10176 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10177 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10178 gen_load_fpr32(ctx, fp0, fs);
10179 gen_load_fpr32(ctx, fp1, ft);
10180 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10181 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10182 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 10183 tcg_temp_free_i32(fp2);
a7812ae4 10184 tcg_temp_free_i32(fp1);
a7812ae4 10185 tcg_temp_free_i32(fp0);
b6d96bed 10186 }
57fa1fb3 10187 break;
e7f16abb 10188 case OPC_MSUBF_S:
2e211e0a 10189 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10190 {
a7812ae4 10191 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
10192 TCGv_i32 fp1 = tcg_temp_new_i32();
10193 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10194 gen_load_fpr32(ctx, fp0, fs);
10195 gen_load_fpr32(ctx, fp1, ft);
10196 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10197 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10198 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10199 tcg_temp_free_i32(fp2);
10200 tcg_temp_free_i32(fp1);
a7812ae4 10201 tcg_temp_free_i32(fp0);
b6d96bed 10202 }
57fa1fb3 10203 break;
e7f16abb 10204 case OPC_RINT_S:
2e211e0a 10205 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10206 {
a7812ae4 10207 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10208 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10209 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 10210 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10211 tcg_temp_free_i32(fp0);
b6d96bed 10212 }
57fa1fb3 10213 break;
e7f16abb 10214 case OPC_CLASS_S:
2e211e0a 10215 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10216 {
e7f16abb 10217 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10218 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 10219 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 10220 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 10221 tcg_temp_free_i32(fp0);
e7f16abb
LA
10222 }
10223 break;
10224 case OPC_MIN_S: /* OPC_RECIP2_S */
2e211e0a 10225 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb 10226 /* OPC_MIN_S */
a7812ae4
PB
10227 TCGv_i32 fp0 = tcg_temp_new_i32();
10228 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10229 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10230 gen_load_fpr32(ctx, fp0, fs);
10231 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10232 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 10233 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10234 tcg_temp_free_i32(fp2);
10235 tcg_temp_free_i32(fp1);
10236 tcg_temp_free_i32(fp0);
e7f16abb
LA
10237 } else {
10238 /* OPC_RECIP2_S */
10239 check_cp1_64bitmode(ctx);
10240 {
10241 TCGv_i32 fp0 = tcg_temp_new_i32();
10242 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10243
7c979afd
LA
10244 gen_load_fpr32(ctx, fp0, fs);
10245 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10246 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10247 tcg_temp_free_i32(fp1);
7c979afd 10248 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10249 tcg_temp_free_i32(fp0);
10250 }
e7f16abb
LA
10251 }
10252 break;
10253 case OPC_MINA_S: /* OPC_RECIP1_S */
2e211e0a 10254 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10255 /* OPC_MINA_S */
10256 TCGv_i32 fp0 = tcg_temp_new_i32();
10257 TCGv_i32 fp1 = tcg_temp_new_i32();
10258 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10259 gen_load_fpr32(ctx, fp0, fs);
10260 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10261 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 10262 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10263 tcg_temp_free_i32(fp2);
10264 tcg_temp_free_i32(fp1);
10265 tcg_temp_free_i32(fp0);
e7f16abb
LA
10266 } else {
10267 /* OPC_RECIP1_S */
10268 check_cp1_64bitmode(ctx);
10269 {
10270 TCGv_i32 fp0 = tcg_temp_new_i32();
10271
7c979afd 10272 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10273 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 10274 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10275 tcg_temp_free_i32(fp0);
10276 }
e7f16abb
LA
10277 }
10278 break;
10279 case OPC_MAX_S: /* OPC_RSQRT1_S */
2e211e0a 10280 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10281 /* OPC_MAX_S */
10282 TCGv_i32 fp0 = tcg_temp_new_i32();
10283 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10284 gen_load_fpr32(ctx, fp0, fs);
10285 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10286 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 10287 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
10288 tcg_temp_free_i32(fp1);
10289 tcg_temp_free_i32(fp0);
e7f16abb
LA
10290 } else {
10291 /* OPC_RSQRT1_S */
10292 check_cp1_64bitmode(ctx);
10293 {
10294 TCGv_i32 fp0 = tcg_temp_new_i32();
10295
7c979afd 10296 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10297 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 10298 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10299 tcg_temp_free_i32(fp0);
10300 }
e7f16abb
LA
10301 }
10302 break;
10303 case OPC_MAXA_S: /* OPC_RSQRT2_S */
2e211e0a 10304 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10305 /* OPC_MAXA_S */
10306 TCGv_i32 fp0 = tcg_temp_new_i32();
10307 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10308 gen_load_fpr32(ctx, fp0, fs);
10309 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10310 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 10311 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 10312 tcg_temp_free_i32(fp1);
a7812ae4 10313 tcg_temp_free_i32(fp0);
e7f16abb
LA
10314 } else {
10315 /* OPC_RSQRT2_S */
10316 check_cp1_64bitmode(ctx);
10317 {
10318 TCGv_i32 fp0 = tcg_temp_new_i32();
10319 TCGv_i32 fp1 = tcg_temp_new_i32();
10320
7c979afd
LA
10321 gen_load_fpr32(ctx, fp0, fs);
10322 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10323 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10324 tcg_temp_free_i32(fp1);
7c979afd 10325 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10326 tcg_temp_free_i32(fp0);
10327 }
b6d96bed 10328 }
57fa1fb3 10329 break;
bf4120ad 10330 case OPC_CVT_D_S:
5e755519 10331 check_cp1_registers(ctx, fd);
b6d96bed 10332 {
a7812ae4
PB
10333 TCGv_i32 fp32 = tcg_temp_new_i32();
10334 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10335
7c979afd 10336 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10337 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 10338 tcg_temp_free_i32(fp32);
b6d96bed 10339 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10340 tcg_temp_free_i64(fp64);
b6d96bed 10341 }
5a5012ec 10342 break;
bf4120ad 10343 case OPC_CVT_W_S:
b6d96bed 10344 {
a7812ae4 10345 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10346
7c979afd 10347 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10348 if (ctx->nan2008) {
10349 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10350 } else {
10351 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10352 }
7c979afd 10353 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10354 tcg_temp_free_i32(fp0);
b6d96bed 10355 }
5a5012ec 10356 break;
bf4120ad 10357 case OPC_CVT_L_S:
5e755519 10358 check_cp1_64bitmode(ctx);
b6d96bed 10359 {
a7812ae4
PB
10360 TCGv_i32 fp32 = tcg_temp_new_i32();
10361 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10362
7c979afd 10363 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10364 if (ctx->nan2008) {
10365 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10366 } else {
10367 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10368 }
a7812ae4 10369 tcg_temp_free_i32(fp32);
b6d96bed 10370 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10371 tcg_temp_free_i64(fp64);
b6d96bed 10372 }
5a5012ec 10373 break;
bf4120ad 10374 case OPC_CVT_PS_S:
e29c9628 10375 check_ps(ctx);
b6d96bed 10376 {
a7812ae4
PB
10377 TCGv_i64 fp64 = tcg_temp_new_i64();
10378 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10379 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 10380
7c979afd
LA
10381 gen_load_fpr32(ctx, fp32_0, fs);
10382 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 10383 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
10384 tcg_temp_free_i32(fp32_1);
10385 tcg_temp_free_i32(fp32_0);
36aa55dc 10386 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10387 tcg_temp_free_i64(fp64);
b6d96bed 10388 }
5a5012ec 10389 break;
bf4120ad
NF
10390 case OPC_CMP_F_S:
10391 case OPC_CMP_UN_S:
10392 case OPC_CMP_EQ_S:
10393 case OPC_CMP_UEQ_S:
10394 case OPC_CMP_OLT_S:
10395 case OPC_CMP_ULT_S:
10396 case OPC_CMP_OLE_S:
10397 case OPC_CMP_ULE_S:
10398 case OPC_CMP_SF_S:
10399 case OPC_CMP_NGLE_S:
10400 case OPC_CMP_SEQ_S:
10401 case OPC_CMP_NGL_S:
10402 case OPC_CMP_LT_S:
10403 case OPC_CMP_NGE_S:
10404 case OPC_CMP_LE_S:
10405 case OPC_CMP_NGT_S:
2e211e0a 10406 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8153667c 10407 if (ctx->opcode & (1 << 6)) {
71375b59 10408 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
8153667c 10409 } else {
71375b59 10410 gen_cmp_s(ctx, func - 48, ft, fs, cc);
5a1e8ffb 10411 }
5a5012ec 10412 break;
bf4120ad 10413 case OPC_ADD_D:
5e755519 10414 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10415 {
a7812ae4
PB
10416 TCGv_i64 fp0 = tcg_temp_new_i64();
10417 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10418
10419 gen_load_fpr64(ctx, fp0, fs);
10420 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10421 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10422 tcg_temp_free_i64(fp1);
b6d96bed 10423 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10424 tcg_temp_free_i64(fp0);
b6d96bed 10425 }
6ea83fed 10426 break;
bf4120ad 10427 case OPC_SUB_D:
5e755519 10428 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10429 {
a7812ae4
PB
10430 TCGv_i64 fp0 = tcg_temp_new_i64();
10431 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10432
10433 gen_load_fpr64(ctx, fp0, fs);
10434 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10435 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10436 tcg_temp_free_i64(fp1);
b6d96bed 10437 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10438 tcg_temp_free_i64(fp0);
b6d96bed 10439 }
6ea83fed 10440 break;
bf4120ad 10441 case OPC_MUL_D:
5e755519 10442 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10443 {
a7812ae4
PB
10444 TCGv_i64 fp0 = tcg_temp_new_i64();
10445 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10446
10447 gen_load_fpr64(ctx, fp0, fs);
10448 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10449 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10450 tcg_temp_free_i64(fp1);
b6d96bed 10451 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10452 tcg_temp_free_i64(fp0);
b6d96bed 10453 }
6ea83fed 10454 break;
bf4120ad 10455 case OPC_DIV_D:
5e755519 10456 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 10457 {
a7812ae4
PB
10458 TCGv_i64 fp0 = tcg_temp_new_i64();
10459 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10460
10461 gen_load_fpr64(ctx, fp0, fs);
10462 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10463 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 10464 tcg_temp_free_i64(fp1);
b6d96bed 10465 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10466 tcg_temp_free_i64(fp0);
b6d96bed 10467 }
6ea83fed 10468 break;
bf4120ad 10469 case OPC_SQRT_D:
5e755519 10470 check_cp1_registers(ctx, fs | fd);
b6d96bed 10471 {
a7812ae4 10472 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10473
10474 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10475 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 10476 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10477 tcg_temp_free_i64(fp0);
b6d96bed 10478 }
6ea83fed 10479 break;
bf4120ad 10480 case OPC_ABS_D:
5e755519 10481 check_cp1_registers(ctx, fs | fd);
b6d96bed 10482 {
a7812ae4 10483 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10484
10485 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
10486 if (ctx->abs2008) {
10487 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10488 } else {
10489 gen_helper_float_abs_d(fp0, fp0);
10490 }
b6d96bed 10491 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10492 tcg_temp_free_i64(fp0);
b6d96bed 10493 }
6ea83fed 10494 break;
bf4120ad 10495 case OPC_MOV_D:
5e755519 10496 check_cp1_registers(ctx, fs | fd);
b6d96bed 10497 {
a7812ae4 10498 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10499
10500 gen_load_fpr64(ctx, fp0, fs);
10501 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10502 tcg_temp_free_i64(fp0);
b6d96bed 10503 }
6ea83fed 10504 break;
bf4120ad 10505 case OPC_NEG_D:
5e755519 10506 check_cp1_registers(ctx, fs | fd);
b6d96bed 10507 {
a7812ae4 10508 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10509
10510 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
10511 if (ctx->abs2008) {
10512 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10513 } else {
10514 gen_helper_float_chs_d(fp0, fp0);
10515 }
b6d96bed 10516 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10517 tcg_temp_free_i64(fp0);
b6d96bed 10518 }
6ea83fed 10519 break;
bf4120ad 10520 case OPC_ROUND_L_D:
5e755519 10521 check_cp1_64bitmode(ctx);
b6d96bed 10522 {
a7812ae4 10523 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10524
10525 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10526 if (ctx->nan2008) {
10527 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10528 } else {
10529 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10530 }
b6d96bed 10531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10532 tcg_temp_free_i64(fp0);
b6d96bed 10533 }
5a5012ec 10534 break;
bf4120ad 10535 case OPC_TRUNC_L_D:
5e755519 10536 check_cp1_64bitmode(ctx);
b6d96bed 10537 {
a7812ae4 10538 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10539
10540 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10541 if (ctx->nan2008) {
10542 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10543 } else {
10544 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10545 }
b6d96bed 10546 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10547 tcg_temp_free_i64(fp0);
b6d96bed 10548 }
5a5012ec 10549 break;
bf4120ad 10550 case OPC_CEIL_L_D:
5e755519 10551 check_cp1_64bitmode(ctx);
b6d96bed 10552 {
a7812ae4 10553 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10554
10555 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10556 if (ctx->nan2008) {
10557 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10558 } else {
10559 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10560 }
b6d96bed 10561 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10562 tcg_temp_free_i64(fp0);
b6d96bed 10563 }
5a5012ec 10564 break;
bf4120ad 10565 case OPC_FLOOR_L_D:
5e755519 10566 check_cp1_64bitmode(ctx);
b6d96bed 10567 {
a7812ae4 10568 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10569
10570 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10571 if (ctx->nan2008) {
10572 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10573 } else {
10574 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10575 }
b6d96bed 10576 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10577 tcg_temp_free_i64(fp0);
b6d96bed 10578 }
5a5012ec 10579 break;
bf4120ad 10580 case OPC_ROUND_W_D:
5e755519 10581 check_cp1_registers(ctx, fs);
b6d96bed 10582 {
a7812ae4
PB
10583 TCGv_i32 fp32 = tcg_temp_new_i32();
10584 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10585
10586 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10587 if (ctx->nan2008) {
10588 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10589 } else {
10590 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10591 }
a7812ae4 10592 tcg_temp_free_i64(fp64);
7c979afd 10593 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10594 tcg_temp_free_i32(fp32);
b6d96bed 10595 }
6ea83fed 10596 break;
bf4120ad 10597 case OPC_TRUNC_W_D:
5e755519 10598 check_cp1_registers(ctx, fs);
b6d96bed 10599 {
a7812ae4
PB
10600 TCGv_i32 fp32 = tcg_temp_new_i32();
10601 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10602
10603 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10604 if (ctx->nan2008) {
10605 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10606 } else {
10607 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10608 }
a7812ae4 10609 tcg_temp_free_i64(fp64);
7c979afd 10610 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10611 tcg_temp_free_i32(fp32);
b6d96bed 10612 }
6ea83fed 10613 break;
bf4120ad 10614 case OPC_CEIL_W_D:
5e755519 10615 check_cp1_registers(ctx, fs);
b6d96bed 10616 {
a7812ae4
PB
10617 TCGv_i32 fp32 = tcg_temp_new_i32();
10618 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10619
10620 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10621 if (ctx->nan2008) {
10622 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10623 } else {
10624 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10625 }
a7812ae4 10626 tcg_temp_free_i64(fp64);
7c979afd 10627 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10628 tcg_temp_free_i32(fp32);
b6d96bed 10629 }
6ea83fed 10630 break;
bf4120ad 10631 case OPC_FLOOR_W_D:
5e755519 10632 check_cp1_registers(ctx, fs);
b6d96bed 10633 {
a7812ae4
PB
10634 TCGv_i32 fp32 = tcg_temp_new_i32();
10635 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10636
10637 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10638 if (ctx->nan2008) {
10639 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10640 } else {
10641 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10642 }
a7812ae4 10643 tcg_temp_free_i64(fp64);
7c979afd 10644 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10645 tcg_temp_free_i32(fp32);
b6d96bed 10646 }
6ea83fed 10647 break;
e7f16abb 10648 case OPC_SEL_D:
2e211e0a 10649 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10650 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10651 break;
10652 case OPC_SELEQZ_D:
2e211e0a 10653 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10654 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10655 break;
10656 case OPC_SELNEZ_D:
2e211e0a 10657 check_insn(ctx, ISA_MIPS_R6);
e7f16abb 10658 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 10659 break;
bf4120ad 10660 case OPC_MOVCF_D:
2e211e0a 10661 check_insn_opc_removed(ctx, ISA_MIPS_R6);
b6d96bed 10662 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 10663 break;
bf4120ad 10664 case OPC_MOVZ_D:
2e211e0a 10665 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10666 {
42a268c2 10667 TCGLabel *l1 = gen_new_label();
c9297f4d 10668 TCGv_i64 fp0;
a16336e4 10669
c9297f4d
AJ
10670 if (ft != 0) {
10671 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10672 }
10673 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10674 gen_load_fpr64(ctx, fp0, fs);
10675 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10676 tcg_temp_free_i64(fp0);
a16336e4
TS
10677 gen_set_label(l1);
10678 }
5a5012ec 10679 break;
bf4120ad 10680 case OPC_MOVN_D:
2e211e0a 10681 check_insn_opc_removed(ctx, ISA_MIPS_R6);
a16336e4 10682 {
42a268c2 10683 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10684 TCGv_i64 fp0;
10685
10686 if (ft != 0) {
10687 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10688 fp0 = tcg_temp_new_i64();
10689 gen_load_fpr64(ctx, fp0, fs);
10690 gen_store_fpr64(ctx, fp0, fd);
10691 tcg_temp_free_i64(fp0);
10692 gen_set_label(l1);
10693 }
a16336e4 10694 }
6ea83fed 10695 break;
bf4120ad 10696 case OPC_RECIP_D:
ca6c7803 10697 check_cp1_registers(ctx, fs | fd);
b6d96bed 10698 {
a7812ae4 10699 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10700
10701 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10702 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 10703 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10704 tcg_temp_free_i64(fp0);
b6d96bed 10705 }
57fa1fb3 10706 break;
bf4120ad 10707 case OPC_RSQRT_D:
ca6c7803 10708 check_cp1_registers(ctx, fs | fd);
b6d96bed 10709 {
a7812ae4 10710 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10711
10712 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10713 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 10714 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10715 tcg_temp_free_i64(fp0);
b6d96bed 10716 }
57fa1fb3 10717 break;
e7f16abb 10718 case OPC_MADDF_D:
2e211e0a 10719 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10720 {
a7812ae4
PB
10721 TCGv_i64 fp0 = tcg_temp_new_i64();
10722 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 10723 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10724 gen_load_fpr64(ctx, fp0, fs);
10725 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10726 gen_load_fpr64(ctx, fp2, fd);
10727 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10728 gen_store_fpr64(ctx, fp2, fd);
10729 tcg_temp_free_i64(fp2);
a7812ae4 10730 tcg_temp_free_i64(fp1);
a7812ae4 10731 tcg_temp_free_i64(fp0);
b6d96bed 10732 }
57fa1fb3 10733 break;
e7f16abb 10734 case OPC_MSUBF_D:
2e211e0a 10735 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10736 {
a7812ae4 10737 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
10738 TCGv_i64 fp1 = tcg_temp_new_i64();
10739 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 10740 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
10741 gen_load_fpr64(ctx, fp1, ft);
10742 gen_load_fpr64(ctx, fp2, fd);
10743 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10744 gen_store_fpr64(ctx, fp2, fd);
10745 tcg_temp_free_i64(fp2);
10746 tcg_temp_free_i64(fp1);
a7812ae4 10747 tcg_temp_free_i64(fp0);
b6d96bed 10748 }
57fa1fb3 10749 break;
e7f16abb 10750 case OPC_RINT_D:
2e211e0a 10751 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10752 {
a7812ae4 10753 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10754 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 10755 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 10756 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10757 tcg_temp_free_i64(fp0);
b6d96bed 10758 }
57fa1fb3 10759 break;
e7f16abb 10760 case OPC_CLASS_D:
2e211e0a 10761 check_insn(ctx, ISA_MIPS_R6);
b6d96bed 10762 {
e7f16abb
LA
10763 TCGv_i64 fp0 = tcg_temp_new_i64();
10764 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 10765 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
10766 gen_store_fpr64(ctx, fp0, fd);
10767 tcg_temp_free_i64(fp0);
e7f16abb
LA
10768 }
10769 break;
10770 case OPC_MIN_D: /* OPC_RECIP2_D */
2e211e0a 10771 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb 10772 /* OPC_MIN_D */
a7812ae4
PB
10773 TCGv_i64 fp0 = tcg_temp_new_i64();
10774 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
10775 gen_load_fpr64(ctx, fp0, fs);
10776 gen_load_fpr64(ctx, fp1, ft);
10777 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10778 gen_store_fpr64(ctx, fp1, fd);
10779 tcg_temp_free_i64(fp1);
10780 tcg_temp_free_i64(fp0);
e7f16abb
LA
10781 } else {
10782 /* OPC_RECIP2_D */
10783 check_cp1_64bitmode(ctx);
10784 {
10785 TCGv_i64 fp0 = tcg_temp_new_i64();
10786 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 10787
e7f16abb
LA
10788 gen_load_fpr64(ctx, fp0, fs);
10789 gen_load_fpr64(ctx, fp1, ft);
10790 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10791 tcg_temp_free_i64(fp1);
10792 gen_store_fpr64(ctx, fp0, fd);
10793 tcg_temp_free_i64(fp0);
10794 }
e7f16abb
LA
10795 }
10796 break;
10797 case OPC_MINA_D: /* OPC_RECIP1_D */
2e211e0a 10798 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10799 /* OPC_MINA_D */
10800 TCGv_i64 fp0 = tcg_temp_new_i64();
10801 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10802 gen_load_fpr64(ctx, fp0, fs);
10803 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10804 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10805 gen_store_fpr64(ctx, fp1, fd);
10806 tcg_temp_free_i64(fp1);
10807 tcg_temp_free_i64(fp0);
e7f16abb
LA
10808 } else {
10809 /* OPC_RECIP1_D */
10810 check_cp1_64bitmode(ctx);
10811 {
10812 TCGv_i64 fp0 = tcg_temp_new_i64();
10813
10814 gen_load_fpr64(ctx, fp0, fs);
10815 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10816 gen_store_fpr64(ctx, fp0, fd);
10817 tcg_temp_free_i64(fp0);
10818 }
e7f16abb
LA
10819 }
10820 break;
10821 case OPC_MAX_D: /* OPC_RSQRT1_D */
2e211e0a 10822 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10823 /* OPC_MAX_D */
10824 TCGv_i64 fp0 = tcg_temp_new_i64();
10825 TCGv_i64 fp1 = tcg_temp_new_i64();
10826 gen_load_fpr64(ctx, fp0, fs);
10827 gen_load_fpr64(ctx, fp1, ft);
10828 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10829 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10830 tcg_temp_free_i64(fp1);
a7812ae4 10831 tcg_temp_free_i64(fp0);
e7f16abb
LA
10832 } else {
10833 /* OPC_RSQRT1_D */
10834 check_cp1_64bitmode(ctx);
10835 {
10836 TCGv_i64 fp0 = tcg_temp_new_i64();
10837
10838 gen_load_fpr64(ctx, fp0, fs);
10839 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10840 gen_store_fpr64(ctx, fp0, fd);
10841 tcg_temp_free_i64(fp0);
10842 }
e7f16abb
LA
10843 }
10844 break;
10845 case OPC_MAXA_D: /* OPC_RSQRT2_D */
2e211e0a 10846 if (ctx->insn_flags & ISA_MIPS_R6) {
e7f16abb
LA
10847 /* OPC_MAXA_D */
10848 TCGv_i64 fp0 = tcg_temp_new_i64();
10849 TCGv_i64 fp1 = tcg_temp_new_i64();
10850 gen_load_fpr64(ctx, fp0, fs);
10851 gen_load_fpr64(ctx, fp1, ft);
10852 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10853 gen_store_fpr64(ctx, fp1, fd);
10854 tcg_temp_free_i64(fp1);
10855 tcg_temp_free_i64(fp0);
e7f16abb
LA
10856 } else {
10857 /* OPC_RSQRT2_D */
10858 check_cp1_64bitmode(ctx);
10859 {
10860 TCGv_i64 fp0 = tcg_temp_new_i64();
10861 TCGv_i64 fp1 = tcg_temp_new_i64();
10862
10863 gen_load_fpr64(ctx, fp0, fs);
10864 gen_load_fpr64(ctx, fp1, ft);
10865 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10866 tcg_temp_free_i64(fp1);
10867 gen_store_fpr64(ctx, fp0, fd);
10868 tcg_temp_free_i64(fp0);
10869 }
b6d96bed 10870 }
57fa1fb3 10871 break;
bf4120ad
NF
10872 case OPC_CMP_F_D:
10873 case OPC_CMP_UN_D:
10874 case OPC_CMP_EQ_D:
10875 case OPC_CMP_UEQ_D:
10876 case OPC_CMP_OLT_D:
10877 case OPC_CMP_ULT_D:
10878 case OPC_CMP_OLE_D:
10879 case OPC_CMP_ULE_D:
10880 case OPC_CMP_SF_D:
10881 case OPC_CMP_NGLE_D:
10882 case OPC_CMP_SEQ_D:
10883 case OPC_CMP_NGL_D:
10884 case OPC_CMP_LT_D:
10885 case OPC_CMP_NGE_D:
10886 case OPC_CMP_LE_D:
10887 case OPC_CMP_NGT_D:
2e211e0a 10888 check_insn_opc_removed(ctx, ISA_MIPS_R6);
8153667c 10889 if (ctx->opcode & (1 << 6)) {
71375b59 10890 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
8153667c 10891 } else {
71375b59 10892 gen_cmp_d(ctx, func - 48, ft, fs, cc);
5a1e8ffb 10893 }
6ea83fed 10894 break;
bf4120ad 10895 case OPC_CVT_S_D:
5e755519 10896 check_cp1_registers(ctx, fs);
b6d96bed 10897 {
a7812ae4
PB
10898 TCGv_i32 fp32 = tcg_temp_new_i32();
10899 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10900
10901 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10902 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10903 tcg_temp_free_i64(fp64);
7c979afd 10904 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10905 tcg_temp_free_i32(fp32);
b6d96bed 10906 }
5a5012ec 10907 break;
bf4120ad 10908 case OPC_CVT_W_D:
5e755519 10909 check_cp1_registers(ctx, fs);
b6d96bed 10910 {
a7812ae4
PB
10911 TCGv_i32 fp32 = tcg_temp_new_i32();
10912 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10913
10914 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10915 if (ctx->nan2008) {
10916 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10917 } else {
10918 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10919 }
a7812ae4 10920 tcg_temp_free_i64(fp64);
7c979afd 10921 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10922 tcg_temp_free_i32(fp32);
b6d96bed 10923 }
5a5012ec 10924 break;
bf4120ad 10925 case OPC_CVT_L_D:
5e755519 10926 check_cp1_64bitmode(ctx);
b6d96bed 10927 {
a7812ae4 10928 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10929
10930 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10931 if (ctx->nan2008) {
10932 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10933 } else {
10934 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10935 }
b6d96bed 10936 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10937 tcg_temp_free_i64(fp0);
b6d96bed 10938 }
5a5012ec 10939 break;
bf4120ad 10940 case OPC_CVT_S_W:
b6d96bed 10941 {
a7812ae4 10942 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10943
7c979afd 10944 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10945 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10946 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10947 tcg_temp_free_i32(fp0);
b6d96bed 10948 }
6ea83fed 10949 break;
bf4120ad 10950 case OPC_CVT_D_W:
5e755519 10951 check_cp1_registers(ctx, fd);
b6d96bed 10952 {
a7812ae4
PB
10953 TCGv_i32 fp32 = tcg_temp_new_i32();
10954 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10955
7c979afd 10956 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10957 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10958 tcg_temp_free_i32(fp32);
b6d96bed 10959 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10960 tcg_temp_free_i64(fp64);
b6d96bed 10961 }
5a5012ec 10962 break;
bf4120ad 10963 case OPC_CVT_S_L:
5e755519 10964 check_cp1_64bitmode(ctx);
b6d96bed 10965 {
a7812ae4
PB
10966 TCGv_i32 fp32 = tcg_temp_new_i32();
10967 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10968
10969 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10970 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10971 tcg_temp_free_i64(fp64);
7c979afd 10972 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10973 tcg_temp_free_i32(fp32);
b6d96bed 10974 }
5a5012ec 10975 break;
bf4120ad 10976 case OPC_CVT_D_L:
5e755519 10977 check_cp1_64bitmode(ctx);
b6d96bed 10978 {
a7812ae4 10979 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10980
10981 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10982 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10983 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10984 tcg_temp_free_i64(fp0);
b6d96bed 10985 }
5a5012ec 10986 break;
bf4120ad 10987 case OPC_CVT_PS_PW:
e29c9628 10988 check_ps(ctx);
b6d96bed 10989 {
a7812ae4 10990 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10991
10992 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10993 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10994 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10995 tcg_temp_free_i64(fp0);
b6d96bed 10996 }
5a5012ec 10997 break;
bf4120ad 10998 case OPC_ADD_PS:
e29c9628 10999 check_ps(ctx);
b6d96bed 11000 {
a7812ae4
PB
11001 TCGv_i64 fp0 = tcg_temp_new_i64();
11002 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11003
11004 gen_load_fpr64(ctx, fp0, fs);
11005 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11006 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11007 tcg_temp_free_i64(fp1);
b6d96bed 11008 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11009 tcg_temp_free_i64(fp0);
b6d96bed 11010 }
6ea83fed 11011 break;
bf4120ad 11012 case OPC_SUB_PS:
e29c9628 11013 check_ps(ctx);
b6d96bed 11014 {
a7812ae4
PB
11015 TCGv_i64 fp0 = tcg_temp_new_i64();
11016 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11017
11018 gen_load_fpr64(ctx, fp0, fs);
11019 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11020 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11021 tcg_temp_free_i64(fp1);
b6d96bed 11022 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11023 tcg_temp_free_i64(fp0);
b6d96bed 11024 }
6ea83fed 11025 break;
bf4120ad 11026 case OPC_MUL_PS:
e29c9628 11027 check_ps(ctx);
b6d96bed 11028 {
a7812ae4
PB
11029 TCGv_i64 fp0 = tcg_temp_new_i64();
11030 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11031
11032 gen_load_fpr64(ctx, fp0, fs);
11033 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11034 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11035 tcg_temp_free_i64(fp1);
b6d96bed 11036 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11037 tcg_temp_free_i64(fp0);
b6d96bed 11038 }
6ea83fed 11039 break;
bf4120ad 11040 case OPC_ABS_PS:
e29c9628 11041 check_ps(ctx);
b6d96bed 11042 {
a7812ae4 11043 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11044
11045 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11046 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 11047 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11048 tcg_temp_free_i64(fp0);
b6d96bed 11049 }
6ea83fed 11050 break;
bf4120ad 11051 case OPC_MOV_PS:
e29c9628 11052 check_ps(ctx);
b6d96bed 11053 {
a7812ae4 11054 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11055
11056 gen_load_fpr64(ctx, fp0, fs);
11057 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11058 tcg_temp_free_i64(fp0);
b6d96bed 11059 }
6ea83fed 11060 break;
bf4120ad 11061 case OPC_NEG_PS:
e29c9628 11062 check_ps(ctx);
b6d96bed 11063 {
a7812ae4 11064 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11065
11066 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11067 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 11068 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11069 tcg_temp_free_i64(fp0);
b6d96bed 11070 }
6ea83fed 11071 break;
bf4120ad 11072 case OPC_MOVCF_PS:
e29c9628 11073 check_ps(ctx);
7f6613ce 11074 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 11075 break;
bf4120ad 11076 case OPC_MOVZ_PS:
e29c9628 11077 check_ps(ctx);
a16336e4 11078 {
42a268c2 11079 TCGLabel *l1 = gen_new_label();
30a3848b 11080 TCGv_i64 fp0;
a16336e4 11081
1f8929d2 11082 if (ft != 0) {
c9297f4d 11083 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
1f8929d2 11084 }
c9297f4d
AJ
11085 fp0 = tcg_temp_new_i64();
11086 gen_load_fpr64(ctx, fp0, fs);
11087 gen_store_fpr64(ctx, fp0, fd);
11088 tcg_temp_free_i64(fp0);
a16336e4
TS
11089 gen_set_label(l1);
11090 }
6ea83fed 11091 break;
bf4120ad 11092 case OPC_MOVN_PS:
e29c9628 11093 check_ps(ctx);
a16336e4 11094 {
42a268c2 11095 TCGLabel *l1 = gen_new_label();
30a3848b 11096 TCGv_i64 fp0;
c9297f4d
AJ
11097
11098 if (ft != 0) {
11099 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11100 fp0 = tcg_temp_new_i64();
11101 gen_load_fpr64(ctx, fp0, fs);
11102 gen_store_fpr64(ctx, fp0, fd);
11103 tcg_temp_free_i64(fp0);
11104 gen_set_label(l1);
11105 }
a16336e4 11106 }
6ea83fed 11107 break;
bf4120ad 11108 case OPC_ADDR_PS:
e29c9628 11109 check_ps(ctx);
b6d96bed 11110 {
a7812ae4
PB
11111 TCGv_i64 fp0 = tcg_temp_new_i64();
11112 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11113
11114 gen_load_fpr64(ctx, fp0, ft);
11115 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11116 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11117 tcg_temp_free_i64(fp1);
b6d96bed 11118 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11119 tcg_temp_free_i64(fp0);
b6d96bed 11120 }
fbcc6828 11121 break;
bf4120ad 11122 case OPC_MULR_PS:
e29c9628 11123 check_ps(ctx);
b6d96bed 11124 {
a7812ae4
PB
11125 TCGv_i64 fp0 = tcg_temp_new_i64();
11126 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11127
11128 gen_load_fpr64(ctx, fp0, ft);
11129 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11130 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11131 tcg_temp_free_i64(fp1);
b6d96bed 11132 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11133 tcg_temp_free_i64(fp0);
b6d96bed 11134 }
57fa1fb3 11135 break;
bf4120ad 11136 case OPC_RECIP2_PS:
e29c9628 11137 check_ps(ctx);
b6d96bed 11138 {
a7812ae4
PB
11139 TCGv_i64 fp0 = tcg_temp_new_i64();
11140 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11141
11142 gen_load_fpr64(ctx, fp0, fs);
d22d7289 11143 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11144 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11145 tcg_temp_free_i64(fp1);
b6d96bed 11146 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11147 tcg_temp_free_i64(fp0);
b6d96bed 11148 }
57fa1fb3 11149 break;
bf4120ad 11150 case OPC_RECIP1_PS:
e29c9628 11151 check_ps(ctx);
b6d96bed 11152 {
a7812ae4 11153 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11154
11155 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11156 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 11157 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11158 tcg_temp_free_i64(fp0);
b6d96bed 11159 }
57fa1fb3 11160 break;
bf4120ad 11161 case OPC_RSQRT1_PS:
e29c9628 11162 check_ps(ctx);
b6d96bed 11163 {
a7812ae4 11164 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11165
11166 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11167 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 11168 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11169 tcg_temp_free_i64(fp0);
b6d96bed 11170 }
57fa1fb3 11171 break;
bf4120ad 11172 case OPC_RSQRT2_PS:
e29c9628 11173 check_ps(ctx);
b6d96bed 11174 {
a7812ae4
PB
11175 TCGv_i64 fp0 = tcg_temp_new_i64();
11176 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11177
11178 gen_load_fpr64(ctx, fp0, fs);
11179 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11180 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11181 tcg_temp_free_i64(fp1);
b6d96bed 11182 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11183 tcg_temp_free_i64(fp0);
b6d96bed 11184 }
57fa1fb3 11185 break;
bf4120ad 11186 case OPC_CVT_S_PU:
5e755519 11187 check_cp1_64bitmode(ctx);
b6d96bed 11188 {
a7812ae4 11189 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11190
7f6613ce 11191 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 11192 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 11193 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11194 tcg_temp_free_i32(fp0);
b6d96bed 11195 }
dd016883 11196 break;
bf4120ad 11197 case OPC_CVT_PW_PS:
e29c9628 11198 check_ps(ctx);
b6d96bed 11199 {
a7812ae4 11200 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11201
11202 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11203 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 11204 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11205 tcg_temp_free_i64(fp0);
b6d96bed 11206 }
6ea83fed 11207 break;
bf4120ad 11208 case OPC_CVT_S_PL:
5e755519 11209 check_cp1_64bitmode(ctx);
b6d96bed 11210 {
a7812ae4 11211 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11212
7c979afd 11213 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11214 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 11215 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11216 tcg_temp_free_i32(fp0);
b6d96bed 11217 }
6ea83fed 11218 break;
bf4120ad 11219 case OPC_PLL_PS:
e29c9628 11220 check_ps(ctx);
b6d96bed 11221 {
a7812ae4
PB
11222 TCGv_i32 fp0 = tcg_temp_new_i32();
11223 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11224
7c979afd
LA
11225 gen_load_fpr32(ctx, fp0, fs);
11226 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 11227 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 11228 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
11229 tcg_temp_free_i32(fp0);
11230 tcg_temp_free_i32(fp1);
b6d96bed 11231 }
6ea83fed 11232 break;
bf4120ad 11233 case OPC_PLU_PS:
e29c9628 11234 check_ps(ctx);
b6d96bed 11235 {
a7812ae4
PB
11236 TCGv_i32 fp0 = tcg_temp_new_i32();
11237 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11238
7c979afd 11239 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 11240 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11241 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11242 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11243 tcg_temp_free_i32(fp0);
11244 tcg_temp_free_i32(fp1);
b6d96bed 11245 }
5a5012ec 11246 break;
bf4120ad 11247 case OPC_PUL_PS:
e29c9628 11248 check_ps(ctx);
b6d96bed 11249 {
a7812ae4
PB
11250 TCGv_i32 fp0 = tcg_temp_new_i32();
11251 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11252
7f6613ce 11253 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
11254 gen_load_fpr32(ctx, fp1, ft);
11255 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11256 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11257 tcg_temp_free_i32(fp0);
11258 tcg_temp_free_i32(fp1);
b6d96bed 11259 }
5a5012ec 11260 break;
bf4120ad 11261 case OPC_PUU_PS:
e29c9628 11262 check_ps(ctx);
b6d96bed 11263 {
a7812ae4
PB
11264 TCGv_i32 fp0 = tcg_temp_new_i32();
11265 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11266
7f6613ce
PJ
11267 gen_load_fpr32h(ctx, fp0, fs);
11268 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11269 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11270 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11271 tcg_temp_free_i32(fp0);
11272 tcg_temp_free_i32(fp1);
b6d96bed 11273 }
5a5012ec 11274 break;
bf4120ad
NF
11275 case OPC_CMP_F_PS:
11276 case OPC_CMP_UN_PS:
11277 case OPC_CMP_EQ_PS:
11278 case OPC_CMP_UEQ_PS:
11279 case OPC_CMP_OLT_PS:
11280 case OPC_CMP_ULT_PS:
11281 case OPC_CMP_OLE_PS:
11282 case OPC_CMP_ULE_PS:
11283 case OPC_CMP_SF_PS:
11284 case OPC_CMP_NGLE_PS:
11285 case OPC_CMP_SEQ_PS:
11286 case OPC_CMP_NGL_PS:
11287 case OPC_CMP_LT_PS:
11288 case OPC_CMP_NGE_PS:
11289 case OPC_CMP_LE_PS:
11290 case OPC_CMP_NGT_PS:
8153667c 11291 if (ctx->opcode & (1 << 6)) {
71375b59 11292 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
8153667c 11293 } else {
71375b59 11294 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
5a1e8ffb 11295 }
6ea83fed 11296 break;
5a5012ec 11297 default:
9d68ac14 11298 MIPS_INVAL("farith");
3a4ef3b7 11299 gen_reserved_instruction(ctx);
6ea83fed
FB
11300 return;
11301 }
6ea83fed 11302}
6af0bf9c 11303
5a5012ec 11304/* Coprocessor 3 (FPU) */
235785e8
AM
11305static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11306 int fd, int fs, int base, int index)
7a387fff 11307{
4e2474d6 11308 TCGv t0 = tcg_temp_new();
7a387fff 11309
93b12ccc 11310 if (base == 0) {
6c5c1e20 11311 gen_load_gpr(t0, index);
93b12ccc 11312 } else if (index == 0) {
6c5c1e20 11313 gen_load_gpr(t0, base);
93b12ccc 11314 } else {
05168674 11315 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 11316 }
7480515f
AM
11317 /*
11318 * Don't do NOP if destination is zero: we must perform the actual
11319 * memory access.
11320 */
5a5012ec
TS
11321 switch (opc) {
11322 case OPC_LWXC1:
8c0ab41f 11323 check_cop1x(ctx);
b6d96bed 11324 {
a7812ae4 11325 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11326
5f68f5ae 11327 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 11328 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 11329 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11330 tcg_temp_free_i32(fp0);
b6d96bed 11331 }
5a5012ec
TS
11332 break;
11333 case OPC_LDXC1:
8c0ab41f
AJ
11334 check_cop1x(ctx);
11335 check_cp1_registers(ctx, fd);
b6d96bed 11336 {
a7812ae4 11337 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 11338 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11339 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11340 tcg_temp_free_i64(fp0);
b6d96bed 11341 }
5a5012ec
TS
11342 break;
11343 case OPC_LUXC1:
8c0ab41f 11344 check_cp1_64bitmode(ctx);
6c5c1e20 11345 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11346 {
a7812ae4 11347 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11348
5f68f5ae 11349 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 11350 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11351 tcg_temp_free_i64(fp0);
b6d96bed 11352 }
5a5012ec
TS
11353 break;
11354 case OPC_SWXC1:
8c0ab41f 11355 check_cop1x(ctx);
b6d96bed 11356 {
a7812ae4 11357 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11358 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 11359 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 11360 tcg_temp_free_i32(fp0);
b6d96bed 11361 }
5a5012ec
TS
11362 break;
11363 case OPC_SDXC1:
8c0ab41f
AJ
11364 check_cop1x(ctx);
11365 check_cp1_registers(ctx, fs);
b6d96bed 11366 {
a7812ae4 11367 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11368 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11369 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11370 tcg_temp_free_i64(fp0);
b6d96bed 11371 }
5a5012ec
TS
11372 break;
11373 case OPC_SUXC1:
8c0ab41f 11374 check_cp1_64bitmode(ctx);
6c5c1e20 11375 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 11376 {
a7812ae4 11377 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11378 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 11379 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 11380 tcg_temp_free_i64(fp0);
b6d96bed 11381 }
5a5012ec 11382 break;
5a5012ec 11383 }
6c5c1e20 11384 tcg_temp_free(t0);
5a5012ec
TS
11385}
11386
235785e8
AM
11387static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11388 int fd, int fr, int fs, int ft)
5a5012ec 11389{
5a5012ec
TS
11390 switch (opc) {
11391 case OPC_ALNV_PS:
e29c9628 11392 check_ps(ctx);
a16336e4 11393 {
a7812ae4 11394 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
11395 TCGv_i32 fp = tcg_temp_new_i32();
11396 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
11397 TCGLabel *l1 = gen_new_label();
11398 TCGLabel *l2 = gen_new_label();
a16336e4 11399
6c5c1e20
TS
11400 gen_load_gpr(t0, fr);
11401 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
11402
11403 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 11404 gen_load_fpr32(ctx, fp, fs);
7f6613ce 11405 gen_load_fpr32h(ctx, fph, fs);
7c979afd 11406 gen_store_fpr32(ctx, fp, fd);
7f6613ce 11407 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
11408 tcg_gen_br(l2);
11409 gen_set_label(l1);
6c5c1e20
TS
11410 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11411 tcg_temp_free(t0);
bf78469c
PMD
11412 if (cpu_is_bigendian(ctx)) {
11413 gen_load_fpr32(ctx, fp, fs);
11414 gen_load_fpr32h(ctx, fph, ft);
11415 gen_store_fpr32h(ctx, fp, fd);
11416 gen_store_fpr32(ctx, fph, fd);
11417 } else {
11418 gen_load_fpr32h(ctx, fph, fs);
11419 gen_load_fpr32(ctx, fp, ft);
11420 gen_store_fpr32(ctx, fph, fd);
11421 gen_store_fpr32h(ctx, fp, fd);
11422 }
a16336e4 11423 gen_set_label(l2);
c905fdac
AJ
11424 tcg_temp_free_i32(fp);
11425 tcg_temp_free_i32(fph);
a16336e4 11426 }
5a5012ec
TS
11427 break;
11428 case OPC_MADD_S:
b8aa4598 11429 check_cop1x(ctx);
b6d96bed 11430 {
a7812ae4
PB
11431 TCGv_i32 fp0 = tcg_temp_new_i32();
11432 TCGv_i32 fp1 = tcg_temp_new_i32();
11433 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11434
7c979afd
LA
11435 gen_load_fpr32(ctx, fp0, fs);
11436 gen_load_fpr32(ctx, fp1, ft);
11437 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11438 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11439 tcg_temp_free_i32(fp0);
11440 tcg_temp_free_i32(fp1);
7c979afd 11441 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11442 tcg_temp_free_i32(fp2);
b6d96bed 11443 }
5a5012ec
TS
11444 break;
11445 case OPC_MADD_D:
b8aa4598
TS
11446 check_cop1x(ctx);
11447 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11448 {
a7812ae4
PB
11449 TCGv_i64 fp0 = tcg_temp_new_i64();
11450 TCGv_i64 fp1 = tcg_temp_new_i64();
11451 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11452
11453 gen_load_fpr64(ctx, fp0, fs);
11454 gen_load_fpr64(ctx, fp1, ft);
11455 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11456 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11457 tcg_temp_free_i64(fp0);
11458 tcg_temp_free_i64(fp1);
b6d96bed 11459 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11460 tcg_temp_free_i64(fp2);
b6d96bed 11461 }
5a5012ec
TS
11462 break;
11463 case OPC_MADD_PS:
e29c9628 11464 check_ps(ctx);
b6d96bed 11465 {
a7812ae4
PB
11466 TCGv_i64 fp0 = tcg_temp_new_i64();
11467 TCGv_i64 fp1 = tcg_temp_new_i64();
11468 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11469
11470 gen_load_fpr64(ctx, fp0, fs);
11471 gen_load_fpr64(ctx, fp1, ft);
11472 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11473 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11474 tcg_temp_free_i64(fp0);
11475 tcg_temp_free_i64(fp1);
b6d96bed 11476 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11477 tcg_temp_free_i64(fp2);
b6d96bed 11478 }
5a5012ec
TS
11479 break;
11480 case OPC_MSUB_S:
b8aa4598 11481 check_cop1x(ctx);
b6d96bed 11482 {
a7812ae4
PB
11483 TCGv_i32 fp0 = tcg_temp_new_i32();
11484 TCGv_i32 fp1 = tcg_temp_new_i32();
11485 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11486
7c979afd
LA
11487 gen_load_fpr32(ctx, fp0, fs);
11488 gen_load_fpr32(ctx, fp1, ft);
11489 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11490 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11491 tcg_temp_free_i32(fp0);
11492 tcg_temp_free_i32(fp1);
7c979afd 11493 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11494 tcg_temp_free_i32(fp2);
b6d96bed 11495 }
5a5012ec
TS
11496 break;
11497 case OPC_MSUB_D:
b8aa4598
TS
11498 check_cop1x(ctx);
11499 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11500 {
a7812ae4
PB
11501 TCGv_i64 fp0 = tcg_temp_new_i64();
11502 TCGv_i64 fp1 = tcg_temp_new_i64();
11503 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11504
11505 gen_load_fpr64(ctx, fp0, fs);
11506 gen_load_fpr64(ctx, fp1, ft);
11507 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11508 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11509 tcg_temp_free_i64(fp0);
11510 tcg_temp_free_i64(fp1);
b6d96bed 11511 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11512 tcg_temp_free_i64(fp2);
b6d96bed 11513 }
5a5012ec
TS
11514 break;
11515 case OPC_MSUB_PS:
e29c9628 11516 check_ps(ctx);
b6d96bed 11517 {
a7812ae4
PB
11518 TCGv_i64 fp0 = tcg_temp_new_i64();
11519 TCGv_i64 fp1 = tcg_temp_new_i64();
11520 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11521
11522 gen_load_fpr64(ctx, fp0, fs);
11523 gen_load_fpr64(ctx, fp1, ft);
11524 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11525 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11526 tcg_temp_free_i64(fp0);
11527 tcg_temp_free_i64(fp1);
b6d96bed 11528 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11529 tcg_temp_free_i64(fp2);
b6d96bed 11530 }
5a5012ec
TS
11531 break;
11532 case OPC_NMADD_S:
b8aa4598 11533 check_cop1x(ctx);
b6d96bed 11534 {
a7812ae4
PB
11535 TCGv_i32 fp0 = tcg_temp_new_i32();
11536 TCGv_i32 fp1 = tcg_temp_new_i32();
11537 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11538
7c979afd
LA
11539 gen_load_fpr32(ctx, fp0, fs);
11540 gen_load_fpr32(ctx, fp1, ft);
11541 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11542 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11543 tcg_temp_free_i32(fp0);
11544 tcg_temp_free_i32(fp1);
7c979afd 11545 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11546 tcg_temp_free_i32(fp2);
b6d96bed 11547 }
5a5012ec
TS
11548 break;
11549 case OPC_NMADD_D:
b8aa4598
TS
11550 check_cop1x(ctx);
11551 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11552 {
a7812ae4
PB
11553 TCGv_i64 fp0 = tcg_temp_new_i64();
11554 TCGv_i64 fp1 = tcg_temp_new_i64();
11555 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11556
11557 gen_load_fpr64(ctx, fp0, fs);
11558 gen_load_fpr64(ctx, fp1, ft);
11559 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11560 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11561 tcg_temp_free_i64(fp0);
11562 tcg_temp_free_i64(fp1);
b6d96bed 11563 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11564 tcg_temp_free_i64(fp2);
b6d96bed 11565 }
5a5012ec
TS
11566 break;
11567 case OPC_NMADD_PS:
e29c9628 11568 check_ps(ctx);
b6d96bed 11569 {
a7812ae4
PB
11570 TCGv_i64 fp0 = tcg_temp_new_i64();
11571 TCGv_i64 fp1 = tcg_temp_new_i64();
11572 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11573
11574 gen_load_fpr64(ctx, fp0, fs);
11575 gen_load_fpr64(ctx, fp1, ft);
11576 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11577 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11578 tcg_temp_free_i64(fp0);
11579 tcg_temp_free_i64(fp1);
b6d96bed 11580 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11581 tcg_temp_free_i64(fp2);
b6d96bed 11582 }
5a5012ec
TS
11583 break;
11584 case OPC_NMSUB_S:
b8aa4598 11585 check_cop1x(ctx);
b6d96bed 11586 {
a7812ae4
PB
11587 TCGv_i32 fp0 = tcg_temp_new_i32();
11588 TCGv_i32 fp1 = tcg_temp_new_i32();
11589 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 11590
7c979afd
LA
11591 gen_load_fpr32(ctx, fp0, fs);
11592 gen_load_fpr32(ctx, fp1, ft);
11593 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 11594 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11595 tcg_temp_free_i32(fp0);
11596 tcg_temp_free_i32(fp1);
7c979afd 11597 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 11598 tcg_temp_free_i32(fp2);
b6d96bed 11599 }
5a5012ec
TS
11600 break;
11601 case OPC_NMSUB_D:
b8aa4598
TS
11602 check_cop1x(ctx);
11603 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 11604 {
a7812ae4
PB
11605 TCGv_i64 fp0 = tcg_temp_new_i64();
11606 TCGv_i64 fp1 = tcg_temp_new_i64();
11607 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11608
11609 gen_load_fpr64(ctx, fp0, fs);
11610 gen_load_fpr64(ctx, fp1, ft);
11611 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11612 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11613 tcg_temp_free_i64(fp0);
11614 tcg_temp_free_i64(fp1);
b6d96bed 11615 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11616 tcg_temp_free_i64(fp2);
b6d96bed 11617 }
5a5012ec
TS
11618 break;
11619 case OPC_NMSUB_PS:
e29c9628 11620 check_ps(ctx);
b6d96bed 11621 {
a7812ae4
PB
11622 TCGv_i64 fp0 = tcg_temp_new_i64();
11623 TCGv_i64 fp1 = tcg_temp_new_i64();
11624 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11625
11626 gen_load_fpr64(ctx, fp0, fs);
11627 gen_load_fpr64(ctx, fp1, ft);
11628 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 11629 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
11630 tcg_temp_free_i64(fp0);
11631 tcg_temp_free_i64(fp1);
b6d96bed 11632 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 11633 tcg_temp_free_i64(fp2);
b6d96bed 11634 }
5a5012ec 11635 break;
923617a3 11636 default:
9d68ac14 11637 MIPS_INVAL("flt3_arith");
3a4ef3b7 11638 gen_reserved_instruction(ctx);
5a5012ec
TS
11639 return;
11640 }
7a387fff
TS
11641}
11642
f9fa53f1 11643void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
11644{
11645 TCGv t0;
11646
b3167288 11647#if !defined(CONFIG_USER_ONLY)
7480515f
AM
11648 /*
11649 * The Linux kernel will emulate rdhwr if it's not supported natively.
11650 * Therefore only check the ISA in system mode.
11651 */
7a47bae5 11652 check_insn(ctx, ISA_MIPS_R2);
b3167288 11653#endif
26ebe468
NF
11654 t0 = tcg_temp_new();
11655
11656 switch (rd) {
11657 case 0:
895c2d04 11658 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
11659 gen_store_gpr(t0, rt);
11660 break;
11661 case 1:
895c2d04 11662 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
11663 gen_store_gpr(t0, rt);
11664 break;
11665 case 2:
eeb3bba8 11666 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
11667 gen_io_start();
11668 }
895c2d04 11669 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468 11670 gen_store_gpr(t0, rt);
7480515f
AM
11671 /*
11672 * Break the TB to be able to take timer interrupts immediately
11673 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11674 * we break completely out of translated code.
11675 */
eeb3bba8
EC
11676 gen_save_pc(ctx->base.pc_next + 4);
11677 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
11678 break;
11679 case 3:
895c2d04 11680 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
11681 gen_store_gpr(t0, rt);
11682 break;
b00c7218 11683 case 4:
2e211e0a 11684 check_insn(ctx, ISA_MIPS_R6);
b00c7218 11685 if (sel != 0) {
7480515f
AM
11686 /*
11687 * Performance counter registers are not implemented other than
b00c7218
YK
11688 * control register 0.
11689 */
11690 generate_exception(ctx, EXCP_RI);
11691 }
11692 gen_helper_rdhwr_performance(t0, cpu_env);
11693 gen_store_gpr(t0, rt);
11694 break;
11695 case 5:
2e211e0a 11696 check_insn(ctx, ISA_MIPS_R6);
b00c7218
YK
11697 gen_helper_rdhwr_xnp(t0, cpu_env);
11698 gen_store_gpr(t0, rt);
11699 break;
26ebe468
NF
11700 case 29:
11701#if defined(CONFIG_USER_ONLY)
d279279e
PJ
11702 tcg_gen_ld_tl(t0, cpu_env,
11703 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
11704 gen_store_gpr(t0, rt);
11705 break;
11706#else
d279279e
PJ
11707 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11708 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11709 tcg_gen_ld_tl(t0, cpu_env,
11710 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11711 gen_store_gpr(t0, rt);
11712 } else {
3a4ef3b7 11713 gen_reserved_instruction(ctx);
d279279e
PJ
11714 }
11715 break;
26ebe468
NF
11716#endif
11717 default: /* Invalid */
11718 MIPS_INVAL("rdhwr");
3a4ef3b7 11719 gen_reserved_instruction(ctx);
26ebe468
NF
11720 break;
11721 }
11722 tcg_temp_free(t0);
11723}
11724
a5f53390
LA
11725static inline void clear_branch_hflags(DisasContext *ctx)
11726{
11727 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 11728 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
11729 save_cpu_state(ctx, 0);
11730 } else {
7480515f
AM
11731 /*
11732 * It is not safe to save ctx->hflags as hflags may be changed
11733 * in execution time by the instruction in delay / forbidden slot.
11734 */
a5f53390
LA
11735 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11736 }
11737}
11738
31837be3 11739static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
11740{
11741 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 11742 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 11743 /* Branches completion */
a5f53390 11744 clear_branch_hflags(ctx);
eeb3bba8 11745 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 11746 /* FIXME: Need to clear can_do_io. */
364d4831 11747 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 11748 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 11749 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 11750 break;
c9602061
NF
11751 case MIPS_HFLAG_B:
11752 /* unconditional branch */
364d4831
NF
11753 if (proc_hflags & MIPS_HFLAG_BX) {
11754 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11755 }
c9602061
NF
11756 gen_goto_tb(ctx, 0, ctx->btarget);
11757 break;
11758 case MIPS_HFLAG_BL:
11759 /* blikely taken case */
c9602061
NF
11760 gen_goto_tb(ctx, 0, ctx->btarget);
11761 break;
11762 case MIPS_HFLAG_BC:
11763 /* Conditional branch */
c9602061 11764 {
42a268c2 11765 TCGLabel *l1 = gen_new_label();
c9602061
NF
11766
11767 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 11768 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
11769 gen_set_label(l1);
11770 gen_goto_tb(ctx, 0, ctx->btarget);
11771 }
11772 break;
11773 case MIPS_HFLAG_BR:
11774 /* unconditional branch to register */
d75c135e 11775 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
11776 TCGv t0 = tcg_temp_new();
11777 TCGv_i32 t1 = tcg_temp_new_i32();
11778
11779 tcg_gen_andi_tl(t0, btarget, 0x1);
11780 tcg_gen_trunc_tl_i32(t1, t0);
11781 tcg_temp_free(t0);
11782 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11783 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11784 tcg_gen_or_i32(hflags, hflags, t1);
11785 tcg_temp_free_i32(t1);
11786
11787 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11788 } else {
11789 tcg_gen_mov_tl(cpu_PC, btarget);
11790 }
eeb3bba8 11791 if (ctx->base.singlestep_enabled) {
c9602061 11792 save_cpu_state(ctx, 0);
9c708c7f 11793 gen_helper_raise_exception_debug(cpu_env);
c9602061 11794 }
7f11636d 11795 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
11796 break;
11797 default:
05d9d035
PMD
11798 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11799 gen_reserved_instruction(ctx);
c9602061
NF
11800 }
11801 }
11802}
11803
6893f074
YK
11804/* Compact Branches */
11805static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11806 int rs, int rt, int32_t offset)
11807{
11808 int bcond_compute = 0;
11809 TCGv t0 = tcg_temp_new();
11810 TCGv t1 = tcg_temp_new();
65935f07 11811 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
11812
11813 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11814#ifdef MIPS_DEBUG_DISAS
11815 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 11816 "\n", ctx->base.pc_next);
6893f074 11817#endif
3a4ef3b7 11818 gen_reserved_instruction(ctx);
6893f074
YK
11819 goto out;
11820 }
11821
11822 /* Load needed operands and calculate btarget */
11823 switch (opc) {
11824 /* compact branch */
11825 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11826 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11827 gen_load_gpr(t0, rs);
11828 gen_load_gpr(t1, rt);
11829 bcond_compute = 1;
eeb3bba8 11830 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11831 if (rs <= rt && rs == 0) {
11832 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11833 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11834 }
11835 break;
11836 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11837 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11838 gen_load_gpr(t0, rs);
11839 gen_load_gpr(t1, rt);
11840 bcond_compute = 1;
eeb3bba8 11841 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11842 break;
11843 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11844 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11845 if (rs == 0 || rs == rt) {
11846 /* OPC_BLEZALC, OPC_BGEZALC */
11847 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11848 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11849 }
11850 gen_load_gpr(t0, rs);
11851 gen_load_gpr(t1, rt);
11852 bcond_compute = 1;
eeb3bba8 11853 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11854 break;
11855 case OPC_BC:
11856 case OPC_BALC:
eeb3bba8 11857 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11858 break;
11859 case OPC_BEQZC:
11860 case OPC_BNEZC:
11861 if (rs != 0) {
11862 /* OPC_BEQZC, OPC_BNEZC */
11863 gen_load_gpr(t0, rs);
11864 bcond_compute = 1;
eeb3bba8 11865 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11866 } else {
11867 /* OPC_JIC, OPC_JIALC */
11868 TCGv tbase = tcg_temp_new();
11869 TCGv toffset = tcg_temp_new();
11870
11871 gen_load_gpr(tbase, rt);
11872 tcg_gen_movi_tl(toffset, offset);
11873 gen_op_addr_add(ctx, btarget, tbase, toffset);
11874 tcg_temp_free(tbase);
11875 tcg_temp_free(toffset);
11876 }
11877 break;
11878 default:
11879 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 11880 gen_reserved_instruction(ctx);
6893f074
YK
11881 goto out;
11882 }
11883
11884 if (bcond_compute == 0) {
63978560 11885 /* Unconditional compact branch */
6893f074
YK
11886 switch (opc) {
11887 case OPC_JIALC:
eeb3bba8 11888 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11889 /* Fallthrough */
11890 case OPC_JIC:
11891 ctx->hflags |= MIPS_HFLAG_BR;
11892 break;
11893 case OPC_BALC:
eeb3bba8 11894 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11895 /* Fallthrough */
11896 case OPC_BC:
11897 ctx->hflags |= MIPS_HFLAG_B;
11898 break;
11899 default:
11900 MIPS_INVAL("Compact branch/jump");
3a4ef3b7 11901 gen_reserved_instruction(ctx);
6893f074
YK
11902 goto out;
11903 }
11904
11905 /* Generating branch here as compact branches don't have delay slot */
11906 gen_branch(ctx, 4);
11907 } else {
11908 /* Conditional compact branch */
11909 TCGLabel *fs = gen_new_label();
11910 save_cpu_state(ctx, 0);
11911
11912 switch (opc) {
11913 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11914 if (rs == 0 && rt != 0) {
11915 /* OPC_BLEZALC */
11916 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11917 } else if (rs != 0 && rt != 0 && rs == rt) {
11918 /* OPC_BGEZALC */
11919 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11920 } else {
11921 /* OPC_BGEUC */
11922 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11923 }
11924 break;
11925 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11926 if (rs == 0 && rt != 0) {
11927 /* OPC_BGTZALC */
11928 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11929 } else if (rs != 0 && rt != 0 && rs == rt) {
11930 /* OPC_BLTZALC */
11931 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11932 } else {
11933 /* OPC_BLTUC */
11934 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11935 }
11936 break;
11937 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11938 if (rs == 0 && rt != 0) {
11939 /* OPC_BLEZC */
11940 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11941 } else if (rs != 0 && rt != 0 && rs == rt) {
11942 /* OPC_BGEZC */
11943 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11944 } else {
11945 /* OPC_BGEC */
11946 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11947 }
11948 break;
11949 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11950 if (rs == 0 && rt != 0) {
11951 /* OPC_BGTZC */
11952 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11953 } else if (rs != 0 && rt != 0 && rs == rt) {
11954 /* OPC_BLTZC */
11955 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11956 } else {
11957 /* OPC_BLTC */
11958 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11959 }
11960 break;
11961 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11962 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11963 if (rs >= rt) {
11964 /* OPC_BOVC, OPC_BNVC */
11965 TCGv t2 = tcg_temp_new();
11966 TCGv t3 = tcg_temp_new();
11967 TCGv t4 = tcg_temp_new();
11968 TCGv input_overflow = tcg_temp_new();
11969
11970 gen_load_gpr(t0, rs);
11971 gen_load_gpr(t1, rt);
11972 tcg_gen_ext32s_tl(t2, t0);
11973 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11974 tcg_gen_ext32s_tl(t3, t1);
11975 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11976 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11977
11978 tcg_gen_add_tl(t4, t2, t3);
11979 tcg_gen_ext32s_tl(t4, t4);
11980 tcg_gen_xor_tl(t2, t2, t3);
11981 tcg_gen_xor_tl(t3, t4, t3);
11982 tcg_gen_andc_tl(t2, t3, t2);
11983 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11984 tcg_gen_or_tl(t4, t4, input_overflow);
11985 if (opc == OPC_BOVC) {
11986 /* OPC_BOVC */
11987 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11988 } else {
11989 /* OPC_BNVC */
11990 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11991 }
11992 tcg_temp_free(input_overflow);
11993 tcg_temp_free(t4);
11994 tcg_temp_free(t3);
11995 tcg_temp_free(t2);
11996 } else if (rs < rt && rs == 0) {
11997 /* OPC_BEQZALC, OPC_BNEZALC */
11998 if (opc == OPC_BEQZALC) {
11999 /* OPC_BEQZALC */
12000 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12001 } else {
12002 /* OPC_BNEZALC */
12003 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12004 }
12005 } else {
12006 /* OPC_BEQC, OPC_BNEC */
12007 if (opc == OPC_BEQC) {
12008 /* OPC_BEQC */
12009 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12010 } else {
12011 /* OPC_BNEC */
12012 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12013 }
12014 }
12015 break;
12016 case OPC_BEQZC:
12017 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12018 break;
12019 case OPC_BNEZC:
12020 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12021 break;
12022 default:
12023 MIPS_INVAL("Compact conditional branch/jump");
3a4ef3b7 12024 gen_reserved_instruction(ctx);
6893f074
YK
12025 goto out;
12026 }
12027
12028 /* Generating branch here as compact branches don't have delay slot */
12029 gen_goto_tb(ctx, 1, ctx->btarget);
12030 gen_set_label(fs);
12031
12032 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
12033 }
12034
12035out:
12036 tcg_temp_free(t0);
12037 tcg_temp_free(t1);
12038}
12039
d5076631
PMD
12040void gen_addiupc(DisasContext *ctx, int rx, int imm,
12041 int is_64_bit, int extended)
364d4831
NF
12042{
12043 TCGv t0;
12044
12045 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 12046 gen_reserved_instruction(ctx);
364d4831
NF
12047 return;
12048 }
12049
12050 t0 = tcg_temp_new();
12051
12052 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12053 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12054 if (!is_64_bit) {
12055 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12056 }
12057
12058 tcg_temp_free(t0);
12059}
12060
0d74a222
LA
12061static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12062 int16_t offset)
12063{
12064 TCGv_i32 t0 = tcg_const_i32(op);
12065 TCGv t1 = tcg_temp_new();
12066 gen_base_offset_addr(ctx, t1, base, offset);
12067 gen_helper_cache(cpu_env, t1, t0);
f4349ba9
PMD
12068 tcg_temp_free(t1);
12069 tcg_temp_free_i32(t0);
0d74a222
LA
12070}
12071
3b3c1694
LA
12072static inline bool is_uhi(int sdbbp_code)
12073{
12074#ifdef CONFIG_USER_ONLY
12075 return false;
12076#else
12077 return semihosting_enabled() && sdbbp_code == 1;
12078#endif
12079}
12080
82ba4266
AB
12081#ifdef CONFIG_USER_ONLY
12082/* The above should dead-code away any calls to this..*/
12083static inline void gen_helper_do_semihosting(void *env)
12084{
12085 g_assert_not_reached();
12086}
12087#endif
12088
d5076631 12089void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
3c824109
NF
12090{
12091 TCGv t0 = tcg_temp_new();
12092 TCGv t1 = tcg_temp_new();
12093
12094 gen_load_gpr(t0, base);
12095
12096 if (index != 0) {
12097 gen_load_gpr(t1, index);
12098 tcg_gen_shli_tl(t1, t1, 2);
12099 gen_op_addr_add(ctx, t0, t1, t0);
12100 }
12101
5f68f5ae 12102 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12103 gen_store_gpr(t1, rd);
12104
12105 tcg_temp_free(t0);
12106 tcg_temp_free(t1);
12107}
12108
d208ac0c
LA
12109static void gen_sync(int stype)
12110{
12111 TCGBar tcg_mo = TCG_BAR_SC;
12112
12113 switch (stype) {
12114 case 0x4: /* SYNC_WMB */
12115 tcg_mo |= TCG_MO_ST_ST;
12116 break;
12117 case 0x10: /* SYNC_MB */
12118 tcg_mo |= TCG_MO_ALL;
12119 break;
12120 case 0x11: /* SYNC_ACQUIRE */
12121 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12122 break;
12123 case 0x12: /* SYNC_RELEASE */
12124 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12125 break;
12126 case 0x13: /* SYNC_RMB */
12127 tcg_mo |= TCG_MO_LD_LD;
12128 break;
12129 default:
12130 tcg_mo |= TCG_MO_ALL;
12131 break;
12132 }
12133
12134 tcg_gen_mb(tcg_mo);
12135}
12136
bf52c45a 12137/* ISA extensions (ASEs) */
3c824109 12138
bf52c45a
PMD
12139/* MIPS16 extension to MIPS32 */
12140#include "mips16e_translate.c.inc"
3c824109 12141
bf52c45a 12142/* microMIPS extension to MIPS32/MIPS64 */
3c824109 12143
7480515f
AM
12144/*
12145 * Values for microMIPS fmt field. Variable-width, depending on which
12146 * formats the instruction supports.
12147 */
3c824109
NF
12148enum {
12149 FMT_SD_S = 0,
12150 FMT_SD_D = 1,
12151
12152 FMT_SDPS_S = 0,
12153 FMT_SDPS_D = 1,
12154 FMT_SDPS_PS = 2,
12155
12156 FMT_SWL_S = 0,
12157 FMT_SWL_W = 1,
12158 FMT_SWL_L = 2,
12159
12160 FMT_DWL_D = 0,
12161 FMT_DWL_W = 1,
12162 FMT_DWL_L = 2
12163};
12164
bf52c45a 12165#include "micromips_translate.c.inc"
3230bad9 12166
3f178b8d 12167#include "nanomips_translate.c.inc"
c533c0f4 12168
9b1a1d68 12169/* MIPSDSP functions. */
d75c135e 12170static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
12171 int rd, int base, int offset)
12172{
9b1a1d68
JL
12173 TCGv t0;
12174
9b1a1d68
JL
12175 check_dsp(ctx);
12176 t0 = tcg_temp_new();
12177
12178 if (base == 0) {
12179 gen_load_gpr(t0, offset);
12180 } else if (offset == 0) {
12181 gen_load_gpr(t0, base);
12182 } else {
12183 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12184 }
12185
9b1a1d68
JL
12186 switch (opc) {
12187 case OPC_LBUX:
5f68f5ae 12188 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 12189 gen_store_gpr(t0, rd);
9b1a1d68
JL
12190 break;
12191 case OPC_LHX:
5f68f5ae 12192 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 12193 gen_store_gpr(t0, rd);
9b1a1d68
JL
12194 break;
12195 case OPC_LWX:
5f68f5ae 12196 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 12197 gen_store_gpr(t0, rd);
9b1a1d68
JL
12198 break;
12199#if defined(TARGET_MIPS64)
12200 case OPC_LDX:
5f68f5ae 12201 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 12202 gen_store_gpr(t0, rd);
9b1a1d68
JL
12203 break;
12204#endif
12205 }
9b1a1d68
JL
12206 tcg_temp_free(t0);
12207}
12208
461c08df
JL
12209static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12210 int ret, int v1, int v2)
12211{
461c08df
JL
12212 TCGv v1_t;
12213 TCGv v2_t;
12214
12215 if (ret == 0) {
12216 /* Treat as NOP. */
461c08df
JL
12217 return;
12218 }
12219
12220 v1_t = tcg_temp_new();
12221 v2_t = tcg_temp_new();
12222
12223 gen_load_gpr(v1_t, v1);
12224 gen_load_gpr(v2_t, v2);
12225
12226 switch (op1) {
12227 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12228 case OPC_MULT_G_2E:
908f6be1 12229 check_dsp_r2(ctx);
461c08df
JL
12230 switch (op2) {
12231 case OPC_ADDUH_QB:
12232 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12233 break;
12234 case OPC_ADDUH_R_QB:
12235 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12236 break;
12237 case OPC_ADDQH_PH:
12238 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12239 break;
12240 case OPC_ADDQH_R_PH:
12241 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12242 break;
12243 case OPC_ADDQH_W:
12244 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12245 break;
12246 case OPC_ADDQH_R_W:
12247 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12248 break;
12249 case OPC_SUBUH_QB:
12250 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12251 break;
12252 case OPC_SUBUH_R_QB:
12253 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12254 break;
12255 case OPC_SUBQH_PH:
12256 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12257 break;
12258 case OPC_SUBQH_R_PH:
12259 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12260 break;
12261 case OPC_SUBQH_W:
12262 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12263 break;
12264 case OPC_SUBQH_R_W:
12265 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12266 break;
12267 }
12268 break;
12269 case OPC_ABSQ_S_PH_DSP:
12270 switch (op2) {
12271 case OPC_ABSQ_S_QB:
908f6be1 12272 check_dsp_r2(ctx);
461c08df
JL
12273 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12274 break;
12275 case OPC_ABSQ_S_PH:
12276 check_dsp(ctx);
12277 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12278 break;
12279 case OPC_ABSQ_S_W:
12280 check_dsp(ctx);
12281 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12282 break;
12283 case OPC_PRECEQ_W_PHL:
12284 check_dsp(ctx);
12285 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12286 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12287 break;
12288 case OPC_PRECEQ_W_PHR:
12289 check_dsp(ctx);
12290 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12291 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12292 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12293 break;
12294 case OPC_PRECEQU_PH_QBL:
12295 check_dsp(ctx);
12296 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12297 break;
12298 case OPC_PRECEQU_PH_QBR:
12299 check_dsp(ctx);
12300 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12301 break;
12302 case OPC_PRECEQU_PH_QBLA:
12303 check_dsp(ctx);
12304 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12305 break;
12306 case OPC_PRECEQU_PH_QBRA:
12307 check_dsp(ctx);
12308 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12309 break;
12310 case OPC_PRECEU_PH_QBL:
12311 check_dsp(ctx);
12312 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12313 break;
12314 case OPC_PRECEU_PH_QBR:
12315 check_dsp(ctx);
12316 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12317 break;
12318 case OPC_PRECEU_PH_QBLA:
12319 check_dsp(ctx);
12320 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12321 break;
12322 case OPC_PRECEU_PH_QBRA:
12323 check_dsp(ctx);
12324 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12325 break;
12326 }
12327 break;
12328 case OPC_ADDU_QB_DSP:
12329 switch (op2) {
12330 case OPC_ADDQ_PH:
12331 check_dsp(ctx);
12332 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12333 break;
12334 case OPC_ADDQ_S_PH:
12335 check_dsp(ctx);
12336 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12337 break;
12338 case OPC_ADDQ_S_W:
12339 check_dsp(ctx);
12340 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12341 break;
12342 case OPC_ADDU_QB:
12343 check_dsp(ctx);
12344 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12345 break;
12346 case OPC_ADDU_S_QB:
12347 check_dsp(ctx);
12348 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12349 break;
12350 case OPC_ADDU_PH:
908f6be1 12351 check_dsp_r2(ctx);
461c08df
JL
12352 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12353 break;
12354 case OPC_ADDU_S_PH:
908f6be1 12355 check_dsp_r2(ctx);
461c08df
JL
12356 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12357 break;
12358 case OPC_SUBQ_PH:
12359 check_dsp(ctx);
12360 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12361 break;
12362 case OPC_SUBQ_S_PH:
12363 check_dsp(ctx);
12364 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12365 break;
12366 case OPC_SUBQ_S_W:
12367 check_dsp(ctx);
12368 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12369 break;
12370 case OPC_SUBU_QB:
12371 check_dsp(ctx);
12372 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12373 break;
12374 case OPC_SUBU_S_QB:
12375 check_dsp(ctx);
12376 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12377 break;
12378 case OPC_SUBU_PH:
908f6be1 12379 check_dsp_r2(ctx);
461c08df
JL
12380 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12381 break;
12382 case OPC_SUBU_S_PH:
908f6be1 12383 check_dsp_r2(ctx);
461c08df
JL
12384 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12385 break;
12386 case OPC_ADDSC:
12387 check_dsp(ctx);
12388 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12389 break;
12390 case OPC_ADDWC:
12391 check_dsp(ctx);
12392 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12393 break;
12394 case OPC_MODSUB:
12395 check_dsp(ctx);
12396 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12397 break;
12398 case OPC_RADDU_W_QB:
12399 check_dsp(ctx);
12400 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12401 break;
12402 }
12403 break;
12404 case OPC_CMPU_EQ_QB_DSP:
12405 switch (op2) {
12406 case OPC_PRECR_QB_PH:
908f6be1 12407 check_dsp_r2(ctx);
461c08df
JL
12408 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12409 break;
12410 case OPC_PRECRQ_QB_PH:
12411 check_dsp(ctx);
12412 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12413 break;
12414 case OPC_PRECR_SRA_PH_W:
908f6be1 12415 check_dsp_r2(ctx);
461c08df
JL
12416 {
12417 TCGv_i32 sa_t = tcg_const_i32(v2);
12418 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12419 cpu_gpr[ret]);
12420 tcg_temp_free_i32(sa_t);
12421 break;
12422 }
12423 case OPC_PRECR_SRA_R_PH_W:
908f6be1 12424 check_dsp_r2(ctx);
461c08df
JL
12425 {
12426 TCGv_i32 sa_t = tcg_const_i32(v2);
12427 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12428 cpu_gpr[ret]);
12429 tcg_temp_free_i32(sa_t);
12430 break;
12431 }
12432 case OPC_PRECRQ_PH_W:
12433 check_dsp(ctx);
12434 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12435 break;
12436 case OPC_PRECRQ_RS_PH_W:
12437 check_dsp(ctx);
12438 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12439 break;
12440 case OPC_PRECRQU_S_QB_PH:
12441 check_dsp(ctx);
12442 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12443 break;
12444 }
12445 break;
12446#ifdef TARGET_MIPS64
12447 case OPC_ABSQ_S_QH_DSP:
12448 switch (op2) {
12449 case OPC_PRECEQ_L_PWL:
12450 check_dsp(ctx);
12451 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12452 break;
12453 case OPC_PRECEQ_L_PWR:
12454 check_dsp(ctx);
12455 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12456 break;
12457 case OPC_PRECEQ_PW_QHL:
12458 check_dsp(ctx);
12459 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12460 break;
12461 case OPC_PRECEQ_PW_QHR:
12462 check_dsp(ctx);
12463 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12464 break;
12465 case OPC_PRECEQ_PW_QHLA:
12466 check_dsp(ctx);
12467 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12468 break;
12469 case OPC_PRECEQ_PW_QHRA:
12470 check_dsp(ctx);
12471 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12472 break;
12473 case OPC_PRECEQU_QH_OBL:
12474 check_dsp(ctx);
12475 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12476 break;
12477 case OPC_PRECEQU_QH_OBR:
12478 check_dsp(ctx);
12479 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12480 break;
12481 case OPC_PRECEQU_QH_OBLA:
12482 check_dsp(ctx);
12483 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12484 break;
12485 case OPC_PRECEQU_QH_OBRA:
12486 check_dsp(ctx);
12487 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12488 break;
12489 case OPC_PRECEU_QH_OBL:
12490 check_dsp(ctx);
12491 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12492 break;
12493 case OPC_PRECEU_QH_OBR:
12494 check_dsp(ctx);
12495 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12496 break;
12497 case OPC_PRECEU_QH_OBLA:
12498 check_dsp(ctx);
12499 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12500 break;
12501 case OPC_PRECEU_QH_OBRA:
12502 check_dsp(ctx);
12503 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12504 break;
12505 case OPC_ABSQ_S_OB:
908f6be1 12506 check_dsp_r2(ctx);
461c08df
JL
12507 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12508 break;
12509 case OPC_ABSQ_S_PW:
12510 check_dsp(ctx);
12511 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12512 break;
12513 case OPC_ABSQ_S_QH:
12514 check_dsp(ctx);
12515 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12516 break;
12517 }
12518 break;
12519 case OPC_ADDU_OB_DSP:
12520 switch (op2) {
12521 case OPC_RADDU_L_OB:
12522 check_dsp(ctx);
12523 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12524 break;
12525 case OPC_SUBQ_PW:
12526 check_dsp(ctx);
12527 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12528 break;
12529 case OPC_SUBQ_S_PW:
12530 check_dsp(ctx);
12531 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12532 break;
12533 case OPC_SUBQ_QH:
12534 check_dsp(ctx);
12535 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12536 break;
12537 case OPC_SUBQ_S_QH:
12538 check_dsp(ctx);
12539 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12540 break;
12541 case OPC_SUBU_OB:
12542 check_dsp(ctx);
12543 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12544 break;
12545 case OPC_SUBU_S_OB:
12546 check_dsp(ctx);
12547 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12548 break;
12549 case OPC_SUBU_QH:
908f6be1 12550 check_dsp_r2(ctx);
461c08df
JL
12551 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12552 break;
12553 case OPC_SUBU_S_QH:
908f6be1 12554 check_dsp_r2(ctx);
461c08df
JL
12555 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12556 break;
12557 case OPC_SUBUH_OB:
908f6be1 12558 check_dsp_r2(ctx);
461c08df
JL
12559 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12560 break;
12561 case OPC_SUBUH_R_OB:
908f6be1 12562 check_dsp_r2(ctx);
461c08df
JL
12563 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12564 break;
12565 case OPC_ADDQ_PW:
12566 check_dsp(ctx);
12567 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12568 break;
12569 case OPC_ADDQ_S_PW:
12570 check_dsp(ctx);
12571 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12572 break;
12573 case OPC_ADDQ_QH:
12574 check_dsp(ctx);
12575 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12576 break;
12577 case OPC_ADDQ_S_QH:
12578 check_dsp(ctx);
12579 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12580 break;
12581 case OPC_ADDU_OB:
12582 check_dsp(ctx);
12583 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12584 break;
12585 case OPC_ADDU_S_OB:
12586 check_dsp(ctx);
12587 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12588 break;
12589 case OPC_ADDU_QH:
908f6be1 12590 check_dsp_r2(ctx);
461c08df
JL
12591 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12592 break;
12593 case OPC_ADDU_S_QH:
908f6be1 12594 check_dsp_r2(ctx);
461c08df
JL
12595 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12596 break;
12597 case OPC_ADDUH_OB:
908f6be1 12598 check_dsp_r2(ctx);
461c08df
JL
12599 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12600 break;
12601 case OPC_ADDUH_R_OB:
908f6be1 12602 check_dsp_r2(ctx);
461c08df
JL
12603 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12604 break;
12605 }
12606 break;
12607 case OPC_CMPU_EQ_OB_DSP:
12608 switch (op2) {
12609 case OPC_PRECR_OB_QH:
908f6be1 12610 check_dsp_r2(ctx);
461c08df
JL
12611 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12612 break;
12613 case OPC_PRECR_SRA_QH_PW:
908f6be1 12614 check_dsp_r2(ctx);
461c08df
JL
12615 {
12616 TCGv_i32 ret_t = tcg_const_i32(ret);
12617 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12618 tcg_temp_free_i32(ret_t);
12619 break;
12620 }
12621 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 12622 check_dsp_r2(ctx);
461c08df
JL
12623 {
12624 TCGv_i32 sa_v = tcg_const_i32(ret);
12625 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12626 tcg_temp_free_i32(sa_v);
12627 break;
12628 }
12629 case OPC_PRECRQ_OB_QH:
12630 check_dsp(ctx);
12631 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12632 break;
12633 case OPC_PRECRQ_PW_L:
12634 check_dsp(ctx);
12635 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12636 break;
12637 case OPC_PRECRQ_QH_PW:
12638 check_dsp(ctx);
12639 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12640 break;
12641 case OPC_PRECRQ_RS_QH_PW:
12642 check_dsp(ctx);
12643 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12644 break;
12645 case OPC_PRECRQU_S_OB_QH:
12646 check_dsp(ctx);
12647 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12648 break;
12649 }
12650 break;
12651#endif
12652 }
12653
12654 tcg_temp_free(v1_t);
12655 tcg_temp_free(v2_t);
461c08df 12656}
9b1a1d68 12657
77c5fa8b
JL
12658static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12659 int ret, int v1, int v2)
12660{
12661 uint32_t op2;
77c5fa8b
JL
12662 TCGv t0;
12663 TCGv v1_t;
12664 TCGv v2_t;
12665
12666 if (ret == 0) {
12667 /* Treat as NOP. */
77c5fa8b
JL
12668 return;
12669 }
12670
12671 t0 = tcg_temp_new();
12672 v1_t = tcg_temp_new();
12673 v2_t = tcg_temp_new();
12674
12675 tcg_gen_movi_tl(t0, v1);
12676 gen_load_gpr(v1_t, v1);
12677 gen_load_gpr(v2_t, v2);
12678
12679 switch (opc) {
12680 case OPC_SHLL_QB_DSP:
12681 {
12682 op2 = MASK_SHLL_QB(ctx->opcode);
12683 switch (op2) {
12684 case OPC_SHLL_QB:
12685 check_dsp(ctx);
12686 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12687 break;
12688 case OPC_SHLLV_QB:
12689 check_dsp(ctx);
12690 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12691 break;
12692 case OPC_SHLL_PH:
12693 check_dsp(ctx);
12694 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12695 break;
12696 case OPC_SHLLV_PH:
12697 check_dsp(ctx);
12698 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12699 break;
12700 case OPC_SHLL_S_PH:
12701 check_dsp(ctx);
12702 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12703 break;
12704 case OPC_SHLLV_S_PH:
12705 check_dsp(ctx);
12706 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12707 break;
12708 case OPC_SHLL_S_W:
12709 check_dsp(ctx);
12710 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12711 break;
12712 case OPC_SHLLV_S_W:
12713 check_dsp(ctx);
12714 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12715 break;
12716 case OPC_SHRL_QB:
12717 check_dsp(ctx);
12718 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12719 break;
12720 case OPC_SHRLV_QB:
12721 check_dsp(ctx);
12722 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12723 break;
12724 case OPC_SHRL_PH:
908f6be1 12725 check_dsp_r2(ctx);
77c5fa8b
JL
12726 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12727 break;
12728 case OPC_SHRLV_PH:
908f6be1 12729 check_dsp_r2(ctx);
77c5fa8b
JL
12730 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12731 break;
12732 case OPC_SHRA_QB:
908f6be1 12733 check_dsp_r2(ctx);
77c5fa8b
JL
12734 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12735 break;
12736 case OPC_SHRA_R_QB:
908f6be1 12737 check_dsp_r2(ctx);
77c5fa8b
JL
12738 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12739 break;
12740 case OPC_SHRAV_QB:
908f6be1 12741 check_dsp_r2(ctx);
77c5fa8b
JL
12742 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12743 break;
12744 case OPC_SHRAV_R_QB:
908f6be1 12745 check_dsp_r2(ctx);
77c5fa8b
JL
12746 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_SHRA_PH:
12749 check_dsp(ctx);
12750 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12751 break;
12752 case OPC_SHRA_R_PH:
12753 check_dsp(ctx);
12754 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12755 break;
12756 case OPC_SHRAV_PH:
12757 check_dsp(ctx);
12758 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SHRAV_R_PH:
12761 check_dsp(ctx);
12762 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12763 break;
12764 case OPC_SHRA_R_W:
12765 check_dsp(ctx);
12766 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12767 break;
12768 case OPC_SHRAV_R_W:
12769 check_dsp(ctx);
12770 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12771 break;
12772 default: /* Invalid */
12773 MIPS_INVAL("MASK SHLL.QB");
3a4ef3b7 12774 gen_reserved_instruction(ctx);
77c5fa8b
JL
12775 break;
12776 }
12777 break;
12778 }
12779#ifdef TARGET_MIPS64
12780 case OPC_SHLL_OB_DSP:
12781 op2 = MASK_SHLL_OB(ctx->opcode);
12782 switch (op2) {
12783 case OPC_SHLL_PW:
12784 check_dsp(ctx);
12785 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12786 break;
12787 case OPC_SHLLV_PW:
12788 check_dsp(ctx);
12789 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12790 break;
12791 case OPC_SHLL_S_PW:
12792 check_dsp(ctx);
12793 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12794 break;
12795 case OPC_SHLLV_S_PW:
12796 check_dsp(ctx);
12797 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12798 break;
12799 case OPC_SHLL_OB:
12800 check_dsp(ctx);
12801 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12802 break;
12803 case OPC_SHLLV_OB:
12804 check_dsp(ctx);
12805 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12806 break;
12807 case OPC_SHLL_QH:
12808 check_dsp(ctx);
12809 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12810 break;
12811 case OPC_SHLLV_QH:
12812 check_dsp(ctx);
12813 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12814 break;
12815 case OPC_SHLL_S_QH:
12816 check_dsp(ctx);
12817 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12818 break;
12819 case OPC_SHLLV_S_QH:
12820 check_dsp(ctx);
12821 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12822 break;
12823 case OPC_SHRA_OB:
908f6be1 12824 check_dsp_r2(ctx);
77c5fa8b
JL
12825 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12826 break;
12827 case OPC_SHRAV_OB:
908f6be1 12828 check_dsp_r2(ctx);
77c5fa8b
JL
12829 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12830 break;
12831 case OPC_SHRA_R_OB:
908f6be1 12832 check_dsp_r2(ctx);
77c5fa8b
JL
12833 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12834 break;
12835 case OPC_SHRAV_R_OB:
908f6be1 12836 check_dsp_r2(ctx);
77c5fa8b
JL
12837 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12838 break;
12839 case OPC_SHRA_PW:
12840 check_dsp(ctx);
12841 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12842 break;
12843 case OPC_SHRAV_PW:
12844 check_dsp(ctx);
12845 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12846 break;
12847 case OPC_SHRA_R_PW:
12848 check_dsp(ctx);
12849 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12850 break;
12851 case OPC_SHRAV_R_PW:
12852 check_dsp(ctx);
12853 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12854 break;
12855 case OPC_SHRA_QH:
12856 check_dsp(ctx);
12857 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12858 break;
12859 case OPC_SHRAV_QH:
12860 check_dsp(ctx);
12861 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12862 break;
12863 case OPC_SHRA_R_QH:
12864 check_dsp(ctx);
12865 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12866 break;
12867 case OPC_SHRAV_R_QH:
12868 check_dsp(ctx);
12869 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12870 break;
12871 case OPC_SHRL_OB:
12872 check_dsp(ctx);
12873 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12874 break;
12875 case OPC_SHRLV_OB:
12876 check_dsp(ctx);
12877 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12878 break;
12879 case OPC_SHRL_QH:
908f6be1 12880 check_dsp_r2(ctx);
77c5fa8b
JL
12881 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12882 break;
12883 case OPC_SHRLV_QH:
908f6be1 12884 check_dsp_r2(ctx);
77c5fa8b
JL
12885 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12886 break;
12887 default: /* Invalid */
12888 MIPS_INVAL("MASK SHLL.OB");
3a4ef3b7 12889 gen_reserved_instruction(ctx);
77c5fa8b
JL
12890 break;
12891 }
12892 break;
12893#endif
12894 }
12895
12896 tcg_temp_free(t0);
12897 tcg_temp_free(v1_t);
12898 tcg_temp_free(v2_t);
77c5fa8b
JL
12899}
12900
a22260ae
JL
12901static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12902 int ret, int v1, int v2, int check_ret)
12903{
a22260ae
JL
12904 TCGv_i32 t0;
12905 TCGv v1_t;
12906 TCGv v2_t;
12907
12908 if ((ret == 0) && (check_ret == 1)) {
12909 /* Treat as NOP. */
a22260ae
JL
12910 return;
12911 }
12912
12913 t0 = tcg_temp_new_i32();
12914 v1_t = tcg_temp_new();
12915 v2_t = tcg_temp_new();
12916
12917 tcg_gen_movi_i32(t0, ret);
12918 gen_load_gpr(v1_t, v1);
12919 gen_load_gpr(v2_t, v2);
12920
12921 switch (op1) {
7480515f
AM
12922 /*
12923 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12924 * the same mask and op1.
12925 */
a22260ae 12926 case OPC_MULT_G_2E:
908f6be1 12927 check_dsp_r2(ctx);
a22260ae
JL
12928 switch (op2) {
12929 case OPC_MUL_PH:
12930 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12931 break;
12932 case OPC_MUL_S_PH:
12933 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12934 break;
12935 case OPC_MULQ_S_W:
12936 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12937 break;
12938 case OPC_MULQ_RS_W:
12939 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12940 break;
12941 }
12942 break;
12943 case OPC_DPA_W_PH_DSP:
12944 switch (op2) {
12945 case OPC_DPAU_H_QBL:
12946 check_dsp(ctx);
12947 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12948 break;
12949 case OPC_DPAU_H_QBR:
12950 check_dsp(ctx);
12951 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12952 break;
12953 case OPC_DPSU_H_QBL:
12954 check_dsp(ctx);
12955 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12956 break;
12957 case OPC_DPSU_H_QBR:
12958 check_dsp(ctx);
12959 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12960 break;
12961 case OPC_DPA_W_PH:
908f6be1 12962 check_dsp_r2(ctx);
a22260ae
JL
12963 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12964 break;
12965 case OPC_DPAX_W_PH:
908f6be1 12966 check_dsp_r2(ctx);
a22260ae
JL
12967 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12968 break;
12969 case OPC_DPAQ_S_W_PH:
12970 check_dsp(ctx);
12971 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12972 break;
12973 case OPC_DPAQX_S_W_PH:
908f6be1 12974 check_dsp_r2(ctx);
a22260ae
JL
12975 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12976 break;
12977 case OPC_DPAQX_SA_W_PH:
908f6be1 12978 check_dsp_r2(ctx);
a22260ae
JL
12979 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12980 break;
12981 case OPC_DPS_W_PH:
908f6be1 12982 check_dsp_r2(ctx);
a22260ae
JL
12983 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
12984 break;
12985 case OPC_DPSX_W_PH:
908f6be1 12986 check_dsp_r2(ctx);
a22260ae
JL
12987 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
12988 break;
12989 case OPC_DPSQ_S_W_PH:
12990 check_dsp(ctx);
12991 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12992 break;
12993 case OPC_DPSQX_S_W_PH:
908f6be1 12994 check_dsp_r2(ctx);
a22260ae
JL
12995 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12996 break;
12997 case OPC_DPSQX_SA_W_PH:
908f6be1 12998 check_dsp_r2(ctx);
a22260ae
JL
12999 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13000 break;
13001 case OPC_MULSAQ_S_W_PH:
13002 check_dsp(ctx);
13003 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13004 break;
13005 case OPC_DPAQ_SA_L_W:
13006 check_dsp(ctx);
13007 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13008 break;
13009 case OPC_DPSQ_SA_L_W:
13010 check_dsp(ctx);
13011 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13012 break;
13013 case OPC_MAQ_S_W_PHL:
13014 check_dsp(ctx);
13015 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13016 break;
13017 case OPC_MAQ_S_W_PHR:
13018 check_dsp(ctx);
13019 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13020 break;
13021 case OPC_MAQ_SA_W_PHL:
13022 check_dsp(ctx);
13023 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13024 break;
13025 case OPC_MAQ_SA_W_PHR:
13026 check_dsp(ctx);
13027 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13028 break;
13029 case OPC_MULSA_W_PH:
908f6be1 13030 check_dsp_r2(ctx);
a22260ae
JL
13031 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13032 break;
13033 }
13034 break;
13035#ifdef TARGET_MIPS64
13036 case OPC_DPAQ_W_QH_DSP:
13037 {
13038 int ac = ret & 0x03;
13039 tcg_gen_movi_i32(t0, ac);
13040
13041 switch (op2) {
13042 case OPC_DMADD:
13043 check_dsp(ctx);
13044 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13045 break;
13046 case OPC_DMADDU:
13047 check_dsp(ctx);
13048 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13049 break;
13050 case OPC_DMSUB:
13051 check_dsp(ctx);
13052 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13053 break;
13054 case OPC_DMSUBU:
13055 check_dsp(ctx);
13056 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13057 break;
13058 case OPC_DPA_W_QH:
908f6be1 13059 check_dsp_r2(ctx);
a22260ae
JL
13060 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13061 break;
13062 case OPC_DPAQ_S_W_QH:
13063 check_dsp(ctx);
13064 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13065 break;
13066 case OPC_DPAQ_SA_L_PW:
13067 check_dsp(ctx);
13068 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13069 break;
13070 case OPC_DPAU_H_OBL:
13071 check_dsp(ctx);
13072 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13073 break;
13074 case OPC_DPAU_H_OBR:
13075 check_dsp(ctx);
13076 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13077 break;
13078 case OPC_DPS_W_QH:
908f6be1 13079 check_dsp_r2(ctx);
a22260ae
JL
13080 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13081 break;
13082 case OPC_DPSQ_S_W_QH:
13083 check_dsp(ctx);
13084 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13085 break;
13086 case OPC_DPSQ_SA_L_PW:
13087 check_dsp(ctx);
13088 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13089 break;
13090 case OPC_DPSU_H_OBL:
13091 check_dsp(ctx);
13092 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13093 break;
13094 case OPC_DPSU_H_OBR:
13095 check_dsp(ctx);
13096 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13097 break;
13098 case OPC_MAQ_S_L_PWL:
13099 check_dsp(ctx);
13100 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13101 break;
13102 case OPC_MAQ_S_L_PWR:
13103 check_dsp(ctx);
13104 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13105 break;
13106 case OPC_MAQ_S_W_QHLL:
13107 check_dsp(ctx);
13108 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13109 break;
13110 case OPC_MAQ_SA_W_QHLL:
13111 check_dsp(ctx);
13112 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13113 break;
13114 case OPC_MAQ_S_W_QHLR:
13115 check_dsp(ctx);
13116 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13117 break;
13118 case OPC_MAQ_SA_W_QHLR:
13119 check_dsp(ctx);
13120 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13121 break;
13122 case OPC_MAQ_S_W_QHRL:
13123 check_dsp(ctx);
13124 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13125 break;
13126 case OPC_MAQ_SA_W_QHRL:
13127 check_dsp(ctx);
13128 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13129 break;
13130 case OPC_MAQ_S_W_QHRR:
13131 check_dsp(ctx);
13132 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13133 break;
13134 case OPC_MAQ_SA_W_QHRR:
13135 check_dsp(ctx);
13136 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13137 break;
13138 case OPC_MULSAQ_S_L_PW:
13139 check_dsp(ctx);
13140 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13141 break;
13142 case OPC_MULSAQ_S_W_QH:
13143 check_dsp(ctx);
13144 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13145 break;
13146 }
13147 }
13148 break;
13149#endif
13150 case OPC_ADDU_QB_DSP:
13151 switch (op2) {
13152 case OPC_MULEU_S_PH_QBL:
13153 check_dsp(ctx);
13154 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13155 break;
13156 case OPC_MULEU_S_PH_QBR:
13157 check_dsp(ctx);
13158 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13159 break;
13160 case OPC_MULQ_RS_PH:
13161 check_dsp(ctx);
13162 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13163 break;
13164 case OPC_MULEQ_S_W_PHL:
13165 check_dsp(ctx);
13166 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13167 break;
13168 case OPC_MULEQ_S_W_PHR:
13169 check_dsp(ctx);
13170 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13171 break;
13172 case OPC_MULQ_S_PH:
908f6be1 13173 check_dsp_r2(ctx);
a22260ae
JL
13174 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13175 break;
13176 }
13177 break;
13178#ifdef TARGET_MIPS64
13179 case OPC_ADDU_OB_DSP:
13180 switch (op2) {
13181 case OPC_MULEQ_S_PW_QHL:
13182 check_dsp(ctx);
13183 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13184 break;
13185 case OPC_MULEQ_S_PW_QHR:
13186 check_dsp(ctx);
13187 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13188 break;
13189 case OPC_MULEU_S_QH_OBL:
13190 check_dsp(ctx);
13191 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13192 break;
13193 case OPC_MULEU_S_QH_OBR:
13194 check_dsp(ctx);
13195 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13196 break;
13197 case OPC_MULQ_RS_QH:
13198 check_dsp(ctx);
13199 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200 break;
13201 }
13202 break;
13203#endif
13204 }
13205
13206 tcg_temp_free_i32(t0);
13207 tcg_temp_free(v1_t);
13208 tcg_temp_free(v2_t);
a22260ae
JL
13209}
13210
d75c135e 13211static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
13212 int ret, int val)
13213{
1cb6686c
JL
13214 int16_t imm;
13215 TCGv t0;
13216 TCGv val_t;
13217
13218 if (ret == 0) {
13219 /* Treat as NOP. */
1cb6686c
JL
13220 return;
13221 }
13222
13223 t0 = tcg_temp_new();
13224 val_t = tcg_temp_new();
13225 gen_load_gpr(val_t, val);
13226
13227 switch (op1) {
13228 case OPC_ABSQ_S_PH_DSP:
13229 switch (op2) {
13230 case OPC_BITREV:
13231 check_dsp(ctx);
13232 gen_helper_bitrev(cpu_gpr[ret], val_t);
13233 break;
13234 case OPC_REPL_QB:
13235 check_dsp(ctx);
13236 {
13237 target_long result;
13238 imm = (ctx->opcode >> 16) & 0xFF;
13239 result = (uint32_t)imm << 24 |
13240 (uint32_t)imm << 16 |
13241 (uint32_t)imm << 8 |
13242 (uint32_t)imm;
13243 result = (int32_t)result;
13244 tcg_gen_movi_tl(cpu_gpr[ret], result);
13245 }
13246 break;
13247 case OPC_REPLV_QB:
13248 check_dsp(ctx);
13249 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13250 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13251 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13252 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13253 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13254 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13255 break;
13256 case OPC_REPL_PH:
13257 check_dsp(ctx);
13258 {
13259 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 13260 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
13261 tcg_gen_movi_tl(cpu_gpr[ret], \
13262 (target_long)((int32_t)imm << 16 | \
c4aaba92 13263 (uint16_t)imm));
1cb6686c
JL
13264 }
13265 break;
13266 case OPC_REPLV_PH:
13267 check_dsp(ctx);
13268 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13269 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13270 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13271 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13272 break;
13273 }
13274 break;
13275#ifdef TARGET_MIPS64
13276 case OPC_ABSQ_S_QH_DSP:
13277 switch (op2) {
13278 case OPC_REPL_OB:
13279 check_dsp(ctx);
13280 {
13281 target_long temp;
13282
13283 imm = (ctx->opcode >> 16) & 0xFF;
13284 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13285 temp = (temp << 16) | temp;
13286 temp = (temp << 32) | temp;
13287 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13288 break;
13289 }
13290 case OPC_REPL_PW:
13291 check_dsp(ctx);
13292 {
13293 target_long temp;
13294
13295 imm = (ctx->opcode >> 16) & 0x03FF;
13296 imm = (int16_t)(imm << 6) >> 6;
13297 temp = ((target_long)imm << 32) \
13298 | ((target_long)imm & 0xFFFFFFFF);
13299 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13300 break;
13301 }
13302 case OPC_REPL_QH:
13303 check_dsp(ctx);
13304 {
13305 target_long temp;
13306
13307 imm = (ctx->opcode >> 16) & 0x03FF;
13308 imm = (int16_t)(imm << 6) >> 6;
13309
13310 temp = ((uint64_t)(uint16_t)imm << 48) |
13311 ((uint64_t)(uint16_t)imm << 32) |
13312 ((uint64_t)(uint16_t)imm << 16) |
13313 (uint64_t)(uint16_t)imm;
13314 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13315 break;
13316 }
13317 case OPC_REPLV_OB:
13318 check_dsp(ctx);
13319 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13320 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13321 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13322 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13323 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13324 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13325 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13326 break;
13327 case OPC_REPLV_PW:
13328 check_dsp(ctx);
13329 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13330 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13331 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13332 break;
13333 case OPC_REPLV_QH:
13334 check_dsp(ctx);
13335 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13336 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13337 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13338 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13339 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13340 break;
13341 }
13342 break;
13343#endif
13344 }
13345 tcg_temp_free(t0);
13346 tcg_temp_free(val_t);
1cb6686c
JL
13347}
13348
26690560
JL
13349static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13350 uint32_t op1, uint32_t op2,
13351 int ret, int v1, int v2, int check_ret)
13352{
26690560
JL
13353 TCGv t1;
13354 TCGv v1_t;
13355 TCGv v2_t;
13356
13357 if ((ret == 0) && (check_ret == 1)) {
13358 /* Treat as NOP. */
26690560
JL
13359 return;
13360 }
13361
26690560
JL
13362 t1 = tcg_temp_new();
13363 v1_t = tcg_temp_new();
13364 v2_t = tcg_temp_new();
13365
13366 gen_load_gpr(v1_t, v1);
13367 gen_load_gpr(v2_t, v2);
13368
13369 switch (op1) {
26690560
JL
13370 case OPC_CMPU_EQ_QB_DSP:
13371 switch (op2) {
13372 case OPC_CMPU_EQ_QB:
13373 check_dsp(ctx);
13374 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13375 break;
13376 case OPC_CMPU_LT_QB:
13377 check_dsp(ctx);
13378 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13379 break;
13380 case OPC_CMPU_LE_QB:
13381 check_dsp(ctx);
13382 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13383 break;
13384 case OPC_CMPGU_EQ_QB:
13385 check_dsp(ctx);
13386 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13387 break;
13388 case OPC_CMPGU_LT_QB:
13389 check_dsp(ctx);
13390 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13391 break;
13392 case OPC_CMPGU_LE_QB:
13393 check_dsp(ctx);
13394 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13395 break;
13396 case OPC_CMPGDU_EQ_QB:
908f6be1 13397 check_dsp_r2(ctx);
26690560
JL
13398 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13399 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13400 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13401 tcg_gen_shli_tl(t1, t1, 24);
13402 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13403 break;
13404 case OPC_CMPGDU_LT_QB:
908f6be1 13405 check_dsp_r2(ctx);
26690560
JL
13406 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13407 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13408 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13409 tcg_gen_shli_tl(t1, t1, 24);
13410 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13411 break;
13412 case OPC_CMPGDU_LE_QB:
908f6be1 13413 check_dsp_r2(ctx);
26690560
JL
13414 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13415 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13416 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13417 tcg_gen_shli_tl(t1, t1, 24);
13418 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13419 break;
13420 case OPC_CMP_EQ_PH:
13421 check_dsp(ctx);
13422 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13423 break;
13424 case OPC_CMP_LT_PH:
13425 check_dsp(ctx);
13426 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13427 break;
13428 case OPC_CMP_LE_PH:
13429 check_dsp(ctx);
13430 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13431 break;
13432 case OPC_PICK_QB:
13433 check_dsp(ctx);
13434 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13435 break;
13436 case OPC_PICK_PH:
13437 check_dsp(ctx);
13438 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13439 break;
13440 case OPC_PACKRL_PH:
13441 check_dsp(ctx);
13442 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13443 break;
13444 }
13445 break;
13446#ifdef TARGET_MIPS64
13447 case OPC_CMPU_EQ_OB_DSP:
13448 switch (op2) {
13449 case OPC_CMP_EQ_PW:
13450 check_dsp(ctx);
13451 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_CMP_LT_PW:
13454 check_dsp(ctx);
13455 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_CMP_LE_PW:
13458 check_dsp(ctx);
13459 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_CMP_EQ_QH:
13462 check_dsp(ctx);
13463 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_CMP_LT_QH:
13466 check_dsp(ctx);
13467 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_CMP_LE_QH:
13470 check_dsp(ctx);
13471 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_CMPGDU_EQ_OB:
908f6be1 13474 check_dsp_r2(ctx);
26690560
JL
13475 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_CMPGDU_LT_OB:
908f6be1 13478 check_dsp_r2(ctx);
26690560
JL
13479 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_CMPGDU_LE_OB:
908f6be1 13482 check_dsp_r2(ctx);
26690560
JL
13483 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_CMPGU_EQ_OB:
13486 check_dsp(ctx);
13487 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13488 break;
13489 case OPC_CMPGU_LT_OB:
13490 check_dsp(ctx);
13491 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13492 break;
13493 case OPC_CMPGU_LE_OB:
13494 check_dsp(ctx);
13495 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13496 break;
13497 case OPC_CMPU_EQ_OB:
13498 check_dsp(ctx);
13499 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_CMPU_LT_OB:
13502 check_dsp(ctx);
13503 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_CMPU_LE_OB:
13506 check_dsp(ctx);
13507 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_PACKRL_PW:
13510 check_dsp(ctx);
13511 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13512 break;
13513 case OPC_PICK_OB:
13514 check_dsp(ctx);
13515 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_PICK_PW:
13518 check_dsp(ctx);
13519 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_PICK_QH:
13522 check_dsp(ctx);
13523 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13524 break;
13525 }
13526 break;
df6126a7
AJ
13527#endif
13528 }
13529
13530 tcg_temp_free(t1);
13531 tcg_temp_free(v1_t);
13532 tcg_temp_free(v2_t);
df6126a7
AJ
13533}
13534
13535static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13536 uint32_t op1, int rt, int rs, int sa)
13537{
df6126a7
AJ
13538 TCGv t0;
13539
908f6be1 13540 check_dsp_r2(ctx);
df6126a7
AJ
13541
13542 if (rt == 0) {
13543 /* Treat as NOP. */
df6126a7
AJ
13544 return;
13545 }
13546
13547 t0 = tcg_temp_new();
13548 gen_load_gpr(t0, rs);
13549
13550 switch (op1) {
13551 case OPC_APPEND_DSP:
13552 switch (MASK_APPEND(ctx->opcode)) {
13553 case OPC_APPEND:
13554 if (sa != 0) {
13555 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13556 }
13557 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13558 break;
13559 case OPC_PREPEND:
13560 if (sa != 0) {
13561 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13562 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13563 tcg_gen_shli_tl(t0, t0, 32 - sa);
13564 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13565 }
13566 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13567 break;
13568 case OPC_BALIGN:
13569 sa &= 3;
13570 if (sa != 0 && sa != 2) {
13571 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13572 tcg_gen_ext32u_tl(t0, t0);
13573 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13574 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13575 }
13576 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13577 break;
13578 default: /* Invalid */
13579 MIPS_INVAL("MASK APPEND");
3a4ef3b7 13580 gen_reserved_instruction(ctx);
df6126a7
AJ
13581 break;
13582 }
13583 break;
13584#ifdef TARGET_MIPS64
26690560 13585 case OPC_DAPPEND_DSP:
df6126a7 13586 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 13587 case OPC_DAPPEND:
df6126a7
AJ
13588 if (sa != 0) {
13589 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13590 }
26690560
JL
13591 break;
13592 case OPC_PREPENDD:
df6126a7
AJ
13593 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13594 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13595 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
13596 break;
13597 case OPC_PREPENDW:
df6126a7
AJ
13598 if (sa != 0) {
13599 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13600 tcg_gen_shli_tl(t0, t0, 64 - sa);
13601 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13602 }
26690560
JL
13603 break;
13604 case OPC_DBALIGN:
df6126a7
AJ
13605 sa &= 7;
13606 if (sa != 0 && sa != 2 && sa != 4) {
13607 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13608 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13609 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13610 }
26690560
JL
13611 break;
13612 default: /* Invalid */
13613 MIPS_INVAL("MASK DAPPEND");
3a4ef3b7 13614 gen_reserved_instruction(ctx);
26690560
JL
13615 break;
13616 }
13617 break;
13618#endif
13619 }
df6126a7 13620 tcg_temp_free(t0);
26690560
JL
13621}
13622
b53371ed
JL
13623static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13624 int ret, int v1, int v2, int check_ret)
13625
13626{
b53371ed
JL
13627 TCGv t0;
13628 TCGv t1;
13629 TCGv v1_t;
13630 TCGv v2_t;
13631 int16_t imm;
13632
13633 if ((ret == 0) && (check_ret == 1)) {
13634 /* Treat as NOP. */
b53371ed
JL
13635 return;
13636 }
13637
13638 t0 = tcg_temp_new();
13639 t1 = tcg_temp_new();
13640 v1_t = tcg_temp_new();
13641 v2_t = tcg_temp_new();
13642
13643 gen_load_gpr(v1_t, v1);
13644 gen_load_gpr(v2_t, v2);
13645
13646 switch (op1) {
13647 case OPC_EXTR_W_DSP:
13648 check_dsp(ctx);
13649 switch (op2) {
13650 case OPC_EXTR_W:
13651 tcg_gen_movi_tl(t0, v2);
13652 tcg_gen_movi_tl(t1, v1);
13653 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13654 break;
13655 case OPC_EXTR_R_W:
13656 tcg_gen_movi_tl(t0, v2);
13657 tcg_gen_movi_tl(t1, v1);
13658 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13659 break;
13660 case OPC_EXTR_RS_W:
13661 tcg_gen_movi_tl(t0, v2);
13662 tcg_gen_movi_tl(t1, v1);
13663 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13664 break;
13665 case OPC_EXTR_S_H:
13666 tcg_gen_movi_tl(t0, v2);
13667 tcg_gen_movi_tl(t1, v1);
13668 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13669 break;
13670 case OPC_EXTRV_S_H:
13671 tcg_gen_movi_tl(t0, v2);
13672 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13673 break;
13674 case OPC_EXTRV_W:
13675 tcg_gen_movi_tl(t0, v2);
13676 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13677 break;
13678 case OPC_EXTRV_R_W:
13679 tcg_gen_movi_tl(t0, v2);
13680 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13681 break;
13682 case OPC_EXTRV_RS_W:
13683 tcg_gen_movi_tl(t0, v2);
13684 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13685 break;
13686 case OPC_EXTP:
13687 tcg_gen_movi_tl(t0, v2);
13688 tcg_gen_movi_tl(t1, v1);
13689 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13690 break;
13691 case OPC_EXTPV:
13692 tcg_gen_movi_tl(t0, v2);
13693 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13694 break;
13695 case OPC_EXTPDP:
13696 tcg_gen_movi_tl(t0, v2);
13697 tcg_gen_movi_tl(t1, v1);
13698 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13699 break;
13700 case OPC_EXTPDPV:
13701 tcg_gen_movi_tl(t0, v2);
13702 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13703 break;
13704 case OPC_SHILO:
13705 imm = (ctx->opcode >> 20) & 0x3F;
13706 tcg_gen_movi_tl(t0, ret);
13707 tcg_gen_movi_tl(t1, imm);
13708 gen_helper_shilo(t0, t1, cpu_env);
13709 break;
13710 case OPC_SHILOV:
13711 tcg_gen_movi_tl(t0, ret);
13712 gen_helper_shilo(t0, v1_t, cpu_env);
13713 break;
13714 case OPC_MTHLIP:
13715 tcg_gen_movi_tl(t0, ret);
13716 gen_helper_mthlip(t0, v1_t, cpu_env);
13717 break;
13718 case OPC_WRDSP:
13719 imm = (ctx->opcode >> 11) & 0x3FF;
13720 tcg_gen_movi_tl(t0, imm);
13721 gen_helper_wrdsp(v1_t, t0, cpu_env);
13722 break;
13723 case OPC_RDDSP:
13724 imm = (ctx->opcode >> 16) & 0x03FF;
13725 tcg_gen_movi_tl(t0, imm);
13726 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13727 break;
13728 }
13729 break;
13730#ifdef TARGET_MIPS64
13731 case OPC_DEXTR_W_DSP:
13732 check_dsp(ctx);
13733 switch (op2) {
13734 case OPC_DMTHLIP:
13735 tcg_gen_movi_tl(t0, ret);
13736 gen_helper_dmthlip(v1_t, t0, cpu_env);
13737 break;
13738 case OPC_DSHILO:
13739 {
13740 int shift = (ctx->opcode >> 19) & 0x7F;
13741 int ac = (ctx->opcode >> 11) & 0x03;
13742 tcg_gen_movi_tl(t0, shift);
13743 tcg_gen_movi_tl(t1, ac);
13744 gen_helper_dshilo(t0, t1, cpu_env);
13745 break;
13746 }
13747 case OPC_DSHILOV:
13748 {
13749 int ac = (ctx->opcode >> 11) & 0x03;
13750 tcg_gen_movi_tl(t0, ac);
13751 gen_helper_dshilo(v1_t, t0, cpu_env);
13752 break;
13753 }
13754 case OPC_DEXTP:
13755 tcg_gen_movi_tl(t0, v2);
13756 tcg_gen_movi_tl(t1, v1);
13757
13758 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13759 break;
13760 case OPC_DEXTPV:
13761 tcg_gen_movi_tl(t0, v2);
13762 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13763 break;
13764 case OPC_DEXTPDP:
13765 tcg_gen_movi_tl(t0, v2);
13766 tcg_gen_movi_tl(t1, v1);
13767 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13768 break;
13769 case OPC_DEXTPDPV:
13770 tcg_gen_movi_tl(t0, v2);
13771 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13772 break;
13773 case OPC_DEXTR_L:
13774 tcg_gen_movi_tl(t0, v2);
13775 tcg_gen_movi_tl(t1, v1);
13776 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13777 break;
13778 case OPC_DEXTR_R_L:
13779 tcg_gen_movi_tl(t0, v2);
13780 tcg_gen_movi_tl(t1, v1);
13781 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13782 break;
13783 case OPC_DEXTR_RS_L:
13784 tcg_gen_movi_tl(t0, v2);
13785 tcg_gen_movi_tl(t1, v1);
13786 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13787 break;
13788 case OPC_DEXTR_W:
13789 tcg_gen_movi_tl(t0, v2);
13790 tcg_gen_movi_tl(t1, v1);
13791 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13792 break;
13793 case OPC_DEXTR_R_W:
13794 tcg_gen_movi_tl(t0, v2);
13795 tcg_gen_movi_tl(t1, v1);
13796 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13797 break;
13798 case OPC_DEXTR_RS_W:
13799 tcg_gen_movi_tl(t0, v2);
13800 tcg_gen_movi_tl(t1, v1);
13801 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13802 break;
13803 case OPC_DEXTR_S_H:
13804 tcg_gen_movi_tl(t0, v2);
13805 tcg_gen_movi_tl(t1, v1);
13806 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13807 break;
13808 case OPC_DEXTRV_S_H:
13809 tcg_gen_movi_tl(t0, v2);
13810 tcg_gen_movi_tl(t1, v1);
13811 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13812 break;
13813 case OPC_DEXTRV_L:
13814 tcg_gen_movi_tl(t0, v2);
13815 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13816 break;
13817 case OPC_DEXTRV_R_L:
13818 tcg_gen_movi_tl(t0, v2);
13819 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13820 break;
13821 case OPC_DEXTRV_RS_L:
13822 tcg_gen_movi_tl(t0, v2);
13823 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13824 break;
13825 case OPC_DEXTRV_W:
13826 tcg_gen_movi_tl(t0, v2);
13827 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13828 break;
13829 case OPC_DEXTRV_R_W:
13830 tcg_gen_movi_tl(t0, v2);
13831 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13832 break;
13833 case OPC_DEXTRV_RS_W:
13834 tcg_gen_movi_tl(t0, v2);
13835 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13836 break;
13837 }
13838 break;
13839#endif
13840 }
13841
13842 tcg_temp_free(t0);
13843 tcg_temp_free(t1);
13844 tcg_temp_free(v1_t);
13845 tcg_temp_free(v2_t);
b53371ed
JL
13846}
13847
9b1a1d68
JL
13848/* End MIPSDSP functions. */
13849
10dc65db
LA
13850static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13851{
4267d3e6 13852 int rs, rt, rd, sa;
b42ee5e1 13853 uint32_t op1, op2;
10dc65db
LA
13854
13855 rs = (ctx->opcode >> 21) & 0x1f;
13856 rt = (ctx->opcode >> 16) & 0x1f;
13857 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 13858 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
13859
13860 op1 = MASK_SPECIAL(ctx->opcode);
13861 switch (op1) {
c2e19f3c
AM
13862 case OPC_MULT:
13863 case OPC_MULTU:
13864 case OPC_DIV:
13865 case OPC_DIVU:
b42ee5e1
LA
13866 op2 = MASK_R6_MULDIV(ctx->opcode);
13867 switch (op2) {
13868 case R6_OPC_MUL:
13869 case R6_OPC_MUH:
13870 case R6_OPC_MULU:
13871 case R6_OPC_MUHU:
13872 case R6_OPC_DIV:
13873 case R6_OPC_MOD:
13874 case R6_OPC_DIVU:
13875 case R6_OPC_MODU:
13876 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13877 break;
13878 default:
13879 MIPS_INVAL("special_r6 muldiv");
3a4ef3b7 13880 gen_reserved_instruction(ctx);
b42ee5e1
LA
13881 break;
13882 }
13883 break;
10dc65db
LA
13884 case OPC_SELEQZ:
13885 case OPC_SELNEZ:
13886 gen_cond_move(ctx, op1, rd, rs, rt);
13887 break;
4267d3e6
LA
13888 case R6_OPC_CLO:
13889 case R6_OPC_CLZ:
13890 if (rt == 0 && sa == 1) {
7480515f
AM
13891 /*
13892 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13893 * We need additionally to check other fields.
13894 */
4267d3e6
LA
13895 gen_cl(ctx, op1, rd, rs);
13896 } else {
3a4ef3b7 13897 gen_reserved_instruction(ctx);
4267d3e6
LA
13898 }
13899 break;
13900 case R6_OPC_SDBBP:
3b3c1694
LA
13901 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13902 gen_helper_do_semihosting(cpu_env);
faf1f68b 13903 } else {
3b3c1694 13904 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3a4ef3b7 13905 gen_reserved_instruction(ctx);
3b3c1694 13906 } else {
9c708c7f 13907 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13908 }
faf1f68b 13909 }
4267d3e6 13910 break;
b42ee5e1 13911#if defined(TARGET_MIPS64)
4267d3e6
LA
13912 case R6_OPC_DCLO:
13913 case R6_OPC_DCLZ:
13914 if (rt == 0 && sa == 1) {
7480515f
AM
13915 /*
13916 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13917 * We need additionally to check other fields.
13918 */
4267d3e6
LA
13919 check_mips_64(ctx);
13920 gen_cl(ctx, op1, rd, rs);
13921 } else {
3a4ef3b7 13922 gen_reserved_instruction(ctx);
4267d3e6
LA
13923 }
13924 break;
c2e19f3c
AM
13925 case OPC_DMULT:
13926 case OPC_DMULTU:
13927 case OPC_DDIV:
13928 case OPC_DDIVU:
13929
b42ee5e1
LA
13930 op2 = MASK_R6_MULDIV(ctx->opcode);
13931 switch (op2) {
13932 case R6_OPC_DMUL:
13933 case R6_OPC_DMUH:
13934 case R6_OPC_DMULU:
13935 case R6_OPC_DMUHU:
13936 case R6_OPC_DDIV:
13937 case R6_OPC_DMOD:
13938 case R6_OPC_DDIVU:
13939 case R6_OPC_DMODU:
13940 check_mips_64(ctx);
13941 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13942 break;
13943 default:
13944 MIPS_INVAL("special_r6 muldiv");
3a4ef3b7 13945 gen_reserved_instruction(ctx);
b42ee5e1
LA
13946 break;
13947 }
13948 break;
13949#endif
10dc65db
LA
13950 default: /* Invalid */
13951 MIPS_INVAL("special_r6");
3a4ef3b7 13952 gen_reserved_instruction(ctx);
10dc65db
LA
13953 break;
13954 }
13955}
13956
9dc324ce
FN
13957static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13958{
13959 int rs = extract32(ctx->opcode, 21, 5);
13960 int rt = extract32(ctx->opcode, 16, 5);
13961 int rd = extract32(ctx->opcode, 11, 5);
13962 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13963
13964 switch (op1) {
13965 case OPC_MOVN: /* Conditional move */
13966 case OPC_MOVZ:
13967 gen_cond_move(ctx, op1, rd, rs, rt);
13968 break;
13969 case OPC_MFHI: /* Move from HI/LO */
13970 case OPC_MFLO:
13971 gen_HILO(ctx, op1, 0, rd);
13972 break;
13973 case OPC_MTHI:
13974 case OPC_MTLO: /* Move to HI/LO */
13975 gen_HILO(ctx, op1, 0, rs);
13976 break;
13977 case OPC_MULT:
13978 case OPC_MULTU:
13979 gen_mul_txx9(ctx, op1, rd, rs, rt);
13980 break;
13981 case OPC_DIV:
13982 case OPC_DIVU:
13983 gen_muldiv(ctx, op1, 0, rs, rt);
13984 break;
13985#if defined(TARGET_MIPS64)
13986 case OPC_DMULT:
13987 case OPC_DMULTU:
13988 case OPC_DDIV:
13989 case OPC_DDIVU:
13990 check_insn_opc_user_only(ctx, INSN_R5900);
13991 gen_muldiv(ctx, op1, 0, rs, rt);
13992 break;
13993#endif
13994 case OPC_JR:
13995 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13996 break;
13997 default: /* Invalid */
13998 MIPS_INVAL("special_tx79");
3a4ef3b7 13999 gen_reserved_instruction(ctx);
9dc324ce
FN
14000 break;
14001 }
14002}
14003
10dc65db
LA
14004static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14005{
bf772002 14006 int rs, rt, rd;
10dc65db
LA
14007 uint32_t op1;
14008
14009 rs = (ctx->opcode >> 21) & 0x1f;
14010 rt = (ctx->opcode >> 16) & 0x1f;
14011 rd = (ctx->opcode >> 11) & 0x1f;
14012
14013 op1 = MASK_SPECIAL(ctx->opcode);
14014 switch (op1) {
14015 case OPC_MOVN: /* Conditional move */
14016 case OPC_MOVZ:
bbd5e4a2 14017 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
9dc324ce 14018 INSN_LOONGSON2E | INSN_LOONGSON2F);
10dc65db
LA
14019 gen_cond_move(ctx, op1, rd, rs, rt);
14020 break;
14021 case OPC_MFHI: /* Move from HI/LO */
14022 case OPC_MFLO:
14023 gen_HILO(ctx, op1, rs & 3, rd);
14024 break;
14025 case OPC_MTHI:
14026 case OPC_MTLO: /* Move to HI/LO */
14027 gen_HILO(ctx, op1, rd & 3, rs);
14028 break;
14029 case OPC_MOVCI:
bbd5e4a2 14030 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
10dc65db
LA
14031 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14032 check_cp1_enabled(ctx);
14033 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14034 (ctx->opcode >> 16) & 1);
14035 } else {
14036 generate_exception_err(ctx, EXCP_CpU, 1);
14037 }
14038 break;
b42ee5e1
LA
14039 case OPC_MULT:
14040 case OPC_MULTU:
bf772002 14041 gen_muldiv(ctx, op1, rd & 3, rs, rt);
b42ee5e1
LA
14042 break;
14043 case OPC_DIV:
14044 case OPC_DIVU:
14045 gen_muldiv(ctx, op1, 0, rs, rt);
14046 break;
14047#if defined(TARGET_MIPS64)
c2e19f3c
AM
14048 case OPC_DMULT:
14049 case OPC_DMULTU:
14050 case OPC_DDIV:
14051 case OPC_DDIVU:
b42ee5e1
LA
14052 check_insn(ctx, ISA_MIPS3);
14053 check_mips_64(ctx);
14054 gen_muldiv(ctx, op1, 0, rs, rt);
14055 break;
14056#endif
0aefa333 14057 case OPC_JR:
c8b69a2a 14058 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
0aefa333 14059 break;
4267d3e6
LA
14060 case OPC_SPIM:
14061#ifdef MIPS_STRICT_STANDARD
14062 MIPS_INVAL("SPIM");
3a4ef3b7 14063 gen_reserved_instruction(ctx);
4267d3e6
LA
14064#else
14065 /* Implemented as RI exception for now. */
14066 MIPS_INVAL("spim (unofficial)");
3a4ef3b7 14067 gen_reserved_instruction(ctx);
4267d3e6
LA
14068#endif
14069 break;
10dc65db
LA
14070 default: /* Invalid */
14071 MIPS_INVAL("special_legacy");
3a4ef3b7 14072 gen_reserved_instruction(ctx);
10dc65db
LA
14073 break;
14074 }
14075}
14076
099e5b4d 14077static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 14078{
3c824109 14079 int rs, rt, rd, sa;
099e5b4d 14080 uint32_t op1;
3c824109 14081
3c824109
NF
14082 rs = (ctx->opcode >> 21) & 0x1f;
14083 rt = (ctx->opcode >> 16) & 0x1f;
14084 rd = (ctx->opcode >> 11) & 0x1f;
14085 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
14086
14087 op1 = MASK_SPECIAL(ctx->opcode);
14088 switch (op1) {
14089 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
14090 if (sa == 5 && rd == 0 &&
14091 rs == 0 && rt == 0) { /* PAUSE */
2e211e0a 14092 if ((ctx->insn_flags & ISA_MIPS_R6) &&
339cd2a8 14093 (ctx->hflags & MIPS_HFLAG_BMASK)) {
3a4ef3b7 14094 gen_reserved_instruction(ctx);
339cd2a8
LA
14095 break;
14096 }
14097 }
14098 /* Fallthrough */
099e5b4d
LA
14099 case OPC_SRA:
14100 gen_shift_imm(ctx, op1, rd, rt, sa);
14101 break;
14102 case OPC_SRL:
14103 switch ((ctx->opcode >> 21) & 0x1f) {
14104 case 1:
14105 /* rotr is decoded as srl on non-R2 CPUs */
7a47bae5 14106 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14107 op1 = OPC_ROTR;
ea63e2c3 14108 }
099e5b4d
LA
14109 /* Fallthrough */
14110 case 0:
14111 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 14112 break;
099e5b4d 14113 default:
3a4ef3b7 14114 gen_reserved_instruction(ctx);
ea63e2c3 14115 break;
099e5b4d
LA
14116 }
14117 break;
c2e19f3c
AM
14118 case OPC_ADD:
14119 case OPC_ADDU:
14120 case OPC_SUB:
14121 case OPC_SUBU:
099e5b4d
LA
14122 gen_arith(ctx, op1, rd, rs, rt);
14123 break;
14124 case OPC_SLLV: /* Shifts */
14125 case OPC_SRAV:
14126 gen_shift(ctx, op1, rd, rs, rt);
14127 break;
14128 case OPC_SRLV:
14129 switch ((ctx->opcode >> 6) & 0x1f) {
14130 case 1:
14131 /* rotrv is decoded as srlv on non-R2 CPUs */
7a47bae5 14132 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14133 op1 = OPC_ROTRV;
26135ead 14134 }
099e5b4d
LA
14135 /* Fallthrough */
14136 case 0:
14137 gen_shift(ctx, op1, rd, rs, rt);
26135ead 14138 break;
099e5b4d 14139 default:
3a4ef3b7 14140 gen_reserved_instruction(ctx);
6af0bf9c 14141 break;
099e5b4d
LA
14142 }
14143 break;
14144 case OPC_SLT: /* Set on less than */
14145 case OPC_SLTU:
14146 gen_slt(ctx, op1, rd, rs, rt);
14147 break;
14148 case OPC_AND: /* Logic*/
14149 case OPC_OR:
14150 case OPC_NOR:
14151 case OPC_XOR:
14152 gen_logic(ctx, op1, rd, rs, rt);
14153 break;
0aefa333 14154 case OPC_JALR:
b231c103 14155 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 14156 break;
c2e19f3c
AM
14157 case OPC_TGE: /* Traps */
14158 case OPC_TGEU:
14159 case OPC_TLT:
14160 case OPC_TLTU:
14161 case OPC_TEQ:
099e5b4d 14162 case OPC_TNE:
d9224450 14163 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
14164 gen_trap(ctx, op1, rs, rt, -1);
14165 break;
0e9524af
PMD
14166 case OPC_PMON:
14167 /* Pmon entry point, also R4010 selsl */
b48cfdff 14168#ifdef MIPS_STRICT_STANDARD
0e9524af
PMD
14169 MIPS_INVAL("PMON / selsl");
14170 gen_reserved_instruction(ctx);
b48cfdff 14171#else
ae71abad 14172 gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
b48cfdff 14173#endif
099e5b4d
LA
14174 break;
14175 case OPC_SYSCALL:
9c708c7f 14176 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
14177 break;
14178 case OPC_BREAK:
9c708c7f 14179 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 14180 break;
099e5b4d 14181 case OPC_SYNC:
d9224450 14182 check_insn(ctx, ISA_MIPS2);
d208ac0c 14183 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 14184 break;
4ad40f36 14185
d26bc211 14186#if defined(TARGET_MIPS64)
099e5b4d
LA
14187 /* MIPS64 specific opcodes */
14188 case OPC_DSLL:
14189 case OPC_DSRA:
14190 case OPC_DSLL32:
14191 case OPC_DSRA32:
14192 check_insn(ctx, ISA_MIPS3);
14193 check_mips_64(ctx);
14194 gen_shift_imm(ctx, op1, rd, rt, sa);
14195 break;
14196 case OPC_DSRL:
14197 switch ((ctx->opcode >> 21) & 0x1f) {
14198 case 1:
14199 /* drotr is decoded as dsrl on non-R2 CPUs */
7a47bae5 14200 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14201 op1 = OPC_DROTR;
ea63e2c3 14202 }
099e5b4d
LA
14203 /* Fallthrough */
14204 case 0:
d75c135e 14205 check_insn(ctx, ISA_MIPS3);
e189e748 14206 check_mips_64(ctx);
099e5b4d 14207 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14208 break;
099e5b4d 14209 default:
3a4ef3b7 14210 gen_reserved_instruction(ctx);
460f00c4 14211 break;
099e5b4d
LA
14212 }
14213 break;
14214 case OPC_DSRL32:
14215 switch ((ctx->opcode >> 21) & 0x1f) {
14216 case 1:
14217 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
7a47bae5 14218 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14219 op1 = OPC_DROTR32;
ea63e2c3 14220 }
099e5b4d
LA
14221 /* Fallthrough */
14222 case 0:
d75c135e 14223 check_insn(ctx, ISA_MIPS3);
e189e748 14224 check_mips_64(ctx);
099e5b4d 14225 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 14226 break;
099e5b4d 14227 default:
3a4ef3b7 14228 gen_reserved_instruction(ctx);
6af0bf9c
FB
14229 break;
14230 }
14231 break;
c2e19f3c
AM
14232 case OPC_DADD:
14233 case OPC_DADDU:
14234 case OPC_DSUB:
14235 case OPC_DSUBU:
099e5b4d
LA
14236 check_insn(ctx, ISA_MIPS3);
14237 check_mips_64(ctx);
14238 gen_arith(ctx, op1, rd, rs, rt);
14239 break;
14240 case OPC_DSLLV:
14241 case OPC_DSRAV:
14242 check_insn(ctx, ISA_MIPS3);
14243 check_mips_64(ctx);
14244 gen_shift(ctx, op1, rd, rs, rt);
14245 break;
14246 case OPC_DSRLV:
14247 switch ((ctx->opcode >> 6) & 0x1f) {
14248 case 1:
14249 /* drotrv is decoded as dsrlv on non-R2 CPUs */
7a47bae5 14250 if (ctx->insn_flags & ISA_MIPS_R2) {
099e5b4d 14251 op1 = OPC_DROTRV;
6af0bf9c 14252 }
099e5b4d
LA
14253 /* Fallthrough */
14254 case 0:
14255 check_insn(ctx, ISA_MIPS3);
e189e748 14256 check_mips_64(ctx);
099e5b4d 14257 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 14258 break;
099e5b4d 14259 default:
3a4ef3b7 14260 gen_reserved_instruction(ctx);
6af0bf9c
FB
14261 break;
14262 }
14263 break;
099e5b4d 14264#endif
10dc65db 14265 default:
2e211e0a 14266 if (ctx->insn_flags & ISA_MIPS_R6) {
10dc65db 14267 decode_opc_special_r6(env, ctx);
9dc324ce
FN
14268 } else if (ctx->insn_flags & INSN_R5900) {
14269 decode_opc_special_tx79(env, ctx);
10dc65db
LA
14270 } else {
14271 decode_opc_special_legacy(env, ctx);
14272 }
14273 }
14274}
14275
d67da337 14276
10dc65db 14277static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
14278{
14279 int rs, rt, rd;
14280 uint32_t op1;
6c5c1e20 14281
099e5b4d
LA
14282 rs = (ctx->opcode >> 21) & 0x1f;
14283 rt = (ctx->opcode >> 16) & 0x1f;
14284 rd = (ctx->opcode >> 11) & 0x1f;
14285
14286 op1 = MASK_SPECIAL2(ctx->opcode);
14287 switch (op1) {
c2e19f3c
AM
14288 case OPC_MADD: /* Multiply and add/sub */
14289 case OPC_MADDU:
14290 case OPC_MSUB:
14291 case OPC_MSUBU:
bbd5e4a2 14292 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
14293 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14294 break;
14295 case OPC_MUL:
099e5b4d
LA
14296 gen_arith(ctx, op1, rd, rs, rt);
14297 break;
fac5a073
LA
14298 case OPC_DIV_G_2F:
14299 case OPC_DIVU_G_2F:
14300 case OPC_MULT_G_2F:
14301 case OPC_MULTU_G_2F:
14302 case OPC_MOD_G_2F:
14303 case OPC_MODU_G_2F:
8e2d5831 14304 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
fac5a073
LA
14305 gen_loongson_integer(ctx, op1, rd, rs, rt);
14306 break;
099e5b4d
LA
14307 case OPC_CLO:
14308 case OPC_CLZ:
bbd5e4a2 14309 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
14310 gen_cl(ctx, op1, rd, rs);
14311 break;
14312 case OPC_SDBBP:
3b3c1694
LA
14313 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14314 gen_helper_do_semihosting(cpu_env);
14315 } else {
7480515f
AM
14316 /*
14317 * XXX: not clear which exception should be raised
3b3c1694
LA
14318 * when in debug mode...
14319 */
bbd5e4a2 14320 check_insn(ctx, ISA_MIPS_R1);
9c708c7f 14321 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14322 }
099e5b4d 14323 break;
9b1a1d68 14324#if defined(TARGET_MIPS64)
099e5b4d
LA
14325 case OPC_DCLO:
14326 case OPC_DCLZ:
bbd5e4a2 14327 check_insn(ctx, ISA_MIPS_R1);
099e5b4d
LA
14328 check_mips_64(ctx);
14329 gen_cl(ctx, op1, rd, rs);
14330 break;
4267d3e6
LA
14331 case OPC_DMULT_G_2F:
14332 case OPC_DMULTU_G_2F:
14333 case OPC_DDIV_G_2F:
14334 case OPC_DDIVU_G_2F:
14335 case OPC_DMOD_G_2F:
14336 case OPC_DMODU_G_2F:
8e2d5831 14337 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
4267d3e6
LA
14338 gen_loongson_integer(ctx, op1, rd, rs, rt);
14339 break;
10dc65db 14340#endif
4267d3e6
LA
14341 default: /* Invalid */
14342 MIPS_INVAL("special2_legacy");
3a4ef3b7 14343 gen_reserved_instruction(ctx);
4267d3e6 14344 break;
10dc65db
LA
14345 }
14346}
14347
14348static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14349{
15eacb9b
YK
14350 int rs, rt, rd, sa;
14351 uint32_t op1, op2;
10dc65db
LA
14352 int16_t imm;
14353
14354 rs = (ctx->opcode >> 21) & 0x1f;
14355 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
14356 rd = (ctx->opcode >> 11) & 0x1f;
14357 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
14358 imm = (int16_t)ctx->opcode >> 7;
14359
14360 op1 = MASK_SPECIAL3(ctx->opcode);
14361 switch (op1) {
bf7910c6
LA
14362 case R6_OPC_PREF:
14363 if (rt >= 24) {
14364 /* hint codes 24-31 are reserved and signal RI */
3a4ef3b7 14365 gen_reserved_instruction(ctx);
bf7910c6
LA
14366 }
14367 /* Treat as NOP. */
14368 break;
14369 case R6_OPC_CACHE:
40d48212 14370 check_cp0_enabled(ctx);
0d74a222
LA
14371 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14372 gen_cache_operation(ctx, rt, rs, imm);
14373 }
bf7910c6 14374 break;
10dc65db 14375 case R6_OPC_SC:
33a07fa2 14376 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
10dc65db
LA
14377 break;
14378 case R6_OPC_LL:
14379 gen_ld(ctx, op1, rt, rs, imm);
14380 break;
15eacb9b
YK
14381 case OPC_BSHFL:
14382 {
14383 if (rd == 0) {
14384 /* Treat as NOP. */
14385 break;
14386 }
15eacb9b
YK
14387 op2 = MASK_BSHFL(ctx->opcode);
14388 switch (op2) {
c2e19f3c 14389 case OPC_ALIGN:
373ecd38
AM
14390 case OPC_ALIGN_1:
14391 case OPC_ALIGN_2:
14392 case OPC_ALIGN_3:
821f2008 14393 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
14394 break;
14395 case OPC_BITSWAP:
1f1b4c00 14396 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
14397 break;
14398 }
15eacb9b
YK
14399 }
14400 break;
99029be1
YK
14401#ifndef CONFIG_USER_ONLY
14402 case OPC_GINV:
14403 if (unlikely(ctx->gi <= 1)) {
3a4ef3b7 14404 gen_reserved_instruction(ctx);
99029be1
YK
14405 }
14406 check_cp0_enabled(ctx);
14407 switch ((ctx->opcode >> 6) & 3) {
14408 case 0: /* GINVI */
14409 /* Treat as NOP. */
14410 break;
14411 case 2: /* GINVT */
14412 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14413 break;
14414 default:
3a4ef3b7 14415 gen_reserved_instruction(ctx);
99029be1
YK
14416 break;
14417 }
14418 break;
14419#endif
bf7910c6
LA
14420#if defined(TARGET_MIPS64)
14421 case R6_OPC_SCD:
33a07fa2 14422 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
bf7910c6
LA
14423 break;
14424 case R6_OPC_LLD:
14425 gen_ld(ctx, op1, rt, rs, imm);
14426 break;
15eacb9b
YK
14427 case OPC_DBSHFL:
14428 check_mips_64(ctx);
14429 {
14430 if (rd == 0) {
14431 /* Treat as NOP. */
14432 break;
14433 }
15eacb9b
YK
14434 op2 = MASK_DBSHFL(ctx->opcode);
14435 switch (op2) {
c2e19f3c 14436 case OPC_DALIGN:
373ecd38
AM
14437 case OPC_DALIGN_1:
14438 case OPC_DALIGN_2:
14439 case OPC_DALIGN_3:
14440 case OPC_DALIGN_4:
14441 case OPC_DALIGN_5:
14442 case OPC_DALIGN_6:
14443 case OPC_DALIGN_7:
821f2008 14444 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
14445 break;
14446 case OPC_DBITSWAP:
1f1b4c00 14447 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
14448 break;
14449 }
1f1b4c00 14450
15eacb9b
YK
14451 }
14452 break;
bf7910c6 14453#endif
10dc65db
LA
14454 default: /* Invalid */
14455 MIPS_INVAL("special3_r6");
3a4ef3b7 14456 gen_reserved_instruction(ctx);
10dc65db
LA
14457 break;
14458 }
14459}
14460
14461static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14462{
fac5a073 14463 int rs, rt, rd;
099e5b4d 14464 uint32_t op1, op2;
099e5b4d
LA
14465
14466 rs = (ctx->opcode >> 21) & 0x1f;
14467 rt = (ctx->opcode >> 16) & 0x1f;
14468 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
14469
14470 op1 = MASK_SPECIAL3(ctx->opcode);
14471 switch (op1) {
c2e19f3c
AM
14472 case OPC_DIV_G_2E:
14473 case OPC_DIVU_G_2E:
14474 case OPC_MOD_G_2E:
14475 case OPC_MODU_G_2E:
14476 case OPC_MULT_G_2E:
14477 case OPC_MULTU_G_2E:
7480515f
AM
14478 /*
14479 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14480 * the same mask and op1.
14481 */
908f6be1 14482 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 14483 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 14484 switch (op2) {
099e5b4d
LA
14485 case OPC_ADDUH_QB:
14486 case OPC_ADDUH_R_QB:
14487 case OPC_ADDQH_PH:
14488 case OPC_ADDQH_R_PH:
14489 case OPC_ADDQH_W:
14490 case OPC_ADDQH_R_W:
14491 case OPC_SUBUH_QB:
14492 case OPC_SUBUH_R_QB:
14493 case OPC_SUBQH_PH:
14494 case OPC_SUBQH_R_PH:
14495 case OPC_SUBQH_W:
14496 case OPC_SUBQH_R_W:
461c08df
JL
14497 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14498 break;
099e5b4d
LA
14499 case OPC_MUL_PH:
14500 case OPC_MUL_S_PH:
14501 case OPC_MULQ_S_W:
14502 case OPC_MULQ_RS_W:
14503 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 14504 break;
461c08df 14505 default:
099e5b4d 14506 MIPS_INVAL("MASK ADDUH.QB");
3a4ef3b7 14507 gen_reserved_instruction(ctx);
461c08df
JL
14508 break;
14509 }
099e5b4d
LA
14510 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14511 gen_loongson_integer(ctx, op1, rd, rs, rt);
14512 } else {
3a4ef3b7 14513 gen_reserved_instruction(ctx);
099e5b4d
LA
14514 }
14515 break;
14516 case OPC_LX_DSP:
14517 op2 = MASK_LX(ctx->opcode);
14518 switch (op2) {
14519#if defined(TARGET_MIPS64)
14520 case OPC_LDX:
14521#endif
14522 case OPC_LBUX:
14523 case OPC_LHX:
14524 case OPC_LWX:
14525 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14526 break;
14527 default: /* Invalid */
14528 MIPS_INVAL("MASK LX");
3a4ef3b7 14529 gen_reserved_instruction(ctx);
099e5b4d
LA
14530 break;
14531 }
14532 break;
14533 case OPC_ABSQ_S_PH_DSP:
14534 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14535 switch (op2) {
14536 case OPC_ABSQ_S_QB:
14537 case OPC_ABSQ_S_PH:
14538 case OPC_ABSQ_S_W:
14539 case OPC_PRECEQ_W_PHL:
14540 case OPC_PRECEQ_W_PHR:
14541 case OPC_PRECEQU_PH_QBL:
14542 case OPC_PRECEQU_PH_QBR:
14543 case OPC_PRECEQU_PH_QBLA:
14544 case OPC_PRECEQU_PH_QBRA:
14545 case OPC_PRECEU_PH_QBL:
14546 case OPC_PRECEU_PH_QBR:
14547 case OPC_PRECEU_PH_QBLA:
14548 case OPC_PRECEU_PH_QBRA:
14549 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14550 break;
14551 case OPC_BITREV:
14552 case OPC_REPL_QB:
14553 case OPC_REPLV_QB:
14554 case OPC_REPL_PH:
14555 case OPC_REPLV_PH:
14556 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14557 break;
14558 default:
14559 MIPS_INVAL("MASK ABSQ_S.PH");
3a4ef3b7 14560 gen_reserved_instruction(ctx);
099e5b4d
LA
14561 break;
14562 }
14563 break;
14564 case OPC_ADDU_QB_DSP:
14565 op2 = MASK_ADDU_QB(ctx->opcode);
14566 switch (op2) {
14567 case OPC_ADDQ_PH:
14568 case OPC_ADDQ_S_PH:
14569 case OPC_ADDQ_S_W:
14570 case OPC_ADDU_QB:
14571 case OPC_ADDU_S_QB:
14572 case OPC_ADDU_PH:
14573 case OPC_ADDU_S_PH:
14574 case OPC_SUBQ_PH:
14575 case OPC_SUBQ_S_PH:
14576 case OPC_SUBQ_S_W:
14577 case OPC_SUBU_QB:
14578 case OPC_SUBU_S_QB:
14579 case OPC_SUBU_PH:
14580 case OPC_SUBU_S_PH:
14581 case OPC_ADDSC:
14582 case OPC_ADDWC:
14583 case OPC_MODSUB:
14584 case OPC_RADDU_W_QB:
14585 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14586 break;
14587 case OPC_MULEU_S_PH_QBL:
14588 case OPC_MULEU_S_PH_QBR:
14589 case OPC_MULQ_RS_PH:
14590 case OPC_MULEQ_S_W_PHL:
14591 case OPC_MULEQ_S_W_PHR:
14592 case OPC_MULQ_S_PH:
14593 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14594 break;
14595 default: /* Invalid */
14596 MIPS_INVAL("MASK ADDU.QB");
3a4ef3b7 14597 gen_reserved_instruction(ctx);
461c08df 14598 break;
461c08df 14599
099e5b4d
LA
14600 }
14601 break;
14602 case OPC_CMPU_EQ_QB_DSP:
14603 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14604 switch (op2) {
14605 case OPC_PRECR_SRA_PH_W:
14606 case OPC_PRECR_SRA_R_PH_W:
14607 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 14608 break;
099e5b4d
LA
14609 case OPC_PRECR_QB_PH:
14610 case OPC_PRECRQ_QB_PH:
14611 case OPC_PRECRQ_PH_W:
14612 case OPC_PRECRQ_RS_PH_W:
14613 case OPC_PRECRQU_S_QB_PH:
14614 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 14615 break;
099e5b4d
LA
14616 case OPC_CMPU_EQ_QB:
14617 case OPC_CMPU_LT_QB:
14618 case OPC_CMPU_LE_QB:
14619 case OPC_CMP_EQ_PH:
14620 case OPC_CMP_LT_PH:
14621 case OPC_CMP_LE_PH:
14622 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 14623 break;
099e5b4d
LA
14624 case OPC_CMPGU_EQ_QB:
14625 case OPC_CMPGU_LT_QB:
14626 case OPC_CMPGU_LE_QB:
14627 case OPC_CMPGDU_EQ_QB:
14628 case OPC_CMPGDU_LT_QB:
14629 case OPC_CMPGDU_LE_QB:
14630 case OPC_PICK_QB:
14631 case OPC_PICK_PH:
14632 case OPC_PACKRL_PH:
14633 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14634 break;
14635 default: /* Invalid */
14636 MIPS_INVAL("MASK CMPU.EQ.QB");
3a4ef3b7 14637 gen_reserved_instruction(ctx);
099e5b4d
LA
14638 break;
14639 }
14640 break;
14641 case OPC_SHLL_QB_DSP:
14642 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14643 break;
14644 case OPC_DPA_W_PH_DSP:
14645 op2 = MASK_DPA_W_PH(ctx->opcode);
14646 switch (op2) {
14647 case OPC_DPAU_H_QBL:
14648 case OPC_DPAU_H_QBR:
14649 case OPC_DPSU_H_QBL:
14650 case OPC_DPSU_H_QBR:
14651 case OPC_DPA_W_PH:
14652 case OPC_DPAX_W_PH:
14653 case OPC_DPAQ_S_W_PH:
14654 case OPC_DPAQX_S_W_PH:
14655 case OPC_DPAQX_SA_W_PH:
14656 case OPC_DPS_W_PH:
14657 case OPC_DPSX_W_PH:
14658 case OPC_DPSQ_S_W_PH:
14659 case OPC_DPSQX_S_W_PH:
14660 case OPC_DPSQX_SA_W_PH:
14661 case OPC_MULSAQ_S_W_PH:
14662 case OPC_DPAQ_SA_L_W:
14663 case OPC_DPSQ_SA_L_W:
14664 case OPC_MAQ_S_W_PHL:
14665 case OPC_MAQ_S_W_PHR:
14666 case OPC_MAQ_SA_W_PHL:
14667 case OPC_MAQ_SA_W_PHR:
14668 case OPC_MULSA_W_PH:
14669 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14670 break;
14671 default: /* Invalid */
14672 MIPS_INVAL("MASK DPAW.PH");
3a4ef3b7 14673 gen_reserved_instruction(ctx);
099e5b4d
LA
14674 break;
14675 }
14676 break;
14677 case OPC_INSV_DSP:
14678 op2 = MASK_INSV(ctx->opcode);
14679 switch (op2) {
14680 case OPC_INSV:
14681 check_dsp(ctx);
14682 {
14683 TCGv t0, t1;
14684
14685 if (rt == 0) {
099e5b4d
LA
14686 break;
14687 }
14688
14689 t0 = tcg_temp_new();
14690 t1 = tcg_temp_new();
14691
14692 gen_load_gpr(t0, rt);
14693 gen_load_gpr(t1, rs);
14694
14695 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14696
14697 tcg_temp_free(t0);
14698 tcg_temp_free(t1);
a22260ae
JL
14699 break;
14700 }
099e5b4d
LA
14701 default: /* Invalid */
14702 MIPS_INVAL("MASK INSV");
3a4ef3b7 14703 gen_reserved_instruction(ctx);
099e5b4d
LA
14704 break;
14705 }
14706 break;
14707 case OPC_APPEND_DSP:
14708 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14709 break;
14710 case OPC_EXTR_W_DSP:
14711 op2 = MASK_EXTR_W(ctx->opcode);
14712 switch (op2) {
14713 case OPC_EXTR_W:
14714 case OPC_EXTR_R_W:
14715 case OPC_EXTR_RS_W:
14716 case OPC_EXTR_S_H:
14717 case OPC_EXTRV_S_H:
14718 case OPC_EXTRV_W:
14719 case OPC_EXTRV_R_W:
14720 case OPC_EXTRV_RS_W:
14721 case OPC_EXTP:
14722 case OPC_EXTPV:
14723 case OPC_EXTPDP:
14724 case OPC_EXTPDPV:
14725 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14726 break;
14727 case OPC_RDDSP:
14728 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14729 break;
14730 case OPC_SHILO:
14731 case OPC_SHILOV:
14732 case OPC_MTHLIP:
14733 case OPC_WRDSP:
14734 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14735 break;
14736 default: /* Invalid */
14737 MIPS_INVAL("MASK EXTR.W");
3a4ef3b7 14738 gen_reserved_instruction(ctx);
099e5b4d
LA
14739 break;
14740 }
14741 break;
099e5b4d 14742#if defined(TARGET_MIPS64)
c2e19f3c
AM
14743 case OPC_DDIV_G_2E:
14744 case OPC_DDIVU_G_2E:
14745 case OPC_DMULT_G_2E:
14746 case OPC_DMULTU_G_2E:
14747 case OPC_DMOD_G_2E:
14748 case OPC_DMODU_G_2E:
fac5a073
LA
14749 check_insn(ctx, INSN_LOONGSON2E);
14750 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 14751 break;
099e5b4d
LA
14752 case OPC_ABSQ_S_QH_DSP:
14753 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14754 switch (op2) {
14755 case OPC_PRECEQ_L_PWL:
14756 case OPC_PRECEQ_L_PWR:
14757 case OPC_PRECEQ_PW_QHL:
14758 case OPC_PRECEQ_PW_QHR:
14759 case OPC_PRECEQ_PW_QHLA:
14760 case OPC_PRECEQ_PW_QHRA:
14761 case OPC_PRECEQU_QH_OBL:
14762 case OPC_PRECEQU_QH_OBR:
14763 case OPC_PRECEQU_QH_OBLA:
14764 case OPC_PRECEQU_QH_OBRA:
14765 case OPC_PRECEU_QH_OBL:
14766 case OPC_PRECEU_QH_OBR:
14767 case OPC_PRECEU_QH_OBLA:
14768 case OPC_PRECEU_QH_OBRA:
14769 case OPC_ABSQ_S_OB:
14770 case OPC_ABSQ_S_PW:
14771 case OPC_ABSQ_S_QH:
14772 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14773 break;
14774 case OPC_REPL_OB:
14775 case OPC_REPL_PW:
14776 case OPC_REPL_QH:
14777 case OPC_REPLV_OB:
14778 case OPC_REPLV_PW:
14779 case OPC_REPLV_QH:
14780 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14781 break;
14782 default: /* Invalid */
14783 MIPS_INVAL("MASK ABSQ_S.QH");
3a4ef3b7 14784 gen_reserved_instruction(ctx);
099e5b4d
LA
14785 break;
14786 }
14787 break;
14788 case OPC_ADDU_OB_DSP:
14789 op2 = MASK_ADDU_OB(ctx->opcode);
14790 switch (op2) {
14791 case OPC_RADDU_L_OB:
14792 case OPC_SUBQ_PW:
14793 case OPC_SUBQ_S_PW:
14794 case OPC_SUBQ_QH:
14795 case OPC_SUBQ_S_QH:
14796 case OPC_SUBU_OB:
14797 case OPC_SUBU_S_OB:
14798 case OPC_SUBU_QH:
14799 case OPC_SUBU_S_QH:
14800 case OPC_SUBUH_OB:
14801 case OPC_SUBUH_R_OB:
14802 case OPC_ADDQ_PW:
14803 case OPC_ADDQ_S_PW:
14804 case OPC_ADDQ_QH:
14805 case OPC_ADDQ_S_QH:
14806 case OPC_ADDU_OB:
14807 case OPC_ADDU_S_OB:
14808 case OPC_ADDU_QH:
14809 case OPC_ADDU_S_QH:
14810 case OPC_ADDUH_OB:
14811 case OPC_ADDUH_R_OB:
14812 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 14813 break;
099e5b4d
LA
14814 case OPC_MULEQ_S_PW_QHL:
14815 case OPC_MULEQ_S_PW_QHR:
14816 case OPC_MULEU_S_QH_OBL:
14817 case OPC_MULEU_S_QH_OBR:
14818 case OPC_MULQ_RS_QH:
14819 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 14820 break;
099e5b4d
LA
14821 default: /* Invalid */
14822 MIPS_INVAL("MASK ADDU.OB");
3a4ef3b7 14823 gen_reserved_instruction(ctx);
26690560 14824 break;
099e5b4d
LA
14825 }
14826 break;
14827 case OPC_CMPU_EQ_OB_DSP:
14828 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14829 switch (op2) {
14830 case OPC_PRECR_SRA_QH_PW:
14831 case OPC_PRECR_SRA_R_QH_PW:
14832 /* Return value is rt. */
14833 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 14834 break;
099e5b4d
LA
14835 case OPC_PRECR_OB_QH:
14836 case OPC_PRECRQ_OB_QH:
14837 case OPC_PRECRQ_PW_L:
14838 case OPC_PRECRQ_QH_PW:
14839 case OPC_PRECRQ_RS_QH_PW:
14840 case OPC_PRECRQU_S_OB_QH:
14841 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 14842 break;
099e5b4d
LA
14843 case OPC_CMPU_EQ_OB:
14844 case OPC_CMPU_LT_OB:
14845 case OPC_CMPU_LE_OB:
14846 case OPC_CMP_EQ_QH:
14847 case OPC_CMP_LT_QH:
14848 case OPC_CMP_LE_QH:
14849 case OPC_CMP_EQ_PW:
14850 case OPC_CMP_LT_PW:
14851 case OPC_CMP_LE_PW:
14852 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 14853 break;
099e5b4d
LA
14854 case OPC_CMPGDU_EQ_OB:
14855 case OPC_CMPGDU_LT_OB:
14856 case OPC_CMPGDU_LE_OB:
14857 case OPC_CMPGU_EQ_OB:
14858 case OPC_CMPGU_LT_OB:
14859 case OPC_CMPGU_LE_OB:
14860 case OPC_PACKRL_PW:
14861 case OPC_PICK_OB:
14862 case OPC_PICK_PW:
14863 case OPC_PICK_QH:
14864 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 14865 break;
099e5b4d
LA
14866 default: /* Invalid */
14867 MIPS_INVAL("MASK CMPU_EQ.OB");
3a4ef3b7 14868 gen_reserved_instruction(ctx);
161f85e6 14869 break;
099e5b4d
LA
14870 }
14871 break;
14872 case OPC_DAPPEND_DSP:
14873 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14874 break;
14875 case OPC_DEXTR_W_DSP:
14876 op2 = MASK_DEXTR_W(ctx->opcode);
14877 switch (op2) {
14878 case OPC_DEXTP:
14879 case OPC_DEXTPDP:
14880 case OPC_DEXTPDPV:
14881 case OPC_DEXTPV:
14882 case OPC_DEXTR_L:
14883 case OPC_DEXTR_R_L:
14884 case OPC_DEXTR_RS_L:
14885 case OPC_DEXTR_W:
14886 case OPC_DEXTR_R_W:
14887 case OPC_DEXTR_RS_W:
14888 case OPC_DEXTR_S_H:
14889 case OPC_DEXTRV_L:
14890 case OPC_DEXTRV_R_L:
14891 case OPC_DEXTRV_RS_L:
14892 case OPC_DEXTRV_S_H:
14893 case OPC_DEXTRV_W:
14894 case OPC_DEXTRV_R_W:
14895 case OPC_DEXTRV_RS_W:
14896 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 14897 break;
099e5b4d
LA
14898 case OPC_DMTHLIP:
14899 case OPC_DSHILO:
14900 case OPC_DSHILOV:
14901 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 14902 break;
099e5b4d
LA
14903 default: /* Invalid */
14904 MIPS_INVAL("MASK EXTR.W");
3a4ef3b7 14905 gen_reserved_instruction(ctx);
461c08df 14906 break;
099e5b4d
LA
14907 }
14908 break;
14909 case OPC_DPAQ_W_QH_DSP:
14910 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14911 switch (op2) {
14912 case OPC_DPAU_H_OBL:
14913 case OPC_DPAU_H_OBR:
14914 case OPC_DPSU_H_OBL:
14915 case OPC_DPSU_H_OBR:
14916 case OPC_DPA_W_QH:
14917 case OPC_DPAQ_S_W_QH:
14918 case OPC_DPS_W_QH:
14919 case OPC_DPSQ_S_W_QH:
14920 case OPC_MULSAQ_S_W_QH:
14921 case OPC_DPAQ_SA_L_PW:
14922 case OPC_DPSQ_SA_L_PW:
14923 case OPC_MULSAQ_S_L_PW:
14924 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14925 break;
14926 case OPC_MAQ_S_W_QHLL:
14927 case OPC_MAQ_S_W_QHLR:
14928 case OPC_MAQ_S_W_QHRL:
14929 case OPC_MAQ_S_W_QHRR:
14930 case OPC_MAQ_SA_W_QHLL:
14931 case OPC_MAQ_SA_W_QHLR:
14932 case OPC_MAQ_SA_W_QHRL:
14933 case OPC_MAQ_SA_W_QHRR:
14934 case OPC_MAQ_S_L_PWL:
14935 case OPC_MAQ_S_L_PWR:
14936 case OPC_DMADD:
14937 case OPC_DMADDU:
14938 case OPC_DMSUB:
14939 case OPC_DMSUBU:
14940 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 14941 break;
099e5b4d
LA
14942 default: /* Invalid */
14943 MIPS_INVAL("MASK DPAQ.W.QH");
3a4ef3b7 14944 gen_reserved_instruction(ctx);
b53371ed 14945 break;
099e5b4d
LA
14946 }
14947 break;
14948 case OPC_DINSV_DSP:
14949 op2 = MASK_INSV(ctx->opcode);
14950 switch (op2) {
14951 case OPC_DINSV:
14952 {
14953 TCGv t0, t1;
14954
a071578b
PMD
14955 check_dsp(ctx);
14956
099e5b4d 14957 if (rt == 0) {
a22260ae
JL
14958 break;
14959 }
1cb6686c 14960
099e5b4d
LA
14961 t0 = tcg_temp_new();
14962 t1 = tcg_temp_new();
1cb6686c 14963
099e5b4d
LA
14964 gen_load_gpr(t0, rt);
14965 gen_load_gpr(t1, rs);
1cb6686c 14966
099e5b4d 14967 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 14968
099e5b4d
LA
14969 tcg_temp_free(t0);
14970 tcg_temp_free(t1);
77c5fa8b 14971 break;
099e5b4d 14972 }
7a387fff 14973 default: /* Invalid */
099e5b4d 14974 MIPS_INVAL("MASK DINSV");
3a4ef3b7 14975 gen_reserved_instruction(ctx);
7a387fff
TS
14976 break;
14977 }
14978 break;
099e5b4d
LA
14979 case OPC_SHLL_OB_DSP:
14980 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14981 break;
14982#endif
fac5a073
LA
14983 default: /* Invalid */
14984 MIPS_INVAL("special3_legacy");
3a4ef3b7 14985 gen_reserved_instruction(ctx);
fac5a073
LA
14986 break;
14987 }
14988}
14989
37b9aae2
MM
14990
14991#if defined(TARGET_MIPS64)
14992
874b2879 14993static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
71b8a6b3 14994{
c8341e00 14995 uint32_t opc = MASK_MMI(ctx->opcode);
06de726b
FN
14996 int rs = extract32(ctx->opcode, 21, 5);
14997 int rt = extract32(ctx->opcode, 16, 5);
14998 int rd = extract32(ctx->opcode, 11, 5);
71b8a6b3
FN
14999
15000 switch (opc) {
baa609db
AM
15001 case MMI_OPC_MULT1:
15002 case MMI_OPC_MULTU1:
3b948f05
PMD
15003 case MMI_OPC_MADD:
15004 case MMI_OPC_MADDU:
a95c4c26
FN
15005 case MMI_OPC_MADD1:
15006 case MMI_OPC_MADDU1:
06de726b
FN
15007 gen_mul_txx9(ctx, opc, rd, rs, rt);
15008 break;
baa609db
AM
15009 case MMI_OPC_DIV1:
15010 case MMI_OPC_DIVU1:
c42171c3 15011 gen_div1_tx79(ctx, opc, rs, rt);
be9c42c9 15012 break;
71b8a6b3
FN
15013 default:
15014 MIPS_INVAL("TX79 MMI class");
3a4ef3b7 15015 gen_reserved_instruction(ctx);
71b8a6b3
FN
15016 break;
15017 }
15018}
15019
874b2879 15020static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
bb41e74b 15021{
3a4ef3b7 15022 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */
bb41e74b
FN
15023}
15024
15025/*
15026 * The TX79-specific instruction Store Quadword
15027 *
15028 * +--------+-------+-------+------------------------+
15029 * | 011111 | base | rt | offset | SQ
15030 * +--------+-------+-------+------------------------+
15031 * 6 5 5 16
15032 *
15033 * has the same opcode as the Read Hardware Register instruction
15034 *
15035 * +--------+-------+-------+-------+-------+--------+
15036 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
15037 * +--------+-------+-------+-------+-------+--------+
15038 * 6 5 5 5 5 6
15039 *
15040 * that is required, trapped and emulated by the Linux kernel. However, all
15041 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
15042 * offset is odd. Therefore all valid SQ instructions can execute normally.
15043 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
15044 * between SQ and RDHWR, as the Linux kernel does.
15045 */
874b2879 15046static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
bb41e74b
FN
15047{
15048 int base = extract32(ctx->opcode, 21, 5);
15049 int rt = extract32(ctx->opcode, 16, 5);
15050 int offset = extract32(ctx->opcode, 0, 16);
15051
15052#ifdef CONFIG_USER_ONLY
15053 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15054 uint32_t op2 = extract32(ctx->opcode, 6, 5);
15055
15056 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15057 int rd = extract32(ctx->opcode, 11, 5);
15058
15059 gen_rdhwr(ctx, rt, rd, 0);
15060 return;
15061 }
15062#endif
15063
874b2879 15064 gen_mmi_sq(ctx, base, rt, offset);
bb41e74b
FN
15065}
15066
37b9aae2
MM
15067#endif
15068
fac5a073
LA
15069static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15070{
15071 int rs, rt, rd, sa;
15072 uint32_t op1, op2;
76964147 15073 int16_t imm;
fac5a073
LA
15074
15075 rs = (ctx->opcode >> 21) & 0x1f;
15076 rt = (ctx->opcode >> 16) & 0x1f;
15077 rd = (ctx->opcode >> 11) & 0x1f;
15078 sa = (ctx->opcode >> 6) & 0x1f;
76964147 15079 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
15080
15081 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
15082
15083 /*
15084 * EVA loads and stores overlap Loongson 2E instructions decoded by
15085 * decode_opc_special3_legacy(), so be careful to allow their decoding when
15086 * EVA is absent.
15087 */
15088 if (ctx->eva) {
15089 switch (op1) {
c2e19f3c
AM
15090 case OPC_LWLE:
15091 case OPC_LWRE:
c2e19f3c
AM
15092 case OPC_LBUE:
15093 case OPC_LHUE:
15094 case OPC_LBE:
15095 case OPC_LHE:
15096 case OPC_LLE:
15097 case OPC_LWE:
76964147
JH
15098 check_cp0_enabled(ctx);
15099 gen_ld(ctx, op1, rt, rs, imm);
15100 return;
c2e19f3c
AM
15101 case OPC_SWLE:
15102 case OPC_SWRE:
c2e19f3c
AM
15103 case OPC_SBE:
15104 case OPC_SHE:
76964147
JH
15105 case OPC_SWE:
15106 check_cp0_enabled(ctx);
15107 gen_st(ctx, op1, rt, rs, imm);
15108 return;
15109 case OPC_SCE:
15110 check_cp0_enabled(ctx);
33a07fa2 15111 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
76964147
JH
15112 return;
15113 case OPC_CACHEE:
84c2fdc3 15114 check_eva(ctx);
76964147
JH
15115 check_cp0_enabled(ctx);
15116 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15117 gen_cache_operation(ctx, rt, rs, imm);
15118 }
76964147
JH
15119 return;
15120 case OPC_PREFE:
15121 check_cp0_enabled(ctx);
15122 /* Treat as NOP. */
15123 return;
15124 }
15125 }
15126
fac5a073
LA
15127 switch (op1) {
15128 case OPC_EXT:
15129 case OPC_INS:
7a47bae5 15130 check_insn(ctx, ISA_MIPS_R2);
fac5a073
LA
15131 gen_bitops(ctx, op1, rt, rs, sa, rd);
15132 break;
15133 case OPC_BSHFL:
fac5a073 15134 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 15135 switch (op2) {
c2e19f3c 15136 case OPC_ALIGN:
373ecd38
AM
15137 case OPC_ALIGN_1:
15138 case OPC_ALIGN_2:
15139 case OPC_ALIGN_3:
15eacb9b 15140 case OPC_BITSWAP:
2e211e0a 15141 check_insn(ctx, ISA_MIPS_R6);
15eacb9b
YK
15142 decode_opc_special3_r6(env, ctx);
15143 break;
15144 default:
7a47bae5 15145 check_insn(ctx, ISA_MIPS_R2);
15eacb9b
YK
15146 gen_bshfl(ctx, op2, rt, rd);
15147 break;
15148 }
fac5a073
LA
15149 break;
15150#if defined(TARGET_MIPS64)
c2e19f3c
AM
15151 case OPC_DEXTM:
15152 case OPC_DEXTU:
15153 case OPC_DEXT:
15154 case OPC_DINSM:
15155 case OPC_DINSU:
15156 case OPC_DINS:
7a47bae5 15157 check_insn(ctx, ISA_MIPS_R2);
fac5a073
LA
15158 check_mips_64(ctx);
15159 gen_bitops(ctx, op1, rt, rs, sa, rd);
15160 break;
15161 case OPC_DBSHFL:
fac5a073 15162 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 15163 switch (op2) {
c2e19f3c 15164 case OPC_DALIGN:
373ecd38
AM
15165 case OPC_DALIGN_1:
15166 case OPC_DALIGN_2:
15167 case OPC_DALIGN_3:
15168 case OPC_DALIGN_4:
15169 case OPC_DALIGN_5:
15170 case OPC_DALIGN_6:
15171 case OPC_DALIGN_7:
15eacb9b 15172 case OPC_DBITSWAP:
2e211e0a 15173 check_insn(ctx, ISA_MIPS_R6);
15eacb9b
YK
15174 decode_opc_special3_r6(env, ctx);
15175 break;
15176 default:
7a47bae5 15177 check_insn(ctx, ISA_MIPS_R2);
15eacb9b
YK
15178 check_mips_64(ctx);
15179 op2 = MASK_DBSHFL(ctx->opcode);
15180 gen_bshfl(ctx, op2, rt, rd);
15181 break;
15182 }
fac5a073
LA
15183 break;
15184#endif
15185 case OPC_RDHWR:
b00c7218 15186 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
15187 break;
15188 case OPC_FORK:
9affc1c5 15189 check_mt(ctx);
fac5a073
LA
15190 {
15191 TCGv t0 = tcg_temp_new();
15192 TCGv t1 = tcg_temp_new();
15193
15194 gen_load_gpr(t0, rt);
15195 gen_load_gpr(t1, rs);
15196 gen_helper_fork(t0, t1);
15197 tcg_temp_free(t0);
15198 tcg_temp_free(t1);
15199 }
15200 break;
15201 case OPC_YIELD:
9affc1c5 15202 check_mt(ctx);
fac5a073
LA
15203 {
15204 TCGv t0 = tcg_temp_new();
15205
fac5a073
LA
15206 gen_load_gpr(t0, rs);
15207 gen_helper_yield(t0, cpu_env, t0);
15208 gen_store_gpr(t0, rd);
15209 tcg_temp_free(t0);
15210 }
15211 break;
10dc65db 15212 default:
2e211e0a 15213 if (ctx->insn_flags & ISA_MIPS_R6) {
10dc65db
LA
15214 decode_opc_special3_r6(env, ctx);
15215 } else {
15216 decode_opc_special3_legacy(env, ctx);
15217 }
099e5b4d
LA
15218 }
15219}
15220
80e64a38 15221static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
4c789546 15222{
80e64a38
PMD
15223 int32_t offset;
15224 int rs, rt, rd, sa;
15225 uint32_t op, op1;
15226 int16_t imm;
4c789546 15227
80e64a38
PMD
15228 op = MASK_OP_MAJOR(ctx->opcode);
15229 rs = (ctx->opcode >> 21) & 0x1f;
15230 rt = (ctx->opcode >> 16) & 0x1f;
15231 rd = (ctx->opcode >> 11) & 0x1f;
15232 sa = (ctx->opcode >> 6) & 0x1f;
15233 imm = (int16_t)ctx->opcode;
15234 switch (op) {
15235 case OPC_SPECIAL:
15236 decode_opc_special(env, ctx);
4c789546 15237 break;
80e64a38
PMD
15238 case OPC_SPECIAL2:
15239#if defined(TARGET_MIPS64)
15240 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15241 decode_mmi(env, ctx);
4f57f43c
PMD
15242 break;
15243 }
15244#endif
c7abe00a 15245 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
22345286
PMD
15246 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15247 gen_arith(ctx, OPC_MUL, rd, rs, rt);
15248 } else {
e31b43ec 15249 decode_ase_mxu(ctx, ctx->opcode);
22345286 15250 }
4f57f43c 15251 break;
4c789546 15252 }
4f57f43c 15253 decode_opc_special2_legacy(env, ctx);
4c789546 15254 break;
80e64a38
PMD
15255 case OPC_SPECIAL3:
15256#if defined(TARGET_MIPS64)
15257 if (ctx->insn_flags & INSN_R5900) {
15258 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
15259 } else {
15260 decode_opc_special3(env, ctx);
80e71591 15261 }
80e64a38
PMD
15262#else
15263 decode_opc_special3(env, ctx);
15264#endif
80e71591 15265 break;
80e64a38
PMD
15266 case OPC_REGIMM:
15267 op1 = MASK_REGIMM(ctx->opcode);
15268 switch (op1) {
15269 case OPC_BLTZL: /* REGIMM branches */
15270 case OPC_BGEZL:
15271 case OPC_BLTZALL:
15272 case OPC_BGEZALL:
15273 check_insn(ctx, ISA_MIPS2);
15274 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15275 /* Fallthrough */
15276 case OPC_BLTZ:
15277 case OPC_BGEZ:
15278 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
2e3eddb0 15279 break;
80e64a38
PMD
15280 case OPC_BLTZAL:
15281 case OPC_BGEZAL:
15282 if (ctx->insn_flags & ISA_MIPS_R6) {
15283 if (rs == 0) {
15284 /* OPC_NAL, OPC_BAL */
15285 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15286 } else {
15287 gen_reserved_instruction(ctx);
15288 }
15289 } else {
15290 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15291 }
2e3eddb0 15292 break;
80e64a38
PMD
15293 case OPC_TGEI: /* REGIMM traps */
15294 case OPC_TGEIU:
15295 case OPC_TLTI:
15296 case OPC_TLTIU:
15297 case OPC_TEQI:
15298
15299 case OPC_TNEI:
15300 check_insn(ctx, ISA_MIPS2);
15301 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15302 gen_trap(ctx, op1, rs, -1, imm);
2e3eddb0 15303 break;
80e64a38
PMD
15304 case OPC_SIGRIE:
15305 check_insn(ctx, ISA_MIPS_R6);
15306 gen_reserved_instruction(ctx);
2e3eddb0 15307 break;
80e64a38
PMD
15308 case OPC_SYNCI:
15309 check_insn(ctx, ISA_MIPS_R2);
15310 /*
15311 * Break the TB to be able to sync copied instructions
15312 * immediately.
15313 */
15314 ctx->base.is_jmp = DISAS_STOP;
2e3eddb0 15315 break;
80e64a38
PMD
15316 case OPC_BPOSGE32: /* MIPS DSP branch */
15317#if defined(TARGET_MIPS64)
15318 case OPC_BPOSGE64:
15319#endif
15320 check_dsp(ctx);
15321 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
a44d6d14 15322 break;
80e64a38
PMD
15323#if defined(TARGET_MIPS64)
15324 case OPC_DAHI:
15325 check_insn(ctx, ISA_MIPS_R6);
15326 check_mips_64(ctx);
15327 if (rs != 0) {
15328 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15329 }
a44d6d14 15330 break;
80e64a38
PMD
15331 case OPC_DATI:
15332 check_insn(ctx, ISA_MIPS_R6);
15333 check_mips_64(ctx);
15334 if (rs != 0) {
15335 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15336 }
a44d6d14 15337 break;
80e64a38
PMD
15338#endif
15339 default: /* Invalid */
15340 MIPS_INVAL("regimm");
15341 gen_reserved_instruction(ctx);
a44d6d14
AM
15342 break;
15343 }
15344 break;
80e64a38
PMD
15345 case OPC_CP0:
15346 check_cp0_enabled(ctx);
15347 op1 = MASK_CP0(ctx->opcode);
15348 switch (op1) {
15349 case OPC_MFC0:
15350 case OPC_MTC0:
15351 case OPC_MFTR:
15352 case OPC_MTTR:
15353 case OPC_MFHC0:
15354 case OPC_MTHC0:
15355#if defined(TARGET_MIPS64)
15356 case OPC_DMFC0:
15357 case OPC_DMTC0:
15358#endif
15359#ifndef CONFIG_USER_ONLY
15360 gen_cp0(env, ctx, op1, rt, rd);
15361#endif /* !CONFIG_USER_ONLY */
7a387fff 15362 break;
c38a1d52
AR
15363 case OPC_C0:
15364 case OPC_C0_1:
15365 case OPC_C0_2:
15366 case OPC_C0_3:
15367 case OPC_C0_4:
15368 case OPC_C0_5:
15369 case OPC_C0_6:
15370 case OPC_C0_7:
15371 case OPC_C0_8:
15372 case OPC_C0_9:
15373 case OPC_C0_A:
15374 case OPC_C0_B:
15375 case OPC_C0_C:
15376 case OPC_C0_D:
15377 case OPC_C0_E:
15378 case OPC_C0_F:
f1aa6320 15379#ifndef CONFIG_USER_ONLY
932e71cd 15380 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15381#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15382 break;
15383 case OPC_MFMC0:
8706c382 15384#ifndef CONFIG_USER_ONLY
932e71cd 15385 {
099e5b4d 15386 uint32_t op2;
35fbce2c 15387 TCGv t0 = tcg_temp_new();
6c5c1e20 15388
0eaef5aa 15389 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15390 switch (op2) {
15391 case OPC_DMT:
9affc1c5 15392 check_cp0_mt(ctx);
9ed5726c 15393 gen_helper_dmt(t0);
35fbce2c 15394 gen_store_gpr(t0, rt);
6c5c1e20
TS
15395 break;
15396 case OPC_EMT:
9affc1c5 15397 check_cp0_mt(ctx);
9ed5726c 15398 gen_helper_emt(t0);
35fbce2c 15399 gen_store_gpr(t0, rt);
da80682b 15400 break;
6c5c1e20 15401 case OPC_DVPE:
9affc1c5 15402 check_cp0_mt(ctx);
895c2d04 15403 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15404 gen_store_gpr(t0, rt);
6c5c1e20
TS
15405 break;
15406 case OPC_EVPE:
9affc1c5 15407 check_cp0_mt(ctx);
895c2d04 15408 gen_helper_evpe(t0, cpu_env);
35fbce2c 15409 gen_store_gpr(t0, rt);
6c5c1e20 15410 break;
01bc435b 15411 case OPC_DVP:
2e211e0a 15412 check_insn(ctx, ISA_MIPS_R6);
01bc435b
YK
15413 if (ctx->vp) {
15414 gen_helper_dvp(t0, cpu_env);
15415 gen_store_gpr(t0, rt);
15416 }
15417 break;
15418 case OPC_EVP:
2e211e0a 15419 check_insn(ctx, ISA_MIPS_R6);
01bc435b
YK
15420 if (ctx->vp) {
15421 gen_helper_evp(t0, cpu_env);
15422 gen_store_gpr(t0, rt);
15423 }
15424 break;
6c5c1e20 15425 case OPC_DI:
7a47bae5 15426 check_insn(ctx, ISA_MIPS_R2);
867abc7e 15427 save_cpu_state(ctx, 1);
895c2d04 15428 gen_helper_di(t0, cpu_env);
35fbce2c 15429 gen_store_gpr(t0, rt);
7480515f
AM
15430 /*
15431 * Stop translation as we may have switched
15432 * the execution mode.
15433 */
eeb3bba8 15434 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
15435 break;
15436 case OPC_EI:
7a47bae5 15437 check_insn(ctx, ISA_MIPS_R2);
867abc7e 15438 save_cpu_state(ctx, 1);
895c2d04 15439 gen_helper_ei(t0, cpu_env);
35fbce2c 15440 gen_store_gpr(t0, rt);
7480515f
AM
15441 /*
15442 * DISAS_STOP isn't sufficient, we need to ensure we break
15443 * out of translated code to check for pending interrupts.
15444 */
eeb3bba8
EC
15445 gen_save_pc(ctx->base.pc_next + 4);
15446 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
15447 break;
15448 default: /* Invalid */
15449 MIPS_INVAL("mfmc0");
3a4ef3b7 15450 gen_reserved_instruction(ctx);
6c5c1e20
TS
15451 break;
15452 }
6c5c1e20 15453 tcg_temp_free(t0);
7a387fff 15454 }
0eaef5aa 15455#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15456 break;
7a387fff 15457 case OPC_RDPGPR:
7a47bae5 15458 check_insn(ctx, ISA_MIPS_R2);
be24bb4f 15459 gen_load_srsgpr(rt, rd);
ead9360e 15460 break;
7a387fff 15461 case OPC_WRPGPR:
7a47bae5 15462 check_insn(ctx, ISA_MIPS_R2);
be24bb4f 15463 gen_store_srsgpr(rt, rd);
38121543 15464 break;
6af0bf9c 15465 default:
923617a3 15466 MIPS_INVAL("cp0");
3a4ef3b7 15467 gen_reserved_instruction(ctx);
6af0bf9c
FB
15468 break;
15469 }
15470 break;
31837be3 15471 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
2e211e0a 15472 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15473 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
15474 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15475 } else {
15476 /* OPC_ADDI */
15477 /* Arithmetic with immediate opcode */
15478 gen_arith_imm(ctx, op, rt, rs, imm);
15479 }
15480 break;
324d9e32 15481 case OPC_ADDIU:
d75c135e 15482 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15483 break;
324d9e32
AJ
15484 case OPC_SLTI: /* Set on less than with immediate opcode */
15485 case OPC_SLTIU:
d75c135e 15486 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15487 break;
15488 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 15489 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
15490 case OPC_ORI:
15491 case OPC_XORI:
d75c135e 15492 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15493 break;
c2e19f3c
AM
15494 case OPC_J: /* Jump */
15495 case OPC_JAL:
7a387fff 15496 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 15497 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 15498 break;
31837be3
YK
15499 /* Branch */
15500 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
2e211e0a 15501 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3 15502 if (rt == 0) {
3a4ef3b7 15503 gen_reserved_instruction(ctx);
31837be3
YK
15504 break;
15505 }
15506 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
15507 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15508 } else {
15509 /* OPC_BLEZL */
b231c103 15510 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
15511 }
15512 break;
15513 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
2e211e0a 15514 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3 15515 if (rt == 0) {
3a4ef3b7 15516 gen_reserved_instruction(ctx);
31837be3
YK
15517 break;
15518 }
15519 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
15520 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15521 } else {
15522 /* OPC_BGTZL */
b231c103 15523 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
15524 }
15525 break;
15526 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
15527 if (rt == 0) {
15528 /* OPC_BLEZ */
b231c103 15529 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3 15530 } else {
2e211e0a 15531 check_insn(ctx, ISA_MIPS_R6);
31837be3
YK
15532 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
15533 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15534 }
15535 break;
15536 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
15537 if (rt == 0) {
15538 /* OPC_BGTZ */
b231c103 15539 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3 15540 } else {
2e211e0a 15541 check_insn(ctx, ISA_MIPS_R6);
31837be3
YK
15542 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
15543 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15544 }
15545 break;
15546 case OPC_BEQL:
15547 case OPC_BNEL:
d9224450 15548 check_insn(ctx, ISA_MIPS2);
2e211e0a 15549 check_insn_opc_removed(ctx, ISA_MIPS_R6);
d9224450 15550 /* Fallthrough */
31837be3
YK
15551 case OPC_BEQ:
15552 case OPC_BNE:
b231c103 15553 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 15554 break;
d9224450
MR
15555 case OPC_LL: /* Load and stores */
15556 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
15557 if (ctx->insn_flags & INSN_R5900) {
15558 check_insn_opc_user_only(ctx, INSN_R5900);
15559 }
d9224450
MR
15560 /* Fallthrough */
15561 case OPC_LWL:
fecd2646 15562 case OPC_LWR:
c2e19f3c
AM
15563 case OPC_LB:
15564 case OPC_LH:
15565 case OPC_LW:
15566 case OPC_LWPC:
15567 case OPC_LBU:
15568 case OPC_LHU:
d75c135e 15569 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15570 break;
fecd2646 15571 case OPC_SWL:
7a387fff 15572 case OPC_SWR:
c2e19f3c
AM
15573 case OPC_SB:
15574 case OPC_SH:
fecd2646 15575 case OPC_SW:
5c13fdfd 15576 gen_st(ctx, op, rt, rs, imm);
7a387fff 15577 break;
d66c7132 15578 case OPC_SC:
d9224450 15579 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
15580 if (ctx->insn_flags & INSN_R5900) {
15581 check_insn_opc_user_only(ctx, INSN_R5900);
15582 }
33a07fa2
LA
15583 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15584 break;
7a387fff 15585 case OPC_CACHE:
2e15497c 15586 check_cp0_enabled(ctx);
bbd5e4a2 15587 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
0d74a222
LA
15588 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15589 gen_cache_operation(ctx, rt, rs, imm);
15590 }
ead9360e 15591 /* Treat as NOP. */
34ae7b51 15592 break;
7a387fff 15593 case OPC_PREF:
2e176eaf
PMD
15594 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15595 /* Treat as NOP. */
6af0bf9c 15596 break;
4ad40f36 15597
923617a3 15598 /* Floating point (COP1). */
7a387fff
TS
15599 case OPC_LWC1:
15600 case OPC_LDC1:
15601 case OPC_SWC1:
15602 case OPC_SDC1:
5ab5c041 15603 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
15604 break;
15605
7a387fff 15606 case OPC_CP1:
5692c6e1
YK
15607 op1 = MASK_CP1(ctx->opcode);
15608
15609 switch (op1) {
15610 case OPC_MFHC1:
15611 case OPC_MTHC1:
5e755519 15612 check_cp1_enabled(ctx);
7a47bae5 15613 check_insn(ctx, ISA_MIPS_R2);
146dd620 15614 /* fall through */
5692c6e1
YK
15615 case OPC_MFC1:
15616 case OPC_CFC1:
15617 case OPC_MTC1:
15618 case OPC_CTC1:
15619 check_cp1_enabled(ctx);
15620 gen_cp1(ctx, op1, rt, rd);
15621 break;
d26bc211 15622#if defined(TARGET_MIPS64)
5692c6e1
YK
15623 case OPC_DMFC1:
15624 case OPC_DMTC1:
15625 check_cp1_enabled(ctx);
15626 check_insn(ctx, ISA_MIPS3);
d9224450 15627 check_mips_64(ctx);
5692c6e1
YK
15628 gen_cp1(ctx, op1, rt, rd);
15629 break;
e189e748 15630#endif
5692c6e1
YK
15631 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15632 check_cp1_enabled(ctx);
2e211e0a 15633 if (ctx->insn_flags & ISA_MIPS_R6) {
5692c6e1 15634 /* OPC_BC1EQZ */
31837be3 15635 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 15636 rt, imm << 2, 4);
5692c6e1
YK
15637 } else {
15638 /* OPC_BC1ANY2 */
b8aa4598 15639 check_cop1x(ctx);
d75c135e 15640 check_insn(ctx, ASE_MIPS3D);
d75c135e 15641 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 15642 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
15643 }
15644 break;
15645 case OPC_BC1NEZ:
15646 check_cp1_enabled(ctx);
2e211e0a 15647 check_insn(ctx, ISA_MIPS_R6);
5692c6e1 15648 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 15649 rt, imm << 2, 4);
5692c6e1
YK
15650 break;
15651 case OPC_BC1ANY4:
15652 check_cp1_enabled(ctx);
2e211e0a 15653 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5692c6e1
YK
15654 check_cop1x(ctx);
15655 check_insn(ctx, ASE_MIPS3D);
15656 /* fall through */
15657 case OPC_BC1:
15658 check_cp1_enabled(ctx);
2e211e0a 15659 check_insn_opc_removed(ctx, ISA_MIPS_R6);
5692c6e1
YK
15660 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15661 (rt >> 2) & 0x7, imm << 2);
15662 break;
15663 case OPC_PS_FMT:
e29c9628 15664 check_ps(ctx);
b6f3b233 15665 /* fall through */
5692c6e1
YK
15666 case OPC_S_FMT:
15667 case OPC_D_FMT:
15668 check_cp1_enabled(ctx);
15669 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15670 (imm >> 8) & 0x7);
15671 break;
15672 case OPC_W_FMT:
15673 case OPC_L_FMT:
15674 {
15675 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15676 check_cp1_enabled(ctx);
2e211e0a 15677 if (ctx->insn_flags & ISA_MIPS_R6) {
5692c6e1
YK
15678 switch (r6_op) {
15679 case R6_OPC_CMP_AF_S:
15680 case R6_OPC_CMP_UN_S:
15681 case R6_OPC_CMP_EQ_S:
15682 case R6_OPC_CMP_UEQ_S:
15683 case R6_OPC_CMP_LT_S:
15684 case R6_OPC_CMP_ULT_S:
15685 case R6_OPC_CMP_LE_S:
15686 case R6_OPC_CMP_ULE_S:
15687 case R6_OPC_CMP_SAF_S:
15688 case R6_OPC_CMP_SUN_S:
15689 case R6_OPC_CMP_SEQ_S:
15690 case R6_OPC_CMP_SEUQ_S:
15691 case R6_OPC_CMP_SLT_S:
15692 case R6_OPC_CMP_SULT_S:
15693 case R6_OPC_CMP_SLE_S:
15694 case R6_OPC_CMP_SULE_S:
15695 case R6_OPC_CMP_OR_S:
15696 case R6_OPC_CMP_UNE_S:
15697 case R6_OPC_CMP_NE_S:
15698 case R6_OPC_CMP_SOR_S:
15699 case R6_OPC_CMP_SUNE_S:
15700 case R6_OPC_CMP_SNE_S:
15701 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15702 break;
15703 case R6_OPC_CMP_AF_D:
15704 case R6_OPC_CMP_UN_D:
15705 case R6_OPC_CMP_EQ_D:
15706 case R6_OPC_CMP_UEQ_D:
15707 case R6_OPC_CMP_LT_D:
15708 case R6_OPC_CMP_ULT_D:
15709 case R6_OPC_CMP_LE_D:
15710 case R6_OPC_CMP_ULE_D:
15711 case R6_OPC_CMP_SAF_D:
15712 case R6_OPC_CMP_SUN_D:
15713 case R6_OPC_CMP_SEQ_D:
15714 case R6_OPC_CMP_SEUQ_D:
15715 case R6_OPC_CMP_SLT_D:
15716 case R6_OPC_CMP_SULT_D:
15717 case R6_OPC_CMP_SLE_D:
15718 case R6_OPC_CMP_SULE_D:
15719 case R6_OPC_CMP_OR_D:
15720 case R6_OPC_CMP_UNE_D:
15721 case R6_OPC_CMP_NE_D:
15722 case R6_OPC_CMP_SOR_D:
15723 case R6_OPC_CMP_SUNE_D:
15724 case R6_OPC_CMP_SNE_D:
15725 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15726 break;
15727 default:
d2bfa6e6
MR
15728 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15729 rt, rd, sa, (imm >> 8) & 0x7);
15730
5692c6e1 15731 break;
3f493883 15732 }
5692c6e1
YK
15733 } else {
15734 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15735 (imm >> 8) & 0x7);
36d23958 15736 }
5692c6e1
YK
15737 break;
15738 }
5692c6e1
YK
15739 default:
15740 MIPS_INVAL("cp1");
3a4ef3b7 15741 gen_reserved_instruction(ctx);
5692c6e1 15742 break;
6ea83fed 15743 }
4ad40f36
FB
15744 break;
15745
31837be3
YK
15746 /* Compact branches [R6] and COP2 [non-R6] */
15747 case OPC_BC: /* OPC_LWC2 */
15748 case OPC_BALC: /* OPC_SWC2 */
2e211e0a 15749 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15750 /* OPC_BC, OPC_BALC */
15751 gen_compute_compact_branch(ctx, op, 0, 0,
15752 sextract32(ctx->opcode << 2, 0, 28));
e10a0ca1
JY
15753 } else if (ctx->insn_flags & ASE_LEXT) {
15754 gen_loongson_lswc2(ctx, rt, rs, rd);
31837be3
YK
15755 } else {
15756 /* OPC_LWC2, OPC_SWC2 */
15757 /* COP2: Not implemented. */
15758 generate_exception_err(ctx, EXCP_CpU, 2);
15759 }
15760 break;
15761 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15762 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
2e211e0a 15763 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15764 if (rs != 0) {
15765 /* OPC_BEQZC, OPC_BNEZC */
15766 gen_compute_compact_branch(ctx, op, rs, 0,
15767 sextract32(ctx->opcode << 2, 0, 23));
15768 } else {
15769 /* OPC_JIC, OPC_JIALC */
15770 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15771 }
90e22a57
JY
15772 } else if (ctx->insn_flags & ASE_LEXT) {
15773 gen_loongson_lsdc2(ctx, rt, rs, rd);
31837be3
YK
15774 } else {
15775 /* OPC_LWC2, OPC_SWC2 */
15776 /* COP2: Not implemented. */
15777 generate_exception_err(ctx, EXCP_CpU, 2);
15778 }
4ad40f36 15779 break;
bd277fa1 15780 case OPC_CP2:
8e2d5831 15781 check_insn(ctx, ASE_LMMI);
bd277fa1
RH
15782 /* Note that these instructions use different fields. */
15783 gen_loongson_multimedia(ctx, sa, rd, rt);
15784 break;
4ad40f36 15785
7a387fff 15786 case OPC_CP3:
5ab5c041 15787 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15788 check_cp1_enabled(ctx);
36d23958
TS
15789 op1 = MASK_CP3(ctx->opcode);
15790 switch (op1) {
d9224450
MR
15791 case OPC_LUXC1:
15792 case OPC_SUXC1:
7a47bae5 15793 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
d9224450 15794 /* Fallthrough */
5a5012ec
TS
15795 case OPC_LWXC1:
15796 case OPC_LDXC1:
5a5012ec
TS
15797 case OPC_SWXC1:
15798 case OPC_SDXC1:
7a47bae5 15799 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
93b12ccc 15800 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15801 break;
e0c84da7 15802 case OPC_PREFX:
7a47bae5 15803 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
ead9360e 15804 /* Treat as NOP. */
e0c84da7 15805 break;
5a5012ec 15806 case OPC_ALNV_PS:
7a47bae5 15807 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
d9224450 15808 /* Fallthrough */
5a5012ec
TS
15809 case OPC_MADD_S:
15810 case OPC_MADD_D:
15811 case OPC_MADD_PS:
15812 case OPC_MSUB_S:
15813 case OPC_MSUB_D:
15814 case OPC_MSUB_PS:
15815 case OPC_NMADD_S:
15816 case OPC_NMADD_D:
15817 case OPC_NMADD_PS:
15818 case OPC_NMSUB_S:
15819 case OPC_NMSUB_D:
15820 case OPC_NMSUB_PS:
7a47bae5 15821 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
5a5012ec
TS
15822 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15823 break;
36d23958 15824 default:
923617a3 15825 MIPS_INVAL("cp3");
3a4ef3b7 15826 gen_reserved_instruction(ctx);
36d23958
TS
15827 break;
15828 }
15829 } else {
e397ee33 15830 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15831 }
4ad40f36
FB
15832 break;
15833
d26bc211 15834#if defined(TARGET_MIPS64)
7a387fff 15835 /* MIPS64 opcodes */
96631327 15836 case OPC_LLD:
55fc7a69
FN
15837 if (ctx->insn_flags & INSN_R5900) {
15838 check_insn_opc_user_only(ctx, INSN_R5900);
15839 }
96631327 15840 /* fall through */
c2e19f3c
AM
15841 case OPC_LDL:
15842 case OPC_LDR:
fecd2646 15843 case OPC_LWU:
7a387fff 15844 case OPC_LD:
d75c135e 15845 check_insn(ctx, ISA_MIPS3);
5c13fdfd 15846 check_mips_64(ctx);
d75c135e 15847 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 15848 break;
c2e19f3c
AM
15849 case OPC_SDL:
15850 case OPC_SDR:
7a387fff 15851 case OPC_SD:
d75c135e 15852 check_insn(ctx, ISA_MIPS3);
e189e748 15853 check_mips_64(ctx);
5c13fdfd 15854 gen_st(ctx, op, rt, rs, imm);
7a387fff 15855 break;
d66c7132 15856 case OPC_SCD:
d75c135e 15857 check_insn(ctx, ISA_MIPS3);
55fc7a69
FN
15858 if (ctx->insn_flags & INSN_R5900) {
15859 check_insn_opc_user_only(ctx, INSN_R5900);
15860 }
d66c7132 15861 check_mips_64(ctx);
33a07fa2 15862 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
d66c7132 15863 break;
31837be3 15864 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
2e211e0a 15865 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15866 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15867 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15868 } else {
15869 /* OPC_DADDI */
15870 check_insn(ctx, ISA_MIPS3);
15871 check_mips_64(ctx);
15872 gen_arith_imm(ctx, op, rt, rs, imm);
15873 }
15874 break;
324d9e32 15875 case OPC_DADDIU:
d75c135e 15876 check_insn(ctx, ISA_MIPS3);
e189e748 15877 check_mips_64(ctx);
d75c135e 15878 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15879 break;
31837be3
YK
15880#else
15881 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
2e211e0a 15882 if (ctx->insn_flags & ISA_MIPS_R6) {
31837be3
YK
15883 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15884 } else {
15885 MIPS_INVAL("major opcode");
3a4ef3b7 15886 gen_reserved_instruction(ctx);
31837be3
YK
15887 }
15888 break;
6af0bf9c 15889#endif
d4ea6acd 15890 case OPC_DAUI: /* OPC_JALX */
2e211e0a 15891 if (ctx->insn_flags & ISA_MIPS_R6) {
d4ea6acd
LA
15892#if defined(TARGET_MIPS64)
15893 /* OPC_DAUI */
15894 check_mips_64(ctx);
db77d852
LA
15895 if (rs == 0) {
15896 generate_exception(ctx, EXCP_RI);
15897 } else if (rt != 0) {
d4ea6acd
LA
15898 TCGv t0 = tcg_temp_new();
15899 gen_load_gpr(t0, rs);
15900 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15901 tcg_temp_free(t0);
15902 }
d4ea6acd 15903#else
3a4ef3b7 15904 gen_reserved_instruction(ctx);
d4ea6acd
LA
15905 MIPS_INVAL("major opcode");
15906#endif
15907 } else {
15908 /* OPC_JALX */
15909 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15910 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 15911 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 15912 }
364d4831 15913 break;
aaaa82a9
PMD
15914 case OPC_MDMX:
15915 /* MDMX: Not implemented. */
d4ea6acd
LA
15916 break;
15917 case OPC_PCREL:
2e211e0a 15918 check_insn(ctx, ISA_MIPS_R6);
eeb3bba8 15919 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 15920 break;
6af0bf9c 15921 default: /* Invalid */
923617a3 15922 MIPS_INVAL("major opcode");
311edee7 15923 return false;
6af0bf9c 15924 }
311edee7
PMD
15925 return true;
15926}
15927
15928static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15929{
15930 /* make sure instructions are on a word boundary */
15931 if (ctx->base.pc_next & 0x3) {
15932 env->CP0_BadVAddr = ctx->base.pc_next;
15933 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15934 return;
15935 }
15936
15937 /* Handle blikely not taken case */
15938 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15939 TCGLabel *l1 = gen_new_label();
15940
15941 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15942 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15943 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15944 gen_set_label(l1);
15945 }
15946
96e5b4c7
PMD
15947 /* Transition to the auto-generated decoder. */
15948
4919f69c
PMD
15949 /* Vendor specific extensions */
15950 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15951 return;
15952 }
9d005392
PMD
15953 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15954 return;
15955 }
4919f69c 15956
96e5b4c7
PMD
15957 /* ISA extensions */
15958 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15959 return;
15960 }
15961
3f7a9278
PMD
15962 /* ISA (from latest to oldest) */
15963 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15964 return;
15965 }
15966
311edee7
PMD
15967 if (decode_opc_legacy(env, ctx)) {
15968 return;
15969 }
15970
15971 gen_reserved_instruction(ctx);
6af0bf9c
FB
15972}
15973
18f440ed 15974static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 15975{
18f440ed 15976 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 15977 CPUMIPSState *env = cs->env_ptr;
12be9258 15978
18f440ed 15979 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
15980 ctx->saved_pc = -1;
15981 ctx->insn_flags = env->insn_flags;
0cfd392d 15982 ctx->CP0_Config0 = env->CP0_Config0;
12be9258 15983 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 15984 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
15985 ctx->CP0_Config3 = env->CP0_Config3;
15986 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
15987 ctx->btarget = 0;
15988 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15989 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15990 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15991 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15992 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15993 ctx->PAMask = env->PAMask;
15994 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15995 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15996 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15997 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15998 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 15999 /* Restore delay slot state from the tb context. */
12be9258
EC
16000 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
16001 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16002 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 16003 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
16004 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16005 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16006 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16007 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
feafe82c 16008 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
99029be1 16009 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
12be9258 16010 restore_cpu_state(env, ctx);
932e71cd 16011#ifdef CONFIG_USER_ONLY
12be9258 16012 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 16013#else
12be9258 16014 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 16015#endif
2e211e0a 16016 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
8a805609 16017 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
190ce7fb 16018
18f440ed
EC
16019 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16020 ctx->hflags);
16021}
12be9258 16022
18f440ed
EC
16023static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16024{
16025}
b933066a 16026
18f440ed
EC
16027static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16028{
16029 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 16030
18f440ed
EC
16031 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16032 ctx->btarget);
16033}
31837be3 16034
18f440ed
EC
16035static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16036{
16037 CPUMIPSState *env = cs->env_ptr;
16038 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16039 int insn_bytes;
16040 int is_slot;
4ad40f36 16041
18f440ed 16042 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4 16043 if (ctx->insn_flags & ISA_NANOMIPS32) {
0ab8e33a 16044 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
3f178b8d 16045 insn_bytes = decode_isa_nanomips(env, ctx);
c533c0f4 16046 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
0ab8e33a 16047 ctx->opcode = translator_ldl(env, ctx->base.pc_next);
18f440ed
EC
16048 insn_bytes = 4;
16049 decode_opc(env, ctx);
16050 } else if (ctx->insn_flags & ASE_MICROMIPS) {
0ab8e33a 16051 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
bf52c45a 16052 insn_bytes = decode_isa_micromips(env, ctx);
18f440ed 16053 } else if (ctx->insn_flags & ASE_MIPS16) {
0ab8e33a 16054 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
3230bad9 16055 insn_bytes = decode_ase_mips16e(env, ctx);
18f440ed 16056 } else {
3a4ef3b7 16057 gen_reserved_instruction(ctx);
18f440ed
EC
16058 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16059 return;
16060 }
faf7aaa9 16061
18f440ed
EC
16062 if (ctx->hflags & MIPS_HFLAG_BMASK) {
16063 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16064 MIPS_HFLAG_FBNSLOT))) {
7480515f
AM
16065 /*
16066 * Force to generate branch as there is neither delay nor
16067 * forbidden slot.
16068 */
18f440ed
EC
16069 is_slot = 1;
16070 }
16071 if ((ctx->hflags & MIPS_HFLAG_M16) &&
16072 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
7480515f
AM
16073 /*
16074 * Force to generate branch as microMIPS R6 doesn't restrict
16075 * branches in the forbidden slot.
16076 */
18f440ed 16077 is_slot = 1;
eeb3bba8 16078 }
18f440ed
EC
16079 }
16080 if (is_slot) {
16081 gen_branch(ctx, insn_bytes);
16082 }
16083 ctx->base.pc_next += insn_bytes;
1b530a6d 16084
18f440ed
EC
16085 if (ctx->base.is_jmp != DISAS_NEXT) {
16086 return;
6af0bf9c 16087 }
7480515f
AM
16088 /*
16089 * Execute a branch and its delay slot as a single instruction.
16090 * This is what GDB expects and is consistent with what the
16091 * hardware does (e.g. if a delay slot instruction faults, the
16092 * reported PC is the PC of the branch).
16093 */
18f440ed
EC
16094 if (ctx->base.singlestep_enabled &&
16095 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
16096 ctx->base.is_jmp = DISAS_TOO_MANY;
16097 }
16098 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
16099 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 16100 }
18f440ed
EC
16101}
16102
16103static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16104{
16105 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16106
12be9258
EC
16107 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
16108 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 16109 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 16110 } else {
12be9258 16111 switch (ctx->base.is_jmp) {
b28425ba 16112 case DISAS_STOP:
12be9258 16113 gen_save_pc(ctx->base.pc_next);
cd314a7d 16114 tcg_gen_lookup_and_goto_ptr();
df1561e2 16115 break;
b28425ba 16116 case DISAS_NEXT:
18f440ed 16117 case DISAS_TOO_MANY:
12be9258
EC
16118 save_cpu_state(ctx, 0);
16119 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 16120 break;
b28425ba 16121 case DISAS_EXIT:
07ea28b4 16122 tcg_gen_exit_tb(NULL, 0);
16c00cb2 16123 break;
b28425ba 16124 case DISAS_NORETURN:
5a5012ec 16125 break;
18f440ed
EC
16126 default:
16127 g_assert_not_reached();
6958549d 16128 }
6af0bf9c 16129 }
18f440ed
EC
16130}
16131
16132static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16133{
16134 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16135 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16136}
16137
16138static const TranslatorOps mips_tr_ops = {
16139 .init_disas_context = mips_tr_init_disas_context,
16140 .tb_start = mips_tr_tb_start,
16141 .insn_start = mips_tr_insn_start,
18f440ed
EC
16142 .translate_insn = mips_tr_translate_insn,
16143 .tb_stop = mips_tr_tb_stop,
16144 .disas_log = mips_tr_disas_log,
16145};
16146
8b86d6d2 16147void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
18f440ed
EC
16148{
16149 DisasContext ctx;
16150
8b86d6d2 16151 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
6af0bf9c
FB
16152}
16153
959c5da2
PMD
16154void mips_tcg_init(void)
16155{
16156 int i;
16157
16158 cpu_gpr[0] = NULL;
16159 for (i = 1; i < 32; i++)
16160 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16161 offsetof(CPUMIPSState,
16162 active_tc.gpr[i]),
16163 regnames[i]);
cefd68f6
PMD
16164#if defined(TARGET_MIPS64)
16165 cpu_gpr_hi[0] = NULL;
16166
16167 for (unsigned i = 1; i < 32; i++) {
b5b63d43
PMD
16168 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16169
cefd68f6
PMD
16170 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16171 offsetof(CPUMIPSState,
16172 active_tc.gpr_hi[i]),
b5b63d43 16173 rname);
cefd68f6
PMD
16174 }
16175#endif /* !TARGET_MIPS64 */
959c5da2
PMD
16176 for (i = 0; i < 32; i++) {
16177 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
863f264d 16178
959c5da2
PMD
16179 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16180 }
16181 msa_translate_init();
e1ccc054 16182 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 16183 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 16184 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 16185 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 16186 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 16187 regnames_HI[i]);
e1ccc054 16188 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 16189 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 16190 regnames_LO[i]);
4b2eb8d2 16191 }
e1ccc054 16192 cpu_dspctrl = tcg_global_mem_new(cpu_env,
71375b59
AM
16193 offsetof(CPUMIPSState,
16194 active_tc.DSPControl),
4b2eb8d2 16195 "DSPControl");
e1ccc054 16196 bcond = tcg_global_mem_new(cpu_env,
7db13fae 16197 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 16198 btarget = tcg_global_mem_new(cpu_env,
7db13fae 16199 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 16200 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 16201 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 16202
e1ccc054 16203 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 16204 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 16205 "fcr0");
e1ccc054 16206 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 16207 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 16208 "fcr31");
33a07fa2
LA
16209 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16210 "lladdr");
16211 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16212 "llval");
a168a796 16213
fe35ea94
PMD
16214 if (TARGET_LONG_BITS == 32) {
16215 mxu_translate_init();
eb5559f6 16216 }
39454628
TS
16217}
16218
bad729e2
RH
16219void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16220 target_ulong *data)
d2856f1a 16221{
bad729e2 16222 env->active_tc.PC = data[0];
d2856f1a 16223 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 16224 env->hflags |= data[1];
4636401d
AJ
16225 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16226 case MIPS_HFLAG_BR:
16227 break;
16228 case MIPS_HFLAG_BC:
16229 case MIPS_HFLAG_BL:
16230 case MIPS_HFLAG_B:
bad729e2 16231 env->btarget = data[2];
4636401d
AJ
16232 break;
16233 }
d2856f1a 16234}