]> Git Repo - qemu.git/blame - target-mips/translate.c
target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA
[qemu.git] / target-mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 emulation for qemu: main translation routines.
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
76cad711 25#include "disas/disas.h"
57fec1fe 26#include "tcg-op.h"
f08b6170 27#include "exec/cpu_ldst.h"
6af0bf9c 28
2ef6175a
RH
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
0a2672b7 31#include "sysemu/kvm.h"
a7812ae4 32
a7e30d84
LV
33#include "trace-tcg.h"
34
35
fb7729e2 36#define MIPS_DEBUG_DISAS 0
c570fd16 37//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 38
7a387fff
TS
39/* MIPS major opcodes */
40#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
41
42enum {
43 /* indirect opcode tables */
7a387fff
TS
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 52 /* arithmetic with immediate */
7a387fff
TS
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
324d9e32 57 /* logic with immediate */
7a387fff
TS
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
324d9e32 62 /* arithmetic with immediate */
7a387fff
TS
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
e37e863f 65 /* Jump and branches */
7a387fff
TS
66 OPC_J = (0x02 << 26),
67 OPC_JAL = (0x03 << 26),
620e48f6 68 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
77 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
d4ea6acd 78 OPC_DAUI = (0x1D << 26),
620e48f6 79 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 80 /* Load and stores */
7a387fff
TS
81 OPC_LDL = (0x1A << 26),
82 OPC_LDR = (0x1B << 26),
83 OPC_LB = (0x20 << 26),
84 OPC_LH = (0x21 << 26),
85 OPC_LWL = (0x22 << 26),
86 OPC_LW = (0x23 << 26),
364d4831 87 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
88 OPC_LBU = (0x24 << 26),
89 OPC_LHU = (0x25 << 26),
90 OPC_LWR = (0x26 << 26),
91 OPC_LWU = (0x27 << 26),
92 OPC_SB = (0x28 << 26),
93 OPC_SH = (0x29 << 26),
94 OPC_SWL = (0x2A << 26),
95 OPC_SW = (0x2B << 26),
96 OPC_SDL = (0x2C << 26),
97 OPC_SDR = (0x2D << 26),
98 OPC_SWR = (0x2E << 26),
99 OPC_LL = (0x30 << 26),
100 OPC_LLD = (0x34 << 26),
101 OPC_LD = (0x37 << 26),
364d4831 102 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
103 OPC_SC = (0x38 << 26),
104 OPC_SCD = (0x3C << 26),
105 OPC_SD = (0x3F << 26),
e37e863f 106 /* Floating point load/store */
7a387fff
TS
107 OPC_LWC1 = (0x31 << 26),
108 OPC_LWC2 = (0x32 << 26),
109 OPC_LDC1 = (0x35 << 26),
110 OPC_LDC2 = (0x36 << 26),
111 OPC_SWC1 = (0x39 << 26),
112 OPC_SWC2 = (0x3A << 26),
113 OPC_SDC1 = (0x3D << 26),
114 OPC_SDC2 = (0x3E << 26),
31837be3
YK
115 /* Compact Branches */
116 OPC_BLEZALC = (0x06 << 26),
117 OPC_BGEZALC = (0x06 << 26),
118 OPC_BGEUC = (0x06 << 26),
119 OPC_BGTZALC = (0x07 << 26),
120 OPC_BLTZALC = (0x07 << 26),
121 OPC_BLTUC = (0x07 << 26),
122 OPC_BOVC = (0x08 << 26),
123 OPC_BEQZALC = (0x08 << 26),
124 OPC_BEQC = (0x08 << 26),
125 OPC_BLEZC = (0x16 << 26),
126 OPC_BGEZC = (0x16 << 26),
127 OPC_BGEC = (0x16 << 26),
128 OPC_BGTZC = (0x17 << 26),
129 OPC_BLTZC = (0x17 << 26),
130 OPC_BLTC = (0x17 << 26),
131 OPC_BNVC = (0x18 << 26),
132 OPC_BNEZALC = (0x18 << 26),
133 OPC_BNEC = (0x18 << 26),
134 OPC_BC = (0x32 << 26),
135 OPC_BEQZC = (0x36 << 26),
136 OPC_JIC = (0x36 << 26),
137 OPC_BALC = (0x3A << 26),
138 OPC_BNEZC = (0x3E << 26),
139 OPC_JIALC = (0x3E << 26),
7a387fff
TS
140 /* MDMX ASE specific */
141 OPC_MDMX = (0x1E << 26),
e37e863f 142 /* Cache and prefetch */
7a387fff
TS
143 OPC_CACHE = (0x2F << 26),
144 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
145 /* PC-relative address computation / loads */
146 OPC_PCREL = (0x3B << 26),
147};
148
149/* PC-relative address computation / loads */
150#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152enum {
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
155 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
156 OPC_LWUPC = OPC_PCREL | (2 << 19),
157
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
160 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
161
162 /* Other */
163 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
164};
165
166/* MIPS special opcodes */
7a387fff
TS
167#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
168
e37e863f
FB
169enum {
170 /* Shifts */
7a387fff 171 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 176 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
177 OPC_SRA = 0x03 | OPC_SPECIAL,
178 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 179 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 180 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
181 OPC_SRAV = 0x07 | OPC_SPECIAL,
182 OPC_DSLLV = 0x14 | OPC_SPECIAL,
183 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 184 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
185 OPC_DSRAV = 0x17 | OPC_SPECIAL,
186 OPC_DSLL = 0x38 | OPC_SPECIAL,
187 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 188 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
189 OPC_DSRA = 0x3B | OPC_SPECIAL,
190 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
191 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 192 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 193 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 194 /* Multiplication / division */
7a387fff
TS
195 OPC_MULT = 0x18 | OPC_SPECIAL,
196 OPC_MULTU = 0x19 | OPC_SPECIAL,
197 OPC_DIV = 0x1A | OPC_SPECIAL,
198 OPC_DIVU = 0x1B | OPC_SPECIAL,
199 OPC_DMULT = 0x1C | OPC_SPECIAL,
200 OPC_DMULTU = 0x1D | OPC_SPECIAL,
201 OPC_DDIV = 0x1E | OPC_SPECIAL,
202 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 203
e37e863f 204 /* 2 registers arithmetic / logic */
7a387fff
TS
205 OPC_ADD = 0x20 | OPC_SPECIAL,
206 OPC_ADDU = 0x21 | OPC_SPECIAL,
207 OPC_SUB = 0x22 | OPC_SPECIAL,
208 OPC_SUBU = 0x23 | OPC_SPECIAL,
209 OPC_AND = 0x24 | OPC_SPECIAL,
210 OPC_OR = 0x25 | OPC_SPECIAL,
211 OPC_XOR = 0x26 | OPC_SPECIAL,
212 OPC_NOR = 0x27 | OPC_SPECIAL,
213 OPC_SLT = 0x2A | OPC_SPECIAL,
214 OPC_SLTU = 0x2B | OPC_SPECIAL,
215 OPC_DADD = 0x2C | OPC_SPECIAL,
216 OPC_DADDU = 0x2D | OPC_SPECIAL,
217 OPC_DSUB = 0x2E | OPC_SPECIAL,
218 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 219 /* Jumps */
7a387fff
TS
220 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
221 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 222 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 223 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 224 /* Traps */
7a387fff
TS
225 OPC_TGE = 0x30 | OPC_SPECIAL,
226 OPC_TGEU = 0x31 | OPC_SPECIAL,
227 OPC_TLT = 0x32 | OPC_SPECIAL,
228 OPC_TLTU = 0x33 | OPC_SPECIAL,
229 OPC_TEQ = 0x34 | OPC_SPECIAL,
230 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 231 /* HI / LO registers load & stores */
7a387fff
TS
232 OPC_MFHI = 0x10 | OPC_SPECIAL,
233 OPC_MTHI = 0x11 | OPC_SPECIAL,
234 OPC_MFLO = 0x12 | OPC_SPECIAL,
235 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 236 /* Conditional moves */
7a387fff
TS
237 OPC_MOVZ = 0x0A | OPC_SPECIAL,
238 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 239
b691d9d2
LA
240 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
241 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
242
7a387fff 243 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
244
245 /* Special */
a0d700e4 246 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
247 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
248 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 249 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
250 OPC_SYNC = 0x0F | OPC_SPECIAL,
251
7a387fff
TS
252 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
253 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
254 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
255 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
256};
257
b42ee5e1
LA
258/* R6 Multiply and Divide instructions have the same Opcode
259 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261
262enum {
263 R6_OPC_MUL = OPC_MULT | (2 << 6),
264 R6_OPC_MUH = OPC_MULT | (3 << 6),
265 R6_OPC_MULU = OPC_MULTU | (2 << 6),
266 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
267 R6_OPC_DIV = OPC_DIV | (2 << 6),
268 R6_OPC_MOD = OPC_DIV | (3 << 6),
269 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
270 R6_OPC_MODU = OPC_DIVU | (3 << 6),
271
272 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
273 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
274 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
275 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
276 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
277 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
278 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
279 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
280
281 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
282 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
283 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
284 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
285 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
286
287 OPC_LSA = 0x05 | OPC_SPECIAL,
288 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
289};
290
e9c71dd1
TS
291/* Multiplication variants of the vr54xx. */
292#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293
294enum {
295 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
296 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
297 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
298 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
299 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
300 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
302 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
303 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
304 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
305 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
306 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
307 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
308 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
309};
310
7a387fff
TS
311/* REGIMM (rt field) opcodes */
312#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313
314enum {
315 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
316 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
317 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
318 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
319 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 320 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
321 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
322 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 323 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
324 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
325 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
326 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
327 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
328 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
329 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
330 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
331 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
332
333 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
334 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
335};
336
7a387fff
TS
337/* Special2 opcodes */
338#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
339
e37e863f 340enum {
7a387fff
TS
341 /* Multiply & xxx operations */
342 OPC_MADD = 0x00 | OPC_SPECIAL2,
343 OPC_MADDU = 0x01 | OPC_SPECIAL2,
344 OPC_MUL = 0x02 | OPC_SPECIAL2,
345 OPC_MSUB = 0x04 | OPC_SPECIAL2,
346 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
347 /* Loongson 2F */
348 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
349 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
350 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
351 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
352 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
353 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
354 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
355 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
356 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
357 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
358 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
359 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 360 /* Misc */
7a387fff
TS
361 OPC_CLZ = 0x20 | OPC_SPECIAL2,
362 OPC_CLO = 0x21 | OPC_SPECIAL2,
363 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
364 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 365 /* Special */
7a387fff
TS
366 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
367};
368
369/* Special3 opcodes */
370#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
371
372enum {
373 OPC_EXT = 0x00 | OPC_SPECIAL3,
374 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
375 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
376 OPC_DEXT = 0x03 | OPC_SPECIAL3,
377 OPC_INS = 0x04 | OPC_SPECIAL3,
378 OPC_DINSM = 0x05 | OPC_SPECIAL3,
379 OPC_DINSU = 0x06 | OPC_SPECIAL3,
380 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
381 OPC_FORK = 0x08 | OPC_SPECIAL3,
382 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
383 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
384 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
385 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
386
387 /* Loongson 2E */
388 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
389 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
390 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
391 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
392 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
393 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
394 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
395 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
396 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
397 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
398 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
399 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
400
401 /* MIPS DSP Load */
402 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
403 /* MIPS DSP Arithmetic */
404 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 405 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 406 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 407 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
408 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
409 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
410 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 411 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
412 /* MIPS DSP GPR-Based Shift Sub-class */
413 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 414 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
415 /* MIPS DSP Multiply Sub-class insns */
416 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
417 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
418 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 419 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
420 /* DSP Bit/Manipulation Sub-class */
421 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 422 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 423 /* MIPS DSP Append Sub-class */
26690560 424 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 425 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
426 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
427 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 428 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
429
430 /* R6 */
bf7910c6
LA
431 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
432 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
433 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
434 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
435 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
436 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
437};
438
7a387fff
TS
439/* BSHFL opcodes */
440#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
441
e37e863f 442enum {
15eacb9b
YK
443 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
444 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
445 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
446 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
447 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
448 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
449};
450
7a387fff
TS
451/* DBSHFL opcodes */
452#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
453
e37e863f 454enum {
15eacb9b
YK
455 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
456 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
457 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
458 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
459 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
460};
461
e45a93e2
JL
462/* MIPS DSP REGIMM opcodes */
463enum {
464 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 465 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
466};
467
9b1a1d68
JL
468#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
469/* MIPS DSP Load */
470enum {
471 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
472 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
473 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 474 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
475};
476
461c08df
JL
477#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
478enum {
479 /* MIPS DSP Arithmetic Sub-class */
480 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
485 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
486 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
492 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
493 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
494 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
495 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
497 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
498 /* MIPS DSP Multiply Sub-class insns */
499 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
503 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
504 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
505};
506
507#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
508#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509enum {
510 /* MIPS DSP Arithmetic Sub-class */
511 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
515 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
521 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
522 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
523 /* MIPS DSP Multiply Sub-class insns */
524 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
526 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
527 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
528};
529
530#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531enum {
532 /* MIPS DSP Arithmetic Sub-class */
533 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
546 /* DSP Bit/Manipulation Sub-class */
547 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
550 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
551 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
552};
553
554#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555enum {
556 /* MIPS DSP Arithmetic Sub-class */
557 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
564 /* DSP Compare-Pick Sub-class */
565 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 580};
a22260ae 581
77c5fa8b
JL
582#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583enum {
584 /* MIPS DSP GPR-Based Shift Sub-class */
585 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
607};
461c08df 608
a22260ae
JL
609#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
610enum {
611 /* MIPS DSP Multiply Sub-class insns */
612 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
628 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
634};
635
1cb6686c
JL
636#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637enum {
638 /* DSP Bit/Manipulation Sub-class */
639 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
640};
641
26690560
JL
642#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
643enum {
df6126a7 644 /* MIPS DSP Append Sub-class */
26690560
JL
645 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
646 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
647 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
648};
649
b53371ed
JL
650#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
651enum {
652 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
653 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
663 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
664 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
665 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
666 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
667 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
668 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
669 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
670};
671
461c08df
JL
672#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673enum {
674 /* MIPS DSP Arithmetic Sub-class */
675 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
692 /* DSP Bit/Manipulation Sub-class */
693 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 699};
461c08df 700
461c08df
JL
701#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702enum {
a22260ae
JL
703 /* MIPS DSP Multiply Sub-class insns */
704 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
707 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
708 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
709 /* MIPS DSP Arithmetic Sub-class */
710 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
719 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
720 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
729 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
730 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
731};
461c08df 732
461c08df
JL
733#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
734enum {
26690560
JL
735 /* DSP Compare-Pick Sub-class */
736 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
755 /* MIPS DSP Arithmetic Sub-class */
756 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
764};
461c08df 765
26690560
JL
766#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
767enum {
df6126a7 768 /* DSP Append Sub-class */
26690560
JL
769 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
770 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
771 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
772 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
773};
26690560 774
b53371ed
JL
775#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776enum {
777 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
778 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
779 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
797 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
798 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
799};
800
1cb6686c
JL
801#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802enum {
803 /* DSP Bit/Manipulation Sub-class */
804 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
805};
1cb6686c 806
a22260ae
JL
807#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808enum {
809 /* MIPS DSP Multiply Sub-class insns */
810 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
836};
a22260ae 837
77c5fa8b
JL
838#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839enum {
840 /* MIPS DSP GPR-Based Shift Sub-class */
841 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
867};
77c5fa8b 868
7a387fff
TS
869/* Coprocessor 0 (rs field) */
870#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
871
6ea83fed 872enum {
7a387fff
TS
873 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
874 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
875 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
876 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 877 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
878 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
879 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 880 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
881 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
882 OPC_C0 = (0x10 << 21) | OPC_CP0,
883 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
884 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 885};
7a387fff
TS
886
887/* MFMC0 opcodes */
b48cfdff 888#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
889
890enum {
ead9360e
TS
891 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
894 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
895 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
896 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
897};
898
899/* Coprocessor 0 (with rs == C0) */
900#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
901
902enum {
903 OPC_TLBR = 0x01 | OPC_C0,
904 OPC_TLBWI = 0x02 | OPC_C0,
905 OPC_TLBWR = 0x06 | OPC_C0,
906 OPC_TLBP = 0x08 | OPC_C0,
907 OPC_RFE = 0x10 | OPC_C0,
908 OPC_ERET = 0x18 | OPC_C0,
909 OPC_DERET = 0x1F | OPC_C0,
910 OPC_WAIT = 0x20 | OPC_C0,
911};
912
913/* Coprocessor 1 (rs field) */
914#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
915
bf4120ad
NF
916/* Values for the fmt field in FP instructions */
917enum {
918 /* 0 - 15 are reserved */
e459440a
AJ
919 FMT_S = 16, /* single fp */
920 FMT_D = 17, /* double fp */
921 FMT_E = 18, /* extended fp */
922 FMT_Q = 19, /* quad fp */
923 FMT_W = 20, /* 32-bit fixed */
924 FMT_L = 21, /* 64-bit fixed */
925 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
926 /* 23 - 31 are reserved */
927};
928
7a387fff
TS
929enum {
930 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
931 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
932 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 933 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
934 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
935 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
936 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 937 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 938 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
939 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
940 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
941 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
942 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
943 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
944 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
945 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
946 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
947 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
948 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
949 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
7a387fff
TS
950};
951
5a5012ec
TS
952#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
953#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
954
7a387fff
TS
955enum {
956 OPC_BC1F = (0x00 << 16) | OPC_BC1,
957 OPC_BC1T = (0x01 << 16) | OPC_BC1,
958 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
959 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
960};
961
5a5012ec
TS
962enum {
963 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
964 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
965};
966
967enum {
968 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
969 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
970};
7a387fff
TS
971
972#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
973
974enum {
975 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
976 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
977 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
978 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
979 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
980 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
981 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
982 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
983 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
984 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
985 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
986};
987
bd277fa1
RH
988#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
989
990enum {
991 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
992 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
993 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
994 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
995 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
996 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
997 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
998 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
999
1000 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1001 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1002 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1003 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1004 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1005 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1006 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1007 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1008
1009 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1010 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1011 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1012 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1013 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1014 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1015 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1016 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1017
1018 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1019 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1020 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1021 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1022 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1023 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1024 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1025 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1026
1027 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1028 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1029 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1030 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1031 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1032 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1033
1034 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1035 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1036 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1037 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1038 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1039 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1040
1041 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1042 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1043 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1044 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1045 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1046 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1047
1048 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1049 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1050 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1051 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1052 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1053 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1054
1055 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1056 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1057 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1058 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1059 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1060 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1061
1062 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1063 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1064 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1065 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1066 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1067 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1068
1069 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1070 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1071 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1072 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1073 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1074 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1075
1076 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1077 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1078 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1079 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1080 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1081 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1082};
1083
1084
e0c84da7
TS
1085#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1086
1087enum {
1088 OPC_LWXC1 = 0x00 | OPC_CP3,
1089 OPC_LDXC1 = 0x01 | OPC_CP3,
1090 OPC_LUXC1 = 0x05 | OPC_CP3,
1091 OPC_SWXC1 = 0x08 | OPC_CP3,
1092 OPC_SDXC1 = 0x09 | OPC_CP3,
1093 OPC_SUXC1 = 0x0D | OPC_CP3,
1094 OPC_PREFX = 0x0F | OPC_CP3,
1095 OPC_ALNV_PS = 0x1E | OPC_CP3,
1096 OPC_MADD_S = 0x20 | OPC_CP3,
1097 OPC_MADD_D = 0x21 | OPC_CP3,
1098 OPC_MADD_PS = 0x26 | OPC_CP3,
1099 OPC_MSUB_S = 0x28 | OPC_CP3,
1100 OPC_MSUB_D = 0x29 | OPC_CP3,
1101 OPC_MSUB_PS = 0x2E | OPC_CP3,
1102 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1103 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1104 OPC_NMADD_PS= 0x36 | OPC_CP3,
1105 OPC_NMSUB_S = 0x38 | OPC_CP3,
1106 OPC_NMSUB_D = 0x39 | OPC_CP3,
1107 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1108};
1109
39454628 1110/* global register indices */
a7812ae4
PB
1111static TCGv_ptr cpu_env;
1112static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1113static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1114static TCGv cpu_dspctrl, btarget, bcond;
1115static TCGv_i32 hflags;
a7812ae4 1116static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1117static TCGv_i64 fpu_f64[32];
aa0bf00b 1118
1a7ff922 1119static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1120static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1121
022c62cb 1122#include "exec/gen-icount.h"
2e70f6ef 1123
895c2d04 1124#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1125 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1126 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1127 tcg_temp_free_i32(helper_tmp); \
1128 } while(0)
be24bb4f 1129
895c2d04 1130#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1131 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1132 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1133 tcg_temp_free_i32(helper_tmp); \
1134 } while(0)
be24bb4f 1135
895c2d04
BS
1136#define gen_helper_1e0i(name, ret, arg1) do { \
1137 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1138 gen_helper_##name(ret, cpu_env, helper_tmp); \
1139 tcg_temp_free_i32(helper_tmp); \
1140 } while(0)
1141
1142#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1143 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1144 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1145 tcg_temp_free_i32(helper_tmp); \
1146 } while(0)
1147
1148#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1149 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1150 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1151 tcg_temp_free_i32(helper_tmp); \
1152 } while(0)
1153
1154#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1155 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1156 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1157 tcg_temp_free_i32(helper_tmp); \
1158 } while(0)
be24bb4f 1159
895c2d04 1160#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1161 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1162 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1163 tcg_temp_free_i32(helper_tmp); \
1164 } while(0)
c239529e 1165
8e9ade68
TS
1166typedef struct DisasContext {
1167 struct TranslationBlock *tb;
1168 target_ulong pc, saved_pc;
1169 uint32_t opcode;
7b270ef2 1170 int singlestep_enabled;
d75c135e 1171 int insn_flags;
5ab5c041 1172 int32_t CP0_Config1;
8e9ade68
TS
1173 /* Routine used to access memory */
1174 int mem_idx;
1175 uint32_t hflags, saved_hflags;
1176 int bstate;
1177 target_ulong btarget;
d279279e 1178 bool ulri;
8e9ade68
TS
1179} DisasContext;
1180
1181enum {
1182 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1183 * exception condition */
8e9ade68
TS
1184 BS_STOP = 1, /* We want to stop translation for any reason */
1185 BS_BRANCH = 2, /* We reached a branch condition */
1186 BS_EXCP = 3, /* We reached an exception condition */
1187};
1188
d73ee8a2
RH
1189static const char * const regnames[] = {
1190 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1191 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1192 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1193 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1194};
6af0bf9c 1195
d73ee8a2
RH
1196static const char * const regnames_HI[] = {
1197 "HI0", "HI1", "HI2", "HI3",
1198};
4b2eb8d2 1199
d73ee8a2
RH
1200static const char * const regnames_LO[] = {
1201 "LO0", "LO1", "LO2", "LO3",
1202};
4b2eb8d2 1203
d73ee8a2
RH
1204static const char * const regnames_ACX[] = {
1205 "ACX0", "ACX1", "ACX2", "ACX3",
1206};
4b2eb8d2 1207
d73ee8a2
RH
1208static const char * const fregnames[] = {
1209 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1210 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1211 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1212 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1213};
958fb4a9 1214
fb7729e2
RH
1215#define MIPS_DEBUG(fmt, ...) \
1216 do { \
1217 if (MIPS_DEBUG_DISAS) { \
1218 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1219 TARGET_FMT_lx ": %08x " fmt "\n", \
1220 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1221 } \
1222 } while (0)
1223
1224#define LOG_DISAS(...) \
1225 do { \
1226 if (MIPS_DEBUG_DISAS) { \
1227 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1228 } \
1229 } while (0)
958fb4a9 1230
8e9ade68 1231#define MIPS_INVAL(op) \
8e9ade68 1232 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1233 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1234
8e9ade68
TS
1235/* General purpose registers moves. */
1236static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1237{
8e9ade68
TS
1238 if (reg == 0)
1239 tcg_gen_movi_tl(t, 0);
1240 else
4b2eb8d2 1241 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1242}
1243
8e9ade68 1244static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1245{
8e9ade68 1246 if (reg != 0)
4b2eb8d2 1247 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1248}
1249
b10fa3c9 1250/* Moves to/from ACX register. */
4b2eb8d2 1251static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1252{
4b2eb8d2 1253 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1254}
1255
4b2eb8d2 1256static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1257{
4b2eb8d2 1258 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1259}
1260
8e9ade68 1261/* Moves to/from shadow registers. */
be24bb4f 1262static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1263{
d9bea114 1264 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1265
1266 if (from == 0)
d9bea114 1267 tcg_gen_movi_tl(t0, 0);
8e9ade68 1268 else {
d9bea114 1269 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1270 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1271
7db13fae 1272 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1273 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1274 tcg_gen_andi_i32(t2, t2, 0xf);
1275 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1276 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1277 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1278
d9bea114 1279 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1280 tcg_temp_free_ptr(addr);
d9bea114 1281 tcg_temp_free_i32(t2);
8e9ade68 1282 }
d9bea114
AJ
1283 gen_store_gpr(t0, to);
1284 tcg_temp_free(t0);
aaa9128a
TS
1285}
1286
be24bb4f 1287static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1288{
be24bb4f 1289 if (to != 0) {
d9bea114
AJ
1290 TCGv t0 = tcg_temp_new();
1291 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1292 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1293
d9bea114 1294 gen_load_gpr(t0, from);
7db13fae 1295 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1296 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1297 tcg_gen_andi_i32(t2, t2, 0xf);
1298 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1299 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1300 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1301
d9bea114 1302 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1303 tcg_temp_free_ptr(addr);
d9bea114
AJ
1304 tcg_temp_free_i32(t2);
1305 tcg_temp_free(t0);
8e9ade68 1306 }
aaa9128a
TS
1307}
1308
aaa9128a 1309/* Floating point register moves. */
d73ee8a2 1310static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1311{
d73ee8a2 1312 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1313}
1314
d73ee8a2 1315static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1316{
d73ee8a2
RH
1317 TCGv_i64 t64 = tcg_temp_new_i64();
1318 tcg_gen_extu_i32_i64(t64, t);
1319 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1320 tcg_temp_free_i64(t64);
6d066274
AJ
1321}
1322
7f6613ce 1323static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1324{
7f6613ce
PJ
1325 if (ctx->hflags & MIPS_HFLAG_F64) {
1326 TCGv_i64 t64 = tcg_temp_new_i64();
1327 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1328 tcg_gen_trunc_i64_i32(t, t64);
1329 tcg_temp_free_i64(t64);
1330 } else {
1331 gen_load_fpr32(t, reg | 1);
1332 }
6d066274
AJ
1333}
1334
7f6613ce 1335static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1336{
7f6613ce
PJ
1337 if (ctx->hflags & MIPS_HFLAG_F64) {
1338 TCGv_i64 t64 = tcg_temp_new_i64();
1339 tcg_gen_extu_i32_i64(t64, t);
1340 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1341 tcg_temp_free_i64(t64);
1342 } else {
1343 gen_store_fpr32(t, reg | 1);
1344 }
aa0bf00b 1345}
6ea83fed 1346
d73ee8a2 1347static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1348{
f364515c 1349 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1350 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1351 } else {
d73ee8a2 1352 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1353 }
1354}
6ea83fed 1355
d73ee8a2 1356static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1357{
f364515c 1358 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1359 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1360 } else {
d73ee8a2
RH
1361 TCGv_i64 t0;
1362 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1363 t0 = tcg_temp_new_i64();
6d066274 1364 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1365 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1366 tcg_temp_free_i64(t0);
aa0bf00b
TS
1367 }
1368}
6ea83fed 1369
d94536f4 1370static inline int get_fp_bit (int cc)
a16336e4 1371{
d94536f4
AJ
1372 if (cc)
1373 return 24 + cc;
1374 else
1375 return 23;
a16336e4
TS
1376}
1377
30898801 1378/* Tests */
8e9ade68
TS
1379static inline void gen_save_pc(target_ulong pc)
1380{
1eb75d4a 1381 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1382}
30898801 1383
356265ae 1384static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1385{
d12d51d5 1386 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1387 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1388 gen_save_pc(ctx->pc);
6af0bf9c
FB
1389 ctx->saved_pc = ctx->pc;
1390 }
1391 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1392 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1393 ctx->saved_hflags = ctx->hflags;
364d4831 1394 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1395 case MIPS_HFLAG_BR:
5a5012ec
TS
1396 break;
1397 case MIPS_HFLAG_BC:
5a5012ec 1398 case MIPS_HFLAG_BL:
5a5012ec 1399 case MIPS_HFLAG_B:
d077b6f7 1400 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1401 break;
6af0bf9c
FB
1402 }
1403 }
1404}
1405
7db13fae 1406static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1407{
fd4a04eb 1408 ctx->saved_hflags = ctx->hflags;
364d4831 1409 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1410 case MIPS_HFLAG_BR:
fd4a04eb
TS
1411 break;
1412 case MIPS_HFLAG_BC:
1413 case MIPS_HFLAG_BL:
39454628 1414 case MIPS_HFLAG_B:
fd4a04eb 1415 ctx->btarget = env->btarget;
fd4a04eb 1416 break;
5a5012ec
TS
1417 }
1418}
1419
356265ae 1420static inline void
48d38ca5 1421generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1422{
a7812ae4
PB
1423 TCGv_i32 texcp = tcg_const_i32(excp);
1424 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1425 save_cpu_state(ctx, 1);
895c2d04 1426 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1427 tcg_temp_free_i32(terr);
1428 tcg_temp_free_i32(texcp);
aaa9128a
TS
1429}
1430
356265ae 1431static inline void
48d38ca5 1432generate_exception (DisasContext *ctx, int excp)
aaa9128a 1433{
6af0bf9c 1434 save_cpu_state(ctx, 1);
895c2d04 1435 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1436}
1437
48d38ca5 1438/* Addresses computation */
941694d0 1439static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1440{
941694d0 1441 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1442
1443#if defined(TARGET_MIPS64)
01f72885 1444 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1445 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1446 }
1447#endif
4ad40f36
FB
1448}
1449
31837be3
YK
1450/* Addresses computation (translation time) */
1451static target_long addr_add(DisasContext *ctx, target_long base,
1452 target_long offset)
1453{
1454 target_long sum = base + offset;
1455
1456#if defined(TARGET_MIPS64)
1457 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1458 sum = (int32_t)sum;
1459 }
1460#endif
1461 return sum;
1462}
1463
356265ae 1464static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1465{
fe253235 1466 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1467 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1468}
1469
356265ae 1470static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1471{
fe253235 1472 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1473 generate_exception_err(ctx, EXCP_CpU, 1);
1474}
1475
b8aa4598
TS
1476/* Verify that the processor is running with COP1X instructions enabled.
1477 This is associated with the nabla symbol in the MIPS32 and MIPS64
1478 opcode tables. */
1479
356265ae 1480static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1481{
1482 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1483 generate_exception(ctx, EXCP_RI);
1484}
1485
1486/* Verify that the processor is running with 64-bit floating-point
1487 operations enabled. */
1488
356265ae 1489static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1490{
b8aa4598 1491 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1492 generate_exception(ctx, EXCP_RI);
1493}
1494
1495/*
1496 * Verify if floating point register is valid; an operation is not defined
1497 * if bit 0 of any register specification is set and the FR bit in the
1498 * Status register equals zero, since the register numbers specify an
1499 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1500 * in the Status register equals one, both even and odd register numbers
1501 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1502 *
1503 * Multiple 64 bit wide registers can be checked by calling
1504 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1505 */
356265ae 1506static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1507{
fe253235 1508 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1509 generate_exception(ctx, EXCP_RI);
1510}
1511
853c3240
JL
1512/* Verify that the processor is running with DSP instructions enabled.
1513 This is enabled by CP0 Status register MX(24) bit.
1514 */
1515
1516static inline void check_dsp(DisasContext *ctx)
1517{
1518 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1519 if (ctx->insn_flags & ASE_DSP) {
1520 generate_exception(ctx, EXCP_DSPDIS);
1521 } else {
1522 generate_exception(ctx, EXCP_RI);
1523 }
853c3240
JL
1524 }
1525}
1526
1527static inline void check_dspr2(DisasContext *ctx)
1528{
1529 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1530 if (ctx->insn_flags & ASE_DSP) {
1531 generate_exception(ctx, EXCP_DSPDIS);
1532 } else {
1533 generate_exception(ctx, EXCP_RI);
1534 }
853c3240
JL
1535 }
1536}
1537
3a95e3a7 1538/* This code generates a "reserved instruction" exception if the
e189e748 1539 CPU does not support the instruction set corresponding to flags. */
d75c135e 1540static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1541{
d75c135e 1542 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1543 generate_exception(ctx, EXCP_RI);
d75c135e 1544 }
3a95e3a7
TS
1545}
1546
fecd2646
LA
1547/* This code generates a "reserved instruction" exception if the
1548 CPU has corresponding flag set which indicates that the instruction
1549 has been removed. */
1550static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1551{
1552 if (unlikely(ctx->insn_flags & flags)) {
1553 generate_exception(ctx, EXCP_RI);
1554 }
1555}
1556
e189e748
TS
1557/* This code generates a "reserved instruction" exception if 64-bit
1558 instructions are not enabled. */
356265ae 1559static inline void check_mips_64(DisasContext *ctx)
e189e748 1560{
fe253235 1561 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1562 generate_exception(ctx, EXCP_RI);
1563}
1564
8153667c
NF
1565/* Define small wrappers for gen_load_fpr* so that we have a uniform
1566 calling interface for 32 and 64-bit FPRs. No sense in changing
1567 all callers for gen_load_fpr32 when we need the CTX parameter for
1568 this one use. */
1569#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1570#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1571#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1572static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1573 int ft, int fs, int cc) \
1574{ \
1575 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1576 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1577 switch (ifmt) { \
1578 case FMT_PS: \
1579 check_cp1_64bitmode(ctx); \
1580 break; \
1581 case FMT_D: \
1582 if (abs) { \
1583 check_cop1x(ctx); \
1584 } \
1585 check_cp1_registers(ctx, fs | ft); \
1586 break; \
1587 case FMT_S: \
1588 if (abs) { \
1589 check_cop1x(ctx); \
1590 } \
1591 break; \
1592 } \
1593 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1594 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1595 switch (n) { \
895c2d04
BS
1596 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1597 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1598 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1599 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1600 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1601 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1602 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1603 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1604 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1605 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1606 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1607 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1608 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1609 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1610 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1611 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1612 default: abort(); \
1613 } \
1614 tcg_temp_free_i##bits (fp0); \
1615 tcg_temp_free_i##bits (fp1); \
1616}
1617
1618FOP_CONDS(, 0, d, FMT_D, 64)
1619FOP_CONDS(abs, 1, d, FMT_D, 64)
1620FOP_CONDS(, 0, s, FMT_S, 32)
1621FOP_CONDS(abs, 1, s, FMT_S, 32)
1622FOP_CONDS(, 0, ps, FMT_PS, 64)
1623FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1624#undef FOP_CONDS
3f493883
YK
1625
1626#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1627static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1628 int ft, int fs, int fd) \
1629{ \
1630 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1631 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1632 switch (ifmt) { \
1633 case FMT_D: \
1634 check_cp1_registers(ctx, fs | ft | fd); \
1635 break; \
1636 } \
1637 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1638 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1639 switch (n) { \
1640 case 0: \
1641 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1642 break; \
1643 case 1: \
1644 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1645 break; \
1646 case 2: \
1647 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1648 break; \
1649 case 3: \
1650 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1651 break; \
1652 case 4: \
1653 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1654 break; \
1655 case 5: \
1656 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1657 break; \
1658 case 6: \
1659 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1660 break; \
1661 case 7: \
1662 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1663 break; \
1664 case 8: \
1665 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1666 break; \
1667 case 9: \
1668 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1669 break; \
1670 case 10: \
1671 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1672 break; \
1673 case 11: \
1674 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1675 break; \
1676 case 12: \
1677 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1678 break; \
1679 case 13: \
1680 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1681 break; \
1682 case 14: \
1683 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1684 break; \
1685 case 15: \
1686 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1687 break; \
1688 case 17: \
1689 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1690 break; \
1691 case 18: \
1692 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1693 break; \
1694 case 19: \
1695 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1696 break; \
1697 case 25: \
1698 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1699 break; \
1700 case 26: \
1701 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1702 break; \
1703 case 27: \
1704 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1705 break; \
1706 default: \
1707 abort(); \
1708 } \
1709 STORE; \
1710 tcg_temp_free_i ## bits (fp0); \
1711 tcg_temp_free_i ## bits (fp1); \
1712}
1713
1714FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1715FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1716#undef FOP_CONDNS
8153667c
NF
1717#undef gen_ldcmp_fpr32
1718#undef gen_ldcmp_fpr64
1719
958fb4a9 1720/* load/store instructions. */
e7139c44 1721#ifdef CONFIG_USER_ONLY
d9bea114 1722#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1723static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1724{ \
1725 TCGv t0 = tcg_temp_new(); \
1726 tcg_gen_mov_tl(t0, arg1); \
1727 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1728 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1729 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1730 tcg_temp_free(t0); \
aaa9128a 1731}
e7139c44
AJ
1732#else
1733#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1734static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1735{ \
895c2d04 1736 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1737}
1738#endif
aaa9128a
TS
1739OP_LD_ATOMIC(ll,ld32s);
1740#if defined(TARGET_MIPS64)
1741OP_LD_ATOMIC(lld,ld64);
1742#endif
1743#undef OP_LD_ATOMIC
1744
590bc601
PB
1745#ifdef CONFIG_USER_ONLY
1746#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1747static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1748{ \
1749 TCGv t0 = tcg_temp_new(); \
1750 int l1 = gen_new_label(); \
1751 int l2 = gen_new_label(); \
1752 \
1753 tcg_gen_andi_tl(t0, arg2, almask); \
1754 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1755 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1756 generate_exception(ctx, EXCP_AdES); \
1757 gen_set_label(l1); \
7db13fae 1758 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1759 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1760 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1761 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1762 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1763 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1764 gen_set_label(l2); \
1765 tcg_gen_movi_tl(t0, 0); \
1766 gen_store_gpr(t0, rt); \
1767 tcg_temp_free(t0); \
1768}
1769#else
1770#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1771static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1772{ \
1773 TCGv t0 = tcg_temp_new(); \
895c2d04 1774 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1775 gen_store_gpr(t0, rt); \
590bc601
PB
1776 tcg_temp_free(t0); \
1777}
1778#endif
590bc601 1779OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1780#if defined(TARGET_MIPS64)
590bc601 1781OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1782#endif
1783#undef OP_ST_ATOMIC
1784
662d7485
NF
1785static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1786 int base, int16_t offset)
1787{
1788 if (base == 0) {
1789 tcg_gen_movi_tl(addr, offset);
1790 } else if (offset == 0) {
1791 gen_load_gpr(addr, base);
1792 } else {
1793 tcg_gen_movi_tl(addr, offset);
1794 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1795 }
1796}
1797
364d4831
NF
1798static target_ulong pc_relative_pc (DisasContext *ctx)
1799{
1800 target_ulong pc = ctx->pc;
1801
1802 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1803 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1804
1805 pc -= branch_bytes;
1806 }
1807
1808 pc &= ~(target_ulong)3;
1809 return pc;
1810}
1811
5c13fdfd 1812/* Load */
d75c135e
AJ
1813static void gen_ld(DisasContext *ctx, uint32_t opc,
1814 int rt, int base, int16_t offset)
6af0bf9c 1815{
5c13fdfd 1816 const char *opn = "ld";
fc40787a 1817 TCGv t0, t1, t2;
afa88c3a 1818
d75c135e 1819 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1820 /* Loongson CPU uses a load to zero register for prefetch.
1821 We emulate it as a NOP. On other CPU we must perform the
1822 actual memory access. */
1823 MIPS_DEBUG("NOP");
1824 return;
1825 }
6af0bf9c 1826
afa88c3a 1827 t0 = tcg_temp_new();
662d7485 1828 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1829
6af0bf9c 1830 switch (opc) {
d26bc211 1831#if defined(TARGET_MIPS64)
6e473128 1832 case OPC_LWU:
5f68f5ae 1833 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1834 gen_store_gpr(t0, rt);
6e473128
TS
1835 opn = "lwu";
1836 break;
6af0bf9c 1837 case OPC_LD:
5f68f5ae 1838 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1839 gen_store_gpr(t0, rt);
6af0bf9c
FB
1840 opn = "ld";
1841 break;
7a387fff 1842 case OPC_LLD:
bf7910c6 1843 case R6_OPC_LLD:
b835e919 1844 save_cpu_state(ctx, 1);
5c13fdfd 1845 op_ld_lld(t0, t0, ctx);
78723684 1846 gen_store_gpr(t0, rt);
7a387fff
TS
1847 opn = "lld";
1848 break;
6af0bf9c 1849 case OPC_LDL:
3cee3050 1850 t1 = tcg_temp_new();
fc40787a
AJ
1851 tcg_gen_andi_tl(t1, t0, 7);
1852#ifndef TARGET_WORDS_BIGENDIAN
1853 tcg_gen_xori_tl(t1, t1, 7);
1854#endif
1855 tcg_gen_shli_tl(t1, t1, 3);
1856 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1857 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1858 tcg_gen_shl_tl(t0, t0, t1);
1859 tcg_gen_xori_tl(t1, t1, 63);
1860 t2 = tcg_const_tl(0x7fffffffffffffffull);
1861 tcg_gen_shr_tl(t2, t2, t1);
78723684 1862 gen_load_gpr(t1, rt);
fc40787a
AJ
1863 tcg_gen_and_tl(t1, t1, t2);
1864 tcg_temp_free(t2);
1865 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1866 tcg_temp_free(t1);
fc40787a 1867 gen_store_gpr(t0, rt);
6af0bf9c
FB
1868 opn = "ldl";
1869 break;
6af0bf9c 1870 case OPC_LDR:
3cee3050 1871 t1 = tcg_temp_new();
fc40787a
AJ
1872 tcg_gen_andi_tl(t1, t0, 7);
1873#ifdef TARGET_WORDS_BIGENDIAN
1874 tcg_gen_xori_tl(t1, t1, 7);
1875#endif
1876 tcg_gen_shli_tl(t1, t1, 3);
1877 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1878 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1879 tcg_gen_shr_tl(t0, t0, t1);
1880 tcg_gen_xori_tl(t1, t1, 63);
1881 t2 = tcg_const_tl(0xfffffffffffffffeull);
1882 tcg_gen_shl_tl(t2, t2, t1);
78723684 1883 gen_load_gpr(t1, rt);
fc40787a
AJ
1884 tcg_gen_and_tl(t1, t1, t2);
1885 tcg_temp_free(t2);
1886 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1887 tcg_temp_free(t1);
fc40787a 1888 gen_store_gpr(t0, rt);
6af0bf9c
FB
1889 opn = "ldr";
1890 break;
364d4831 1891 case OPC_LDPC:
3cee3050 1892 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1893 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1894 tcg_temp_free(t1);
5f68f5ae 1895 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1896 gen_store_gpr(t0, rt);
5c13fdfd 1897 opn = "ldpc";
364d4831 1898 break;
6af0bf9c 1899#endif
364d4831 1900 case OPC_LWPC:
3cee3050 1901 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1902 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1903 tcg_temp_free(t1);
5f68f5ae 1904 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1905 gen_store_gpr(t0, rt);
5c13fdfd 1906 opn = "lwpc";
364d4831 1907 break;
6af0bf9c 1908 case OPC_LW:
5f68f5ae 1909 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1910 gen_store_gpr(t0, rt);
6af0bf9c
FB
1911 opn = "lw";
1912 break;
6af0bf9c 1913 case OPC_LH:
5f68f5ae 1914 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1915 gen_store_gpr(t0, rt);
6af0bf9c
FB
1916 opn = "lh";
1917 break;
6af0bf9c 1918 case OPC_LHU:
5f68f5ae 1919 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1920 gen_store_gpr(t0, rt);
6af0bf9c
FB
1921 opn = "lhu";
1922 break;
1923 case OPC_LB:
5f68f5ae 1924 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1925 gen_store_gpr(t0, rt);
6af0bf9c
FB
1926 opn = "lb";
1927 break;
6af0bf9c 1928 case OPC_LBU:
5f68f5ae 1929 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1930 gen_store_gpr(t0, rt);
6af0bf9c
FB
1931 opn = "lbu";
1932 break;
1933 case OPC_LWL:
3cee3050 1934 t1 = tcg_temp_new();
fc40787a
AJ
1935 tcg_gen_andi_tl(t1, t0, 3);
1936#ifndef TARGET_WORDS_BIGENDIAN
1937 tcg_gen_xori_tl(t1, t1, 3);
1938#endif
1939 tcg_gen_shli_tl(t1, t1, 3);
1940 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1941 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1942 tcg_gen_shl_tl(t0, t0, t1);
1943 tcg_gen_xori_tl(t1, t1, 31);
1944 t2 = tcg_const_tl(0x7fffffffull);
1945 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1946 gen_load_gpr(t1, rt);
fc40787a
AJ
1947 tcg_gen_and_tl(t1, t1, t2);
1948 tcg_temp_free(t2);
1949 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1950 tcg_temp_free(t1);
fc40787a
AJ
1951 tcg_gen_ext32s_tl(t0, t0);
1952 gen_store_gpr(t0, rt);
6af0bf9c
FB
1953 opn = "lwl";
1954 break;
6af0bf9c 1955 case OPC_LWR:
3cee3050 1956 t1 = tcg_temp_new();
fc40787a
AJ
1957 tcg_gen_andi_tl(t1, t0, 3);
1958#ifdef TARGET_WORDS_BIGENDIAN
1959 tcg_gen_xori_tl(t1, t1, 3);
1960#endif
1961 tcg_gen_shli_tl(t1, t1, 3);
1962 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1963 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1964 tcg_gen_shr_tl(t0, t0, t1);
1965 tcg_gen_xori_tl(t1, t1, 31);
1966 t2 = tcg_const_tl(0xfffffffeull);
1967 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1968 gen_load_gpr(t1, rt);
fc40787a
AJ
1969 tcg_gen_and_tl(t1, t1, t2);
1970 tcg_temp_free(t2);
1971 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1972 tcg_temp_free(t1);
c728154b 1973 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1974 gen_store_gpr(t0, rt);
6af0bf9c
FB
1975 opn = "lwr";
1976 break;
6af0bf9c 1977 case OPC_LL:
4368b29a 1978 case R6_OPC_LL:
e7139c44 1979 save_cpu_state(ctx, 1);
5c13fdfd 1980 op_ld_ll(t0, t0, ctx);
78723684 1981 gen_store_gpr(t0, rt);
6af0bf9c
FB
1982 opn = "ll";
1983 break;
d66c7132 1984 }
2abf314d 1985 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1986 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1987 tcg_temp_free(t0);
d66c7132
AJ
1988}
1989
5c13fdfd
AJ
1990/* Store */
1991static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1992 int base, int16_t offset)
1993{
1994 const char *opn = "st";
1995 TCGv t0 = tcg_temp_new();
1996 TCGv t1 = tcg_temp_new();
1997
1998 gen_base_offset_addr(ctx, t0, base, offset);
1999 gen_load_gpr(t1, rt);
2000 switch (opc) {
2001#if defined(TARGET_MIPS64)
2002 case OPC_SD:
5f68f5ae 2003 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
2004 opn = "sd";
2005 break;
2006 case OPC_SDL:
2007 save_cpu_state(ctx, 1);
895c2d04 2008 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2009 opn = "sdl";
2010 break;
2011 case OPC_SDR:
2012 save_cpu_state(ctx, 1);
895c2d04 2013 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2014 opn = "sdr";
2015 break;
2016#endif
2017 case OPC_SW:
5f68f5ae 2018 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
2019 opn = "sw";
2020 break;
2021 case OPC_SH:
5f68f5ae 2022 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
2023 opn = "sh";
2024 break;
2025 case OPC_SB:
5f68f5ae 2026 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
2027 opn = "sb";
2028 break;
2029 case OPC_SWL:
2030 save_cpu_state(ctx, 1);
895c2d04 2031 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2032 opn = "swl";
2033 break;
2034 case OPC_SWR:
2035 save_cpu_state(ctx, 1);
895c2d04 2036 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
2037 opn = "swr";
2038 break;
2039 }
2abf314d 2040 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
2041 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2042 tcg_temp_free(t0);
2043 tcg_temp_free(t1);
2044}
2045
2046
d66c7132
AJ
2047/* Store conditional */
2048static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2049 int base, int16_t offset)
2050{
2051 const char *opn = "st_cond";
2052 TCGv t0, t1;
2053
2d2826b9 2054#ifdef CONFIG_USER_ONLY
d66c7132 2055 t0 = tcg_temp_local_new();
d66c7132 2056 t1 = tcg_temp_local_new();
2d2826b9
AJ
2057#else
2058 t0 = tcg_temp_new();
2059 t1 = tcg_temp_new();
2060#endif
2061 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2062 gen_load_gpr(t1, rt);
2063 switch (opc) {
2064#if defined(TARGET_MIPS64)
2065 case OPC_SCD:
bf7910c6 2066 case R6_OPC_SCD:
b835e919 2067 save_cpu_state(ctx, 1);
5c13fdfd 2068 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
2069 opn = "scd";
2070 break;
2071#endif
6af0bf9c 2072 case OPC_SC:
4368b29a 2073 case R6_OPC_SC:
e7139c44 2074 save_cpu_state(ctx, 1);
5c13fdfd 2075 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
2076 opn = "sc";
2077 break;
6af0bf9c 2078 }
2abf314d 2079 (void)opn; /* avoid a compiler warning */
6af0bf9c 2080 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 2081 tcg_temp_free(t1);
d66c7132 2082 tcg_temp_free(t0);
6af0bf9c
FB
2083}
2084
6ea83fed 2085/* Load and store */
7a387fff 2086static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2087 int base, int16_t offset)
6ea83fed 2088{
923617a3 2089 const char *opn = "flt_ldst";
4e2474d6 2090 TCGv t0 = tcg_temp_new();
6ea83fed 2091
662d7485 2092 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2093 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2094 memory access. */
6ea83fed
FB
2095 switch (opc) {
2096 case OPC_LWC1:
b6d96bed 2097 {
a7812ae4 2098 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 2099 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 2100 gen_store_fpr32(fp0, ft);
a7812ae4 2101 tcg_temp_free_i32(fp0);
b6d96bed 2102 }
6ea83fed
FB
2103 opn = "lwc1";
2104 break;
2105 case OPC_SWC1:
b6d96bed 2106 {
a7812ae4 2107 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 2108 gen_load_fpr32(fp0, ft);
5f68f5ae 2109 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 2110 tcg_temp_free_i32(fp0);
b6d96bed 2111 }
6ea83fed
FB
2112 opn = "swc1";
2113 break;
2114 case OPC_LDC1:
b6d96bed 2115 {
a7812ae4 2116 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 2117 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 2118 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2119 tcg_temp_free_i64(fp0);
b6d96bed 2120 }
6ea83fed
FB
2121 opn = "ldc1";
2122 break;
2123 case OPC_SDC1:
b6d96bed 2124 {
a7812ae4 2125 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2126 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 2127 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 2128 tcg_temp_free_i64(fp0);
b6d96bed 2129 }
6ea83fed
FB
2130 opn = "sdc1";
2131 break;
2132 default:
923617a3 2133 MIPS_INVAL(opn);
e397ee33 2134 generate_exception(ctx, EXCP_RI);
78723684 2135 goto out;
6ea83fed 2136 }
2abf314d 2137 (void)opn; /* avoid a compiler warning */
6ea83fed 2138 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
2139 out:
2140 tcg_temp_free(t0);
6ea83fed 2141}
6ea83fed 2142
5ab5c041
AJ
2143static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2144 int rs, int16_t imm)
26ebe468 2145{
5ab5c041 2146 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
2147 check_cp1_enabled(ctx);
2148 gen_flt_ldst(ctx, op, rt, rs, imm);
2149 } else {
2150 generate_exception_err(ctx, EXCP_CpU, 1);
2151 }
2152}
2153
6af0bf9c 2154/* Arithmetic with immediate operand */
d75c135e
AJ
2155static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2156 int rt, int rs, int16_t imm)
6af0bf9c 2157{
324d9e32 2158 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 2159 const char *opn = "imm arith";
6af0bf9c 2160
7a387fff 2161 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2162 /* If no destination, treat it as a NOP.
2163 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2164 MIPS_DEBUG("NOP");
324d9e32 2165 return;
6af0bf9c
FB
2166 }
2167 switch (opc) {
2168 case OPC_ADDI:
48d38ca5 2169 {
324d9e32
AJ
2170 TCGv t0 = tcg_temp_local_new();
2171 TCGv t1 = tcg_temp_new();
2172 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2173 int l1 = gen_new_label();
2174
324d9e32
AJ
2175 gen_load_gpr(t1, rs);
2176 tcg_gen_addi_tl(t0, t1, uimm);
2177 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2178
324d9e32
AJ
2179 tcg_gen_xori_tl(t1, t1, ~uimm);
2180 tcg_gen_xori_tl(t2, t0, uimm);
2181 tcg_gen_and_tl(t1, t1, t2);
2182 tcg_temp_free(t2);
2183 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2184 tcg_temp_free(t1);
48d38ca5
TS
2185 /* operands of same sign, result different sign */
2186 generate_exception(ctx, EXCP_OVERFLOW);
2187 gen_set_label(l1);
78723684 2188 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2189 gen_store_gpr(t0, rt);
2190 tcg_temp_free(t0);
48d38ca5 2191 }
6af0bf9c
FB
2192 opn = "addi";
2193 break;
2194 case OPC_ADDIU:
324d9e32
AJ
2195 if (rs != 0) {
2196 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2197 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2198 } else {
2199 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2200 }
6af0bf9c
FB
2201 opn = "addiu";
2202 break;
d26bc211 2203#if defined(TARGET_MIPS64)
7a387fff 2204 case OPC_DADDI:
48d38ca5 2205 {
324d9e32
AJ
2206 TCGv t0 = tcg_temp_local_new();
2207 TCGv t1 = tcg_temp_new();
2208 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2209 int l1 = gen_new_label();
2210
324d9e32
AJ
2211 gen_load_gpr(t1, rs);
2212 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2213
324d9e32
AJ
2214 tcg_gen_xori_tl(t1, t1, ~uimm);
2215 tcg_gen_xori_tl(t2, t0, uimm);
2216 tcg_gen_and_tl(t1, t1, t2);
2217 tcg_temp_free(t2);
2218 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2219 tcg_temp_free(t1);
48d38ca5
TS
2220 /* operands of same sign, result different sign */
2221 generate_exception(ctx, EXCP_OVERFLOW);
2222 gen_set_label(l1);
324d9e32
AJ
2223 gen_store_gpr(t0, rt);
2224 tcg_temp_free(t0);
48d38ca5 2225 }
7a387fff
TS
2226 opn = "daddi";
2227 break;
2228 case OPC_DADDIU:
324d9e32
AJ
2229 if (rs != 0) {
2230 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2231 } else {
2232 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2233 }
7a387fff
TS
2234 opn = "daddiu";
2235 break;
2236#endif
324d9e32 2237 }
2abf314d 2238 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2239 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2240}
2241
2242/* Logic with immediate operand */
d75c135e 2243static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2244 int rt, int rs, int16_t imm)
324d9e32
AJ
2245{
2246 target_ulong uimm;
324d9e32
AJ
2247
2248 if (rt == 0) {
2249 /* If no destination, treat it as a NOP. */
2250 MIPS_DEBUG("NOP");
2251 return;
2252 }
2253 uimm = (uint16_t)imm;
2254 switch (opc) {
6af0bf9c 2255 case OPC_ANDI:
324d9e32
AJ
2256 if (likely(rs != 0))
2257 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2258 else
2259 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2260 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2261 regnames[rs], uimm);
6af0bf9c
FB
2262 break;
2263 case OPC_ORI:
324d9e32
AJ
2264 if (rs != 0)
2265 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2266 else
2267 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2268 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2269 regnames[rs], uimm);
6af0bf9c
FB
2270 break;
2271 case OPC_XORI:
324d9e32
AJ
2272 if (likely(rs != 0))
2273 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2274 else
2275 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2276 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2277 regnames[rs], uimm);
6af0bf9c
FB
2278 break;
2279 case OPC_LUI:
d4ea6acd
LA
2280 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2281 /* OPC_AUI */
2282 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2283 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2284 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2285 } else {
2286 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2287 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2288 }
7c2c3ea3
EJ
2289 break;
2290
2291 default:
2292 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2293 break;
324d9e32 2294 }
324d9e32
AJ
2295}
2296
2297/* Set on less than with immediate operand */
d75c135e 2298static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2299 int rt, int rs, int16_t imm)
324d9e32
AJ
2300{
2301 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2302 const char *opn = "imm arith";
2303 TCGv t0;
2304
2305 if (rt == 0) {
2306 /* If no destination, treat it as a NOP. */
2307 MIPS_DEBUG("NOP");
2308 return;
2309 }
2310 t0 = tcg_temp_new();
2311 gen_load_gpr(t0, rs);
2312 switch (opc) {
2313 case OPC_SLTI:
e68dd28f 2314 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2315 opn = "slti";
2316 break;
2317 case OPC_SLTIU:
e68dd28f 2318 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2319 opn = "sltiu";
2320 break;
2321 }
2abf314d 2322 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2323 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2324 tcg_temp_free(t0);
2325}
2326
2327/* Shifts with immediate operand */
d75c135e 2328static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2329 int rt, int rs, int16_t imm)
2330{
2331 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2332 const char *opn = "imm shift";
2333 TCGv t0;
2334
2335 if (rt == 0) {
2336 /* If no destination, treat it as a NOP. */
2337 MIPS_DEBUG("NOP");
2338 return;
2339 }
2340
2341 t0 = tcg_temp_new();
2342 gen_load_gpr(t0, rs);
2343 switch (opc) {
6af0bf9c 2344 case OPC_SLL:
78723684 2345 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2346 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2347 opn = "sll";
2348 break;
2349 case OPC_SRA:
324d9e32 2350 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2351 opn = "sra";
2352 break;
2353 case OPC_SRL:
ea63e2c3
NF
2354 if (uimm != 0) {
2355 tcg_gen_ext32u_tl(t0, t0);
2356 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2357 } else {
2358 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2359 }
ea63e2c3
NF
2360 opn = "srl";
2361 break;
2362 case OPC_ROTR:
2363 if (uimm != 0) {
2364 TCGv_i32 t1 = tcg_temp_new_i32();
2365
2366 tcg_gen_trunc_tl_i32(t1, t0);
2367 tcg_gen_rotri_i32(t1, t1, uimm);
2368 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2369 tcg_temp_free_i32(t1);
3399e30f
NF
2370 } else {
2371 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2372 }
2373 opn = "rotr";
7a387fff 2374 break;
d26bc211 2375#if defined(TARGET_MIPS64)
7a387fff 2376 case OPC_DSLL:
324d9e32 2377 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2378 opn = "dsll";
2379 break;
2380 case OPC_DSRA:
324d9e32 2381 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2382 opn = "dsra";
2383 break;
2384 case OPC_DSRL:
ea63e2c3
NF
2385 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2386 opn = "dsrl";
2387 break;
2388 case OPC_DROTR:
2389 if (uimm != 0) {
2390 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2391 } else {
2392 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2393 }
ea63e2c3 2394 opn = "drotr";
7a387fff
TS
2395 break;
2396 case OPC_DSLL32:
324d9e32 2397 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2398 opn = "dsll32";
2399 break;
2400 case OPC_DSRA32:
324d9e32 2401 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2402 opn = "dsra32";
2403 break;
2404 case OPC_DSRL32:
ea63e2c3
NF
2405 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2406 opn = "dsrl32";
2407 break;
2408 case OPC_DROTR32:
2409 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2410 opn = "drotr32";
6af0bf9c 2411 break;
7a387fff 2412#endif
6af0bf9c 2413 }
2abf314d 2414 (void)opn; /* avoid a compiler warning */
93b12ccc 2415 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2416 tcg_temp_free(t0);
6af0bf9c
FB
2417}
2418
2419/* Arithmetic */
d75c135e
AJ
2420static void gen_arith(DisasContext *ctx, uint32_t opc,
2421 int rd, int rs, int rt)
6af0bf9c 2422{
923617a3 2423 const char *opn = "arith";
6af0bf9c 2424
7a387fff
TS
2425 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2426 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2427 /* If no destination, treat it as a NOP.
2428 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2429 MIPS_DEBUG("NOP");
460f00c4 2430 return;
185f0762 2431 }
460f00c4 2432
6af0bf9c
FB
2433 switch (opc) {
2434 case OPC_ADD:
48d38ca5 2435 {
460f00c4
AJ
2436 TCGv t0 = tcg_temp_local_new();
2437 TCGv t1 = tcg_temp_new();
2438 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2439 int l1 = gen_new_label();
2440
460f00c4
AJ
2441 gen_load_gpr(t1, rs);
2442 gen_load_gpr(t2, rt);
2443 tcg_gen_add_tl(t0, t1, t2);
2444 tcg_gen_ext32s_tl(t0, t0);
2445 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2446 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2447 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2448 tcg_temp_free(t2);
2449 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2450 tcg_temp_free(t1);
48d38ca5
TS
2451 /* operands of same sign, result different sign */
2452 generate_exception(ctx, EXCP_OVERFLOW);
2453 gen_set_label(l1);
460f00c4
AJ
2454 gen_store_gpr(t0, rd);
2455 tcg_temp_free(t0);
48d38ca5 2456 }
6af0bf9c
FB
2457 opn = "add";
2458 break;
2459 case OPC_ADDU:
460f00c4
AJ
2460 if (rs != 0 && rt != 0) {
2461 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2462 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2463 } else if (rs == 0 && rt != 0) {
2464 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2465 } else if (rs != 0 && rt == 0) {
2466 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2467 } else {
2468 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2469 }
6af0bf9c
FB
2470 opn = "addu";
2471 break;
2472 case OPC_SUB:
48d38ca5 2473 {
460f00c4
AJ
2474 TCGv t0 = tcg_temp_local_new();
2475 TCGv t1 = tcg_temp_new();
2476 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2477 int l1 = gen_new_label();
2478
460f00c4
AJ
2479 gen_load_gpr(t1, rs);
2480 gen_load_gpr(t2, rt);
2481 tcg_gen_sub_tl(t0, t1, t2);
2482 tcg_gen_ext32s_tl(t0, t0);
2483 tcg_gen_xor_tl(t2, t1, t2);
2484 tcg_gen_xor_tl(t1, t0, t1);
2485 tcg_gen_and_tl(t1, t1, t2);
2486 tcg_temp_free(t2);
2487 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2488 tcg_temp_free(t1);
31e3104f 2489 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2490 generate_exception(ctx, EXCP_OVERFLOW);
2491 gen_set_label(l1);
460f00c4
AJ
2492 gen_store_gpr(t0, rd);
2493 tcg_temp_free(t0);
48d38ca5 2494 }
6af0bf9c
FB
2495 opn = "sub";
2496 break;
2497 case OPC_SUBU:
460f00c4
AJ
2498 if (rs != 0 && rt != 0) {
2499 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2500 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2501 } else if (rs == 0 && rt != 0) {
2502 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2503 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2504 } else if (rs != 0 && rt == 0) {
2505 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2506 } else {
2507 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2508 }
6af0bf9c
FB
2509 opn = "subu";
2510 break;
d26bc211 2511#if defined(TARGET_MIPS64)
7a387fff 2512 case OPC_DADD:
48d38ca5 2513 {
460f00c4
AJ
2514 TCGv t0 = tcg_temp_local_new();
2515 TCGv t1 = tcg_temp_new();
2516 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2517 int l1 = gen_new_label();
2518
460f00c4
AJ
2519 gen_load_gpr(t1, rs);
2520 gen_load_gpr(t2, rt);
2521 tcg_gen_add_tl(t0, t1, t2);
2522 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2523 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2524 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2525 tcg_temp_free(t2);
2526 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2527 tcg_temp_free(t1);
48d38ca5
TS
2528 /* operands of same sign, result different sign */
2529 generate_exception(ctx, EXCP_OVERFLOW);
2530 gen_set_label(l1);
460f00c4
AJ
2531 gen_store_gpr(t0, rd);
2532 tcg_temp_free(t0);
48d38ca5 2533 }
7a387fff
TS
2534 opn = "dadd";
2535 break;
2536 case OPC_DADDU:
460f00c4
AJ
2537 if (rs != 0 && rt != 0) {
2538 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2539 } else if (rs == 0 && rt != 0) {
2540 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2541 } else if (rs != 0 && rt == 0) {
2542 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2543 } else {
2544 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2545 }
7a387fff
TS
2546 opn = "daddu";
2547 break;
2548 case OPC_DSUB:
48d38ca5 2549 {
460f00c4
AJ
2550 TCGv t0 = tcg_temp_local_new();
2551 TCGv t1 = tcg_temp_new();
2552 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2553 int l1 = gen_new_label();
2554
460f00c4
AJ
2555 gen_load_gpr(t1, rs);
2556 gen_load_gpr(t2, rt);
2557 tcg_gen_sub_tl(t0, t1, t2);
2558 tcg_gen_xor_tl(t2, t1, t2);
2559 tcg_gen_xor_tl(t1, t0, t1);
2560 tcg_gen_and_tl(t1, t1, t2);
2561 tcg_temp_free(t2);
2562 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2563 tcg_temp_free(t1);
31e3104f 2564 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2565 generate_exception(ctx, EXCP_OVERFLOW);
2566 gen_set_label(l1);
460f00c4
AJ
2567 gen_store_gpr(t0, rd);
2568 tcg_temp_free(t0);
48d38ca5 2569 }
7a387fff
TS
2570 opn = "dsub";
2571 break;
2572 case OPC_DSUBU:
460f00c4
AJ
2573 if (rs != 0 && rt != 0) {
2574 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2575 } else if (rs == 0 && rt != 0) {
2576 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2577 } else if (rs != 0 && rt == 0) {
2578 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2579 } else {
2580 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2581 }
7a387fff
TS
2582 opn = "dsubu";
2583 break;
2584#endif
460f00c4
AJ
2585 case OPC_MUL:
2586 if (likely(rs != 0 && rt != 0)) {
2587 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2588 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2589 } else {
2590 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2591 }
2592 opn = "mul";
6af0bf9c 2593 break;
460f00c4 2594 }
2abf314d 2595 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2596 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2597}
2598
2599/* Conditional move */
d75c135e 2600static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2601 int rd, int rs, int rt)
460f00c4
AJ
2602{
2603 const char *opn = "cond move";
acf12465 2604 TCGv t0, t1, t2;
460f00c4
AJ
2605
2606 if (rd == 0) {
acf12465 2607 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2608 MIPS_DEBUG("NOP");
2609 return;
2610 }
2611
acf12465
AJ
2612 t0 = tcg_temp_new();
2613 gen_load_gpr(t0, rt);
2614 t1 = tcg_const_tl(0);
2615 t2 = tcg_temp_new();
2616 gen_load_gpr(t2, rs);
460f00c4
AJ
2617 switch (opc) {
2618 case OPC_MOVN:
acf12465 2619 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2620 opn = "movn";
6af0bf9c 2621 break;
460f00c4 2622 case OPC_MOVZ:
acf12465 2623 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2624 opn = "movz";
2625 break;
b691d9d2
LA
2626 case OPC_SELNEZ:
2627 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2628 opn = "selnez";
2629 break;
2630 case OPC_SELEQZ:
2631 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2632 opn = "seleqz";
2633 break;
460f00c4 2634 }
acf12465
AJ
2635 tcg_temp_free(t2);
2636 tcg_temp_free(t1);
2637 tcg_temp_free(t0);
460f00c4 2638
2abf314d 2639 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2640 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2641}
2642
2643/* Logic */
d75c135e 2644static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2645 int rd, int rs, int rt)
460f00c4
AJ
2646{
2647 const char *opn = "logic";
2648
2649 if (rd == 0) {
2650 /* If no destination, treat it as a NOP. */
2651 MIPS_DEBUG("NOP");
2652 return;
2653 }
2654
2655 switch (opc) {
6af0bf9c 2656 case OPC_AND:
460f00c4
AJ
2657 if (likely(rs != 0 && rt != 0)) {
2658 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2659 } else {
2660 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2661 }
6af0bf9c
FB
2662 opn = "and";
2663 break;
2664 case OPC_NOR:
460f00c4
AJ
2665 if (rs != 0 && rt != 0) {
2666 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2667 } else if (rs == 0 && rt != 0) {
2668 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2669 } else if (rs != 0 && rt == 0) {
2670 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2671 } else {
2672 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2673 }
6af0bf9c
FB
2674 opn = "nor";
2675 break;
2676 case OPC_OR:
460f00c4
AJ
2677 if (likely(rs != 0 && rt != 0)) {
2678 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2679 } else if (rs == 0 && rt != 0) {
2680 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2681 } else if (rs != 0 && rt == 0) {
2682 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2683 } else {
2684 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2685 }
6af0bf9c
FB
2686 opn = "or";
2687 break;
2688 case OPC_XOR:
460f00c4
AJ
2689 if (likely(rs != 0 && rt != 0)) {
2690 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2691 } else if (rs == 0 && rt != 0) {
2692 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2693 } else if (rs != 0 && rt == 0) {
2694 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2695 } else {
2696 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2697 }
6af0bf9c
FB
2698 opn = "xor";
2699 break;
460f00c4 2700 }
2abf314d 2701 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2702 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2703}
2704
2705/* Set on lower than */
d75c135e 2706static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2707 int rd, int rs, int rt)
460f00c4
AJ
2708{
2709 const char *opn = "slt";
2710 TCGv t0, t1;
2711
2712 if (rd == 0) {
2713 /* If no destination, treat it as a NOP. */
2714 MIPS_DEBUG("NOP");
2715 return;
2716 }
2717
2718 t0 = tcg_temp_new();
2719 t1 = tcg_temp_new();
2720 gen_load_gpr(t0, rs);
2721 gen_load_gpr(t1, rt);
2722 switch (opc) {
2723 case OPC_SLT:
e68dd28f 2724 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2725 opn = "slt";
6af0bf9c 2726 break;
460f00c4 2727 case OPC_SLTU:
e68dd28f 2728 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2729 opn = "sltu";
2730 break;
2731 }
2abf314d 2732 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2733 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2734 tcg_temp_free(t0);
2735 tcg_temp_free(t1);
2736}
20c4c97c 2737
460f00c4 2738/* Shifts */
d75c135e
AJ
2739static void gen_shift(DisasContext *ctx, uint32_t opc,
2740 int rd, int rs, int rt)
460f00c4
AJ
2741{
2742 const char *opn = "shifts";
2743 TCGv t0, t1;
20c4c97c 2744
460f00c4
AJ
2745 if (rd == 0) {
2746 /* If no destination, treat it as a NOP.
2747 For add & sub, we must generate the overflow exception when needed. */
2748 MIPS_DEBUG("NOP");
2749 return;
2750 }
2751
2752 t0 = tcg_temp_new();
2753 t1 = tcg_temp_new();
2754 gen_load_gpr(t0, rs);
2755 gen_load_gpr(t1, rt);
2756 switch (opc) {
6af0bf9c 2757 case OPC_SLLV:
78723684
TS
2758 tcg_gen_andi_tl(t0, t0, 0x1f);
2759 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2760 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2761 opn = "sllv";
2762 break;
2763 case OPC_SRAV:
78723684 2764 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2765 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2766 opn = "srav";
2767 break;
2768 case OPC_SRLV:
ea63e2c3
NF
2769 tcg_gen_ext32u_tl(t1, t1);
2770 tcg_gen_andi_tl(t0, t0, 0x1f);
2771 tcg_gen_shr_tl(t0, t1, t0);
2772 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2773 opn = "srlv";
2774 break;
2775 case OPC_ROTRV:
2776 {
2777 TCGv_i32 t2 = tcg_temp_new_i32();
2778 TCGv_i32 t3 = tcg_temp_new_i32();
2779
2780 tcg_gen_trunc_tl_i32(t2, t0);
2781 tcg_gen_trunc_tl_i32(t3, t1);
2782 tcg_gen_andi_i32(t2, t2, 0x1f);
2783 tcg_gen_rotr_i32(t2, t3, t2);
2784 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2785 tcg_temp_free_i32(t2);
2786 tcg_temp_free_i32(t3);
2787 opn = "rotrv";
5a63bcb2 2788 }
7a387fff 2789 break;
d26bc211 2790#if defined(TARGET_MIPS64)
7a387fff 2791 case OPC_DSLLV:
78723684 2792 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2793 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2794 opn = "dsllv";
2795 break;
2796 case OPC_DSRAV:
78723684 2797 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2798 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2799 opn = "dsrav";
2800 break;
2801 case OPC_DSRLV:
ea63e2c3
NF
2802 tcg_gen_andi_tl(t0, t0, 0x3f);
2803 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2804 opn = "dsrlv";
2805 break;
2806 case OPC_DROTRV:
2807 tcg_gen_andi_tl(t0, t0, 0x3f);
2808 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2809 opn = "drotrv";
6af0bf9c 2810 break;
7a387fff 2811#endif
6af0bf9c 2812 }
2abf314d 2813 (void)opn; /* avoid a compiler warning */
6af0bf9c 2814 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2815 tcg_temp_free(t0);
2816 tcg_temp_free(t1);
6af0bf9c
FB
2817}
2818
2819/* Arithmetic on HI/LO registers */
26135ead 2820static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2821{
923617a3 2822 const char *opn = "hilo";
6af0bf9c
FB
2823
2824 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2825 /* Treat as NOP. */
6af0bf9c 2826 MIPS_DEBUG("NOP");
a1f6684d 2827 return;
6af0bf9c 2828 }
4133498f 2829
4133498f
JL
2830 if (acc != 0) {
2831 check_dsp(ctx);
2832 }
2833
6af0bf9c
FB
2834 switch (opc) {
2835 case OPC_MFHI:
4133498f
JL
2836#if defined(TARGET_MIPS64)
2837 if (acc != 0) {
2838 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2839 } else
2840#endif
2841 {
2842 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2843 }
6af0bf9c
FB
2844 opn = "mfhi";
2845 break;
2846 case OPC_MFLO:
4133498f
JL
2847#if defined(TARGET_MIPS64)
2848 if (acc != 0) {
2849 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2850 } else
2851#endif
2852 {
2853 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2854 }
6af0bf9c
FB
2855 opn = "mflo";
2856 break;
2857 case OPC_MTHI:
4133498f
JL
2858 if (reg != 0) {
2859#if defined(TARGET_MIPS64)
2860 if (acc != 0) {
2861 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2862 } else
2863#endif
2864 {
2865 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2866 }
2867 } else {
2868 tcg_gen_movi_tl(cpu_HI[acc], 0);
2869 }
6af0bf9c
FB
2870 opn = "mthi";
2871 break;
2872 case OPC_MTLO:
4133498f
JL
2873 if (reg != 0) {
2874#if defined(TARGET_MIPS64)
2875 if (acc != 0) {
2876 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2877 } else
2878#endif
2879 {
2880 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2881 }
2882 } else {
2883 tcg_gen_movi_tl(cpu_LO[acc], 0);
2884 }
6af0bf9c
FB
2885 opn = "mtlo";
2886 break;
6af0bf9c 2887 }
2abf314d 2888 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2889 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2890}
2891
d4ea6acd
LA
2892static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2893 TCGMemOp memop)
2894{
2895 TCGv t0 = tcg_const_tl(addr);
2896 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
2897 gen_store_gpr(t0, reg);
2898 tcg_temp_free(t0);
2899}
2900
2901static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
2902{
2903 target_long offset;
2904 target_long addr;
2905
2906 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
2907 case OPC_ADDIUPC:
2908 if (rs != 0) {
2909 offset = sextract32(ctx->opcode << 2, 0, 21);
2910 addr = addr_add(ctx, ctx->pc, offset);
2911 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2912 }
2913 break;
2914 case R6_OPC_LWPC:
2915 offset = sextract32(ctx->opcode << 2, 0, 21);
2916 addr = addr_add(ctx, ctx->pc, offset);
2917 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
2918 break;
2919#if defined(TARGET_MIPS64)
2920 case OPC_LWUPC:
2921 check_mips_64(ctx);
2922 offset = sextract32(ctx->opcode << 2, 0, 21);
2923 addr = addr_add(ctx, ctx->pc, offset);
2924 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
2925 break;
2926#endif
2927 default:
2928 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
2929 case OPC_AUIPC:
2930 if (rs != 0) {
2931 offset = imm << 16;
2932 addr = addr_add(ctx, ctx->pc, offset);
2933 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2934 }
2935 break;
2936 case OPC_ALUIPC:
2937 if (rs != 0) {
2938 offset = imm << 16;
2939 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
2940 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2941 }
2942 break;
2943#if defined(TARGET_MIPS64)
2944 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
2945 case R6_OPC_LDPC + (1 << 16):
2946 case R6_OPC_LDPC + (2 << 16):
2947 case R6_OPC_LDPC + (3 << 16):
2948 check_mips_64(ctx);
2949 offset = sextract32(ctx->opcode << 3, 0, 21);
2950 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
2951 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
2952 break;
2953#endif
2954 default:
2955 MIPS_INVAL("OPC_PCREL");
2956 generate_exception(ctx, EXCP_RI);
2957 break;
2958 }
2959 break;
2960 }
2961}
2962
b42ee5e1
LA
2963static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
2964{
2965 const char *opn = "r6 mul/div";
2966 TCGv t0, t1;
2967
2968 if (rd == 0) {
2969 /* Treat as NOP. */
2970 MIPS_DEBUG("NOP");
2971 return;
2972 }
2973
2974 t0 = tcg_temp_new();
2975 t1 = tcg_temp_new();
2976
2977 gen_load_gpr(t0, rs);
2978 gen_load_gpr(t1, rt);
2979
2980 switch (opc) {
2981 case R6_OPC_DIV:
2982 {
2983 TCGv t2 = tcg_temp_new();
2984 TCGv t3 = tcg_temp_new();
2985 tcg_gen_ext32s_tl(t0, t0);
2986 tcg_gen_ext32s_tl(t1, t1);
2987 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2988 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2989 tcg_gen_and_tl(t2, t2, t3);
2990 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2991 tcg_gen_or_tl(t2, t2, t3);
2992 tcg_gen_movi_tl(t3, 0);
2993 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2994 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2995 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2996 tcg_temp_free(t3);
2997 tcg_temp_free(t2);
2998 }
2999 opn = "div";
3000 break;
3001 case R6_OPC_MOD:
3002 {
3003 TCGv t2 = tcg_temp_new();
3004 TCGv t3 = tcg_temp_new();
3005 tcg_gen_ext32s_tl(t0, t0);
3006 tcg_gen_ext32s_tl(t1, t1);
3007 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3008 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3009 tcg_gen_and_tl(t2, t2, t3);
3010 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3011 tcg_gen_or_tl(t2, t2, t3);
3012 tcg_gen_movi_tl(t3, 0);
3013 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3014 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3015 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3016 tcg_temp_free(t3);
3017 tcg_temp_free(t2);
3018 }
3019 opn = "mod";
3020 break;
3021 case R6_OPC_DIVU:
3022 {
3023 TCGv t2 = tcg_const_tl(0);
3024 TCGv t3 = tcg_const_tl(1);
3025 tcg_gen_ext32u_tl(t0, t0);
3026 tcg_gen_ext32u_tl(t1, t1);
3027 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3028 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3029 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3030 tcg_temp_free(t3);
3031 tcg_temp_free(t2);
3032 }
3033 opn = "divu";
3034 break;
3035 case R6_OPC_MODU:
3036 {
3037 TCGv t2 = tcg_const_tl(0);
3038 TCGv t3 = tcg_const_tl(1);
3039 tcg_gen_ext32u_tl(t0, t0);
3040 tcg_gen_ext32u_tl(t1, t1);
3041 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3042 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044 tcg_temp_free(t3);
3045 tcg_temp_free(t2);
3046 }
3047 opn = "modu";
3048 break;
3049 case R6_OPC_MUL:
3050 {
3051 TCGv_i32 t2 = tcg_temp_new_i32();
3052 TCGv_i32 t3 = tcg_temp_new_i32();
3053 tcg_gen_trunc_tl_i32(t2, t0);
3054 tcg_gen_trunc_tl_i32(t3, t1);
3055 tcg_gen_mul_i32(t2, t2, t3);
3056 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3057 tcg_temp_free_i32(t2);
3058 tcg_temp_free_i32(t3);
3059 }
3060 opn = "mul";
3061 break;
3062 case R6_OPC_MUH:
3063 {
3064 TCGv_i32 t2 = tcg_temp_new_i32();
3065 TCGv_i32 t3 = tcg_temp_new_i32();
3066 tcg_gen_trunc_tl_i32(t2, t0);
3067 tcg_gen_trunc_tl_i32(t3, t1);
3068 tcg_gen_muls2_i32(t2, t3, t2, t3);
3069 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3070 tcg_temp_free_i32(t2);
3071 tcg_temp_free_i32(t3);
3072 }
3073 opn = "muh";
3074 break;
3075 case R6_OPC_MULU:
3076 {
3077 TCGv_i32 t2 = tcg_temp_new_i32();
3078 TCGv_i32 t3 = tcg_temp_new_i32();
3079 tcg_gen_trunc_tl_i32(t2, t0);
3080 tcg_gen_trunc_tl_i32(t3, t1);
3081 tcg_gen_mul_i32(t2, t2, t3);
3082 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3083 tcg_temp_free_i32(t2);
3084 tcg_temp_free_i32(t3);
3085 }
3086 opn = "mulu";
3087 break;
3088 case R6_OPC_MUHU:
3089 {
3090 TCGv_i32 t2 = tcg_temp_new_i32();
3091 TCGv_i32 t3 = tcg_temp_new_i32();
3092 tcg_gen_trunc_tl_i32(t2, t0);
3093 tcg_gen_trunc_tl_i32(t3, t1);
3094 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3095 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3096 tcg_temp_free_i32(t2);
3097 tcg_temp_free_i32(t3);
3098 }
3099 opn = "muhu";
3100 break;
3101#if defined(TARGET_MIPS64)
3102 case R6_OPC_DDIV:
3103 {
3104 TCGv t2 = tcg_temp_new();
3105 TCGv t3 = tcg_temp_new();
3106 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3107 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3108 tcg_gen_and_tl(t2, t2, t3);
3109 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3110 tcg_gen_or_tl(t2, t2, t3);
3111 tcg_gen_movi_tl(t3, 0);
3112 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3113 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3114 tcg_temp_free(t3);
3115 tcg_temp_free(t2);
3116 }
3117 opn = "ddiv";
3118 break;
3119 case R6_OPC_DMOD:
3120 {
3121 TCGv t2 = tcg_temp_new();
3122 TCGv t3 = tcg_temp_new();
3123 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3124 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3125 tcg_gen_and_tl(t2, t2, t3);
3126 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3127 tcg_gen_or_tl(t2, t2, t3);
3128 tcg_gen_movi_tl(t3, 0);
3129 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3130 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3131 tcg_temp_free(t3);
3132 tcg_temp_free(t2);
3133 }
3134 opn = "dmod";
3135 break;
3136 case R6_OPC_DDIVU:
3137 {
3138 TCGv t2 = tcg_const_tl(0);
3139 TCGv t3 = tcg_const_tl(1);
3140 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3141 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3142 tcg_temp_free(t3);
3143 tcg_temp_free(t2);
3144 }
3145 opn = "ddivu";
3146 break;
3147 case R6_OPC_DMODU:
3148 {
3149 TCGv t2 = tcg_const_tl(0);
3150 TCGv t3 = tcg_const_tl(1);
3151 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3152 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3153 tcg_temp_free(t3);
3154 tcg_temp_free(t2);
3155 }
3156 opn = "dmodu";
3157 break;
3158 case R6_OPC_DMUL:
3159 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3160 opn = "dmul";
3161 break;
3162 case R6_OPC_DMUH:
3163 {
3164 TCGv t2 = tcg_temp_new();
3165 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3166 tcg_temp_free(t2);
3167 }
3168 opn = "dmuh";
3169 break;
3170 case R6_OPC_DMULU:
3171 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3172 opn = "dmulu";
3173 break;
3174 case R6_OPC_DMUHU:
3175 {
3176 TCGv t2 = tcg_temp_new();
3177 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3178 tcg_temp_free(t2);
3179 }
3180 opn = "dmuhu";
3181 break;
3182#endif
3183 default:
3184 MIPS_INVAL(opn);
3185 generate_exception(ctx, EXCP_RI);
3186 goto out;
3187 }
3188 (void)opn; /* avoid a compiler warning */
3189 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3190 out:
3191 tcg_temp_free(t0);
3192 tcg_temp_free(t1);
3193}
3194
26135ead
RS
3195static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3196 int acc, int rs, int rt)
6af0bf9c 3197{
923617a3 3198 const char *opn = "mul/div";
d45f89f4
AJ
3199 TCGv t0, t1;
3200
51127181
AJ
3201 t0 = tcg_temp_new();
3202 t1 = tcg_temp_new();
6af0bf9c 3203
78723684
TS
3204 gen_load_gpr(t0, rs);
3205 gen_load_gpr(t1, rt);
51127181 3206
26135ead
RS
3207 if (acc != 0) {
3208 check_dsp(ctx);
3209 }
3210
6af0bf9c
FB
3211 switch (opc) {
3212 case OPC_DIV:
48d38ca5 3213 {
51127181
AJ
3214 TCGv t2 = tcg_temp_new();
3215 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3216 tcg_gen_ext32s_tl(t0, t0);
3217 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3218 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3219 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3220 tcg_gen_and_tl(t2, t2, t3);
3221 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3222 tcg_gen_or_tl(t2, t2, t3);
3223 tcg_gen_movi_tl(t3, 0);
3224 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3225 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3226 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3227 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3228 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3229 tcg_temp_free(t3);
3230 tcg_temp_free(t2);
48d38ca5 3231 }
6af0bf9c
FB
3232 opn = "div";
3233 break;
3234 case OPC_DIVU:
48d38ca5 3235 {
51127181
AJ
3236 TCGv t2 = tcg_const_tl(0);
3237 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3238 tcg_gen_ext32u_tl(t0, t0);
3239 tcg_gen_ext32u_tl(t1, t1);
51127181 3240 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3241 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3242 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3243 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3244 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3245 tcg_temp_free(t3);
3246 tcg_temp_free(t2);
48d38ca5 3247 }
6af0bf9c
FB
3248 opn = "divu";
3249 break;
3250 case OPC_MULT:
214c465f 3251 {
ce1dd5d1
RH
3252 TCGv_i32 t2 = tcg_temp_new_i32();
3253 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3254 tcg_gen_trunc_tl_i32(t2, t0);
3255 tcg_gen_trunc_tl_i32(t3, t1);
3256 tcg_gen_muls2_i32(t2, t3, t2, t3);
3257 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3258 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3259 tcg_temp_free_i32(t2);
3260 tcg_temp_free_i32(t3);
214c465f 3261 }
6af0bf9c
FB
3262 opn = "mult";
3263 break;
3264 case OPC_MULTU:
214c465f 3265 {
ce1dd5d1
RH
3266 TCGv_i32 t2 = tcg_temp_new_i32();
3267 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3268 tcg_gen_trunc_tl_i32(t2, t0);
3269 tcg_gen_trunc_tl_i32(t3, t1);
3270 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3271 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3272 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3273 tcg_temp_free_i32(t2);
3274 tcg_temp_free_i32(t3);
214c465f 3275 }
6af0bf9c
FB
3276 opn = "multu";
3277 break;
d26bc211 3278#if defined(TARGET_MIPS64)
7a387fff 3279 case OPC_DDIV:
48d38ca5 3280 {
51127181
AJ
3281 TCGv t2 = tcg_temp_new();
3282 TCGv t3 = tcg_temp_new();
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3285 tcg_gen_and_tl(t2, t2, t3);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3287 tcg_gen_or_tl(t2, t2, t3);
3288 tcg_gen_movi_tl(t3, 0);
3289 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3290 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3291 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3292 tcg_temp_free(t3);
3293 tcg_temp_free(t2);
48d38ca5 3294 }
7a387fff
TS
3295 opn = "ddiv";
3296 break;
3297 case OPC_DDIVU:
48d38ca5 3298 {
51127181
AJ
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3302 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3303 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3304 tcg_temp_free(t3);
3305 tcg_temp_free(t2);
48d38ca5 3306 }
7a387fff
TS
3307 opn = "ddivu";
3308 break;
3309 case OPC_DMULT:
26135ead 3310 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3311 opn = "dmult";
3312 break;
3313 case OPC_DMULTU:
26135ead 3314 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3315 opn = "dmultu";
3316 break;
3317#endif
6af0bf9c 3318 case OPC_MADD:
214c465f 3319 {
d45f89f4
AJ
3320 TCGv_i64 t2 = tcg_temp_new_i64();
3321 TCGv_i64 t3 = tcg_temp_new_i64();
3322
3323 tcg_gen_ext_tl_i64(t2, t0);
3324 tcg_gen_ext_tl_i64(t3, t1);
3325 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3326 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3327 tcg_gen_add_i64(t2, t2, t3);
3328 tcg_temp_free_i64(t3);
3329 tcg_gen_trunc_i64_tl(t0, t2);
3330 tcg_gen_shri_i64(t2, t2, 32);
3331 tcg_gen_trunc_i64_tl(t1, t2);
3332 tcg_temp_free_i64(t2);
4133498f
JL
3333 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3334 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3335 }
6af0bf9c
FB
3336 opn = "madd";
3337 break;
3338 case OPC_MADDU:
4133498f 3339 {
d45f89f4
AJ
3340 TCGv_i64 t2 = tcg_temp_new_i64();
3341 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3342
78723684
TS
3343 tcg_gen_ext32u_tl(t0, t0);
3344 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3345 tcg_gen_extu_tl_i64(t2, t0);
3346 tcg_gen_extu_tl_i64(t3, t1);
3347 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3348 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3349 tcg_gen_add_i64(t2, t2, t3);
3350 tcg_temp_free_i64(t3);
3351 tcg_gen_trunc_i64_tl(t0, t2);
3352 tcg_gen_shri_i64(t2, t2, 32);
3353 tcg_gen_trunc_i64_tl(t1, t2);
3354 tcg_temp_free_i64(t2);
4133498f
JL
3355 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3356 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3357 }
6af0bf9c
FB
3358 opn = "maddu";
3359 break;
3360 case OPC_MSUB:
214c465f 3361 {
d45f89f4
AJ
3362 TCGv_i64 t2 = tcg_temp_new_i64();
3363 TCGv_i64 t3 = tcg_temp_new_i64();
3364
3365 tcg_gen_ext_tl_i64(t2, t0);
3366 tcg_gen_ext_tl_i64(t3, t1);
3367 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3368 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3369 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3370 tcg_temp_free_i64(t3);
3371 tcg_gen_trunc_i64_tl(t0, t2);
3372 tcg_gen_shri_i64(t2, t2, 32);
3373 tcg_gen_trunc_i64_tl(t1, t2);
3374 tcg_temp_free_i64(t2);
4133498f
JL
3375 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3376 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3377 }
6af0bf9c
FB
3378 opn = "msub";
3379 break;
3380 case OPC_MSUBU:
214c465f 3381 {
d45f89f4
AJ
3382 TCGv_i64 t2 = tcg_temp_new_i64();
3383 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3384
78723684
TS
3385 tcg_gen_ext32u_tl(t0, t0);
3386 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3387 tcg_gen_extu_tl_i64(t2, t0);
3388 tcg_gen_extu_tl_i64(t3, t1);
3389 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3390 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3391 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3392 tcg_temp_free_i64(t3);
3393 tcg_gen_trunc_i64_tl(t0, t2);
3394 tcg_gen_shri_i64(t2, t2, 32);
3395 tcg_gen_trunc_i64_tl(t1, t2);
3396 tcg_temp_free_i64(t2);
4133498f
JL
3397 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3398 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3399 }
6af0bf9c
FB
3400 opn = "msubu";
3401 break;
3402 default:
923617a3 3403 MIPS_INVAL(opn);
6af0bf9c 3404 generate_exception(ctx, EXCP_RI);
78723684 3405 goto out;
6af0bf9c 3406 }
2abf314d 3407 (void)opn; /* avoid a compiler warning */
6af0bf9c 3408 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3409 out:
3410 tcg_temp_free(t0);
3411 tcg_temp_free(t1);
6af0bf9c
FB
3412}
3413
e9c71dd1
TS
3414static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3415 int rd, int rs, int rt)
3416{
3417 const char *opn = "mul vr54xx";
f157bfe1
AJ
3418 TCGv t0 = tcg_temp_new();
3419 TCGv t1 = tcg_temp_new();
e9c71dd1 3420
6c5c1e20
TS
3421 gen_load_gpr(t0, rs);
3422 gen_load_gpr(t1, rt);
e9c71dd1
TS
3423
3424 switch (opc) {
3425 case OPC_VR54XX_MULS:
895c2d04 3426 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3427 opn = "muls";
6958549d 3428 break;
e9c71dd1 3429 case OPC_VR54XX_MULSU:
895c2d04 3430 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3431 opn = "mulsu";
6958549d 3432 break;
e9c71dd1 3433 case OPC_VR54XX_MACC:
895c2d04 3434 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3435 opn = "macc";
6958549d 3436 break;
e9c71dd1 3437 case OPC_VR54XX_MACCU:
895c2d04 3438 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3439 opn = "maccu";
6958549d 3440 break;
e9c71dd1 3441 case OPC_VR54XX_MSAC:
895c2d04 3442 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3443 opn = "msac";
6958549d 3444 break;
e9c71dd1 3445 case OPC_VR54XX_MSACU:
895c2d04 3446 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3447 opn = "msacu";
6958549d 3448 break;
e9c71dd1 3449 case OPC_VR54XX_MULHI:
895c2d04 3450 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3451 opn = "mulhi";
6958549d 3452 break;
e9c71dd1 3453 case OPC_VR54XX_MULHIU:
895c2d04 3454 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3455 opn = "mulhiu";
6958549d 3456 break;
e9c71dd1 3457 case OPC_VR54XX_MULSHI:
895c2d04 3458 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3459 opn = "mulshi";
6958549d 3460 break;
e9c71dd1 3461 case OPC_VR54XX_MULSHIU:
895c2d04 3462 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3463 opn = "mulshiu";
6958549d 3464 break;
e9c71dd1 3465 case OPC_VR54XX_MACCHI:
895c2d04 3466 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3467 opn = "macchi";
6958549d 3468 break;
e9c71dd1 3469 case OPC_VR54XX_MACCHIU:
895c2d04 3470 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3471 opn = "macchiu";
6958549d 3472 break;
e9c71dd1 3473 case OPC_VR54XX_MSACHI:
895c2d04 3474 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3475 opn = "msachi";
6958549d 3476 break;
e9c71dd1 3477 case OPC_VR54XX_MSACHIU:
895c2d04 3478 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3479 opn = "msachiu";
6958549d 3480 break;
e9c71dd1
TS
3481 default:
3482 MIPS_INVAL("mul vr54xx");
3483 generate_exception(ctx, EXCP_RI);
6c5c1e20 3484 goto out;
e9c71dd1 3485 }
6c5c1e20 3486 gen_store_gpr(t0, rd);
2abf314d 3487 (void)opn; /* avoid a compiler warning */
e9c71dd1 3488 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3489
3490 out:
3491 tcg_temp_free(t0);
3492 tcg_temp_free(t1);
e9c71dd1
TS
3493}
3494
7a387fff 3495static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3496 int rd, int rs)
3497{
923617a3 3498 const char *opn = "CLx";
20e1fb52 3499 TCGv t0;
6c5c1e20 3500
6af0bf9c 3501 if (rd == 0) {
ead9360e 3502 /* Treat as NOP. */
6af0bf9c 3503 MIPS_DEBUG("NOP");
20e1fb52 3504 return;
6af0bf9c 3505 }
20e1fb52 3506 t0 = tcg_temp_new();
6c5c1e20 3507 gen_load_gpr(t0, rs);
6af0bf9c
FB
3508 switch (opc) {
3509 case OPC_CLO:
4267d3e6 3510 case R6_OPC_CLO:
20e1fb52 3511 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3512 opn = "clo";
3513 break;
3514 case OPC_CLZ:
4267d3e6 3515 case R6_OPC_CLZ:
20e1fb52 3516 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3517 opn = "clz";
3518 break;
d26bc211 3519#if defined(TARGET_MIPS64)
7a387fff 3520 case OPC_DCLO:
4267d3e6 3521 case R6_OPC_DCLO:
20e1fb52 3522 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3523 opn = "dclo";
3524 break;
3525 case OPC_DCLZ:
4267d3e6 3526 case R6_OPC_DCLZ:
20e1fb52 3527 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3528 opn = "dclz";
3529 break;
3530#endif
6af0bf9c 3531 }
2abf314d 3532 (void)opn; /* avoid a compiler warning */
6af0bf9c 3533 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3534 tcg_temp_free(t0);
6af0bf9c
FB
3535}
3536
161f85e6 3537/* Godson integer instructions */
bd277fa1
RH
3538static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3539 int rd, int rs, int rt)
161f85e6
AJ
3540{
3541 const char *opn = "loongson";
3542 TCGv t0, t1;
3543
3544 if (rd == 0) {
3545 /* Treat as NOP. */
3546 MIPS_DEBUG("NOP");
3547 return;
3548 }
3549
3550 switch (opc) {
3551 case OPC_MULT_G_2E:
3552 case OPC_MULT_G_2F:
3553 case OPC_MULTU_G_2E:
3554 case OPC_MULTU_G_2F:
3555#if defined(TARGET_MIPS64)
3556 case OPC_DMULT_G_2E:
3557 case OPC_DMULT_G_2F:
3558 case OPC_DMULTU_G_2E:
3559 case OPC_DMULTU_G_2F:
3560#endif
3561 t0 = tcg_temp_new();
3562 t1 = tcg_temp_new();
3563 break;
3564 default:
3565 t0 = tcg_temp_local_new();
3566 t1 = tcg_temp_local_new();
3567 break;
3568 }
3569
3570 gen_load_gpr(t0, rs);
3571 gen_load_gpr(t1, rt);
3572
3573 switch (opc) {
3574 case OPC_MULT_G_2E:
3575 case OPC_MULT_G_2F:
3576 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3577 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3578 opn = "mult.g";
3579 break;
3580 case OPC_MULTU_G_2E:
3581 case OPC_MULTU_G_2F:
3582 tcg_gen_ext32u_tl(t0, t0);
3583 tcg_gen_ext32u_tl(t1, t1);
3584 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3585 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3586 opn = "multu.g";
3587 break;
3588 case OPC_DIV_G_2E:
3589 case OPC_DIV_G_2F:
3590 {
3591 int l1 = gen_new_label();
3592 int l2 = gen_new_label();
3593 int l3 = gen_new_label();
3594 tcg_gen_ext32s_tl(t0, t0);
3595 tcg_gen_ext32s_tl(t1, t1);
3596 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3597 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3598 tcg_gen_br(l3);
3599 gen_set_label(l1);
3600 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3601 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3602 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3603 tcg_gen_br(l3);
3604 gen_set_label(l2);
3605 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3606 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3607 gen_set_label(l3);
3608 }
3609 opn = "div.g";
3610 break;
3611 case OPC_DIVU_G_2E:
3612 case OPC_DIVU_G_2F:
3613 {
3614 int l1 = gen_new_label();
3615 int l2 = gen_new_label();
3616 tcg_gen_ext32u_tl(t0, t0);
3617 tcg_gen_ext32u_tl(t1, t1);
3618 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3619 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3620 tcg_gen_br(l2);
3621 gen_set_label(l1);
3622 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3623 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3624 gen_set_label(l2);
3625 }
3626 opn = "divu.g";
3627 break;
3628 case OPC_MOD_G_2E:
3629 case OPC_MOD_G_2F:
3630 {
3631 int l1 = gen_new_label();
3632 int l2 = gen_new_label();
3633 int l3 = gen_new_label();
3634 tcg_gen_ext32u_tl(t0, t0);
3635 tcg_gen_ext32u_tl(t1, t1);
3636 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3637 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3638 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3639 gen_set_label(l1);
3640 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3641 tcg_gen_br(l3);
3642 gen_set_label(l2);
3643 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3644 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3645 gen_set_label(l3);
3646 }
3647 opn = "mod.g";
3648 break;
3649 case OPC_MODU_G_2E:
3650 case OPC_MODU_G_2F:
3651 {
3652 int l1 = gen_new_label();
3653 int l2 = gen_new_label();
3654 tcg_gen_ext32u_tl(t0, t0);
3655 tcg_gen_ext32u_tl(t1, t1);
3656 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3657 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3658 tcg_gen_br(l2);
3659 gen_set_label(l1);
3660 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3661 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3662 gen_set_label(l2);
3663 }
3664 opn = "modu.g";
3665 break;
3666#if defined(TARGET_MIPS64)
3667 case OPC_DMULT_G_2E:
3668 case OPC_DMULT_G_2F:
3669 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3670 opn = "dmult.g";
3671 break;
3672 case OPC_DMULTU_G_2E:
3673 case OPC_DMULTU_G_2F:
3674 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3675 opn = "dmultu.g";
3676 break;
3677 case OPC_DDIV_G_2E:
3678 case OPC_DDIV_G_2F:
3679 {
3680 int l1 = gen_new_label();
3681 int l2 = gen_new_label();
3682 int l3 = gen_new_label();
3683 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3684 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3685 tcg_gen_br(l3);
3686 gen_set_label(l1);
3687 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3688 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3689 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3690 tcg_gen_br(l3);
3691 gen_set_label(l2);
3692 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3693 gen_set_label(l3);
3694 }
3695 opn = "ddiv.g";
3696 break;
3697 case OPC_DDIVU_G_2E:
3698 case OPC_DDIVU_G_2F:
3699 {
3700 int l1 = gen_new_label();
3701 int l2 = gen_new_label();
3702 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3703 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3704 tcg_gen_br(l2);
3705 gen_set_label(l1);
3706 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3707 gen_set_label(l2);
3708 }
3709 opn = "ddivu.g";
3710 break;
3711 case OPC_DMOD_G_2E:
3712 case OPC_DMOD_G_2F:
3713 {
3714 int l1 = gen_new_label();
3715 int l2 = gen_new_label();
3716 int l3 = gen_new_label();
3717 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3718 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3719 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3720 gen_set_label(l1);
3721 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3722 tcg_gen_br(l3);
3723 gen_set_label(l2);
3724 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3725 gen_set_label(l3);
3726 }
3727 opn = "dmod.g";
3728 break;
3729 case OPC_DMODU_G_2E:
3730 case OPC_DMODU_G_2F:
3731 {
3732 int l1 = gen_new_label();
3733 int l2 = gen_new_label();
3734 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3735 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3736 tcg_gen_br(l2);
3737 gen_set_label(l1);
3738 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3739 gen_set_label(l2);
3740 }
3741 opn = "dmodu.g";
3742 break;
3743#endif
3744 }
3745
2abf314d 3746 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3747 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3748 tcg_temp_free(t0);
3749 tcg_temp_free(t1);
3750}
3751
bd277fa1
RH
3752/* Loongson multimedia instructions */
3753static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3754{
3755 const char *opn = "loongson_cp2";
3756 uint32_t opc, shift_max;
3757 TCGv_i64 t0, t1;
3758
3759 opc = MASK_LMI(ctx->opcode);
3760 switch (opc) {
3761 case OPC_ADD_CP2:
3762 case OPC_SUB_CP2:
3763 case OPC_DADD_CP2:
3764 case OPC_DSUB_CP2:
3765 t0 = tcg_temp_local_new_i64();
3766 t1 = tcg_temp_local_new_i64();
3767 break;
3768 default:
3769 t0 = tcg_temp_new_i64();
3770 t1 = tcg_temp_new_i64();
3771 break;
3772 }
3773
3774 gen_load_fpr64(ctx, t0, rs);
3775 gen_load_fpr64(ctx, t1, rt);
3776
3777#define LMI_HELPER(UP, LO) \
3778 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3779#define LMI_HELPER_1(UP, LO) \
3780 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3781#define LMI_DIRECT(UP, LO, OP) \
3782 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3783
3784 switch (opc) {
3785 LMI_HELPER(PADDSH, paddsh);
3786 LMI_HELPER(PADDUSH, paddush);
3787 LMI_HELPER(PADDH, paddh);
3788 LMI_HELPER(PADDW, paddw);
3789 LMI_HELPER(PADDSB, paddsb);
3790 LMI_HELPER(PADDUSB, paddusb);
3791 LMI_HELPER(PADDB, paddb);
3792
3793 LMI_HELPER(PSUBSH, psubsh);
3794 LMI_HELPER(PSUBUSH, psubush);
3795 LMI_HELPER(PSUBH, psubh);
3796 LMI_HELPER(PSUBW, psubw);
3797 LMI_HELPER(PSUBSB, psubsb);
3798 LMI_HELPER(PSUBUSB, psubusb);
3799 LMI_HELPER(PSUBB, psubb);
3800
3801 LMI_HELPER(PSHUFH, pshufh);
3802 LMI_HELPER(PACKSSWH, packsswh);
3803 LMI_HELPER(PACKSSHB, packsshb);
3804 LMI_HELPER(PACKUSHB, packushb);
3805
3806 LMI_HELPER(PUNPCKLHW, punpcklhw);
3807 LMI_HELPER(PUNPCKHHW, punpckhhw);
3808 LMI_HELPER(PUNPCKLBH, punpcklbh);
3809 LMI_HELPER(PUNPCKHBH, punpckhbh);
3810 LMI_HELPER(PUNPCKLWD, punpcklwd);
3811 LMI_HELPER(PUNPCKHWD, punpckhwd);
3812
3813 LMI_HELPER(PAVGH, pavgh);
3814 LMI_HELPER(PAVGB, pavgb);
3815 LMI_HELPER(PMAXSH, pmaxsh);
3816 LMI_HELPER(PMINSH, pminsh);
3817 LMI_HELPER(PMAXUB, pmaxub);
3818 LMI_HELPER(PMINUB, pminub);
3819
3820 LMI_HELPER(PCMPEQW, pcmpeqw);
3821 LMI_HELPER(PCMPGTW, pcmpgtw);
3822 LMI_HELPER(PCMPEQH, pcmpeqh);
3823 LMI_HELPER(PCMPGTH, pcmpgth);
3824 LMI_HELPER(PCMPEQB, pcmpeqb);
3825 LMI_HELPER(PCMPGTB, pcmpgtb);
3826
3827 LMI_HELPER(PSLLW, psllw);
3828 LMI_HELPER(PSLLH, psllh);
3829 LMI_HELPER(PSRLW, psrlw);
3830 LMI_HELPER(PSRLH, psrlh);
3831 LMI_HELPER(PSRAW, psraw);
3832 LMI_HELPER(PSRAH, psrah);
3833
3834 LMI_HELPER(PMULLH, pmullh);
3835 LMI_HELPER(PMULHH, pmulhh);
3836 LMI_HELPER(PMULHUH, pmulhuh);
3837 LMI_HELPER(PMADDHW, pmaddhw);
3838
3839 LMI_HELPER(PASUBUB, pasubub);
3840 LMI_HELPER_1(BIADD, biadd);
3841 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3842
3843 LMI_DIRECT(PADDD, paddd, add);
3844 LMI_DIRECT(PSUBD, psubd, sub);
3845 LMI_DIRECT(XOR_CP2, xor, xor);
3846 LMI_DIRECT(NOR_CP2, nor, nor);
3847 LMI_DIRECT(AND_CP2, and, and);
3848 LMI_DIRECT(PANDN, pandn, andc);
3849 LMI_DIRECT(OR, or, or);
3850
3851 case OPC_PINSRH_0:
3852 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3853 opn = "pinsrh_0";
3854 break;
3855 case OPC_PINSRH_1:
3856 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3857 opn = "pinsrh_1";
3858 break;
3859 case OPC_PINSRH_2:
3860 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3861 opn = "pinsrh_2";
3862 break;
3863 case OPC_PINSRH_3:
3864 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3865 opn = "pinsrh_3";
3866 break;
3867
3868 case OPC_PEXTRH:
3869 tcg_gen_andi_i64(t1, t1, 3);
3870 tcg_gen_shli_i64(t1, t1, 4);
3871 tcg_gen_shr_i64(t0, t0, t1);
3872 tcg_gen_ext16u_i64(t0, t0);
3873 opn = "pextrh";
3874 break;
3875
3876 case OPC_ADDU_CP2:
3877 tcg_gen_add_i64(t0, t0, t1);
3878 tcg_gen_ext32s_i64(t0, t0);
3879 opn = "addu";
3880 break;
3881 case OPC_SUBU_CP2:
3882 tcg_gen_sub_i64(t0, t0, t1);
3883 tcg_gen_ext32s_i64(t0, t0);
3884 opn = "addu";
3885 break;
3886
3887 case OPC_SLL_CP2:
3888 opn = "sll";
3889 shift_max = 32;
3890 goto do_shift;
3891 case OPC_SRL_CP2:
3892 opn = "srl";
3893 shift_max = 32;
3894 goto do_shift;
3895 case OPC_SRA_CP2:
3896 opn = "sra";
3897 shift_max = 32;
3898 goto do_shift;
3899 case OPC_DSLL_CP2:
3900 opn = "dsll";
3901 shift_max = 64;
3902 goto do_shift;
3903 case OPC_DSRL_CP2:
3904 opn = "dsrl";
3905 shift_max = 64;
3906 goto do_shift;
3907 case OPC_DSRA_CP2:
3908 opn = "dsra";
3909 shift_max = 64;
3910 goto do_shift;
3911 do_shift:
3912 /* Make sure shift count isn't TCG undefined behaviour. */
3913 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3914
3915 switch (opc) {
3916 case OPC_SLL_CP2:
3917 case OPC_DSLL_CP2:
3918 tcg_gen_shl_i64(t0, t0, t1);
3919 break;
3920 case OPC_SRA_CP2:
3921 case OPC_DSRA_CP2:
3922 /* Since SRA is UndefinedResult without sign-extended inputs,
3923 we can treat SRA and DSRA the same. */
3924 tcg_gen_sar_i64(t0, t0, t1);
3925 break;
3926 case OPC_SRL_CP2:
3927 /* We want to shift in zeros for SRL; zero-extend first. */
3928 tcg_gen_ext32u_i64(t0, t0);
3929 /* FALLTHRU */
3930 case OPC_DSRL_CP2:
3931 tcg_gen_shr_i64(t0, t0, t1);
3932 break;
3933 }
3934
3935 if (shift_max == 32) {
3936 tcg_gen_ext32s_i64(t0, t0);
3937 }
3938
3939 /* Shifts larger than MAX produce zero. */
3940 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3941 tcg_gen_neg_i64(t1, t1);
3942 tcg_gen_and_i64(t0, t0, t1);
3943 break;
3944
3945 case OPC_ADD_CP2:
3946 case OPC_DADD_CP2:
3947 {
3948 TCGv_i64 t2 = tcg_temp_new_i64();
3949 int lab = gen_new_label();
3950
3951 tcg_gen_mov_i64(t2, t0);
3952 tcg_gen_add_i64(t0, t1, t2);
3953 if (opc == OPC_ADD_CP2) {
3954 tcg_gen_ext32s_i64(t0, t0);
3955 }
3956 tcg_gen_xor_i64(t1, t1, t2);
3957 tcg_gen_xor_i64(t2, t2, t0);
3958 tcg_gen_andc_i64(t1, t2, t1);
3959 tcg_temp_free_i64(t2);
3960 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3961 generate_exception(ctx, EXCP_OVERFLOW);
3962 gen_set_label(lab);
3963
3964 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3965 break;
3966 }
3967
3968 case OPC_SUB_CP2:
3969 case OPC_DSUB_CP2:
3970 {
3971 TCGv_i64 t2 = tcg_temp_new_i64();
3972 int lab = gen_new_label();
3973
3974 tcg_gen_mov_i64(t2, t0);
3975 tcg_gen_sub_i64(t0, t1, t2);
3976 if (opc == OPC_SUB_CP2) {
3977 tcg_gen_ext32s_i64(t0, t0);
3978 }
3979 tcg_gen_xor_i64(t1, t1, t2);
3980 tcg_gen_xor_i64(t2, t2, t0);
3981 tcg_gen_and_i64(t1, t1, t2);
3982 tcg_temp_free_i64(t2);
3983 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3984 generate_exception(ctx, EXCP_OVERFLOW);
3985 gen_set_label(lab);
3986
3987 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3988 break;
3989 }
3990
3991 case OPC_PMULUW:
3992 tcg_gen_ext32u_i64(t0, t0);
3993 tcg_gen_ext32u_i64(t1, t1);
3994 tcg_gen_mul_i64(t0, t0, t1);
3995 opn = "pmuluw";
3996 break;
3997
3998 case OPC_SEQU_CP2:
3999 case OPC_SEQ_CP2:
4000 case OPC_SLTU_CP2:
4001 case OPC_SLT_CP2:
4002 case OPC_SLEU_CP2:
4003 case OPC_SLE_CP2:
4004 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4005 FD field is the CC field? */
4006 default:
4007 MIPS_INVAL(opn);
4008 generate_exception(ctx, EXCP_RI);
4009 return;
4010 }
4011
4012#undef LMI_HELPER
4013#undef LMI_DIRECT
4014
4015 gen_store_fpr64(ctx, t0, rd);
4016
4017 (void)opn; /* avoid a compiler warning */
4018 MIPS_DEBUG("%s %s, %s, %s", opn,
4019 fregnames[rd], fregnames[rs], fregnames[rt]);
4020 tcg_temp_free_i64(t0);
4021 tcg_temp_free_i64(t1);
4022}
4023
6af0bf9c 4024/* Traps */
7a387fff 4025static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4026 int rs, int rt, int16_t imm)
4027{
4028 int cond;
cdc0faa6 4029 TCGv t0 = tcg_temp_new();
1ba74fb8 4030 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4031
4032 cond = 0;
4033 /* Load needed operands */
4034 switch (opc) {
4035 case OPC_TEQ:
4036 case OPC_TGE:
4037 case OPC_TGEU:
4038 case OPC_TLT:
4039 case OPC_TLTU:
4040 case OPC_TNE:
4041 /* Compare two registers */
4042 if (rs != rt) {
be24bb4f
TS
4043 gen_load_gpr(t0, rs);
4044 gen_load_gpr(t1, rt);
6af0bf9c
FB
4045 cond = 1;
4046 }
179e32bb 4047 break;
6af0bf9c
FB
4048 case OPC_TEQI:
4049 case OPC_TGEI:
4050 case OPC_TGEIU:
4051 case OPC_TLTI:
4052 case OPC_TLTIU:
4053 case OPC_TNEI:
4054 /* Compare register to immediate */
4055 if (rs != 0 || imm != 0) {
be24bb4f
TS
4056 gen_load_gpr(t0, rs);
4057 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4058 cond = 1;
4059 }
4060 break;
4061 }
4062 if (cond == 0) {
4063 switch (opc) {
4064 case OPC_TEQ: /* rs == rs */
4065 case OPC_TEQI: /* r0 == 0 */
4066 case OPC_TGE: /* rs >= rs */
4067 case OPC_TGEI: /* r0 >= 0 */
4068 case OPC_TGEU: /* rs >= rs unsigned */
4069 case OPC_TGEIU: /* r0 >= 0 unsigned */
4070 /* Always trap */
cdc0faa6 4071 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
4072 break;
4073 case OPC_TLT: /* rs < rs */
4074 case OPC_TLTI: /* r0 < 0 */
4075 case OPC_TLTU: /* rs < rs unsigned */
4076 case OPC_TLTIU: /* r0 < 0 unsigned */
4077 case OPC_TNE: /* rs != rs */
4078 case OPC_TNEI: /* r0 != 0 */
ead9360e 4079 /* Never trap: treat as NOP. */
cdc0faa6 4080 break;
6af0bf9c
FB
4081 }
4082 } else {
cdc0faa6
AJ
4083 int l1 = gen_new_label();
4084
6af0bf9c
FB
4085 switch (opc) {
4086 case OPC_TEQ:
4087 case OPC_TEQI:
cdc0faa6 4088 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4089 break;
4090 case OPC_TGE:
4091 case OPC_TGEI:
cdc0faa6 4092 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4093 break;
4094 case OPC_TGEU:
4095 case OPC_TGEIU:
cdc0faa6 4096 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4097 break;
4098 case OPC_TLT:
4099 case OPC_TLTI:
cdc0faa6 4100 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4101 break;
4102 case OPC_TLTU:
4103 case OPC_TLTIU:
cdc0faa6 4104 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4105 break;
4106 case OPC_TNE:
4107 case OPC_TNEI:
cdc0faa6 4108 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4109 break;
6af0bf9c 4110 }
cdc0faa6 4111 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4112 gen_set_label(l1);
4113 }
be24bb4f
TS
4114 tcg_temp_free(t0);
4115 tcg_temp_free(t1);
6af0bf9c
FB
4116}
4117
356265ae 4118static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4119{
6e256c93
FB
4120 TranslationBlock *tb;
4121 tb = ctx->tb;
7b270ef2
NF
4122 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4123 likely(!ctx->singlestep_enabled)) {
57fec1fe 4124 tcg_gen_goto_tb(n);
9b9e4393 4125 gen_save_pc(dest);
8cfd0495 4126 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 4127 } else {
9b9e4393 4128 gen_save_pc(dest);
7b270ef2
NF
4129 if (ctx->singlestep_enabled) {
4130 save_cpu_state(ctx, 0);
895c2d04 4131 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 4132 }
57fec1fe 4133 tcg_gen_exit_tb(0);
6e256c93 4134 }
c53be334
FB
4135}
4136
6af0bf9c 4137/* Branches (before delay slot) */
7a387fff 4138static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4139 int insn_bytes,
6af0bf9c
FB
4140 int rs, int rt, int32_t offset)
4141{
d077b6f7 4142 target_ulong btgt = -1;
3ad4bb2d 4143 int blink = 0;
2fdbad25 4144 int bcond_compute = 0;
1ba74fb8
AJ
4145 TCGv t0 = tcg_temp_new();
4146 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4147
4148 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4149#ifdef MIPS_DEBUG_DISAS
d12d51d5 4150 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 4151#endif
3ad4bb2d 4152 generate_exception(ctx, EXCP_RI);
6c5c1e20 4153 goto out;
3ad4bb2d 4154 }
6af0bf9c 4155
6af0bf9c
FB
4156 /* Load needed operands */
4157 switch (opc) {
4158 case OPC_BEQ:
4159 case OPC_BEQL:
4160 case OPC_BNE:
4161 case OPC_BNEL:
4162 /* Compare two registers */
4163 if (rs != rt) {
6c5c1e20
TS
4164 gen_load_gpr(t0, rs);
4165 gen_load_gpr(t1, rt);
2fdbad25 4166 bcond_compute = 1;
6af0bf9c 4167 }
7dca4ad0 4168 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
4169 break;
4170 case OPC_BGEZ:
4171 case OPC_BGEZAL:
3c824109 4172 case OPC_BGEZALS:
6af0bf9c
FB
4173 case OPC_BGEZALL:
4174 case OPC_BGEZL:
4175 case OPC_BGTZ:
4176 case OPC_BGTZL:
4177 case OPC_BLEZ:
4178 case OPC_BLEZL:
4179 case OPC_BLTZ:
4180 case OPC_BLTZAL:
3c824109 4181 case OPC_BLTZALS:
6af0bf9c
FB
4182 case OPC_BLTZALL:
4183 case OPC_BLTZL:
4184 /* Compare to zero */
4185 if (rs != 0) {
6c5c1e20 4186 gen_load_gpr(t0, rs);
2fdbad25 4187 bcond_compute = 1;
6af0bf9c 4188 }
7dca4ad0 4189 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 4190 break;
e45a93e2
JL
4191 case OPC_BPOSGE32:
4192#if defined(TARGET_MIPS64)
4193 case OPC_BPOSGE64:
4194 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4195#else
4196 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4197#endif
4198 bcond_compute = 1;
4199 btgt = ctx->pc + insn_bytes + offset;
4200 break;
6af0bf9c
FB
4201 case OPC_J:
4202 case OPC_JAL:
364d4831 4203 case OPC_JALX:
620e48f6
NF
4204 case OPC_JALS:
4205 case OPC_JALXS:
6af0bf9c 4206 /* Jump to immediate */
7dca4ad0 4207 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
4208 break;
4209 case OPC_JR:
4210 case OPC_JALR:
364d4831 4211 case OPC_JALRC:
620e48f6 4212 case OPC_JALRS:
6af0bf9c 4213 /* Jump to register */
7a387fff
TS
4214 if (offset != 0 && offset != 16) {
4215 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4216 others are reserved. */
923617a3 4217 MIPS_INVAL("jump hint");
6af0bf9c 4218 generate_exception(ctx, EXCP_RI);
6c5c1e20 4219 goto out;
6af0bf9c 4220 }
d077b6f7 4221 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4222 break;
4223 default:
4224 MIPS_INVAL("branch/jump");
4225 generate_exception(ctx, EXCP_RI);
6c5c1e20 4226 goto out;
6af0bf9c 4227 }
2fdbad25 4228 if (bcond_compute == 0) {
6af0bf9c
FB
4229 /* No condition to be computed */
4230 switch (opc) {
4231 case OPC_BEQ: /* rx == rx */
4232 case OPC_BEQL: /* rx == rx likely */
4233 case OPC_BGEZ: /* 0 >= 0 */
4234 case OPC_BGEZL: /* 0 >= 0 likely */
4235 case OPC_BLEZ: /* 0 <= 0 */
4236 case OPC_BLEZL: /* 0 <= 0 likely */
4237 /* Always take */
4ad40f36 4238 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4239 MIPS_DEBUG("balways");
4240 break;
3c824109 4241 case OPC_BGEZALS:
6af0bf9c
FB
4242 case OPC_BGEZAL: /* 0 >= 0 */
4243 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
4244 ctx->hflags |= (opc == OPC_BGEZALS
4245 ? MIPS_HFLAG_BDS16
4246 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
4247 /* Always take and link */
4248 blink = 31;
4ad40f36 4249 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4250 MIPS_DEBUG("balways and link");
4251 break;
4252 case OPC_BNE: /* rx != rx */
4253 case OPC_BGTZ: /* 0 > 0 */
4254 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4255 /* Treat as NOP. */
6af0bf9c 4256 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4257 goto out;
3c824109 4258 case OPC_BLTZALS:
eeef26cd 4259 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4260 ctx->hflags |= (opc == OPC_BLTZALS
4261 ? MIPS_HFLAG_BDS16
4262 : MIPS_HFLAG_BDS32);
4263 /* Handle as an unconditional branch to get correct delay
4264 slot checking. */
4265 blink = 31;
4266 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
4267 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4268 MIPS_DEBUG("bnever and link");
3c824109 4269 break;
eeef26cd 4270 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4271 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4272 /* Skip the instruction in the delay slot */
4273 MIPS_DEBUG("bnever, link and skip");
4274 ctx->pc += 4;
6c5c1e20 4275 goto out;
6af0bf9c
FB
4276 case OPC_BNEL: /* rx != rx likely */
4277 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4278 case OPC_BLTZL: /* 0 < 0 likely */
4279 /* Skip the instruction in the delay slot */
4280 MIPS_DEBUG("bnever and skip");
9898128f 4281 ctx->pc += 4;
6c5c1e20 4282 goto out;
6af0bf9c 4283 case OPC_J:
4ad40f36 4284 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4285 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4286 break;
620e48f6 4287 case OPC_JALXS:
364d4831
NF
4288 case OPC_JALX:
4289 ctx->hflags |= MIPS_HFLAG_BX;
4290 /* Fallthrough */
620e48f6 4291 case OPC_JALS:
6af0bf9c
FB
4292 case OPC_JAL:
4293 blink = 31;
4ad40f36 4294 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 4295 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
4296 ? MIPS_HFLAG_BDS16
4297 : MIPS_HFLAG_BDS32);
d077b6f7 4298 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4299 break;
4300 case OPC_JR:
4ad40f36 4301 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
4302 if (insn_bytes == 4)
4303 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
4304 MIPS_DEBUG("jr %s", regnames[rs]);
4305 break;
620e48f6 4306 case OPC_JALRS:
6af0bf9c 4307 case OPC_JALR:
364d4831 4308 case OPC_JALRC:
6af0bf9c 4309 blink = rt;
4ad40f36 4310 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
4311 ctx->hflags |= (opc == OPC_JALRS
4312 ? MIPS_HFLAG_BDS16
4313 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
4314 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4315 break;
4316 default:
4317 MIPS_INVAL("branch/jump");
4318 generate_exception(ctx, EXCP_RI);
6c5c1e20 4319 goto out;
6af0bf9c
FB
4320 }
4321 } else {
4322 switch (opc) {
4323 case OPC_BEQ:
e68dd28f 4324 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4325 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4326 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4327 goto not_likely;
4328 case OPC_BEQL:
e68dd28f 4329 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4330 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4331 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4332 goto likely;
4333 case OPC_BNE:
e68dd28f 4334 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4335 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4336 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4337 goto not_likely;
4338 case OPC_BNEL:
e68dd28f 4339 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4340 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4341 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4342 goto likely;
4343 case OPC_BGEZ:
e68dd28f 4344 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4345 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4346 goto not_likely;
4347 case OPC_BGEZL:
e68dd28f 4348 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4349 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4350 goto likely;
3c824109 4351 case OPC_BGEZALS:
6af0bf9c 4352 case OPC_BGEZAL:
3c824109
NF
4353 ctx->hflags |= (opc == OPC_BGEZALS
4354 ? MIPS_HFLAG_BDS16
4355 : MIPS_HFLAG_BDS32);
e68dd28f 4356 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4357 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4358 blink = 31;
4359 goto not_likely;
4360 case OPC_BGEZALL:
e68dd28f 4361 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4362 blink = 31;
d077b6f7 4363 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4364 goto likely;
4365 case OPC_BGTZ:
e68dd28f 4366 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4367 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4368 goto not_likely;
4369 case OPC_BGTZL:
e68dd28f 4370 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4371 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4372 goto likely;
4373 case OPC_BLEZ:
e68dd28f 4374 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4375 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4376 goto not_likely;
4377 case OPC_BLEZL:
e68dd28f 4378 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4379 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4380 goto likely;
4381 case OPC_BLTZ:
e68dd28f 4382 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4383 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4384 goto not_likely;
4385 case OPC_BLTZL:
e68dd28f 4386 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4387 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4388 goto likely;
e45a93e2
JL
4389 case OPC_BPOSGE32:
4390 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4391 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4392 goto not_likely;
4393#if defined(TARGET_MIPS64)
4394 case OPC_BPOSGE64:
4395 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4396 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4397 goto not_likely;
4398#endif
3c824109 4399 case OPC_BLTZALS:
6af0bf9c 4400 case OPC_BLTZAL:
3c824109
NF
4401 ctx->hflags |= (opc == OPC_BLTZALS
4402 ? MIPS_HFLAG_BDS16
4403 : MIPS_HFLAG_BDS32);
e68dd28f 4404 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4405 blink = 31;
d077b6f7 4406 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4407 not_likely:
4ad40f36 4408 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4409 break;
4410 case OPC_BLTZALL:
e68dd28f 4411 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4412 blink = 31;
d077b6f7 4413 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4414 likely:
4ad40f36 4415 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4416 break;
c53f4a62
TS
4417 default:
4418 MIPS_INVAL("conditional branch/jump");
4419 generate_exception(ctx, EXCP_RI);
6c5c1e20 4420 goto out;
6af0bf9c 4421 }
6af0bf9c 4422 }
923617a3 4423 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4424 blink, ctx->hflags, btgt);
9b9e4393 4425
d077b6f7 4426 ctx->btarget = btgt;
6af0bf9c 4427 if (blink > 0) {
364d4831
NF
4428 int post_delay = insn_bytes;
4429 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4430
4431 if (opc != OPC_JALRC)
4432 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
4433
4434 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4435 }
6c5c1e20
TS
4436
4437 out:
364d4831
NF
4438 if (insn_bytes == 2)
4439 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4440 tcg_temp_free(t0);
4441 tcg_temp_free(t1);
6af0bf9c
FB
4442}
4443
7a387fff
TS
4444/* special3 bitfield operations */
4445static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4446 int rs, int lsb, int msb)
7a387fff 4447{
a7812ae4
PB
4448 TCGv t0 = tcg_temp_new();
4449 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4450
4451 gen_load_gpr(t1, rs);
7a387fff
TS
4452 switch (opc) {
4453 case OPC_EXT:
4454 if (lsb + msb > 31)
4455 goto fail;
505ad7c2
AJ
4456 tcg_gen_shri_tl(t0, t1, lsb);
4457 if (msb != 31) {
4458 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4459 } else {
4460 tcg_gen_ext32s_tl(t0, t0);
4461 }
7a387fff 4462 break;
c6d6dd7c 4463#if defined(TARGET_MIPS64)
7a387fff 4464 case OPC_DEXTM:
505ad7c2
AJ
4465 tcg_gen_shri_tl(t0, t1, lsb);
4466 if (msb != 31) {
4467 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4468 }
7a387fff
TS
4469 break;
4470 case OPC_DEXTU:
505ad7c2
AJ
4471 tcg_gen_shri_tl(t0, t1, lsb + 32);
4472 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4473 break;
4474 case OPC_DEXT:
505ad7c2
AJ
4475 tcg_gen_shri_tl(t0, t1, lsb);
4476 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4477 break;
c6d6dd7c 4478#endif
7a387fff
TS
4479 case OPC_INS:
4480 if (lsb > msb)
4481 goto fail;
6c5c1e20 4482 gen_load_gpr(t0, rt);
e0d002f1 4483 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4484 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4485 break;
c6d6dd7c 4486#if defined(TARGET_MIPS64)
7a387fff 4487 case OPC_DINSM:
6c5c1e20 4488 gen_load_gpr(t0, rt);
e0d002f1 4489 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4490 break;
4491 case OPC_DINSU:
6c5c1e20 4492 gen_load_gpr(t0, rt);
e0d002f1 4493 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4494 break;
4495 case OPC_DINS:
6c5c1e20 4496 gen_load_gpr(t0, rt);
e0d002f1 4497 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4498 break;
c6d6dd7c 4499#endif
7a387fff
TS
4500 default:
4501fail:
4502 MIPS_INVAL("bitops");
4503 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4504 tcg_temp_free(t0);
4505 tcg_temp_free(t1);
7a387fff
TS
4506 return;
4507 }
6c5c1e20
TS
4508 gen_store_gpr(t0, rt);
4509 tcg_temp_free(t0);
4510 tcg_temp_free(t1);
7a387fff
TS
4511}
4512
49bcf33c
AJ
4513static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4514{
3a55fa47 4515 TCGv t0;
49bcf33c 4516
3a55fa47
AJ
4517 if (rd == 0) {
4518 /* If no destination, treat it as a NOP. */
4519 MIPS_DEBUG("NOP");
4520 return;
4521 }
4522
4523 t0 = tcg_temp_new();
4524 gen_load_gpr(t0, rt);
49bcf33c
AJ
4525 switch (op2) {
4526 case OPC_WSBH:
3a55fa47
AJ
4527 {
4528 TCGv t1 = tcg_temp_new();
4529
4530 tcg_gen_shri_tl(t1, t0, 8);
4531 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4532 tcg_gen_shli_tl(t0, t0, 8);
4533 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4534 tcg_gen_or_tl(t0, t0, t1);
4535 tcg_temp_free(t1);
4536 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4537 }
49bcf33c
AJ
4538 break;
4539 case OPC_SEB:
3a55fa47 4540 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4541 break;
4542 case OPC_SEH:
3a55fa47 4543 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4544 break;
4545#if defined(TARGET_MIPS64)
4546 case OPC_DSBH:
3a55fa47
AJ
4547 {
4548 TCGv t1 = tcg_temp_new();
4549
4550 tcg_gen_shri_tl(t1, t0, 8);
4551 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4552 tcg_gen_shli_tl(t0, t0, 8);
4553 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4554 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4555 tcg_temp_free(t1);
4556 }
49bcf33c
AJ
4557 break;
4558 case OPC_DSHD:
3a55fa47
AJ
4559 {
4560 TCGv t1 = tcg_temp_new();
4561
4562 tcg_gen_shri_tl(t1, t0, 16);
4563 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4564 tcg_gen_shli_tl(t0, t0, 16);
4565 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4566 tcg_gen_or_tl(t0, t0, t1);
4567 tcg_gen_shri_tl(t1, t0, 32);
4568 tcg_gen_shli_tl(t0, t0, 32);
4569 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4570 tcg_temp_free(t1);
4571 }
49bcf33c
AJ
4572 break;
4573#endif
4574 default:
4575 MIPS_INVAL("bsfhl");
4576 generate_exception(ctx, EXCP_RI);
4577 tcg_temp_free(t0);
49bcf33c
AJ
4578 return;
4579 }
49bcf33c 4580 tcg_temp_free(t0);
49bcf33c
AJ
4581}
4582
f1aa6320 4583#ifndef CONFIG_USER_ONLY
0eaef5aa 4584/* CP0 (MMU and control) */
d9bea114 4585static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4586{
d9bea114 4587 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4588
d9bea114
AJ
4589 tcg_gen_ld_i32(t0, cpu_env, off);
4590 tcg_gen_ext_i32_tl(arg, t0);
4591 tcg_temp_free_i32(t0);
4f57689a
TS
4592}
4593
d9bea114 4594static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4595{
d9bea114
AJ
4596 tcg_gen_ld_tl(arg, cpu_env, off);
4597 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4598}
4599
d9bea114 4600static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4601{
d9bea114 4602 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4603
d9bea114
AJ
4604 tcg_gen_trunc_tl_i32(t0, arg);
4605 tcg_gen_st_i32(t0, cpu_env, off);
4606 tcg_temp_free_i32(t0);
f1aa6320
TS
4607}
4608
d9bea114 4609static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4610{
d9bea114
AJ
4611 tcg_gen_ext32s_tl(arg, arg);
4612 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4613}
4614
d75c135e 4615static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4616{
7a387fff 4617 const char *rn = "invalid";
873eb012 4618
e189e748 4619 if (sel != 0)
d75c135e 4620 check_insn(ctx, ISA_MIPS32);
e189e748 4621
873eb012
TS
4622 switch (reg) {
4623 case 0:
7a387fff
TS
4624 switch (sel) {
4625 case 0:
7db13fae 4626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4627 rn = "Index";
4628 break;
4629 case 1:
d75c135e 4630 check_insn(ctx, ASE_MT);
895c2d04 4631 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4632 rn = "MVPControl";
ead9360e 4633 break;
7a387fff 4634 case 2:
d75c135e 4635 check_insn(ctx, ASE_MT);
895c2d04 4636 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4637 rn = "MVPConf0";
ead9360e 4638 break;
7a387fff 4639 case 3:
d75c135e 4640 check_insn(ctx, ASE_MT);
895c2d04 4641 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4642 rn = "MVPConf1";
ead9360e 4643 break;
7a387fff
TS
4644 default:
4645 goto die;
4646 }
873eb012
TS
4647 break;
4648 case 1:
7a387fff
TS
4649 switch (sel) {
4650 case 0:
895c2d04 4651 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4652 rn = "Random";
2423f660 4653 break;
7a387fff 4654 case 1:
d75c135e 4655 check_insn(ctx, ASE_MT);
7db13fae 4656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4657 rn = "VPEControl";
ead9360e 4658 break;
7a387fff 4659 case 2:
d75c135e 4660 check_insn(ctx, ASE_MT);
7db13fae 4661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4662 rn = "VPEConf0";
ead9360e 4663 break;
7a387fff 4664 case 3:
d75c135e 4665 check_insn(ctx, ASE_MT);
7db13fae 4666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4667 rn = "VPEConf1";
ead9360e 4668 break;
7a387fff 4669 case 4:
d75c135e 4670 check_insn(ctx, ASE_MT);
7db13fae 4671 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4672 rn = "YQMask";
ead9360e 4673 break;
7a387fff 4674 case 5:
d75c135e 4675 check_insn(ctx, ASE_MT);
7db13fae 4676 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4677 rn = "VPESchedule";
ead9360e 4678 break;
7a387fff 4679 case 6:
d75c135e 4680 check_insn(ctx, ASE_MT);
7db13fae 4681 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4682 rn = "VPEScheFBack";
ead9360e 4683 break;
7a387fff 4684 case 7:
d75c135e 4685 check_insn(ctx, ASE_MT);
7db13fae 4686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4687 rn = "VPEOpt";
ead9360e 4688 break;
7a387fff
TS
4689 default:
4690 goto die;
4691 }
873eb012
TS
4692 break;
4693 case 2:
7a387fff
TS
4694 switch (sel) {
4695 case 0:
7db13fae 4696 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4697 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4698 rn = "EntryLo0";
4699 break;
7a387fff 4700 case 1:
d75c135e 4701 check_insn(ctx, ASE_MT);
895c2d04 4702 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4703 rn = "TCStatus";
ead9360e 4704 break;
7a387fff 4705 case 2:
d75c135e 4706 check_insn(ctx, ASE_MT);
895c2d04 4707 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4708 rn = "TCBind";
ead9360e 4709 break;
7a387fff 4710 case 3:
d75c135e 4711 check_insn(ctx, ASE_MT);
895c2d04 4712 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4713 rn = "TCRestart";
ead9360e 4714 break;
7a387fff 4715 case 4:
d75c135e 4716 check_insn(ctx, ASE_MT);
895c2d04 4717 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4718 rn = "TCHalt";
ead9360e 4719 break;
7a387fff 4720 case 5:
d75c135e 4721 check_insn(ctx, ASE_MT);
895c2d04 4722 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4723 rn = "TCContext";
ead9360e 4724 break;
7a387fff 4725 case 6:
d75c135e 4726 check_insn(ctx, ASE_MT);
895c2d04 4727 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4728 rn = "TCSchedule";
ead9360e 4729 break;
7a387fff 4730 case 7:
d75c135e 4731 check_insn(ctx, ASE_MT);
895c2d04 4732 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4733 rn = "TCScheFBack";
ead9360e 4734 break;
7a387fff
TS
4735 default:
4736 goto die;
4737 }
873eb012
TS
4738 break;
4739 case 3:
7a387fff
TS
4740 switch (sel) {
4741 case 0:
7db13fae 4742 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4743 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4744 rn = "EntryLo1";
4745 break;
7a387fff
TS
4746 default:
4747 goto die;
1579a72e 4748 }
873eb012
TS
4749 break;
4750 case 4:
7a387fff
TS
4751 switch (sel) {
4752 case 0:
7db13fae 4753 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4754 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4755 rn = "Context";
4756 break;
7a387fff 4757 case 1:
d9bea114 4758// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 4759 rn = "ContextConfig";
d279279e 4760 goto die;
2423f660 4761// break;
d279279e
PJ
4762 case 2:
4763 if (ctx->ulri) {
4764 tcg_gen_ld32s_tl(arg, cpu_env,
4765 offsetof(CPUMIPSState,
4766 active_tc.CP0_UserLocal));
4767 rn = "UserLocal";
4768 } else {
4769 tcg_gen_movi_tl(arg, 0);
4770 }
4771 break;
7a387fff
TS
4772 default:
4773 goto die;
1579a72e 4774 }
873eb012
TS
4775 break;
4776 case 5:
7a387fff
TS
4777 switch (sel) {
4778 case 0:
7db13fae 4779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4780 rn = "PageMask";
4781 break;
7a387fff 4782 case 1:
d75c135e 4783 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4785 rn = "PageGrain";
4786 break;
7a387fff
TS
4787 default:
4788 goto die;
1579a72e 4789 }
873eb012
TS
4790 break;
4791 case 6:
7a387fff
TS
4792 switch (sel) {
4793 case 0:
7db13fae 4794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4795 rn = "Wired";
4796 break;
7a387fff 4797 case 1:
d75c135e 4798 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4800 rn = "SRSConf0";
ead9360e 4801 break;
7a387fff 4802 case 2:
d75c135e 4803 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4805 rn = "SRSConf1";
ead9360e 4806 break;
7a387fff 4807 case 3:
d75c135e 4808 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4810 rn = "SRSConf2";
ead9360e 4811 break;
7a387fff 4812 case 4:
d75c135e 4813 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4815 rn = "SRSConf3";
ead9360e 4816 break;
7a387fff 4817 case 5:
d75c135e 4818 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4820 rn = "SRSConf4";
ead9360e 4821 break;
7a387fff
TS
4822 default:
4823 goto die;
1579a72e 4824 }
873eb012 4825 break;
8c0fdd85 4826 case 7:
7a387fff
TS
4827 switch (sel) {
4828 case 0:
d75c135e 4829 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4831 rn = "HWREna";
4832 break;
7a387fff
TS
4833 default:
4834 goto die;
1579a72e 4835 }
8c0fdd85 4836 break;
873eb012 4837 case 8:
7a387fff
TS
4838 switch (sel) {
4839 case 0:
7db13fae 4840 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4841 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4842 rn = "BadVAddr";
2423f660 4843 break;
7a387fff
TS
4844 default:
4845 goto die;
4846 }
873eb012
TS
4847 break;
4848 case 9:
7a387fff
TS
4849 switch (sel) {
4850 case 0:
2e70f6ef
PB
4851 /* Mark as an IO operation because we read the time. */
4852 if (use_icount)
4853 gen_io_start();
895c2d04 4854 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4855 if (use_icount) {
4856 gen_io_end();
2e70f6ef 4857 }
55807224
EI
4858 /* Break the TB to be able to take timer interrupts immediately
4859 after reading count. */
4860 ctx->bstate = BS_STOP;
2423f660
TS
4861 rn = "Count";
4862 break;
4863 /* 6,7 are implementation dependent */
7a387fff
TS
4864 default:
4865 goto die;
2423f660 4866 }
873eb012
TS
4867 break;
4868 case 10:
7a387fff
TS
4869 switch (sel) {
4870 case 0:
7db13fae 4871 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4872 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4873 rn = "EntryHi";
4874 break;
7a387fff
TS
4875 default:
4876 goto die;
1579a72e 4877 }
873eb012
TS
4878 break;
4879 case 11:
7a387fff
TS
4880 switch (sel) {
4881 case 0:
7db13fae 4882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4883 rn = "Compare";
4884 break;
4885 /* 6,7 are implementation dependent */
7a387fff
TS
4886 default:
4887 goto die;
2423f660 4888 }
873eb012
TS
4889 break;
4890 case 12:
7a387fff
TS
4891 switch (sel) {
4892 case 0:
7db13fae 4893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4894 rn = "Status";
4895 break;
7a387fff 4896 case 1:
d75c135e 4897 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4898 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4899 rn = "IntCtl";
4900 break;
7a387fff 4901 case 2:
d75c135e 4902 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4903 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4904 rn = "SRSCtl";
4905 break;
7a387fff 4906 case 3:
d75c135e 4907 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4908 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4909 rn = "SRSMap";
fd88b6ab 4910 break;
7a387fff
TS
4911 default:
4912 goto die;
4913 }
873eb012
TS
4914 break;
4915 case 13:
7a387fff
TS
4916 switch (sel) {
4917 case 0:
7db13fae 4918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4919 rn = "Cause";
4920 break;
7a387fff
TS
4921 default:
4922 goto die;
4923 }
873eb012
TS
4924 break;
4925 case 14:
7a387fff
TS
4926 switch (sel) {
4927 case 0:
7db13fae 4928 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4929 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4930 rn = "EPC";
4931 break;
7a387fff
TS
4932 default:
4933 goto die;
1579a72e 4934 }
873eb012
TS
4935 break;
4936 case 15:
7a387fff
TS
4937 switch (sel) {
4938 case 0:
7db13fae 4939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4940 rn = "PRid";
4941 break;
7a387fff 4942 case 1:
d75c135e 4943 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4945 rn = "EBase";
4946 break;
7a387fff
TS
4947 default:
4948 goto die;
4949 }
873eb012
TS
4950 break;
4951 case 16:
4952 switch (sel) {
4953 case 0:
7db13fae 4954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4955 rn = "Config";
4956 break;
4957 case 1:
7db13fae 4958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4959 rn = "Config1";
4960 break;
7a387fff 4961 case 2:
7db13fae 4962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4963 rn = "Config2";
4964 break;
4965 case 3:
7db13fae 4966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4967 rn = "Config3";
4968 break;
b4160af1
PJ
4969 case 4:
4970 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4971 rn = "Config4";
4972 break;
b4dd99a3
PJ
4973 case 5:
4974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4975 rn = "Config5";
4976 break;
e397ee33
TS
4977 /* 6,7 are implementation dependent */
4978 case 6:
7db13fae 4979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4980 rn = "Config6";
4981 break;
4982 case 7:
7db13fae 4983 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4984 rn = "Config7";
4985 break;
873eb012 4986 default:
873eb012
TS
4987 goto die;
4988 }
4989 break;
4990 case 17:
7a387fff
TS
4991 switch (sel) {
4992 case 0:
895c2d04 4993 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4994 rn = "LLAddr";
4995 break;
7a387fff
TS
4996 default:
4997 goto die;
4998 }
873eb012
TS
4999 break;
5000 case 18:
7a387fff 5001 switch (sel) {
fd88b6ab 5002 case 0 ... 7:
895c2d04 5003 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5004 rn = "WatchLo";
5005 break;
7a387fff
TS
5006 default:
5007 goto die;
5008 }
873eb012
TS
5009 break;
5010 case 19:
7a387fff 5011 switch (sel) {
fd88b6ab 5012 case 0 ...7:
895c2d04 5013 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5014 rn = "WatchHi";
5015 break;
7a387fff
TS
5016 default:
5017 goto die;
5018 }
873eb012 5019 break;
8c0fdd85 5020 case 20:
7a387fff
TS
5021 switch (sel) {
5022 case 0:
d26bc211 5023#if defined(TARGET_MIPS64)
d75c135e 5024 check_insn(ctx, ISA_MIPS3);
7db13fae 5025 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5026 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5027 rn = "XContext";
5028 break;
703eaf37 5029#endif
7a387fff
TS
5030 default:
5031 goto die;
5032 }
8c0fdd85
TS
5033 break;
5034 case 21:
7a387fff
TS
5035 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5036 switch (sel) {
5037 case 0:
7db13fae 5038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5039 rn = "Framemask";
5040 break;
7a387fff
TS
5041 default:
5042 goto die;
5043 }
8c0fdd85
TS
5044 break;
5045 case 22:
d9bea114 5046 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5047 rn = "'Diagnostic"; /* implementation dependent */
5048 break;
873eb012 5049 case 23:
7a387fff
TS
5050 switch (sel) {
5051 case 0:
895c2d04 5052 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5053 rn = "Debug";
5054 break;
7a387fff 5055 case 1:
d9bea114 5056// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
5057 rn = "TraceControl";
5058// break;
7a387fff 5059 case 2:
d9bea114 5060// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
5061 rn = "TraceControl2";
5062// break;
7a387fff 5063 case 3:
d9bea114 5064// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
5065 rn = "UserTraceData";
5066// break;
7a387fff 5067 case 4:
d9bea114 5068// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
5069 rn = "TraceBPC";
5070// break;
7a387fff
TS
5071 default:
5072 goto die;
5073 }
873eb012
TS
5074 break;
5075 case 24:
7a387fff
TS
5076 switch (sel) {
5077 case 0:
f0b3f3ae 5078 /* EJTAG support */
7db13fae 5079 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5080 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5081 rn = "DEPC";
5082 break;
7a387fff
TS
5083 default:
5084 goto die;
5085 }
873eb012 5086 break;
8c0fdd85 5087 case 25:
7a387fff
TS
5088 switch (sel) {
5089 case 0:
7db13fae 5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5091 rn = "Performance0";
7a387fff
TS
5092 break;
5093 case 1:
d9bea114 5094// gen_helper_mfc0_performance1(arg);
2423f660
TS
5095 rn = "Performance1";
5096// break;
7a387fff 5097 case 2:
d9bea114 5098// gen_helper_mfc0_performance2(arg);
2423f660
TS
5099 rn = "Performance2";
5100// break;
7a387fff 5101 case 3:
d9bea114 5102// gen_helper_mfc0_performance3(arg);
2423f660
TS
5103 rn = "Performance3";
5104// break;
7a387fff 5105 case 4:
d9bea114 5106// gen_helper_mfc0_performance4(arg);
2423f660
TS
5107 rn = "Performance4";
5108// break;
7a387fff 5109 case 5:
d9bea114 5110// gen_helper_mfc0_performance5(arg);
2423f660
TS
5111 rn = "Performance5";
5112// break;
7a387fff 5113 case 6:
d9bea114 5114// gen_helper_mfc0_performance6(arg);
2423f660
TS
5115 rn = "Performance6";
5116// break;
7a387fff 5117 case 7:
d9bea114 5118// gen_helper_mfc0_performance7(arg);
2423f660
TS
5119 rn = "Performance7";
5120// break;
7a387fff
TS
5121 default:
5122 goto die;
5123 }
8c0fdd85
TS
5124 break;
5125 case 26:
d9bea114 5126 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5127 rn = "ECC";
5128 break;
8c0fdd85 5129 case 27:
7a387fff 5130 switch (sel) {
7a387fff 5131 case 0 ... 3:
d9bea114 5132 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5133 rn = "CacheErr";
5134 break;
7a387fff
TS
5135 default:
5136 goto die;
5137 }
8c0fdd85 5138 break;
873eb012
TS
5139 case 28:
5140 switch (sel) {
5141 case 0:
7a387fff
TS
5142 case 2:
5143 case 4:
5144 case 6:
7db13fae 5145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
5146 rn = "TagLo";
5147 break;
5148 case 1:
7a387fff
TS
5149 case 3:
5150 case 5:
5151 case 7:
7db13fae 5152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5153 rn = "DataLo";
5154 break;
5155 default:
873eb012
TS
5156 goto die;
5157 }
5158 break;
8c0fdd85 5159 case 29:
7a387fff
TS
5160 switch (sel) {
5161 case 0:
5162 case 2:
5163 case 4:
5164 case 6:
7db13fae 5165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5166 rn = "TagHi";
5167 break;
5168 case 1:
5169 case 3:
5170 case 5:
5171 case 7:
7db13fae 5172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5173 rn = "DataHi";
5174 break;
5175 default:
5176 goto die;
5177 }
8c0fdd85 5178 break;
873eb012 5179 case 30:
7a387fff
TS
5180 switch (sel) {
5181 case 0:
7db13fae 5182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5183 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5184 rn = "ErrorEPC";
5185 break;
7a387fff
TS
5186 default:
5187 goto die;
5188 }
873eb012
TS
5189 break;
5190 case 31:
7a387fff
TS
5191 switch (sel) {
5192 case 0:
f0b3f3ae 5193 /* EJTAG support */
7db13fae 5194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5195 rn = "DESAVE";
5196 break;
7a387fff
TS
5197 default:
5198 goto die;
5199 }
873eb012
TS
5200 break;
5201 default:
873eb012
TS
5202 goto die;
5203 }
2abf314d 5204 (void)rn; /* avoid a compiler warning */
d12d51d5 5205 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5206 return;
5207
5208die:
d12d51d5 5209 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
5210 generate_exception(ctx, EXCP_RI);
5211}
5212
d75c135e 5213static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5214{
7a387fff
TS
5215 const char *rn = "invalid";
5216
e189e748 5217 if (sel != 0)
d75c135e 5218 check_insn(ctx, ISA_MIPS32);
e189e748 5219
2e70f6ef
PB
5220 if (use_icount)
5221 gen_io_start();
5222
8c0fdd85
TS
5223 switch (reg) {
5224 case 0:
7a387fff
TS
5225 switch (sel) {
5226 case 0:
895c2d04 5227 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5228 rn = "Index";
5229 break;
5230 case 1:
d75c135e 5231 check_insn(ctx, ASE_MT);
895c2d04 5232 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5233 rn = "MVPControl";
ead9360e 5234 break;
7a387fff 5235 case 2:
d75c135e 5236 check_insn(ctx, ASE_MT);
ead9360e 5237 /* ignored */
7a387fff 5238 rn = "MVPConf0";
ead9360e 5239 break;
7a387fff 5240 case 3:
d75c135e 5241 check_insn(ctx, ASE_MT);
ead9360e 5242 /* ignored */
7a387fff 5243 rn = "MVPConf1";
ead9360e 5244 break;
7a387fff
TS
5245 default:
5246 goto die;
5247 }
8c0fdd85
TS
5248 break;
5249 case 1:
7a387fff
TS
5250 switch (sel) {
5251 case 0:
2423f660 5252 /* ignored */
7a387fff 5253 rn = "Random";
2423f660 5254 break;
7a387fff 5255 case 1:
d75c135e 5256 check_insn(ctx, ASE_MT);
895c2d04 5257 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5258 rn = "VPEControl";
ead9360e 5259 break;
7a387fff 5260 case 2:
d75c135e 5261 check_insn(ctx, ASE_MT);
895c2d04 5262 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5263 rn = "VPEConf0";
ead9360e 5264 break;
7a387fff 5265 case 3:
d75c135e 5266 check_insn(ctx, ASE_MT);
895c2d04 5267 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5268 rn = "VPEConf1";
ead9360e 5269 break;
7a387fff 5270 case 4:
d75c135e 5271 check_insn(ctx, ASE_MT);
895c2d04 5272 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5273 rn = "YQMask";
ead9360e 5274 break;
7a387fff 5275 case 5:
d75c135e 5276 check_insn(ctx, ASE_MT);
7db13fae 5277 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5278 rn = "VPESchedule";
ead9360e 5279 break;
7a387fff 5280 case 6:
d75c135e 5281 check_insn(ctx, ASE_MT);
7db13fae 5282 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5283 rn = "VPEScheFBack";
ead9360e 5284 break;
7a387fff 5285 case 7:
d75c135e 5286 check_insn(ctx, ASE_MT);
895c2d04 5287 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5288 rn = "VPEOpt";
ead9360e 5289 break;
7a387fff
TS
5290 default:
5291 goto die;
5292 }
8c0fdd85
TS
5293 break;
5294 case 2:
7a387fff
TS
5295 switch (sel) {
5296 case 0:
895c2d04 5297 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5298 rn = "EntryLo0";
5299 break;
7a387fff 5300 case 1:
d75c135e 5301 check_insn(ctx, ASE_MT);
895c2d04 5302 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5303 rn = "TCStatus";
ead9360e 5304 break;
7a387fff 5305 case 2:
d75c135e 5306 check_insn(ctx, ASE_MT);
895c2d04 5307 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5308 rn = "TCBind";
ead9360e 5309 break;
7a387fff 5310 case 3:
d75c135e 5311 check_insn(ctx, ASE_MT);
895c2d04 5312 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5313 rn = "TCRestart";
ead9360e 5314 break;
7a387fff 5315 case 4:
d75c135e 5316 check_insn(ctx, ASE_MT);
895c2d04 5317 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5318 rn = "TCHalt";
ead9360e 5319 break;
7a387fff 5320 case 5:
d75c135e 5321 check_insn(ctx, ASE_MT);
895c2d04 5322 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5323 rn = "TCContext";
ead9360e 5324 break;
7a387fff 5325 case 6:
d75c135e 5326 check_insn(ctx, ASE_MT);
895c2d04 5327 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5328 rn = "TCSchedule";
ead9360e 5329 break;
7a387fff 5330 case 7:
d75c135e 5331 check_insn(ctx, ASE_MT);
895c2d04 5332 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5333 rn = "TCScheFBack";
ead9360e 5334 break;
7a387fff
TS
5335 default:
5336 goto die;
5337 }
8c0fdd85
TS
5338 break;
5339 case 3:
7a387fff
TS
5340 switch (sel) {
5341 case 0:
895c2d04 5342 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5343 rn = "EntryLo1";
5344 break;
7a387fff
TS
5345 default:
5346 goto die;
876d4b07 5347 }
8c0fdd85
TS
5348 break;
5349 case 4:
7a387fff
TS
5350 switch (sel) {
5351 case 0:
895c2d04 5352 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5353 rn = "Context";
5354 break;
7a387fff 5355 case 1:
895c2d04 5356// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5357 rn = "ContextConfig";
d279279e 5358 goto die;
2423f660 5359// break;
d279279e
PJ
5360 case 2:
5361 if (ctx->ulri) {
5362 tcg_gen_st_tl(arg, cpu_env,
5363 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5364 rn = "UserLocal";
5365 }
5366 break;
7a387fff
TS
5367 default:
5368 goto die;
876d4b07 5369 }
8c0fdd85
TS
5370 break;
5371 case 5:
7a387fff
TS
5372 switch (sel) {
5373 case 0:
895c2d04 5374 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5375 rn = "PageMask";
5376 break;
7a387fff 5377 case 1:
d75c135e 5378 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5379 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5380 rn = "PageGrain";
5381 break;
7a387fff
TS
5382 default:
5383 goto die;
876d4b07 5384 }
8c0fdd85
TS
5385 break;
5386 case 6:
7a387fff
TS
5387 switch (sel) {
5388 case 0:
895c2d04 5389 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5390 rn = "Wired";
5391 break;
7a387fff 5392 case 1:
d75c135e 5393 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5394 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5395 rn = "SRSConf0";
ead9360e 5396 break;
7a387fff 5397 case 2:
d75c135e 5398 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5399 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5400 rn = "SRSConf1";
ead9360e 5401 break;
7a387fff 5402 case 3:
d75c135e 5403 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5404 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5405 rn = "SRSConf2";
ead9360e 5406 break;
7a387fff 5407 case 4:
d75c135e 5408 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5409 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5410 rn = "SRSConf3";
ead9360e 5411 break;
7a387fff 5412 case 5:
d75c135e 5413 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5414 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5415 rn = "SRSConf4";
ead9360e 5416 break;
7a387fff
TS
5417 default:
5418 goto die;
876d4b07 5419 }
8c0fdd85
TS
5420 break;
5421 case 7:
7a387fff
TS
5422 switch (sel) {
5423 case 0:
d75c135e 5424 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5425 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5426 ctx->bstate = BS_STOP;
2423f660
TS
5427 rn = "HWREna";
5428 break;
7a387fff
TS
5429 default:
5430 goto die;
876d4b07 5431 }
8c0fdd85
TS
5432 break;
5433 case 8:
7a387fff 5434 /* ignored */
f0b3f3ae 5435 rn = "BadVAddr";
8c0fdd85
TS
5436 break;
5437 case 9:
7a387fff
TS
5438 switch (sel) {
5439 case 0:
895c2d04 5440 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5441 rn = "Count";
5442 break;
876d4b07 5443 /* 6,7 are implementation dependent */
7a387fff
TS
5444 default:
5445 goto die;
876d4b07 5446 }
8c0fdd85
TS
5447 break;
5448 case 10:
7a387fff
TS
5449 switch (sel) {
5450 case 0:
895c2d04 5451 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5452 rn = "EntryHi";
5453 break;
7a387fff
TS
5454 default:
5455 goto die;
876d4b07 5456 }
8c0fdd85
TS
5457 break;
5458 case 11:
7a387fff
TS
5459 switch (sel) {
5460 case 0:
895c2d04 5461 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5462 rn = "Compare";
5463 break;
5464 /* 6,7 are implementation dependent */
7a387fff
TS
5465 default:
5466 goto die;
876d4b07 5467 }
8c0fdd85
TS
5468 break;
5469 case 12:
7a387fff
TS
5470 switch (sel) {
5471 case 0:
867abc7e 5472 save_cpu_state(ctx, 1);
895c2d04 5473 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5474 /* BS_STOP isn't good enough here, hflags may have changed. */
5475 gen_save_pc(ctx->pc + 4);
5476 ctx->bstate = BS_EXCP;
2423f660
TS
5477 rn = "Status";
5478 break;
7a387fff 5479 case 1:
d75c135e 5480 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5481 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5482 /* Stop translation as we may have switched the execution mode */
5483 ctx->bstate = BS_STOP;
2423f660
TS
5484 rn = "IntCtl";
5485 break;
7a387fff 5486 case 2:
d75c135e 5487 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5488 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5489 /* Stop translation as we may have switched the execution mode */
5490 ctx->bstate = BS_STOP;
2423f660
TS
5491 rn = "SRSCtl";
5492 break;
7a387fff 5493 case 3:
d75c135e 5494 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5495 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5496 /* Stop translation as we may have switched the execution mode */
5497 ctx->bstate = BS_STOP;
2423f660 5498 rn = "SRSMap";
fd88b6ab 5499 break;
7a387fff
TS
5500 default:
5501 goto die;
876d4b07 5502 }
8c0fdd85
TS
5503 break;
5504 case 13:
7a387fff
TS
5505 switch (sel) {
5506 case 0:
867abc7e 5507 save_cpu_state(ctx, 1);
895c2d04 5508 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5509 rn = "Cause";
5510 break;
7a387fff
TS
5511 default:
5512 goto die;
876d4b07 5513 }
8c0fdd85
TS
5514 break;
5515 case 14:
7a387fff
TS
5516 switch (sel) {
5517 case 0:
7db13fae 5518 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5519 rn = "EPC";
5520 break;
7a387fff
TS
5521 default:
5522 goto die;
876d4b07 5523 }
8c0fdd85
TS
5524 break;
5525 case 15:
7a387fff
TS
5526 switch (sel) {
5527 case 0:
2423f660
TS
5528 /* ignored */
5529 rn = "PRid";
5530 break;
7a387fff 5531 case 1:
d75c135e 5532 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5533 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5534 rn = "EBase";
5535 break;
7a387fff
TS
5536 default:
5537 goto die;
1579a72e 5538 }
8c0fdd85
TS
5539 break;
5540 case 16:
5541 switch (sel) {
5542 case 0:
895c2d04 5543 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5544 rn = "Config";
2423f660
TS
5545 /* Stop translation as we may have switched the execution mode */
5546 ctx->bstate = BS_STOP;
7a387fff
TS
5547 break;
5548 case 1:
e397ee33 5549 /* ignored, read only */
7a387fff
TS
5550 rn = "Config1";
5551 break;
5552 case 2:
895c2d04 5553 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5554 rn = "Config2";
2423f660
TS
5555 /* Stop translation as we may have switched the execution mode */
5556 ctx->bstate = BS_STOP;
8c0fdd85 5557 break;
7a387fff 5558 case 3:
e397ee33 5559 /* ignored, read only */
7a387fff
TS
5560 rn = "Config3";
5561 break;
b4160af1
PJ
5562 case 4:
5563 gen_helper_mtc0_config4(cpu_env, arg);
5564 rn = "Config4";
5565 ctx->bstate = BS_STOP;
5566 break;
b4dd99a3
PJ
5567 case 5:
5568 gen_helper_mtc0_config5(cpu_env, arg);
5569 rn = "Config5";
5570 /* Stop translation as we may have switched the execution mode */
5571 ctx->bstate = BS_STOP;
5572 break;
e397ee33
TS
5573 /* 6,7 are implementation dependent */
5574 case 6:
5575 /* ignored */
5576 rn = "Config6";
5577 break;
5578 case 7:
5579 /* ignored */
5580 rn = "Config7";
5581 break;
8c0fdd85
TS
5582 default:
5583 rn = "Invalid config selector";
5584 goto die;
5585 }
5586 break;
5587 case 17:
7a387fff
TS
5588 switch (sel) {
5589 case 0:
895c2d04 5590 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5591 rn = "LLAddr";
5592 break;
7a387fff
TS
5593 default:
5594 goto die;
5595 }
8c0fdd85
TS
5596 break;
5597 case 18:
7a387fff 5598 switch (sel) {
fd88b6ab 5599 case 0 ... 7:
895c2d04 5600 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5601 rn = "WatchLo";
5602 break;
7a387fff
TS
5603 default:
5604 goto die;
5605 }
8c0fdd85
TS
5606 break;
5607 case 19:
7a387fff 5608 switch (sel) {
fd88b6ab 5609 case 0 ... 7:
895c2d04 5610 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5611 rn = "WatchHi";
5612 break;
7a387fff
TS
5613 default:
5614 goto die;
5615 }
8c0fdd85
TS
5616 break;
5617 case 20:
7a387fff
TS
5618 switch (sel) {
5619 case 0:
d26bc211 5620#if defined(TARGET_MIPS64)
d75c135e 5621 check_insn(ctx, ISA_MIPS3);
895c2d04 5622 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5623 rn = "XContext";
5624 break;
703eaf37 5625#endif
7a387fff
TS
5626 default:
5627 goto die;
5628 }
8c0fdd85
TS
5629 break;
5630 case 21:
7a387fff
TS
5631 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5632 switch (sel) {
5633 case 0:
895c2d04 5634 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5635 rn = "Framemask";
5636 break;
7a387fff
TS
5637 default:
5638 goto die;
5639 }
5640 break;
8c0fdd85 5641 case 22:
7a387fff
TS
5642 /* ignored */
5643 rn = "Diagnostic"; /* implementation dependent */
2423f660 5644 break;
8c0fdd85 5645 case 23:
7a387fff
TS
5646 switch (sel) {
5647 case 0:
895c2d04 5648 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5649 /* BS_STOP isn't good enough here, hflags may have changed. */
5650 gen_save_pc(ctx->pc + 4);
5651 ctx->bstate = BS_EXCP;
2423f660
TS
5652 rn = "Debug";
5653 break;
7a387fff 5654 case 1:
895c2d04 5655// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5656 rn = "TraceControl";
8487327a
TS
5657 /* Stop translation as we may have switched the execution mode */
5658 ctx->bstate = BS_STOP;
2423f660 5659// break;
7a387fff 5660 case 2:
895c2d04 5661// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5662 rn = "TraceControl2";
8487327a
TS
5663 /* Stop translation as we may have switched the execution mode */
5664 ctx->bstate = BS_STOP;
2423f660 5665// break;
7a387fff 5666 case 3:
8487327a
TS
5667 /* Stop translation as we may have switched the execution mode */
5668 ctx->bstate = BS_STOP;
895c2d04 5669// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5670 rn = "UserTraceData";
8487327a
TS
5671 /* Stop translation as we may have switched the execution mode */
5672 ctx->bstate = BS_STOP;
2423f660 5673// break;
7a387fff 5674 case 4:
895c2d04 5675// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5676 /* Stop translation as we may have switched the execution mode */
5677 ctx->bstate = BS_STOP;
2423f660
TS
5678 rn = "TraceBPC";
5679// break;
7a387fff
TS
5680 default:
5681 goto die;
5682 }
8c0fdd85
TS
5683 break;
5684 case 24:
7a387fff
TS
5685 switch (sel) {
5686 case 0:
f1aa6320 5687 /* EJTAG support */
7db13fae 5688 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5689 rn = "DEPC";
5690 break;
7a387fff
TS
5691 default:
5692 goto die;
5693 }
8c0fdd85
TS
5694 break;
5695 case 25:
7a387fff
TS
5696 switch (sel) {
5697 case 0:
895c2d04 5698 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5699 rn = "Performance0";
5700 break;
7a387fff 5701 case 1:
d9bea114 5702// gen_helper_mtc0_performance1(arg);
2423f660
TS
5703 rn = "Performance1";
5704// break;
7a387fff 5705 case 2:
d9bea114 5706// gen_helper_mtc0_performance2(arg);
2423f660
TS
5707 rn = "Performance2";
5708// break;
7a387fff 5709 case 3:
d9bea114 5710// gen_helper_mtc0_performance3(arg);
2423f660
TS
5711 rn = "Performance3";
5712// break;
7a387fff 5713 case 4:
d9bea114 5714// gen_helper_mtc0_performance4(arg);
2423f660
TS
5715 rn = "Performance4";
5716// break;
7a387fff 5717 case 5:
d9bea114 5718// gen_helper_mtc0_performance5(arg);
2423f660
TS
5719 rn = "Performance5";
5720// break;
7a387fff 5721 case 6:
d9bea114 5722// gen_helper_mtc0_performance6(arg);
2423f660
TS
5723 rn = "Performance6";
5724// break;
7a387fff 5725 case 7:
d9bea114 5726// gen_helper_mtc0_performance7(arg);
2423f660
TS
5727 rn = "Performance7";
5728// break;
7a387fff
TS
5729 default:
5730 goto die;
5731 }
8c0fdd85
TS
5732 break;
5733 case 26:
2423f660 5734 /* ignored */
8c0fdd85 5735 rn = "ECC";
2423f660 5736 break;
8c0fdd85 5737 case 27:
7a387fff
TS
5738 switch (sel) {
5739 case 0 ... 3:
2423f660
TS
5740 /* ignored */
5741 rn = "CacheErr";
5742 break;
7a387fff
TS
5743 default:
5744 goto die;
5745 }
8c0fdd85
TS
5746 break;
5747 case 28:
5748 switch (sel) {
5749 case 0:
7a387fff
TS
5750 case 2:
5751 case 4:
5752 case 6:
895c2d04 5753 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5754 rn = "TagLo";
5755 break;
7a387fff
TS
5756 case 1:
5757 case 3:
5758 case 5:
5759 case 7:
895c2d04 5760 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5761 rn = "DataLo";
5762 break;
8c0fdd85 5763 default:
8c0fdd85
TS
5764 goto die;
5765 }
5766 break;
5767 case 29:
7a387fff
TS
5768 switch (sel) {
5769 case 0:
5770 case 2:
5771 case 4:
5772 case 6:
895c2d04 5773 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5774 rn = "TagHi";
5775 break;
5776 case 1:
5777 case 3:
5778 case 5:
5779 case 7:
895c2d04 5780 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5781 rn = "DataHi";
5782 break;
5783 default:
5784 rn = "invalid sel";
5785 goto die;
5786 }
8c0fdd85
TS
5787 break;
5788 case 30:
7a387fff
TS
5789 switch (sel) {
5790 case 0:
7db13fae 5791 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5792 rn = "ErrorEPC";
5793 break;
7a387fff
TS
5794 default:
5795 goto die;
5796 }
8c0fdd85
TS
5797 break;
5798 case 31:
7a387fff
TS
5799 switch (sel) {
5800 case 0:
f1aa6320 5801 /* EJTAG support */
7db13fae 5802 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5803 rn = "DESAVE";
5804 break;
7a387fff
TS
5805 default:
5806 goto die;
5807 }
2423f660
TS
5808 /* Stop translation as we may have switched the execution mode */
5809 ctx->bstate = BS_STOP;
8c0fdd85
TS
5810 break;
5811 default:
8c0fdd85
TS
5812 goto die;
5813 }
2abf314d 5814 (void)rn; /* avoid a compiler warning */
d12d51d5 5815 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5816 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5817 if (use_icount) {
5818 gen_io_end();
5819 ctx->bstate = BS_STOP;
5820 }
8c0fdd85
TS
5821 return;
5822
5823die:
d12d51d5 5824 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5825 generate_exception(ctx, EXCP_RI);
5826}
5827
d26bc211 5828#if defined(TARGET_MIPS64)
d75c135e 5829static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5830{
5831 const char *rn = "invalid";
5832
e189e748 5833 if (sel != 0)
d75c135e 5834 check_insn(ctx, ISA_MIPS64);
e189e748 5835
9c2149c8
TS
5836 switch (reg) {
5837 case 0:
5838 switch (sel) {
5839 case 0:
7db13fae 5840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5841 rn = "Index";
5842 break;
5843 case 1:
d75c135e 5844 check_insn(ctx, ASE_MT);
895c2d04 5845 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5846 rn = "MVPControl";
ead9360e 5847 break;
9c2149c8 5848 case 2:
d75c135e 5849 check_insn(ctx, ASE_MT);
895c2d04 5850 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5851 rn = "MVPConf0";
ead9360e 5852 break;
9c2149c8 5853 case 3:
d75c135e 5854 check_insn(ctx, ASE_MT);
895c2d04 5855 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5856 rn = "MVPConf1";
ead9360e 5857 break;
9c2149c8
TS
5858 default:
5859 goto die;
5860 }
5861 break;
5862 case 1:
5863 switch (sel) {
5864 case 0:
895c2d04 5865 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5866 rn = "Random";
2423f660 5867 break;
9c2149c8 5868 case 1:
d75c135e 5869 check_insn(ctx, ASE_MT);
7db13fae 5870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5871 rn = "VPEControl";
ead9360e 5872 break;
9c2149c8 5873 case 2:
d75c135e 5874 check_insn(ctx, ASE_MT);
7db13fae 5875 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5876 rn = "VPEConf0";
ead9360e 5877 break;
9c2149c8 5878 case 3:
d75c135e 5879 check_insn(ctx, ASE_MT);
7db13fae 5880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5881 rn = "VPEConf1";
ead9360e 5882 break;
9c2149c8 5883 case 4:
d75c135e 5884 check_insn(ctx, ASE_MT);
7db13fae 5885 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5886 rn = "YQMask";
ead9360e 5887 break;
9c2149c8 5888 case 5:
d75c135e 5889 check_insn(ctx, ASE_MT);
7db13fae 5890 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5891 rn = "VPESchedule";
ead9360e 5892 break;
9c2149c8 5893 case 6:
d75c135e 5894 check_insn(ctx, ASE_MT);
7db13fae 5895 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5896 rn = "VPEScheFBack";
ead9360e 5897 break;
9c2149c8 5898 case 7:
d75c135e 5899 check_insn(ctx, ASE_MT);
7db13fae 5900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5901 rn = "VPEOpt";
ead9360e 5902 break;
9c2149c8
TS
5903 default:
5904 goto die;
5905 }
5906 break;
5907 case 2:
5908 switch (sel) {
5909 case 0:
7db13fae 5910 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5911 rn = "EntryLo0";
5912 break;
9c2149c8 5913 case 1:
d75c135e 5914 check_insn(ctx, ASE_MT);
895c2d04 5915 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5916 rn = "TCStatus";
ead9360e 5917 break;
9c2149c8 5918 case 2:
d75c135e 5919 check_insn(ctx, ASE_MT);
895c2d04 5920 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5921 rn = "TCBind";
ead9360e 5922 break;
9c2149c8 5923 case 3:
d75c135e 5924 check_insn(ctx, ASE_MT);
895c2d04 5925 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5926 rn = "TCRestart";
ead9360e 5927 break;
9c2149c8 5928 case 4:
d75c135e 5929 check_insn(ctx, ASE_MT);
895c2d04 5930 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5931 rn = "TCHalt";
ead9360e 5932 break;
9c2149c8 5933 case 5:
d75c135e 5934 check_insn(ctx, ASE_MT);
895c2d04 5935 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5936 rn = "TCContext";
ead9360e 5937 break;
9c2149c8 5938 case 6:
d75c135e 5939 check_insn(ctx, ASE_MT);
895c2d04 5940 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5941 rn = "TCSchedule";
ead9360e 5942 break;
9c2149c8 5943 case 7:
d75c135e 5944 check_insn(ctx, ASE_MT);
895c2d04 5945 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5946 rn = "TCScheFBack";
ead9360e 5947 break;
9c2149c8
TS
5948 default:
5949 goto die;
5950 }
5951 break;
5952 case 3:
5953 switch (sel) {
5954 case 0:
7db13fae 5955 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5956 rn = "EntryLo1";
5957 break;
9c2149c8
TS
5958 default:
5959 goto die;
1579a72e 5960 }
9c2149c8
TS
5961 break;
5962 case 4:
5963 switch (sel) {
5964 case 0:
7db13fae 5965 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5966 rn = "Context";
5967 break;
9c2149c8 5968 case 1:
d9bea114 5969// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5970 rn = "ContextConfig";
d279279e 5971 goto die;
2423f660 5972// break;
d279279e
PJ
5973 case 2:
5974 if (ctx->ulri) {
5975 tcg_gen_ld_tl(arg, cpu_env,
5976 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5977 rn = "UserLocal";
5978 } else {
5979 tcg_gen_movi_tl(arg, 0);
5980 }
5981 break;
9c2149c8
TS
5982 default:
5983 goto die;
876d4b07 5984 }
9c2149c8
TS
5985 break;
5986 case 5:
5987 switch (sel) {
5988 case 0:
7db13fae 5989 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5990 rn = "PageMask";
5991 break;
9c2149c8 5992 case 1:
d75c135e 5993 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5994 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5995 rn = "PageGrain";
5996 break;
9c2149c8
TS
5997 default:
5998 goto die;
876d4b07 5999 }
9c2149c8
TS
6000 break;
6001 case 6:
6002 switch (sel) {
6003 case 0:
7db13fae 6004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6005 rn = "Wired";
6006 break;
9c2149c8 6007 case 1:
d75c135e 6008 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6009 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6010 rn = "SRSConf0";
ead9360e 6011 break;
9c2149c8 6012 case 2:
d75c135e 6013 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6014 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6015 rn = "SRSConf1";
ead9360e 6016 break;
9c2149c8 6017 case 3:
d75c135e 6018 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6020 rn = "SRSConf2";
ead9360e 6021 break;
9c2149c8 6022 case 4:
d75c135e 6023 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6025 rn = "SRSConf3";
ead9360e 6026 break;
9c2149c8 6027 case 5:
d75c135e 6028 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6030 rn = "SRSConf4";
ead9360e 6031 break;
9c2149c8
TS
6032 default:
6033 goto die;
876d4b07 6034 }
9c2149c8
TS
6035 break;
6036 case 7:
6037 switch (sel) {
6038 case 0:
d75c135e 6039 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6040 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6041 rn = "HWREna";
6042 break;
9c2149c8
TS
6043 default:
6044 goto die;
876d4b07 6045 }
9c2149c8
TS
6046 break;
6047 case 8:
6048 switch (sel) {
6049 case 0:
7db13fae 6050 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6051 rn = "BadVAddr";
2423f660 6052 break;
9c2149c8
TS
6053 default:
6054 goto die;
876d4b07 6055 }
9c2149c8
TS
6056 break;
6057 case 9:
6058 switch (sel) {
6059 case 0:
2e70f6ef
PB
6060 /* Mark as an IO operation because we read the time. */
6061 if (use_icount)
6062 gen_io_start();
895c2d04 6063 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
6064 if (use_icount) {
6065 gen_io_end();
2e70f6ef 6066 }
55807224
EI
6067 /* Break the TB to be able to take timer interrupts immediately
6068 after reading count. */
6069 ctx->bstate = BS_STOP;
2423f660
TS
6070 rn = "Count";
6071 break;
6072 /* 6,7 are implementation dependent */
9c2149c8
TS
6073 default:
6074 goto die;
876d4b07 6075 }
9c2149c8
TS
6076 break;
6077 case 10:
6078 switch (sel) {
6079 case 0:
7db13fae 6080 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6081 rn = "EntryHi";
6082 break;
9c2149c8
TS
6083 default:
6084 goto die;
876d4b07 6085 }
9c2149c8
TS
6086 break;
6087 case 11:
6088 switch (sel) {
6089 case 0:
7db13fae 6090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6091 rn = "Compare";
6092 break;
876d4b07 6093 /* 6,7 are implementation dependent */
9c2149c8
TS
6094 default:
6095 goto die;
876d4b07 6096 }
9c2149c8
TS
6097 break;
6098 case 12:
6099 switch (sel) {
6100 case 0:
7db13fae 6101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6102 rn = "Status";
6103 break;
9c2149c8 6104 case 1:
d75c135e 6105 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6107 rn = "IntCtl";
6108 break;
9c2149c8 6109 case 2:
d75c135e 6110 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6112 rn = "SRSCtl";
6113 break;
9c2149c8 6114 case 3:
d75c135e 6115 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6117 rn = "SRSMap";
6118 break;
9c2149c8
TS
6119 default:
6120 goto die;
876d4b07 6121 }
9c2149c8
TS
6122 break;
6123 case 13:
6124 switch (sel) {
6125 case 0:
7db13fae 6126 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6127 rn = "Cause";
6128 break;
9c2149c8
TS
6129 default:
6130 goto die;
876d4b07 6131 }
9c2149c8
TS
6132 break;
6133 case 14:
6134 switch (sel) {
6135 case 0:
7db13fae 6136 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6137 rn = "EPC";
6138 break;
9c2149c8
TS
6139 default:
6140 goto die;
876d4b07 6141 }
9c2149c8
TS
6142 break;
6143 case 15:
6144 switch (sel) {
6145 case 0:
7db13fae 6146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6147 rn = "PRid";
6148 break;
9c2149c8 6149 case 1:
d75c135e 6150 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6152 rn = "EBase";
6153 break;
9c2149c8
TS
6154 default:
6155 goto die;
876d4b07 6156 }
9c2149c8
TS
6157 break;
6158 case 16:
6159 switch (sel) {
6160 case 0:
7db13fae 6161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6162 rn = "Config";
6163 break;
6164 case 1:
7db13fae 6165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6166 rn = "Config1";
6167 break;
6168 case 2:
7db13fae 6169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6170 rn = "Config2";
6171 break;
6172 case 3:
7db13fae 6173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6174 rn = "Config3";
6175 break;
6176 /* 6,7 are implementation dependent */
f0b3f3ae 6177 case 6:
7db13fae 6178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6179 rn = "Config6";
6180 break;
6181 case 7:
7db13fae 6182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6183 rn = "Config7";
6184 break;
9c2149c8
TS
6185 default:
6186 goto die;
6187 }
6188 break;
6189 case 17:
6190 switch (sel) {
6191 case 0:
895c2d04 6192 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6193 rn = "LLAddr";
6194 break;
9c2149c8
TS
6195 default:
6196 goto die;
6197 }
6198 break;
6199 case 18:
6200 switch (sel) {
fd88b6ab 6201 case 0 ... 7:
895c2d04 6202 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6203 rn = "WatchLo";
6204 break;
9c2149c8
TS
6205 default:
6206 goto die;
6207 }
6208 break;
6209 case 19:
6210 switch (sel) {
fd88b6ab 6211 case 0 ... 7:
895c2d04 6212 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6213 rn = "WatchHi";
6214 break;
9c2149c8
TS
6215 default:
6216 goto die;
6217 }
6218 break;
6219 case 20:
6220 switch (sel) {
6221 case 0:
d75c135e 6222 check_insn(ctx, ISA_MIPS3);
7db13fae 6223 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6224 rn = "XContext";
6225 break;
9c2149c8
TS
6226 default:
6227 goto die;
6228 }
6229 break;
6230 case 21:
6231 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6232 switch (sel) {
6233 case 0:
7db13fae 6234 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6235 rn = "Framemask";
6236 break;
9c2149c8
TS
6237 default:
6238 goto die;
6239 }
6240 break;
6241 case 22:
d9bea114 6242 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6243 rn = "'Diagnostic"; /* implementation dependent */
6244 break;
9c2149c8
TS
6245 case 23:
6246 switch (sel) {
6247 case 0:
895c2d04 6248 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6249 rn = "Debug";
6250 break;
9c2149c8 6251 case 1:
895c2d04 6252// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6253 rn = "TraceControl";
6254// break;
9c2149c8 6255 case 2:
895c2d04 6256// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6257 rn = "TraceControl2";
6258// break;
9c2149c8 6259 case 3:
895c2d04 6260// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6261 rn = "UserTraceData";
6262// break;
9c2149c8 6263 case 4:
895c2d04 6264// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6265 rn = "TraceBPC";
6266// break;
9c2149c8
TS
6267 default:
6268 goto die;
6269 }
6270 break;
6271 case 24:
6272 switch (sel) {
6273 case 0:
f0b3f3ae 6274 /* EJTAG support */
7db13fae 6275 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6276 rn = "DEPC";
6277 break;
9c2149c8
TS
6278 default:
6279 goto die;
6280 }
6281 break;
6282 case 25:
6283 switch (sel) {
6284 case 0:
7db13fae 6285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6286 rn = "Performance0";
9c2149c8
TS
6287 break;
6288 case 1:
d9bea114 6289// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6290 rn = "Performance1";
6291// break;
9c2149c8 6292 case 2:
d9bea114 6293// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6294 rn = "Performance2";
6295// break;
9c2149c8 6296 case 3:
d9bea114 6297// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6298 rn = "Performance3";
6299// break;
9c2149c8 6300 case 4:
d9bea114 6301// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6302 rn = "Performance4";
6303// break;
9c2149c8 6304 case 5:
d9bea114 6305// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6306 rn = "Performance5";
6307// break;
9c2149c8 6308 case 6:
d9bea114 6309// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6310 rn = "Performance6";
6311// break;
9c2149c8 6312 case 7:
d9bea114 6313// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6314 rn = "Performance7";
6315// break;
9c2149c8
TS
6316 default:
6317 goto die;
6318 }
6319 break;
6320 case 26:
d9bea114 6321 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6322 rn = "ECC";
6323 break;
9c2149c8
TS
6324 case 27:
6325 switch (sel) {
6326 /* ignored */
6327 case 0 ... 3:
d9bea114 6328 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6329 rn = "CacheErr";
6330 break;
9c2149c8
TS
6331 default:
6332 goto die;
6333 }
6334 break;
6335 case 28:
6336 switch (sel) {
6337 case 0:
6338 case 2:
6339 case 4:
6340 case 6:
7db13fae 6341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6342 rn = "TagLo";
6343 break;
6344 case 1:
6345 case 3:
6346 case 5:
6347 case 7:
7db13fae 6348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6349 rn = "DataLo";
6350 break;
6351 default:
6352 goto die;
6353 }
6354 break;
6355 case 29:
6356 switch (sel) {
6357 case 0:
6358 case 2:
6359 case 4:
6360 case 6:
7db13fae 6361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6362 rn = "TagHi";
6363 break;
6364 case 1:
6365 case 3:
6366 case 5:
6367 case 7:
7db13fae 6368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6369 rn = "DataHi";
6370 break;
6371 default:
6372 goto die;
6373 }
6374 break;
6375 case 30:
6376 switch (sel) {
6377 case 0:
7db13fae 6378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6379 rn = "ErrorEPC";
6380 break;
9c2149c8
TS
6381 default:
6382 goto die;
6383 }
6384 break;
6385 case 31:
6386 switch (sel) {
6387 case 0:
f0b3f3ae 6388 /* EJTAG support */
7db13fae 6389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6390 rn = "DESAVE";
6391 break;
9c2149c8
TS
6392 default:
6393 goto die;
6394 }
6395 break;
6396 default:
876d4b07 6397 goto die;
9c2149c8 6398 }
2abf314d 6399 (void)rn; /* avoid a compiler warning */
d12d51d5 6400 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6401 return;
6402
6403die:
d12d51d5 6404 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6405 generate_exception(ctx, EXCP_RI);
6406}
6407
d75c135e 6408static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6409{
6410 const char *rn = "invalid";
6411
e189e748 6412 if (sel != 0)
d75c135e 6413 check_insn(ctx, ISA_MIPS64);
e189e748 6414
2e70f6ef
PB
6415 if (use_icount)
6416 gen_io_start();
6417
9c2149c8
TS
6418 switch (reg) {
6419 case 0:
6420 switch (sel) {
6421 case 0:
895c2d04 6422 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6423 rn = "Index";
6424 break;
6425 case 1:
d75c135e 6426 check_insn(ctx, ASE_MT);
895c2d04 6427 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6428 rn = "MVPControl";
ead9360e 6429 break;
9c2149c8 6430 case 2:
d75c135e 6431 check_insn(ctx, ASE_MT);
ead9360e 6432 /* ignored */
9c2149c8 6433 rn = "MVPConf0";
ead9360e 6434 break;
9c2149c8 6435 case 3:
d75c135e 6436 check_insn(ctx, ASE_MT);
ead9360e 6437 /* ignored */
9c2149c8 6438 rn = "MVPConf1";
ead9360e 6439 break;
9c2149c8
TS
6440 default:
6441 goto die;
6442 }
6443 break;
6444 case 1:
6445 switch (sel) {
6446 case 0:
2423f660 6447 /* ignored */
9c2149c8 6448 rn = "Random";
2423f660 6449 break;
9c2149c8 6450 case 1:
d75c135e 6451 check_insn(ctx, ASE_MT);
895c2d04 6452 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6453 rn = "VPEControl";
ead9360e 6454 break;
9c2149c8 6455 case 2:
d75c135e 6456 check_insn(ctx, ASE_MT);
895c2d04 6457 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6458 rn = "VPEConf0";
ead9360e 6459 break;
9c2149c8 6460 case 3:
d75c135e 6461 check_insn(ctx, ASE_MT);
895c2d04 6462 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6463 rn = "VPEConf1";
ead9360e 6464 break;
9c2149c8 6465 case 4:
d75c135e 6466 check_insn(ctx, ASE_MT);
895c2d04 6467 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6468 rn = "YQMask";
ead9360e 6469 break;
9c2149c8 6470 case 5:
d75c135e 6471 check_insn(ctx, ASE_MT);
7db13fae 6472 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6473 rn = "VPESchedule";
ead9360e 6474 break;
9c2149c8 6475 case 6:
d75c135e 6476 check_insn(ctx, ASE_MT);
7db13fae 6477 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6478 rn = "VPEScheFBack";
ead9360e 6479 break;
9c2149c8 6480 case 7:
d75c135e 6481 check_insn(ctx, ASE_MT);
895c2d04 6482 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6483 rn = "VPEOpt";
ead9360e 6484 break;
9c2149c8
TS
6485 default:
6486 goto die;
6487 }
6488 break;
6489 case 2:
6490 switch (sel) {
6491 case 0:
895c2d04 6492 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
6493 rn = "EntryLo0";
6494 break;
9c2149c8 6495 case 1:
d75c135e 6496 check_insn(ctx, ASE_MT);
895c2d04 6497 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6498 rn = "TCStatus";
ead9360e 6499 break;
9c2149c8 6500 case 2:
d75c135e 6501 check_insn(ctx, ASE_MT);
895c2d04 6502 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6503 rn = "TCBind";
ead9360e 6504 break;
9c2149c8 6505 case 3:
d75c135e 6506 check_insn(ctx, ASE_MT);
895c2d04 6507 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6508 rn = "TCRestart";
ead9360e 6509 break;
9c2149c8 6510 case 4:
d75c135e 6511 check_insn(ctx, ASE_MT);
895c2d04 6512 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6513 rn = "TCHalt";
ead9360e 6514 break;
9c2149c8 6515 case 5:
d75c135e 6516 check_insn(ctx, ASE_MT);
895c2d04 6517 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6518 rn = "TCContext";
ead9360e 6519 break;
9c2149c8 6520 case 6:
d75c135e 6521 check_insn(ctx, ASE_MT);
895c2d04 6522 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6523 rn = "TCSchedule";
ead9360e 6524 break;
9c2149c8 6525 case 7:
d75c135e 6526 check_insn(ctx, ASE_MT);
895c2d04 6527 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6528 rn = "TCScheFBack";
ead9360e 6529 break;
9c2149c8
TS
6530 default:
6531 goto die;
6532 }
6533 break;
6534 case 3:
6535 switch (sel) {
6536 case 0:
895c2d04 6537 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6538 rn = "EntryLo1";
6539 break;
9c2149c8
TS
6540 default:
6541 goto die;
876d4b07 6542 }
9c2149c8
TS
6543 break;
6544 case 4:
6545 switch (sel) {
6546 case 0:
895c2d04 6547 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6548 rn = "Context";
6549 break;
9c2149c8 6550 case 1:
895c2d04 6551// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6552 rn = "ContextConfig";
d279279e 6553 goto die;
2423f660 6554// break;
d279279e
PJ
6555 case 2:
6556 if (ctx->ulri) {
6557 tcg_gen_st_tl(arg, cpu_env,
6558 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6559 rn = "UserLocal";
6560 }
6561 break;
9c2149c8
TS
6562 default:
6563 goto die;
876d4b07 6564 }
9c2149c8
TS
6565 break;
6566 case 5:
6567 switch (sel) {
6568 case 0:
895c2d04 6569 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6570 rn = "PageMask";
6571 break;
9c2149c8 6572 case 1:
d75c135e 6573 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6574 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6575 rn = "PageGrain";
6576 break;
9c2149c8
TS
6577 default:
6578 goto die;
876d4b07 6579 }
9c2149c8
TS
6580 break;
6581 case 6:
6582 switch (sel) {
6583 case 0:
895c2d04 6584 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6585 rn = "Wired";
6586 break;
9c2149c8 6587 case 1:
d75c135e 6588 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6589 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6590 rn = "SRSConf0";
ead9360e 6591 break;
9c2149c8 6592 case 2:
d75c135e 6593 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6594 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6595 rn = "SRSConf1";
ead9360e 6596 break;
9c2149c8 6597 case 3:
d75c135e 6598 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6599 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6600 rn = "SRSConf2";
ead9360e 6601 break;
9c2149c8 6602 case 4:
d75c135e 6603 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6604 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6605 rn = "SRSConf3";
ead9360e 6606 break;
9c2149c8 6607 case 5:
d75c135e 6608 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6609 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6610 rn = "SRSConf4";
ead9360e 6611 break;
9c2149c8
TS
6612 default:
6613 goto die;
876d4b07 6614 }
9c2149c8
TS
6615 break;
6616 case 7:
6617 switch (sel) {
6618 case 0:
d75c135e 6619 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6620 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6621 ctx->bstate = BS_STOP;
2423f660
TS
6622 rn = "HWREna";
6623 break;
9c2149c8
TS
6624 default:
6625 goto die;
876d4b07 6626 }
9c2149c8
TS
6627 break;
6628 case 8:
6629 /* ignored */
f0b3f3ae 6630 rn = "BadVAddr";
9c2149c8
TS
6631 break;
6632 case 9:
6633 switch (sel) {
6634 case 0:
895c2d04 6635 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6636 rn = "Count";
6637 break;
876d4b07 6638 /* 6,7 are implementation dependent */
9c2149c8
TS
6639 default:
6640 goto die;
876d4b07
TS
6641 }
6642 /* Stop translation as we may have switched the execution mode */
6643 ctx->bstate = BS_STOP;
9c2149c8
TS
6644 break;
6645 case 10:
6646 switch (sel) {
6647 case 0:
895c2d04 6648 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6649 rn = "EntryHi";
6650 break;
9c2149c8
TS
6651 default:
6652 goto die;
876d4b07 6653 }
9c2149c8
TS
6654 break;
6655 case 11:
6656 switch (sel) {
6657 case 0:
895c2d04 6658 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6659 rn = "Compare";
6660 break;
876d4b07 6661 /* 6,7 are implementation dependent */
9c2149c8
TS
6662 default:
6663 goto die;
876d4b07 6664 }
de9a95f0
AJ
6665 /* Stop translation as we may have switched the execution mode */
6666 ctx->bstate = BS_STOP;
9c2149c8
TS
6667 break;
6668 case 12:
6669 switch (sel) {
6670 case 0:
867abc7e 6671 save_cpu_state(ctx, 1);
895c2d04 6672 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6673 /* BS_STOP isn't good enough here, hflags may have changed. */
6674 gen_save_pc(ctx->pc + 4);
6675 ctx->bstate = BS_EXCP;
2423f660
TS
6676 rn = "Status";
6677 break;
9c2149c8 6678 case 1:
d75c135e 6679 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6680 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6681 /* Stop translation as we may have switched the execution mode */
6682 ctx->bstate = BS_STOP;
2423f660
TS
6683 rn = "IntCtl";
6684 break;
9c2149c8 6685 case 2:
d75c135e 6686 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6687 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6688 /* Stop translation as we may have switched the execution mode */
6689 ctx->bstate = BS_STOP;
2423f660
TS
6690 rn = "SRSCtl";
6691 break;
9c2149c8 6692 case 3:
d75c135e 6693 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6694 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6695 /* Stop translation as we may have switched the execution mode */
6696 ctx->bstate = BS_STOP;
2423f660
TS
6697 rn = "SRSMap";
6698 break;
6699 default:
9c2149c8 6700 goto die;
876d4b07 6701 }
9c2149c8
TS
6702 break;
6703 case 13:
6704 switch (sel) {
6705 case 0:
867abc7e 6706 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6707 /* Mark as an IO operation because we may trigger a software
6708 interrupt. */
6709 if (use_icount) {
6710 gen_io_start();
6711 }
895c2d04 6712 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6713 if (use_icount) {
6714 gen_io_end();
6715 }
6716 /* Stop translation as we may have triggered an intetrupt */
6717 ctx->bstate = BS_STOP;
2423f660
TS
6718 rn = "Cause";
6719 break;
9c2149c8
TS
6720 default:
6721 goto die;
876d4b07 6722 }
9c2149c8
TS
6723 break;
6724 case 14:
6725 switch (sel) {
6726 case 0:
7db13fae 6727 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6728 rn = "EPC";
6729 break;
9c2149c8
TS
6730 default:
6731 goto die;
876d4b07 6732 }
9c2149c8
TS
6733 break;
6734 case 15:
6735 switch (sel) {
6736 case 0:
2423f660
TS
6737 /* ignored */
6738 rn = "PRid";
6739 break;
9c2149c8 6740 case 1:
d75c135e 6741 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6742 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6743 rn = "EBase";
6744 break;
9c2149c8
TS
6745 default:
6746 goto die;
876d4b07 6747 }
9c2149c8
TS
6748 break;
6749 case 16:
6750 switch (sel) {
6751 case 0:
895c2d04 6752 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6753 rn = "Config";
2423f660
TS
6754 /* Stop translation as we may have switched the execution mode */
6755 ctx->bstate = BS_STOP;
9c2149c8
TS
6756 break;
6757 case 1:
1fc7bf6e 6758 /* ignored, read only */
9c2149c8
TS
6759 rn = "Config1";
6760 break;
6761 case 2:
895c2d04 6762 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6763 rn = "Config2";
2423f660
TS
6764 /* Stop translation as we may have switched the execution mode */
6765 ctx->bstate = BS_STOP;
9c2149c8
TS
6766 break;
6767 case 3:
2423f660 6768 /* ignored */
9c2149c8
TS
6769 rn = "Config3";
6770 break;
6771 /* 6,7 are implementation dependent */
6772 default:
6773 rn = "Invalid config selector";
6774 goto die;
6775 }
9c2149c8
TS
6776 break;
6777 case 17:
6778 switch (sel) {
6779 case 0:
895c2d04 6780 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6781 rn = "LLAddr";
6782 break;
9c2149c8
TS
6783 default:
6784 goto die;
6785 }
6786 break;
6787 case 18:
6788 switch (sel) {
fd88b6ab 6789 case 0 ... 7:
895c2d04 6790 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6791 rn = "WatchLo";
6792 break;
9c2149c8
TS
6793 default:
6794 goto die;
6795 }
6796 break;
6797 case 19:
6798 switch (sel) {
fd88b6ab 6799 case 0 ... 7:
895c2d04 6800 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6801 rn = "WatchHi";
6802 break;
9c2149c8
TS
6803 default:
6804 goto die;
6805 }
6806 break;
6807 case 20:
6808 switch (sel) {
6809 case 0:
d75c135e 6810 check_insn(ctx, ISA_MIPS3);
895c2d04 6811 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6812 rn = "XContext";
6813 break;
9c2149c8
TS
6814 default:
6815 goto die;
6816 }
6817 break;
6818 case 21:
6819 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6820 switch (sel) {
6821 case 0:
895c2d04 6822 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6823 rn = "Framemask";
6824 break;
9c2149c8
TS
6825 default:
6826 goto die;
6827 }
6828 break;
6829 case 22:
6830 /* ignored */
6831 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6832 break;
9c2149c8
TS
6833 case 23:
6834 switch (sel) {
6835 case 0:
895c2d04 6836 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6837 /* BS_STOP isn't good enough here, hflags may have changed. */
6838 gen_save_pc(ctx->pc + 4);
6839 ctx->bstate = BS_EXCP;
2423f660
TS
6840 rn = "Debug";
6841 break;
9c2149c8 6842 case 1:
895c2d04 6843// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6844 /* Stop translation as we may have switched the execution mode */
6845 ctx->bstate = BS_STOP;
2423f660
TS
6846 rn = "TraceControl";
6847// break;
9c2149c8 6848 case 2:
895c2d04 6849// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6850 /* Stop translation as we may have switched the execution mode */
6851 ctx->bstate = BS_STOP;
2423f660
TS
6852 rn = "TraceControl2";
6853// break;
9c2149c8 6854 case 3:
895c2d04 6855// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6856 /* Stop translation as we may have switched the execution mode */
6857 ctx->bstate = BS_STOP;
2423f660
TS
6858 rn = "UserTraceData";
6859// break;
9c2149c8 6860 case 4:
895c2d04 6861// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6862 /* Stop translation as we may have switched the execution mode */
6863 ctx->bstate = BS_STOP;
2423f660
TS
6864 rn = "TraceBPC";
6865// break;
9c2149c8
TS
6866 default:
6867 goto die;
6868 }
9c2149c8
TS
6869 break;
6870 case 24:
6871 switch (sel) {
6872 case 0:
f1aa6320 6873 /* EJTAG support */
7db13fae 6874 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6875 rn = "DEPC";
6876 break;
9c2149c8
TS
6877 default:
6878 goto die;
6879 }
6880 break;
6881 case 25:
6882 switch (sel) {
6883 case 0:
895c2d04 6884 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6885 rn = "Performance0";
6886 break;
9c2149c8 6887 case 1:
895c2d04 6888// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6889 rn = "Performance1";
6890// break;
9c2149c8 6891 case 2:
895c2d04 6892// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6893 rn = "Performance2";
6894// break;
9c2149c8 6895 case 3:
895c2d04 6896// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6897 rn = "Performance3";
6898// break;
9c2149c8 6899 case 4:
895c2d04 6900// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6901 rn = "Performance4";
6902// break;
9c2149c8 6903 case 5:
895c2d04 6904// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6905 rn = "Performance5";
6906// break;
9c2149c8 6907 case 6:
895c2d04 6908// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6909 rn = "Performance6";
6910// break;
9c2149c8 6911 case 7:
895c2d04 6912// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6913 rn = "Performance7";
6914// break;
9c2149c8
TS
6915 default:
6916 goto die;
6917 }
876d4b07 6918 break;
9c2149c8 6919 case 26:
876d4b07 6920 /* ignored */
9c2149c8 6921 rn = "ECC";
876d4b07 6922 break;
9c2149c8
TS
6923 case 27:
6924 switch (sel) {
6925 case 0 ... 3:
2423f660
TS
6926 /* ignored */
6927 rn = "CacheErr";
6928 break;
9c2149c8
TS
6929 default:
6930 goto die;
6931 }
876d4b07 6932 break;
9c2149c8
TS
6933 case 28:
6934 switch (sel) {
6935 case 0:
6936 case 2:
6937 case 4:
6938 case 6:
895c2d04 6939 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6940 rn = "TagLo";
6941 break;
6942 case 1:
6943 case 3:
6944 case 5:
6945 case 7:
895c2d04 6946 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6947 rn = "DataLo";
6948 break;
6949 default:
6950 goto die;
6951 }
6952 break;
6953 case 29:
6954 switch (sel) {
6955 case 0:
6956 case 2:
6957 case 4:
6958 case 6:
895c2d04 6959 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6960 rn = "TagHi";
6961 break;
6962 case 1:
6963 case 3:
6964 case 5:
6965 case 7:
895c2d04 6966 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6967 rn = "DataHi";
6968 break;
6969 default:
6970 rn = "invalid sel";
6971 goto die;
6972 }
876d4b07 6973 break;
9c2149c8
TS
6974 case 30:
6975 switch (sel) {
6976 case 0:
7db13fae 6977 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6978 rn = "ErrorEPC";
6979 break;
9c2149c8
TS
6980 default:
6981 goto die;
6982 }
6983 break;
6984 case 31:
6985 switch (sel) {
6986 case 0:
f1aa6320 6987 /* EJTAG support */
7db13fae 6988 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6989 rn = "DESAVE";
6990 break;
9c2149c8
TS
6991 default:
6992 goto die;
6993 }
876d4b07
TS
6994 /* Stop translation as we may have switched the execution mode */
6995 ctx->bstate = BS_STOP;
9c2149c8
TS
6996 break;
6997 default:
876d4b07 6998 goto die;
9c2149c8 6999 }
2abf314d 7000 (void)rn; /* avoid a compiler warning */
d12d51d5 7001 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 7002 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
7003 if (use_icount) {
7004 gen_io_end();
7005 ctx->bstate = BS_STOP;
7006 }
9c2149c8
TS
7007 return;
7008
7009die:
d12d51d5 7010 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
7011 generate_exception(ctx, EXCP_RI);
7012}
d26bc211 7013#endif /* TARGET_MIPS64 */
9c2149c8 7014
7db13fae 7015static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7016 int u, int sel, int h)
7017{
7018 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7019 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7020
7021 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7022 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7023 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7024 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7025 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7026 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7027 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7028 else if (u == 0) {
7029 switch (rt) {
5a25ce94
EI
7030 case 1:
7031 switch (sel) {
7032 case 1:
895c2d04 7033 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7034 break;
7035 case 2:
895c2d04 7036 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7037 break;
7038 default:
7039 goto die;
7040 break;
7041 }
7042 break;
ead9360e
TS
7043 case 2:
7044 switch (sel) {
7045 case 1:
895c2d04 7046 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7047 break;
7048 case 2:
895c2d04 7049 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7050 break;
7051 case 3:
895c2d04 7052 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7053 break;
7054 case 4:
895c2d04 7055 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7056 break;
7057 case 5:
895c2d04 7058 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7059 break;
7060 case 6:
895c2d04 7061 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7062 break;
7063 case 7:
895c2d04 7064 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7065 break;
7066 default:
d75c135e 7067 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7068 break;
7069 }
7070 break;
7071 case 10:
7072 switch (sel) {
7073 case 0:
895c2d04 7074 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7075 break;
7076 default:
d75c135e 7077 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7078 break;
7079 }
7080 case 12:
7081 switch (sel) {
7082 case 0:
895c2d04 7083 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7084 break;
7085 default:
d75c135e 7086 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7087 break;
7088 }
5a25ce94
EI
7089 case 13:
7090 switch (sel) {
7091 case 0:
895c2d04 7092 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7093 break;
7094 default:
7095 goto die;
7096 break;
7097 }
7098 break;
7099 case 14:
7100 switch (sel) {
7101 case 0:
895c2d04 7102 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7103 break;
7104 default:
7105 goto die;
7106 break;
7107 }
7108 break;
7109 case 15:
7110 switch (sel) {
7111 case 1:
895c2d04 7112 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7113 break;
7114 default:
7115 goto die;
7116 break;
7117 }
7118 break;
7119 case 16:
7120 switch (sel) {
7121 case 0 ... 7:
895c2d04 7122 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7123 break;
7124 default:
7125 goto die;
7126 break;
7127 }
7128 break;
ead9360e
TS
7129 case 23:
7130 switch (sel) {
7131 case 0:
895c2d04 7132 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7133 break;
7134 default:
d75c135e 7135 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7136 break;
7137 }
7138 break;
7139 default:
d75c135e 7140 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7141 }
7142 } else switch (sel) {
7143 /* GPR registers. */
7144 case 0:
895c2d04 7145 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7146 break;
7147 /* Auxiliary CPU registers */
7148 case 1:
7149 switch (rt) {
7150 case 0:
895c2d04 7151 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7152 break;
7153 case 1:
895c2d04 7154 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7155 break;
7156 case 2:
895c2d04 7157 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7158 break;
7159 case 4:
895c2d04 7160 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7161 break;
7162 case 5:
895c2d04 7163 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7164 break;
7165 case 6:
895c2d04 7166 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7167 break;
7168 case 8:
895c2d04 7169 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7170 break;
7171 case 9:
895c2d04 7172 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7173 break;
7174 case 10:
895c2d04 7175 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7176 break;
7177 case 12:
895c2d04 7178 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7179 break;
7180 case 13:
895c2d04 7181 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7182 break;
7183 case 14:
895c2d04 7184 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7185 break;
7186 case 16:
895c2d04 7187 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7188 break;
7189 default:
7190 goto die;
7191 }
7192 break;
7193 /* Floating point (COP1). */
7194 case 2:
7195 /* XXX: For now we support only a single FPU context. */
7196 if (h == 0) {
a7812ae4 7197 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7198
7199 gen_load_fpr32(fp0, rt);
7200 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7201 tcg_temp_free_i32(fp0);
ead9360e 7202 } else {
a7812ae4 7203 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7204
7f6613ce 7205 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7206 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7207 tcg_temp_free_i32(fp0);
ead9360e
TS
7208 }
7209 break;
7210 case 3:
7211 /* XXX: For now we support only a single FPU context. */
895c2d04 7212 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7213 break;
7214 /* COP2: Not implemented. */
7215 case 4:
7216 case 5:
7217 /* fall through */
7218 default:
7219 goto die;
7220 }
d12d51d5 7221 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
7222 gen_store_gpr(t0, rd);
7223 tcg_temp_free(t0);
ead9360e
TS
7224 return;
7225
7226die:
1a3fd9c3 7227 tcg_temp_free(t0);
d12d51d5 7228 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
7229 generate_exception(ctx, EXCP_RI);
7230}
7231
7db13fae 7232static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7233 int u, int sel, int h)
7234{
7235 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7236 TCGv t0 = tcg_temp_local_new();
ead9360e 7237
1a3fd9c3 7238 gen_load_gpr(t0, rt);
ead9360e 7239 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7240 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7241 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7242 /* NOP */ ;
7243 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7244 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7245 /* NOP */ ;
7246 else if (u == 0) {
7247 switch (rd) {
5a25ce94
EI
7248 case 1:
7249 switch (sel) {
7250 case 1:
895c2d04 7251 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7252 break;
7253 case 2:
895c2d04 7254 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7255 break;
7256 default:
7257 goto die;
7258 break;
7259 }
7260 break;
ead9360e
TS
7261 case 2:
7262 switch (sel) {
7263 case 1:
895c2d04 7264 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7265 break;
7266 case 2:
895c2d04 7267 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7268 break;
7269 case 3:
895c2d04 7270 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7271 break;
7272 case 4:
895c2d04 7273 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7274 break;
7275 case 5:
895c2d04 7276 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7277 break;
7278 case 6:
895c2d04 7279 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7280 break;
7281 case 7:
895c2d04 7282 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7283 break;
7284 default:
d75c135e 7285 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7286 break;
7287 }
7288 break;
7289 case 10:
7290 switch (sel) {
7291 case 0:
895c2d04 7292 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7293 break;
7294 default:
d75c135e 7295 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7296 break;
7297 }
7298 case 12:
7299 switch (sel) {
7300 case 0:
895c2d04 7301 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7302 break;
7303 default:
d75c135e 7304 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7305 break;
7306 }
5a25ce94
EI
7307 case 13:
7308 switch (sel) {
7309 case 0:
895c2d04 7310 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7311 break;
7312 default:
7313 goto die;
7314 break;
7315 }
7316 break;
7317 case 15:
7318 switch (sel) {
7319 case 1:
895c2d04 7320 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7321 break;
7322 default:
7323 goto die;
7324 break;
7325 }
7326 break;
ead9360e
TS
7327 case 23:
7328 switch (sel) {
7329 case 0:
895c2d04 7330 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7331 break;
7332 default:
d75c135e 7333 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7334 break;
7335 }
7336 break;
7337 default:
d75c135e 7338 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7339 }
7340 } else switch (sel) {
7341 /* GPR registers. */
7342 case 0:
895c2d04 7343 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7344 break;
7345 /* Auxiliary CPU registers */
7346 case 1:
7347 switch (rd) {
7348 case 0:
895c2d04 7349 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7350 break;
7351 case 1:
895c2d04 7352 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7353 break;
7354 case 2:
895c2d04 7355 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7356 break;
7357 case 4:
895c2d04 7358 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7359 break;
7360 case 5:
895c2d04 7361 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7362 break;
7363 case 6:
895c2d04 7364 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7365 break;
7366 case 8:
895c2d04 7367 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7368 break;
7369 case 9:
895c2d04 7370 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7371 break;
7372 case 10:
895c2d04 7373 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7374 break;
7375 case 12:
895c2d04 7376 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7377 break;
7378 case 13:
895c2d04 7379 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7380 break;
7381 case 14:
895c2d04 7382 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7383 break;
7384 case 16:
895c2d04 7385 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7386 break;
7387 default:
7388 goto die;
7389 }
7390 break;
7391 /* Floating point (COP1). */
7392 case 2:
7393 /* XXX: For now we support only a single FPU context. */
7394 if (h == 0) {
a7812ae4 7395 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7396
7397 tcg_gen_trunc_tl_i32(fp0, t0);
7398 gen_store_fpr32(fp0, rd);
a7812ae4 7399 tcg_temp_free_i32(fp0);
ead9360e 7400 } else {
a7812ae4 7401 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7402
7403 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7404 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7405 tcg_temp_free_i32(fp0);
ead9360e
TS
7406 }
7407 break;
7408 case 3:
7409 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7410 {
7411 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7412
7413 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7414 tcg_temp_free_i32(fs_tmp);
7415 }
ead9360e
TS
7416 break;
7417 /* COP2: Not implemented. */
7418 case 4:
7419 case 5:
7420 /* fall through */
7421 default:
7422 goto die;
7423 }
d12d51d5 7424 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7425 tcg_temp_free(t0);
ead9360e
TS
7426 return;
7427
7428die:
1a3fd9c3 7429 tcg_temp_free(t0);
d12d51d5 7430 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7431 generate_exception(ctx, EXCP_RI);
7432}
7433
7db13fae 7434static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7435{
287c4b84 7436 const char *opn = "ldst";
6af0bf9c 7437
2e15497c 7438 check_cp0_enabled(ctx);
6af0bf9c
FB
7439 switch (opc) {
7440 case OPC_MFC0:
7441 if (rt == 0) {
ead9360e 7442 /* Treat as NOP. */
6af0bf9c
FB
7443 return;
7444 }
d75c135e 7445 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7446 opn = "mfc0";
7447 break;
7448 case OPC_MTC0:
1a3fd9c3 7449 {
1fc7bf6e 7450 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7451
7452 gen_load_gpr(t0, rt);
d75c135e 7453 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7454 tcg_temp_free(t0);
7455 }
6af0bf9c
FB
7456 opn = "mtc0";
7457 break;
d26bc211 7458#if defined(TARGET_MIPS64)
9c2149c8 7459 case OPC_DMFC0:
d75c135e 7460 check_insn(ctx, ISA_MIPS3);
9c2149c8 7461 if (rt == 0) {
ead9360e 7462 /* Treat as NOP. */
9c2149c8
TS
7463 return;
7464 }
d75c135e 7465 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7466 opn = "dmfc0";
7467 break;
7468 case OPC_DMTC0:
d75c135e 7469 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7470 {
1fc7bf6e 7471 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7472
7473 gen_load_gpr(t0, rt);
d75c135e 7474 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7475 tcg_temp_free(t0);
7476 }
9c2149c8
TS
7477 opn = "dmtc0";
7478 break;
534ce69f 7479#endif
ead9360e 7480 case OPC_MFTR:
d75c135e 7481 check_insn(ctx, ASE_MT);
ead9360e
TS
7482 if (rd == 0) {
7483 /* Treat as NOP. */
7484 return;
7485 }
6c5c1e20 7486 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7487 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7488 opn = "mftr";
7489 break;
7490 case OPC_MTTR:
d75c135e 7491 check_insn(ctx, ASE_MT);
6c5c1e20 7492 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7493 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7494 opn = "mttr";
7495 break;
6af0bf9c 7496 case OPC_TLBWI:
6af0bf9c 7497 opn = "tlbwi";
c01fccd2 7498 if (!env->tlb->helper_tlbwi)
29929e34 7499 goto die;
895c2d04 7500 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
7501 break;
7502 case OPC_TLBWR:
6af0bf9c 7503 opn = "tlbwr";
c01fccd2 7504 if (!env->tlb->helper_tlbwr)
29929e34 7505 goto die;
895c2d04 7506 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7507 break;
7508 case OPC_TLBP:
6af0bf9c 7509 opn = "tlbp";
c01fccd2 7510 if (!env->tlb->helper_tlbp)
29929e34 7511 goto die;
895c2d04 7512 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7513 break;
7514 case OPC_TLBR:
6af0bf9c 7515 opn = "tlbr";
c01fccd2 7516 if (!env->tlb->helper_tlbr)
29929e34 7517 goto die;
895c2d04 7518 gen_helper_tlbr(cpu_env);
6af0bf9c 7519 break;
6af0bf9c
FB
7520 case OPC_ERET:
7521 opn = "eret";
d75c135e 7522 check_insn(ctx, ISA_MIPS2);
895c2d04 7523 gen_helper_eret(cpu_env);
6af0bf9c
FB
7524 ctx->bstate = BS_EXCP;
7525 break;
7526 case OPC_DERET:
7527 opn = "deret";
d75c135e 7528 check_insn(ctx, ISA_MIPS32);
6af0bf9c 7529 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7530 MIPS_INVAL(opn);
6af0bf9c
FB
7531 generate_exception(ctx, EXCP_RI);
7532 } else {
895c2d04 7533 gen_helper_deret(cpu_env);
6af0bf9c
FB
7534 ctx->bstate = BS_EXCP;
7535 }
7536 break;
4ad40f36
FB
7537 case OPC_WAIT:
7538 opn = "wait";
d75c135e 7539 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
7540 /* If we get an exception, we want to restart at next instruction */
7541 ctx->pc += 4;
7542 save_cpu_state(ctx, 1);
7543 ctx->pc -= 4;
895c2d04 7544 gen_helper_wait(cpu_env);
4ad40f36
FB
7545 ctx->bstate = BS_EXCP;
7546 break;
6af0bf9c 7547 default:
29929e34 7548 die:
923617a3 7549 MIPS_INVAL(opn);
6af0bf9c
FB
7550 generate_exception(ctx, EXCP_RI);
7551 return;
7552 }
2abf314d 7553 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7554 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7555}
f1aa6320 7556#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7557
6ea83fed 7558/* CP1 Branches (before delay slot) */
d75c135e
AJ
7559static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7560 int32_t cc, int32_t offset)
6ea83fed
FB
7561{
7562 target_ulong btarget;
923617a3 7563 const char *opn = "cp1 cond branch";
a7812ae4 7564 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7565
e189e748 7566 if (cc != 0)
d75c135e 7567 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7568
6ea83fed
FB
7569 btarget = ctx->pc + 4 + offset;
7570
7a387fff
TS
7571 switch (op) {
7572 case OPC_BC1F:
d94536f4
AJ
7573 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7574 tcg_gen_not_i32(t0, t0);
7575 tcg_gen_andi_i32(t0, t0, 1);
7576 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7577 opn = "bc1f";
6ea83fed 7578 goto not_likely;
7a387fff 7579 case OPC_BC1FL:
d94536f4
AJ
7580 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7581 tcg_gen_not_i32(t0, t0);
7582 tcg_gen_andi_i32(t0, t0, 1);
7583 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7584 opn = "bc1fl";
6ea83fed 7585 goto likely;
7a387fff 7586 case OPC_BC1T:
d94536f4
AJ
7587 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7588 tcg_gen_andi_i32(t0, t0, 1);
7589 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7590 opn = "bc1t";
5a5012ec 7591 goto not_likely;
7a387fff 7592 case OPC_BC1TL:
d94536f4
AJ
7593 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7594 tcg_gen_andi_i32(t0, t0, 1);
7595 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7596 opn = "bc1tl";
6ea83fed
FB
7597 likely:
7598 ctx->hflags |= MIPS_HFLAG_BL;
7599 break;
5a5012ec 7600 case OPC_BC1FANY2:
a16336e4 7601 {
d94536f4
AJ
7602 TCGv_i32 t1 = tcg_temp_new_i32();
7603 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7604 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7605 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7606 tcg_temp_free_i32(t1);
d94536f4
AJ
7607 tcg_gen_andi_i32(t0, t0, 1);
7608 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7609 }
fd4a04eb 7610 opn = "bc1any2f";
5a5012ec
TS
7611 goto not_likely;
7612 case OPC_BC1TANY2:
a16336e4 7613 {
d94536f4
AJ
7614 TCGv_i32 t1 = tcg_temp_new_i32();
7615 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7616 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7617 tcg_gen_or_i32(t0, t0, t1);
7618 tcg_temp_free_i32(t1);
7619 tcg_gen_andi_i32(t0, t0, 1);
7620 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7621 }
fd4a04eb 7622 opn = "bc1any2t";
5a5012ec
TS
7623 goto not_likely;
7624 case OPC_BC1FANY4:
a16336e4 7625 {
d94536f4
AJ
7626 TCGv_i32 t1 = tcg_temp_new_i32();
7627 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7628 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7629 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7630 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7631 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7632 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7633 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7634 tcg_temp_free_i32(t1);
d94536f4
AJ
7635 tcg_gen_andi_i32(t0, t0, 1);
7636 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7637 }
fd4a04eb 7638 opn = "bc1any4f";
5a5012ec
TS
7639 goto not_likely;
7640 case OPC_BC1TANY4:
a16336e4 7641 {
d94536f4
AJ
7642 TCGv_i32 t1 = tcg_temp_new_i32();
7643 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7644 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7645 tcg_gen_or_i32(t0, t0, t1);
7646 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7647 tcg_gen_or_i32(t0, t0, t1);
7648 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7649 tcg_gen_or_i32(t0, t0, t1);
7650 tcg_temp_free_i32(t1);
7651 tcg_gen_andi_i32(t0, t0, 1);
7652 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7653 }
fd4a04eb 7654 opn = "bc1any4t";
5a5012ec
TS
7655 not_likely:
7656 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7657 break;
7658 default:
923617a3 7659 MIPS_INVAL(opn);
e397ee33 7660 generate_exception (ctx, EXCP_RI);
6c5c1e20 7661 goto out;
6ea83fed 7662 }
2abf314d 7663 (void)opn; /* avoid a compiler warning */
923617a3 7664 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7665 ctx->hflags, btarget);
7666 ctx->btarget = btarget;
6c5c1e20
TS
7667
7668 out:
a7812ae4 7669 tcg_temp_free_i32(t0);
6ea83fed
FB
7670}
7671
31837be3
YK
7672/* R6 CP1 Branches */
7673static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
7674 int32_t ft, int32_t offset)
7675{
7676 target_ulong btarget;
7677 const char *opn = "cp1 cond branch";
7678 TCGv_i64 t0 = tcg_temp_new_i64();
7679
7680 if (ctx->hflags & MIPS_HFLAG_BMASK) {
7681#ifdef MIPS_DEBUG_DISAS
7682 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
7683#endif
7684 generate_exception(ctx, EXCP_RI);
7685 goto out;
7686 }
7687
7688 gen_load_fpr64(ctx, t0, ft);
7689 tcg_gen_andi_i64(t0, t0, 1);
7690
7691 btarget = addr_add(ctx, ctx->pc + 4, offset);
7692
7693 switch (op) {
7694 case OPC_BC1EQZ:
7695 tcg_gen_xori_i64(t0, t0, 1);
7696 opn = "bc1eqz";
7697 ctx->hflags |= MIPS_HFLAG_BC;
7698 break;
7699 case OPC_BC1NEZ:
7700 /* t0 already set */
7701 opn = "bc1nez";
7702 ctx->hflags |= MIPS_HFLAG_BC;
7703 break;
7704 default:
7705 MIPS_INVAL(opn);
7706 generate_exception(ctx, EXCP_RI);
7707 goto out;
7708 }
7709
7710 tcg_gen_trunc_i64_tl(bcond, t0);
7711
7712 (void)opn; /* avoid a compiler warning */
7713 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7714 ctx->hflags, btarget);
7715 ctx->btarget = btarget;
7716
7717out:
7718 tcg_temp_free_i64(t0);
7719}
7720
6af0bf9c 7721/* Coprocessor 1 (FPU) */
5a5012ec 7722
5a5012ec
TS
7723#define FOP(func, fmt) (((fmt) << 21) | (func))
7724
bf4120ad
NF
7725enum fopcode {
7726 OPC_ADD_S = FOP(0, FMT_S),
7727 OPC_SUB_S = FOP(1, FMT_S),
7728 OPC_MUL_S = FOP(2, FMT_S),
7729 OPC_DIV_S = FOP(3, FMT_S),
7730 OPC_SQRT_S = FOP(4, FMT_S),
7731 OPC_ABS_S = FOP(5, FMT_S),
7732 OPC_MOV_S = FOP(6, FMT_S),
7733 OPC_NEG_S = FOP(7, FMT_S),
7734 OPC_ROUND_L_S = FOP(8, FMT_S),
7735 OPC_TRUNC_L_S = FOP(9, FMT_S),
7736 OPC_CEIL_L_S = FOP(10, FMT_S),
7737 OPC_FLOOR_L_S = FOP(11, FMT_S),
7738 OPC_ROUND_W_S = FOP(12, FMT_S),
7739 OPC_TRUNC_W_S = FOP(13, FMT_S),
7740 OPC_CEIL_W_S = FOP(14, FMT_S),
7741 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 7742 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
7743 OPC_MOVCF_S = FOP(17, FMT_S),
7744 OPC_MOVZ_S = FOP(18, FMT_S),
7745 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 7746 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
7747 OPC_RECIP_S = FOP(21, FMT_S),
7748 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
7749 OPC_SELNEZ_S = FOP(23, FMT_S),
7750 OPC_MADDF_S = FOP(24, FMT_S),
7751 OPC_MSUBF_S = FOP(25, FMT_S),
7752 OPC_RINT_S = FOP(26, FMT_S),
7753 OPC_CLASS_S = FOP(27, FMT_S),
7754 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 7755 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 7756 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 7757 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 7758 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 7759 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 7760 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
7761 OPC_RSQRT2_S = FOP(31, FMT_S),
7762 OPC_CVT_D_S = FOP(33, FMT_S),
7763 OPC_CVT_W_S = FOP(36, FMT_S),
7764 OPC_CVT_L_S = FOP(37, FMT_S),
7765 OPC_CVT_PS_S = FOP(38, FMT_S),
7766 OPC_CMP_F_S = FOP (48, FMT_S),
7767 OPC_CMP_UN_S = FOP (49, FMT_S),
7768 OPC_CMP_EQ_S = FOP (50, FMT_S),
7769 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7770 OPC_CMP_OLT_S = FOP (52, FMT_S),
7771 OPC_CMP_ULT_S = FOP (53, FMT_S),
7772 OPC_CMP_OLE_S = FOP (54, FMT_S),
7773 OPC_CMP_ULE_S = FOP (55, FMT_S),
7774 OPC_CMP_SF_S = FOP (56, FMT_S),
7775 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7776 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7777 OPC_CMP_NGL_S = FOP (59, FMT_S),
7778 OPC_CMP_LT_S = FOP (60, FMT_S),
7779 OPC_CMP_NGE_S = FOP (61, FMT_S),
7780 OPC_CMP_LE_S = FOP (62, FMT_S),
7781 OPC_CMP_NGT_S = FOP (63, FMT_S),
7782
7783 OPC_ADD_D = FOP(0, FMT_D),
7784 OPC_SUB_D = FOP(1, FMT_D),
7785 OPC_MUL_D = FOP(2, FMT_D),
7786 OPC_DIV_D = FOP(3, FMT_D),
7787 OPC_SQRT_D = FOP(4, FMT_D),
7788 OPC_ABS_D = FOP(5, FMT_D),
7789 OPC_MOV_D = FOP(6, FMT_D),
7790 OPC_NEG_D = FOP(7, FMT_D),
7791 OPC_ROUND_L_D = FOP(8, FMT_D),
7792 OPC_TRUNC_L_D = FOP(9, FMT_D),
7793 OPC_CEIL_L_D = FOP(10, FMT_D),
7794 OPC_FLOOR_L_D = FOP(11, FMT_D),
7795 OPC_ROUND_W_D = FOP(12, FMT_D),
7796 OPC_TRUNC_W_D = FOP(13, FMT_D),
7797 OPC_CEIL_W_D = FOP(14, FMT_D),
7798 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 7799 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
7800 OPC_MOVCF_D = FOP(17, FMT_D),
7801 OPC_MOVZ_D = FOP(18, FMT_D),
7802 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 7803 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
7804 OPC_RECIP_D = FOP(21, FMT_D),
7805 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
7806 OPC_SELNEZ_D = FOP(23, FMT_D),
7807 OPC_MADDF_D = FOP(24, FMT_D),
7808 OPC_MSUBF_D = FOP(25, FMT_D),
7809 OPC_RINT_D = FOP(26, FMT_D),
7810 OPC_CLASS_D = FOP(27, FMT_D),
7811 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 7812 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 7813 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 7814 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 7815 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 7816 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 7817 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
7818 OPC_RSQRT2_D = FOP(31, FMT_D),
7819 OPC_CVT_S_D = FOP(32, FMT_D),
7820 OPC_CVT_W_D = FOP(36, FMT_D),
7821 OPC_CVT_L_D = FOP(37, FMT_D),
7822 OPC_CMP_F_D = FOP (48, FMT_D),
7823 OPC_CMP_UN_D = FOP (49, FMT_D),
7824 OPC_CMP_EQ_D = FOP (50, FMT_D),
7825 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7826 OPC_CMP_OLT_D = FOP (52, FMT_D),
7827 OPC_CMP_ULT_D = FOP (53, FMT_D),
7828 OPC_CMP_OLE_D = FOP (54, FMT_D),
7829 OPC_CMP_ULE_D = FOP (55, FMT_D),
7830 OPC_CMP_SF_D = FOP (56, FMT_D),
7831 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7832 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7833 OPC_CMP_NGL_D = FOP (59, FMT_D),
7834 OPC_CMP_LT_D = FOP (60, FMT_D),
7835 OPC_CMP_NGE_D = FOP (61, FMT_D),
7836 OPC_CMP_LE_D = FOP (62, FMT_D),
7837 OPC_CMP_NGT_D = FOP (63, FMT_D),
7838
7839 OPC_CVT_S_W = FOP(32, FMT_W),
7840 OPC_CVT_D_W = FOP(33, FMT_W),
7841 OPC_CVT_S_L = FOP(32, FMT_L),
7842 OPC_CVT_D_L = FOP(33, FMT_L),
7843 OPC_CVT_PS_PW = FOP(38, FMT_W),
7844
7845 OPC_ADD_PS = FOP(0, FMT_PS),
7846 OPC_SUB_PS = FOP(1, FMT_PS),
7847 OPC_MUL_PS = FOP(2, FMT_PS),
7848 OPC_DIV_PS = FOP(3, FMT_PS),
7849 OPC_ABS_PS = FOP(5, FMT_PS),
7850 OPC_MOV_PS = FOP(6, FMT_PS),
7851 OPC_NEG_PS = FOP(7, FMT_PS),
7852 OPC_MOVCF_PS = FOP(17, FMT_PS),
7853 OPC_MOVZ_PS = FOP(18, FMT_PS),
7854 OPC_MOVN_PS = FOP(19, FMT_PS),
7855 OPC_ADDR_PS = FOP(24, FMT_PS),
7856 OPC_MULR_PS = FOP(26, FMT_PS),
7857 OPC_RECIP2_PS = FOP(28, FMT_PS),
7858 OPC_RECIP1_PS = FOP(29, FMT_PS),
7859 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7860 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7861
7862 OPC_CVT_S_PU = FOP(32, FMT_PS),
7863 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7864 OPC_CVT_S_PL = FOP(40, FMT_PS),
7865 OPC_PLL_PS = FOP(44, FMT_PS),
7866 OPC_PLU_PS = FOP(45, FMT_PS),
7867 OPC_PUL_PS = FOP(46, FMT_PS),
7868 OPC_PUU_PS = FOP(47, FMT_PS),
7869 OPC_CMP_F_PS = FOP (48, FMT_PS),
7870 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7871 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7872 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7873 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7874 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7875 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7876 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7877 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7878 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7879 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7880 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7881 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7882 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7883 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7884 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7885};
7886
3f493883
YK
7887enum r6_f_cmp_op {
7888 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
7889 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
7890 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
7891 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
7892 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
7893 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
7894 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
7895 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
7896 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
7897 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
7898 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
7899 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
7900 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
7901 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
7902 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
7903 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
7904 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
7905 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
7906 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
7907 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
7908 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
7909 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
7910
7911 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
7912 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
7913 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
7914 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
7915 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
7916 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
7917 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
7918 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
7919 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
7920 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
7921 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
7922 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
7923 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
7924 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
7925 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
7926 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
7927 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
7928 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
7929 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
7930 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
7931 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
7932 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
7933};
7a387fff 7934static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7935{
923617a3 7936 const char *opn = "cp1 move";
72c3a3ee 7937 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7938
7939 switch (opc) {
7940 case OPC_MFC1:
b6d96bed 7941 {
a7812ae4 7942 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7943
7944 gen_load_fpr32(fp0, fs);
7945 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7946 tcg_temp_free_i32(fp0);
6958549d 7947 }
6c5c1e20 7948 gen_store_gpr(t0, rt);
6ea83fed
FB
7949 opn = "mfc1";
7950 break;
7951 case OPC_MTC1:
6c5c1e20 7952 gen_load_gpr(t0, rt);
b6d96bed 7953 {
a7812ae4 7954 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7955
7956 tcg_gen_trunc_tl_i32(fp0, t0);
7957 gen_store_fpr32(fp0, fs);
a7812ae4 7958 tcg_temp_free_i32(fp0);
6958549d 7959 }
6ea83fed
FB
7960 opn = "mtc1";
7961 break;
7962 case OPC_CFC1:
895c2d04 7963 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7964 gen_store_gpr(t0, rt);
6ea83fed
FB
7965 opn = "cfc1";
7966 break;
7967 case OPC_CTC1:
6c5c1e20 7968 gen_load_gpr(t0, rt);
736d120a
PJ
7969 {
7970 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7971
7972 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7973 tcg_temp_free_i32(fs_tmp);
7974 }
6ea83fed
FB
7975 opn = "ctc1";
7976 break;
72c3a3ee 7977#if defined(TARGET_MIPS64)
9c2149c8 7978 case OPC_DMFC1:
72c3a3ee 7979 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7980 gen_store_gpr(t0, rt);
5a5012ec
TS
7981 opn = "dmfc1";
7982 break;
9c2149c8 7983 case OPC_DMTC1:
6c5c1e20 7984 gen_load_gpr(t0, rt);
72c3a3ee 7985 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7986 opn = "dmtc1";
7987 break;
72c3a3ee 7988#endif
5a5012ec 7989 case OPC_MFHC1:
b6d96bed 7990 {
a7812ae4 7991 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7992
7f6613ce 7993 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7994 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7995 tcg_temp_free_i32(fp0);
6958549d 7996 }
6c5c1e20 7997 gen_store_gpr(t0, rt);
5a5012ec
TS
7998 opn = "mfhc1";
7999 break;
8000 case OPC_MTHC1:
6c5c1e20 8001 gen_load_gpr(t0, rt);
b6d96bed 8002 {
a7812ae4 8003 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8004
8005 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8006 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8007 tcg_temp_free_i32(fp0);
6958549d 8008 }
5a5012ec
TS
8009 opn = "mthc1";
8010 break;
6ea83fed 8011 default:
923617a3 8012 MIPS_INVAL(opn);
e397ee33 8013 generate_exception (ctx, EXCP_RI);
6c5c1e20 8014 goto out;
6ea83fed 8015 }
2abf314d 8016 (void)opn; /* avoid a compiler warning */
6ea83fed 8017 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
8018
8019 out:
8020 tcg_temp_free(t0);
6ea83fed
FB
8021}
8022
5a5012ec
TS
8023static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8024{
af58f9ca 8025 int l1;
e214b9bb 8026 TCGCond cond;
af58f9ca
AJ
8027 TCGv_i32 t0;
8028
8029 if (rd == 0) {
8030 /* Treat as NOP. */
8031 return;
8032 }
6ea83fed 8033
e214b9bb 8034 if (tf)
e214b9bb 8035 cond = TCG_COND_EQ;
27848470
TS
8036 else
8037 cond = TCG_COND_NE;
8038
af58f9ca
AJ
8039 l1 = gen_new_label();
8040 t0 = tcg_temp_new_i32();
fa31af0e 8041 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8042 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8043 tcg_temp_free_i32(t0);
af58f9ca
AJ
8044 if (rs == 0) {
8045 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8046 } else {
8047 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8048 }
e214b9bb 8049 gen_set_label(l1);
5a5012ec
TS
8050}
8051
b6d96bed 8052static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 8053{
a16336e4 8054 int cond;
cbc37b28 8055 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8056 int l1 = gen_new_label();
8057
a16336e4
TS
8058 if (tf)
8059 cond = TCG_COND_EQ;
8060 else
8061 cond = TCG_COND_NE;
8062
fa31af0e 8063 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8064 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8065 gen_load_fpr32(t0, fs);
8066 gen_store_fpr32(t0, fd);
a16336e4 8067 gen_set_label(l1);
cbc37b28 8068 tcg_temp_free_i32(t0);
5a5012ec 8069}
a16336e4 8070
b6d96bed 8071static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8072{
a16336e4 8073 int cond;
cbc37b28
AJ
8074 TCGv_i32 t0 = tcg_temp_new_i32();
8075 TCGv_i64 fp0;
a16336e4
TS
8076 int l1 = gen_new_label();
8077
a16336e4
TS
8078 if (tf)
8079 cond = TCG_COND_EQ;
8080 else
8081 cond = TCG_COND_NE;
8082
fa31af0e 8083 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8084 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8085 tcg_temp_free_i32(t0);
11f94258 8086 fp0 = tcg_temp_new_i64();
9bf3eb2c 8087 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8088 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8089 tcg_temp_free_i64(fp0);
cbc37b28 8090 gen_set_label(l1);
a16336e4
TS
8091}
8092
7f6613ce
PJ
8093static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8094 int cc, int tf)
a16336e4
TS
8095{
8096 int cond;
cbc37b28 8097 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
8098 int l1 = gen_new_label();
8099 int l2 = gen_new_label();
8100
8101 if (tf)
8102 cond = TCG_COND_EQ;
8103 else
8104 cond = TCG_COND_NE;
8105
fa31af0e 8106 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
8107 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8108 gen_load_fpr32(t0, fs);
8109 gen_store_fpr32(t0, fd);
a16336e4 8110 gen_set_label(l1);
9bf3eb2c 8111
fa31af0e 8112 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8113 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8114 gen_load_fpr32h(ctx, t0, fs);
8115 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8116 tcg_temp_free_i32(t0);
a16336e4 8117 gen_set_label(l2);
a16336e4
TS
8118}
8119
e7f16abb
LA
8120static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8121 int fs)
8122{
8123 TCGv_i32 t1 = tcg_const_i32(0);
8124 TCGv_i32 fp0 = tcg_temp_new_i32();
8125 TCGv_i32 fp1 = tcg_temp_new_i32();
8126 TCGv_i32 fp2 = tcg_temp_new_i32();
8127 gen_load_fpr32(fp0, fd);
8128 gen_load_fpr32(fp1, ft);
8129 gen_load_fpr32(fp2, fs);
8130
8131 switch (op1) {
8132 case OPC_SEL_S:
8133 tcg_gen_andi_i32(fp0, fp0, 1);
8134 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8135 break;
8136 case OPC_SELEQZ_S:
8137 tcg_gen_andi_i32(fp1, fp1, 1);
8138 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8139 break;
8140 case OPC_SELNEZ_S:
8141 tcg_gen_andi_i32(fp1, fp1, 1);
8142 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8143 break;
8144 default:
8145 MIPS_INVAL("gen_sel_s");
8146 generate_exception (ctx, EXCP_RI);
8147 break;
8148 }
8149
8150 gen_store_fpr32(fp0, fd);
8151 tcg_temp_free_i32(fp2);
8152 tcg_temp_free_i32(fp1);
8153 tcg_temp_free_i32(fp0);
8154 tcg_temp_free_i32(t1);
8155}
8156
8157static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8158 int fs)
8159{
8160 TCGv_i64 t1 = tcg_const_i64(0);
8161 TCGv_i64 fp0 = tcg_temp_new_i64();
8162 TCGv_i64 fp1 = tcg_temp_new_i64();
8163 TCGv_i64 fp2 = tcg_temp_new_i64();
8164 gen_load_fpr64(ctx, fp0, fd);
8165 gen_load_fpr64(ctx, fp1, ft);
8166 gen_load_fpr64(ctx, fp2, fs);
8167
8168 switch (op1) {
8169 case OPC_SEL_D:
8170 tcg_gen_andi_i64(fp0, fp0, 1);
8171 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8172 break;
8173 case OPC_SELEQZ_D:
8174 tcg_gen_andi_i64(fp1, fp1, 1);
8175 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8176 break;
8177 case OPC_SELNEZ_D:
8178 tcg_gen_andi_i64(fp1, fp1, 1);
8179 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8180 break;
8181 default:
8182 MIPS_INVAL("gen_sel_d");
8183 generate_exception (ctx, EXCP_RI);
8184 break;
8185 }
8186
8187 gen_store_fpr64(ctx, fp0, fd);
8188 tcg_temp_free_i64(fp2);
8189 tcg_temp_free_i64(fp1);
8190 tcg_temp_free_i64(fp0);
8191 tcg_temp_free_i64(t1);
8192}
6ea83fed 8193
bf4120ad 8194static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8195 int ft, int fs, int fd, int cc)
6ea83fed 8196{
923617a3 8197 const char *opn = "farith";
6ea83fed
FB
8198 const char *condnames[] = {
8199 "c.f",
8200 "c.un",
8201 "c.eq",
8202 "c.ueq",
8203 "c.olt",
8204 "c.ult",
8205 "c.ole",
8206 "c.ule",
8207 "c.sf",
8208 "c.ngle",
8209 "c.seq",
8210 "c.ngl",
8211 "c.lt",
8212 "c.nge",
8213 "c.le",
8214 "c.ngt",
8215 };
5a1e8ffb
TS
8216 const char *condnames_abs[] = {
8217 "cabs.f",
8218 "cabs.un",
8219 "cabs.eq",
8220 "cabs.ueq",
8221 "cabs.olt",
8222 "cabs.ult",
8223 "cabs.ole",
8224 "cabs.ule",
8225 "cabs.sf",
8226 "cabs.ngle",
8227 "cabs.seq",
8228 "cabs.ngl",
8229 "cabs.lt",
8230 "cabs.nge",
8231 "cabs.le",
8232 "cabs.ngt",
8233 };
8234 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
8235 uint32_t func = ctx->opcode & 0x3f;
8236
bf4120ad
NF
8237 switch (op1) {
8238 case OPC_ADD_S:
b6d96bed 8239 {
a7812ae4
PB
8240 TCGv_i32 fp0 = tcg_temp_new_i32();
8241 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8242
8243 gen_load_fpr32(fp0, fs);
8244 gen_load_fpr32(fp1, ft);
895c2d04 8245 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8246 tcg_temp_free_i32(fp1);
b6d96bed 8247 gen_store_fpr32(fp0, fd);
a7812ae4 8248 tcg_temp_free_i32(fp0);
b6d96bed 8249 }
5a5012ec 8250 opn = "add.s";
5a1e8ffb 8251 optype = BINOP;
5a5012ec 8252 break;
bf4120ad 8253 case OPC_SUB_S:
b6d96bed 8254 {
a7812ae4
PB
8255 TCGv_i32 fp0 = tcg_temp_new_i32();
8256 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8257
8258 gen_load_fpr32(fp0, fs);
8259 gen_load_fpr32(fp1, ft);
895c2d04 8260 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8261 tcg_temp_free_i32(fp1);
b6d96bed 8262 gen_store_fpr32(fp0, fd);
a7812ae4 8263 tcg_temp_free_i32(fp0);
b6d96bed 8264 }
5a5012ec 8265 opn = "sub.s";
5a1e8ffb 8266 optype = BINOP;
5a5012ec 8267 break;
bf4120ad 8268 case OPC_MUL_S:
b6d96bed 8269 {
a7812ae4
PB
8270 TCGv_i32 fp0 = tcg_temp_new_i32();
8271 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8272
8273 gen_load_fpr32(fp0, fs);
8274 gen_load_fpr32(fp1, ft);
895c2d04 8275 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8276 tcg_temp_free_i32(fp1);
b6d96bed 8277 gen_store_fpr32(fp0, fd);
a7812ae4 8278 tcg_temp_free_i32(fp0);
b6d96bed 8279 }
5a5012ec 8280 opn = "mul.s";
5a1e8ffb 8281 optype = BINOP;
5a5012ec 8282 break;
bf4120ad 8283 case OPC_DIV_S:
b6d96bed 8284 {
a7812ae4
PB
8285 TCGv_i32 fp0 = tcg_temp_new_i32();
8286 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8287
8288 gen_load_fpr32(fp0, fs);
8289 gen_load_fpr32(fp1, ft);
895c2d04 8290 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8291 tcg_temp_free_i32(fp1);
b6d96bed 8292 gen_store_fpr32(fp0, fd);
a7812ae4 8293 tcg_temp_free_i32(fp0);
b6d96bed 8294 }
5a5012ec 8295 opn = "div.s";
5a1e8ffb 8296 optype = BINOP;
5a5012ec 8297 break;
bf4120ad 8298 case OPC_SQRT_S:
b6d96bed 8299 {
a7812ae4 8300 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8301
8302 gen_load_fpr32(fp0, fs);
895c2d04 8303 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 8304 gen_store_fpr32(fp0, fd);
a7812ae4 8305 tcg_temp_free_i32(fp0);
b6d96bed 8306 }
5a5012ec
TS
8307 opn = "sqrt.s";
8308 break;
bf4120ad 8309 case OPC_ABS_S:
b6d96bed 8310 {
a7812ae4 8311 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8312
8313 gen_load_fpr32(fp0, fs);
a7812ae4 8314 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 8315 gen_store_fpr32(fp0, fd);
a7812ae4 8316 tcg_temp_free_i32(fp0);
b6d96bed 8317 }
5a5012ec
TS
8318 opn = "abs.s";
8319 break;
bf4120ad 8320 case OPC_MOV_S:
b6d96bed 8321 {
a7812ae4 8322 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8323
8324 gen_load_fpr32(fp0, fs);
8325 gen_store_fpr32(fp0, fd);
a7812ae4 8326 tcg_temp_free_i32(fp0);
b6d96bed 8327 }
5a5012ec
TS
8328 opn = "mov.s";
8329 break;
bf4120ad 8330 case OPC_NEG_S:
b6d96bed 8331 {
a7812ae4 8332 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8333
8334 gen_load_fpr32(fp0, fs);
a7812ae4 8335 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 8336 gen_store_fpr32(fp0, fd);
a7812ae4 8337 tcg_temp_free_i32(fp0);
b6d96bed 8338 }
5a5012ec
TS
8339 opn = "neg.s";
8340 break;
bf4120ad 8341 case OPC_ROUND_L_S:
5e755519 8342 check_cp1_64bitmode(ctx);
b6d96bed 8343 {
a7812ae4
PB
8344 TCGv_i32 fp32 = tcg_temp_new_i32();
8345 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8346
8347 gen_load_fpr32(fp32, fs);
895c2d04 8348 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 8349 tcg_temp_free_i32(fp32);
b6d96bed 8350 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8351 tcg_temp_free_i64(fp64);
b6d96bed 8352 }
5a5012ec
TS
8353 opn = "round.l.s";
8354 break;
bf4120ad 8355 case OPC_TRUNC_L_S:
5e755519 8356 check_cp1_64bitmode(ctx);
b6d96bed 8357 {
a7812ae4
PB
8358 TCGv_i32 fp32 = tcg_temp_new_i32();
8359 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8360
8361 gen_load_fpr32(fp32, fs);
895c2d04 8362 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 8363 tcg_temp_free_i32(fp32);
b6d96bed 8364 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8365 tcg_temp_free_i64(fp64);
b6d96bed 8366 }
5a5012ec
TS
8367 opn = "trunc.l.s";
8368 break;
bf4120ad 8369 case OPC_CEIL_L_S:
5e755519 8370 check_cp1_64bitmode(ctx);
b6d96bed 8371 {
a7812ae4
PB
8372 TCGv_i32 fp32 = tcg_temp_new_i32();
8373 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8374
8375 gen_load_fpr32(fp32, fs);
895c2d04 8376 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 8377 tcg_temp_free_i32(fp32);
b6d96bed 8378 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8379 tcg_temp_free_i64(fp64);
b6d96bed 8380 }
5a5012ec
TS
8381 opn = "ceil.l.s";
8382 break;
bf4120ad 8383 case OPC_FLOOR_L_S:
5e755519 8384 check_cp1_64bitmode(ctx);
b6d96bed 8385 {
a7812ae4
PB
8386 TCGv_i32 fp32 = tcg_temp_new_i32();
8387 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8388
8389 gen_load_fpr32(fp32, fs);
895c2d04 8390 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 8391 tcg_temp_free_i32(fp32);
b6d96bed 8392 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8393 tcg_temp_free_i64(fp64);
b6d96bed 8394 }
5a5012ec
TS
8395 opn = "floor.l.s";
8396 break;
bf4120ad 8397 case OPC_ROUND_W_S:
b6d96bed 8398 {
a7812ae4 8399 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8400
8401 gen_load_fpr32(fp0, fs);
895c2d04 8402 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 8403 gen_store_fpr32(fp0, fd);
a7812ae4 8404 tcg_temp_free_i32(fp0);
b6d96bed 8405 }
5a5012ec
TS
8406 opn = "round.w.s";
8407 break;
bf4120ad 8408 case OPC_TRUNC_W_S:
b6d96bed 8409 {
a7812ae4 8410 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8411
8412 gen_load_fpr32(fp0, fs);
895c2d04 8413 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 8414 gen_store_fpr32(fp0, fd);
a7812ae4 8415 tcg_temp_free_i32(fp0);
b6d96bed 8416 }
5a5012ec
TS
8417 opn = "trunc.w.s";
8418 break;
bf4120ad 8419 case OPC_CEIL_W_S:
b6d96bed 8420 {
a7812ae4 8421 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8422
8423 gen_load_fpr32(fp0, fs);
895c2d04 8424 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 8425 gen_store_fpr32(fp0, fd);
a7812ae4 8426 tcg_temp_free_i32(fp0);
b6d96bed 8427 }
5a5012ec
TS
8428 opn = "ceil.w.s";
8429 break;
bf4120ad 8430 case OPC_FLOOR_W_S:
b6d96bed 8431 {
a7812ae4 8432 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8433
8434 gen_load_fpr32(fp0, fs);
895c2d04 8435 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8436 gen_store_fpr32(fp0, fd);
a7812ae4 8437 tcg_temp_free_i32(fp0);
b6d96bed 8438 }
5a5012ec
TS
8439 opn = "floor.w.s";
8440 break;
e7f16abb
LA
8441 case OPC_SEL_S:
8442 check_insn(ctx, ISA_MIPS32R6);
8443 gen_sel_s(ctx, op1, fd, ft, fs);
8444 opn = "sel.s";
8445 break;
8446 case OPC_SELEQZ_S:
8447 check_insn(ctx, ISA_MIPS32R6);
8448 gen_sel_s(ctx, op1, fd, ft, fs);
8449 opn = "seleqz.s";
8450 break;
8451 case OPC_SELNEZ_S:
8452 check_insn(ctx, ISA_MIPS32R6);
8453 gen_sel_s(ctx, op1, fd, ft, fs);
8454 opn = "selnez.s";
8455 break;
bf4120ad 8456 case OPC_MOVCF_S:
fecd2646 8457 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8458 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8459 opn = "movcf.s";
8460 break;
bf4120ad 8461 case OPC_MOVZ_S:
fecd2646 8462 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8463 {
8464 int l1 = gen_new_label();
c9297f4d 8465 TCGv_i32 fp0;
a16336e4 8466
c9297f4d
AJ
8467 if (ft != 0) {
8468 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8469 }
8470 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8471 gen_load_fpr32(fp0, fs);
8472 gen_store_fpr32(fp0, fd);
a7812ae4 8473 tcg_temp_free_i32(fp0);
a16336e4
TS
8474 gen_set_label(l1);
8475 }
5a5012ec
TS
8476 opn = "movz.s";
8477 break;
bf4120ad 8478 case OPC_MOVN_S:
fecd2646 8479 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8480 {
8481 int l1 = gen_new_label();
c9297f4d
AJ
8482 TCGv_i32 fp0;
8483
8484 if (ft != 0) {
8485 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8486 fp0 = tcg_temp_new_i32();
8487 gen_load_fpr32(fp0, fs);
8488 gen_store_fpr32(fp0, fd);
8489 tcg_temp_free_i32(fp0);
8490 gen_set_label(l1);
8491 }
a16336e4 8492 }
5a5012ec
TS
8493 opn = "movn.s";
8494 break;
bf4120ad 8495 case OPC_RECIP_S:
b8aa4598 8496 check_cop1x(ctx);
b6d96bed 8497 {
a7812ae4 8498 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8499
8500 gen_load_fpr32(fp0, fs);
895c2d04 8501 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8502 gen_store_fpr32(fp0, fd);
a7812ae4 8503 tcg_temp_free_i32(fp0);
b6d96bed 8504 }
57fa1fb3
TS
8505 opn = "recip.s";
8506 break;
bf4120ad 8507 case OPC_RSQRT_S:
b8aa4598 8508 check_cop1x(ctx);
b6d96bed 8509 {
a7812ae4 8510 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8511
8512 gen_load_fpr32(fp0, fs);
895c2d04 8513 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8514 gen_store_fpr32(fp0, fd);
a7812ae4 8515 tcg_temp_free_i32(fp0);
b6d96bed 8516 }
57fa1fb3
TS
8517 opn = "rsqrt.s";
8518 break;
e7f16abb
LA
8519 case OPC_MADDF_S:
8520 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8521 {
a7812ae4
PB
8522 TCGv_i32 fp0 = tcg_temp_new_i32();
8523 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 8524 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8525 gen_load_fpr32(fp0, fs);
d22d7289 8526 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8527 gen_load_fpr32(fp2, fd);
8528 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8529 gen_store_fpr32(fp2, fd);
8530 tcg_temp_free_i32(fp2);
a7812ae4 8531 tcg_temp_free_i32(fp1);
a7812ae4 8532 tcg_temp_free_i32(fp0);
e7f16abb 8533 opn = "maddf.s";
b6d96bed 8534 }
57fa1fb3 8535 break;
e7f16abb
LA
8536 case OPC_MSUBF_S:
8537 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8538 {
a7812ae4 8539 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
8540 TCGv_i32 fp1 = tcg_temp_new_i32();
8541 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 8542 gen_load_fpr32(fp0, fs);
e7f16abb
LA
8543 gen_load_fpr32(fp1, ft);
8544 gen_load_fpr32(fp2, fd);
8545 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8546 gen_store_fpr32(fp2, fd);
8547 tcg_temp_free_i32(fp2);
8548 tcg_temp_free_i32(fp1);
a7812ae4 8549 tcg_temp_free_i32(fp0);
e7f16abb 8550 opn = "msubf.s";
b6d96bed 8551 }
57fa1fb3 8552 break;
e7f16abb
LA
8553 case OPC_RINT_S:
8554 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8555 {
a7812ae4 8556 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8557 gen_load_fpr32(fp0, fs);
e7f16abb 8558 gen_helper_float_rint_s(fp0, cpu_env, fp0);
b6d96bed 8559 gen_store_fpr32(fp0, fd);
a7812ae4 8560 tcg_temp_free_i32(fp0);
e7f16abb 8561 opn = "rint.s";
b6d96bed 8562 }
57fa1fb3 8563 break;
e7f16abb
LA
8564 case OPC_CLASS_S:
8565 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 8566 {
e7f16abb
LA
8567 TCGv_i32 fp0 = tcg_temp_new_i32();
8568 gen_load_fpr32(fp0, fs);
8569 gen_helper_float_class_s(fp0, fp0);
8570 gen_store_fpr32(fp0, fd);
8571 tcg_temp_free_i32(fp0);
8572 opn = "class.s";
8573 }
8574 break;
8575 case OPC_MIN_S: /* OPC_RECIP2_S */
8576 if (ctx->insn_flags & ISA_MIPS32R6) {
8577 /* OPC_MIN_S */
a7812ae4
PB
8578 TCGv_i32 fp0 = tcg_temp_new_i32();
8579 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb
LA
8580 TCGv_i32 fp2 = tcg_temp_new_i32();
8581 gen_load_fpr32(fp0, fs);
8582 gen_load_fpr32(fp1, ft);
8583 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8584 gen_store_fpr32(fp2, fd);
8585 tcg_temp_free_i32(fp2);
8586 tcg_temp_free_i32(fp1);
8587 tcg_temp_free_i32(fp0);
8588 opn = "min.s";
8589 } else {
8590 /* OPC_RECIP2_S */
8591 check_cp1_64bitmode(ctx);
8592 {
8593 TCGv_i32 fp0 = tcg_temp_new_i32();
8594 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8595
e7f16abb
LA
8596 gen_load_fpr32(fp0, fs);
8597 gen_load_fpr32(fp1, ft);
8598 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
8599 tcg_temp_free_i32(fp1);
8600 gen_store_fpr32(fp0, fd);
8601 tcg_temp_free_i32(fp0);
8602 }
8603 opn = "recip2.s";
8604 }
8605 break;
8606 case OPC_MINA_S: /* OPC_RECIP1_S */
8607 if (ctx->insn_flags & ISA_MIPS32R6) {
8608 /* OPC_MINA_S */
8609 TCGv_i32 fp0 = tcg_temp_new_i32();
8610 TCGv_i32 fp1 = tcg_temp_new_i32();
8611 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8612 gen_load_fpr32(fp0, fs);
8613 gen_load_fpr32(fp1, ft);
e7f16abb
LA
8614 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
8615 gen_store_fpr32(fp2, fd);
8616 tcg_temp_free_i32(fp2);
8617 tcg_temp_free_i32(fp1);
8618 tcg_temp_free_i32(fp0);
8619 opn = "mina.s";
8620 } else {
8621 /* OPC_RECIP1_S */
8622 check_cp1_64bitmode(ctx);
8623 {
8624 TCGv_i32 fp0 = tcg_temp_new_i32();
8625
8626 gen_load_fpr32(fp0, fs);
8627 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
8628 gen_store_fpr32(fp0, fd);
8629 tcg_temp_free_i32(fp0);
8630 }
8631 opn = "recip1.s";
8632 }
8633 break;
8634 case OPC_MAX_S: /* OPC_RSQRT1_S */
8635 if (ctx->insn_flags & ISA_MIPS32R6) {
8636 /* OPC_MAX_S */
8637 TCGv_i32 fp0 = tcg_temp_new_i32();
8638 TCGv_i32 fp1 = tcg_temp_new_i32();
8639 gen_load_fpr32(fp0, fs);
8640 gen_load_fpr32(fp1, ft);
8641 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
8642 gen_store_fpr32(fp1, fd);
8643 tcg_temp_free_i32(fp1);
8644 tcg_temp_free_i32(fp0);
8645 opn = "max.s";
8646 } else {
8647 /* OPC_RSQRT1_S */
8648 check_cp1_64bitmode(ctx);
8649 {
8650 TCGv_i32 fp0 = tcg_temp_new_i32();
8651
8652 gen_load_fpr32(fp0, fs);
8653 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
8654 gen_store_fpr32(fp0, fd);
8655 tcg_temp_free_i32(fp0);
8656 }
8657 opn = "rsqrt1.s";
8658 }
8659 break;
8660 case OPC_MAXA_S: /* OPC_RSQRT2_S */
8661 if (ctx->insn_flags & ISA_MIPS32R6) {
8662 /* OPC_MAXA_S */
8663 TCGv_i32 fp0 = tcg_temp_new_i32();
8664 TCGv_i32 fp1 = tcg_temp_new_i32();
8665 gen_load_fpr32(fp0, fs);
8666 gen_load_fpr32(fp1, ft);
8667 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
8668 gen_store_fpr32(fp1, fd);
a7812ae4 8669 tcg_temp_free_i32(fp1);
a7812ae4 8670 tcg_temp_free_i32(fp0);
e7f16abb
LA
8671 opn = "maxa.s";
8672 } else {
8673 /* OPC_RSQRT2_S */
8674 check_cp1_64bitmode(ctx);
8675 {
8676 TCGv_i32 fp0 = tcg_temp_new_i32();
8677 TCGv_i32 fp1 = tcg_temp_new_i32();
8678
8679 gen_load_fpr32(fp0, fs);
8680 gen_load_fpr32(fp1, ft);
8681 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
8682 tcg_temp_free_i32(fp1);
8683 gen_store_fpr32(fp0, fd);
8684 tcg_temp_free_i32(fp0);
8685 }
8686 opn = "rsqrt2.s";
b6d96bed 8687 }
57fa1fb3 8688 break;
bf4120ad 8689 case OPC_CVT_D_S:
5e755519 8690 check_cp1_registers(ctx, fd);
b6d96bed 8691 {
a7812ae4
PB
8692 TCGv_i32 fp32 = tcg_temp_new_i32();
8693 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8694
8695 gen_load_fpr32(fp32, fs);
895c2d04 8696 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 8697 tcg_temp_free_i32(fp32);
b6d96bed 8698 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8699 tcg_temp_free_i64(fp64);
b6d96bed 8700 }
5a5012ec
TS
8701 opn = "cvt.d.s";
8702 break;
bf4120ad 8703 case OPC_CVT_W_S:
b6d96bed 8704 {
a7812ae4 8705 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8706
8707 gen_load_fpr32(fp0, fs);
895c2d04 8708 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 8709 gen_store_fpr32(fp0, fd);
a7812ae4 8710 tcg_temp_free_i32(fp0);
b6d96bed 8711 }
5a5012ec
TS
8712 opn = "cvt.w.s";
8713 break;
bf4120ad 8714 case OPC_CVT_L_S:
5e755519 8715 check_cp1_64bitmode(ctx);
b6d96bed 8716 {
a7812ae4
PB
8717 TCGv_i32 fp32 = tcg_temp_new_i32();
8718 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8719
8720 gen_load_fpr32(fp32, fs);
895c2d04 8721 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 8722 tcg_temp_free_i32(fp32);
b6d96bed 8723 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8724 tcg_temp_free_i64(fp64);
b6d96bed 8725 }
5a5012ec
TS
8726 opn = "cvt.l.s";
8727 break;
bf4120ad 8728 case OPC_CVT_PS_S:
fecd2646 8729 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 8730 check_cp1_64bitmode(ctx);
b6d96bed 8731 {
a7812ae4
PB
8732 TCGv_i64 fp64 = tcg_temp_new_i64();
8733 TCGv_i32 fp32_0 = tcg_temp_new_i32();
8734 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
8735
8736 gen_load_fpr32(fp32_0, fs);
8737 gen_load_fpr32(fp32_1, ft);
13d24f49 8738 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
8739 tcg_temp_free_i32(fp32_1);
8740 tcg_temp_free_i32(fp32_0);
36aa55dc 8741 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8742 tcg_temp_free_i64(fp64);
b6d96bed 8743 }
5a5012ec
TS
8744 opn = "cvt.ps.s";
8745 break;
bf4120ad
NF
8746 case OPC_CMP_F_S:
8747 case OPC_CMP_UN_S:
8748 case OPC_CMP_EQ_S:
8749 case OPC_CMP_UEQ_S:
8750 case OPC_CMP_OLT_S:
8751 case OPC_CMP_ULT_S:
8752 case OPC_CMP_OLE_S:
8753 case OPC_CMP_ULE_S:
8754 case OPC_CMP_SF_S:
8755 case OPC_CMP_NGLE_S:
8756 case OPC_CMP_SEQ_S:
8757 case OPC_CMP_NGL_S:
8758 case OPC_CMP_LT_S:
8759 case OPC_CMP_NGE_S:
8760 case OPC_CMP_LE_S:
8761 case OPC_CMP_NGT_S:
fecd2646 8762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
8763 if (ctx->opcode & (1 << 6)) {
8764 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8765 opn = condnames_abs[func-48];
8766 } else {
8767 gen_cmp_s(ctx, func-48, ft, fs, cc);
8768 opn = condnames[func-48];
5a1e8ffb 8769 }
5a5012ec 8770 break;
bf4120ad 8771 case OPC_ADD_D:
5e755519 8772 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8773 {
a7812ae4
PB
8774 TCGv_i64 fp0 = tcg_temp_new_i64();
8775 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8776
8777 gen_load_fpr64(ctx, fp0, fs);
8778 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8779 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8780 tcg_temp_free_i64(fp1);
b6d96bed 8781 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8782 tcg_temp_free_i64(fp0);
b6d96bed 8783 }
6ea83fed 8784 opn = "add.d";
5a1e8ffb 8785 optype = BINOP;
6ea83fed 8786 break;
bf4120ad 8787 case OPC_SUB_D:
5e755519 8788 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8789 {
a7812ae4
PB
8790 TCGv_i64 fp0 = tcg_temp_new_i64();
8791 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8792
8793 gen_load_fpr64(ctx, fp0, fs);
8794 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8795 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8796 tcg_temp_free_i64(fp1);
b6d96bed 8797 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8798 tcg_temp_free_i64(fp0);
b6d96bed 8799 }
6ea83fed 8800 opn = "sub.d";
5a1e8ffb 8801 optype = BINOP;
6ea83fed 8802 break;
bf4120ad 8803 case OPC_MUL_D:
5e755519 8804 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8805 {
a7812ae4
PB
8806 TCGv_i64 fp0 = tcg_temp_new_i64();
8807 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8808
8809 gen_load_fpr64(ctx, fp0, fs);
8810 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8811 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8812 tcg_temp_free_i64(fp1);
b6d96bed 8813 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8814 tcg_temp_free_i64(fp0);
b6d96bed 8815 }
6ea83fed 8816 opn = "mul.d";
5a1e8ffb 8817 optype = BINOP;
6ea83fed 8818 break;
bf4120ad 8819 case OPC_DIV_D:
5e755519 8820 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8821 {
a7812ae4
PB
8822 TCGv_i64 fp0 = tcg_temp_new_i64();
8823 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8824
8825 gen_load_fpr64(ctx, fp0, fs);
8826 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8827 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8828 tcg_temp_free_i64(fp1);
b6d96bed 8829 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8830 tcg_temp_free_i64(fp0);
b6d96bed 8831 }
6ea83fed 8832 opn = "div.d";
5a1e8ffb 8833 optype = BINOP;
6ea83fed 8834 break;
bf4120ad 8835 case OPC_SQRT_D:
5e755519 8836 check_cp1_registers(ctx, fs | fd);
b6d96bed 8837 {
a7812ae4 8838 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8839
8840 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8841 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 8842 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8843 tcg_temp_free_i64(fp0);
b6d96bed 8844 }
6ea83fed
FB
8845 opn = "sqrt.d";
8846 break;
bf4120ad 8847 case OPC_ABS_D:
5e755519 8848 check_cp1_registers(ctx, fs | fd);
b6d96bed 8849 {
a7812ae4 8850 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8851
8852 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8853 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 8854 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8855 tcg_temp_free_i64(fp0);
b6d96bed 8856 }
6ea83fed
FB
8857 opn = "abs.d";
8858 break;
bf4120ad 8859 case OPC_MOV_D:
5e755519 8860 check_cp1_registers(ctx, fs | fd);
b6d96bed 8861 {
a7812ae4 8862 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8863
8864 gen_load_fpr64(ctx, fp0, fs);
8865 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8866 tcg_temp_free_i64(fp0);
b6d96bed 8867 }
6ea83fed
FB
8868 opn = "mov.d";
8869 break;
bf4120ad 8870 case OPC_NEG_D:
5e755519 8871 check_cp1_registers(ctx, fs | fd);
b6d96bed 8872 {
a7812ae4 8873 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8874
8875 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8876 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 8877 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8878 tcg_temp_free_i64(fp0);
b6d96bed 8879 }
6ea83fed
FB
8880 opn = "neg.d";
8881 break;
bf4120ad 8882 case OPC_ROUND_L_D:
5e755519 8883 check_cp1_64bitmode(ctx);
b6d96bed 8884 {
a7812ae4 8885 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8886
8887 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8888 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8889 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8890 tcg_temp_free_i64(fp0);
b6d96bed 8891 }
5a5012ec
TS
8892 opn = "round.l.d";
8893 break;
bf4120ad 8894 case OPC_TRUNC_L_D:
5e755519 8895 check_cp1_64bitmode(ctx);
b6d96bed 8896 {
a7812ae4 8897 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8898
8899 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8900 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8901 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8902 tcg_temp_free_i64(fp0);
b6d96bed 8903 }
5a5012ec
TS
8904 opn = "trunc.l.d";
8905 break;
bf4120ad 8906 case OPC_CEIL_L_D:
5e755519 8907 check_cp1_64bitmode(ctx);
b6d96bed 8908 {
a7812ae4 8909 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8910
8911 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8912 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8913 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8914 tcg_temp_free_i64(fp0);
b6d96bed 8915 }
5a5012ec
TS
8916 opn = "ceil.l.d";
8917 break;
bf4120ad 8918 case OPC_FLOOR_L_D:
5e755519 8919 check_cp1_64bitmode(ctx);
b6d96bed 8920 {
a7812ae4 8921 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8922
8923 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8924 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8925 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8926 tcg_temp_free_i64(fp0);
b6d96bed 8927 }
5a5012ec
TS
8928 opn = "floor.l.d";
8929 break;
bf4120ad 8930 case OPC_ROUND_W_D:
5e755519 8931 check_cp1_registers(ctx, fs);
b6d96bed 8932 {
a7812ae4
PB
8933 TCGv_i32 fp32 = tcg_temp_new_i32();
8934 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8935
8936 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8937 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8938 tcg_temp_free_i64(fp64);
b6d96bed 8939 gen_store_fpr32(fp32, fd);
a7812ae4 8940 tcg_temp_free_i32(fp32);
b6d96bed 8941 }
6ea83fed
FB
8942 opn = "round.w.d";
8943 break;
bf4120ad 8944 case OPC_TRUNC_W_D:
5e755519 8945 check_cp1_registers(ctx, fs);
b6d96bed 8946 {
a7812ae4
PB
8947 TCGv_i32 fp32 = tcg_temp_new_i32();
8948 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8949
8950 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8951 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8952 tcg_temp_free_i64(fp64);
b6d96bed 8953 gen_store_fpr32(fp32, fd);
a7812ae4 8954 tcg_temp_free_i32(fp32);
b6d96bed 8955 }
6ea83fed
FB
8956 opn = "trunc.w.d";
8957 break;
bf4120ad 8958 case OPC_CEIL_W_D:
5e755519 8959 check_cp1_registers(ctx, fs);
b6d96bed 8960 {
a7812ae4
PB
8961 TCGv_i32 fp32 = tcg_temp_new_i32();
8962 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8963
8964 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8965 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8966 tcg_temp_free_i64(fp64);
b6d96bed 8967 gen_store_fpr32(fp32, fd);
a7812ae4 8968 tcg_temp_free_i32(fp32);
b6d96bed 8969 }
6ea83fed
FB
8970 opn = "ceil.w.d";
8971 break;
bf4120ad 8972 case OPC_FLOOR_W_D:
5e755519 8973 check_cp1_registers(ctx, fs);
b6d96bed 8974 {
a7812ae4
PB
8975 TCGv_i32 fp32 = tcg_temp_new_i32();
8976 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8977
8978 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8979 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8980 tcg_temp_free_i64(fp64);
b6d96bed 8981 gen_store_fpr32(fp32, fd);
a7812ae4 8982 tcg_temp_free_i32(fp32);
b6d96bed 8983 }
7a387fff 8984 opn = "floor.w.d";
6ea83fed 8985 break;
e7f16abb
LA
8986 case OPC_SEL_D:
8987 check_insn(ctx, ISA_MIPS32R6);
8988 gen_sel_d(ctx, op1, fd, ft, fs);
8989 opn = "sel.d";
8990 break;
8991 case OPC_SELEQZ_D:
8992 check_insn(ctx, ISA_MIPS32R6);
8993 gen_sel_d(ctx, op1, fd, ft, fs);
8994 opn = "seleqz.d";
8995 break;
8996 case OPC_SELNEZ_D:
8997 check_insn(ctx, ISA_MIPS32R6);
8998 gen_sel_d(ctx, op1, fd, ft, fs);
8999 opn = "selnez.d";
9000 break;
bf4120ad 9001 case OPC_MOVCF_D:
fecd2646 9002 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9003 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9004 opn = "movcf.d";
dd016883 9005 break;
bf4120ad 9006 case OPC_MOVZ_D:
fecd2646 9007 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9008 {
9009 int l1 = gen_new_label();
c9297f4d 9010 TCGv_i64 fp0;
a16336e4 9011
c9297f4d
AJ
9012 if (ft != 0) {
9013 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9014 }
9015 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9016 gen_load_fpr64(ctx, fp0, fs);
9017 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9018 tcg_temp_free_i64(fp0);
a16336e4
TS
9019 gen_set_label(l1);
9020 }
5a5012ec
TS
9021 opn = "movz.d";
9022 break;
bf4120ad 9023 case OPC_MOVN_D:
fecd2646 9024 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
9025 {
9026 int l1 = gen_new_label();
c9297f4d
AJ
9027 TCGv_i64 fp0;
9028
9029 if (ft != 0) {
9030 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9031 fp0 = tcg_temp_new_i64();
9032 gen_load_fpr64(ctx, fp0, fs);
9033 gen_store_fpr64(ctx, fp0, fd);
9034 tcg_temp_free_i64(fp0);
9035 gen_set_label(l1);
9036 }
a16336e4 9037 }
5a5012ec 9038 opn = "movn.d";
6ea83fed 9039 break;
bf4120ad 9040 case OPC_RECIP_D:
b8aa4598 9041 check_cp1_64bitmode(ctx);
b6d96bed 9042 {
a7812ae4 9043 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9044
9045 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9046 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9047 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9048 tcg_temp_free_i64(fp0);
b6d96bed 9049 }
57fa1fb3
TS
9050 opn = "recip.d";
9051 break;
bf4120ad 9052 case OPC_RSQRT_D:
b8aa4598 9053 check_cp1_64bitmode(ctx);
b6d96bed 9054 {
a7812ae4 9055 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9056
9057 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9058 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9059 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9060 tcg_temp_free_i64(fp0);
b6d96bed 9061 }
57fa1fb3
TS
9062 opn = "rsqrt.d";
9063 break;
e7f16abb
LA
9064 case OPC_MADDF_D:
9065 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9066 {
a7812ae4
PB
9067 TCGv_i64 fp0 = tcg_temp_new_i64();
9068 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9069 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9070 gen_load_fpr64(ctx, fp0, fs);
9071 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9072 gen_load_fpr64(ctx, fp2, fd);
9073 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9074 gen_store_fpr64(ctx, fp2, fd);
9075 tcg_temp_free_i64(fp2);
a7812ae4 9076 tcg_temp_free_i64(fp1);
a7812ae4 9077 tcg_temp_free_i64(fp0);
e7f16abb 9078 opn = "maddf.d";
b6d96bed 9079 }
57fa1fb3 9080 break;
e7f16abb
LA
9081 case OPC_MSUBF_D:
9082 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9083 {
a7812ae4 9084 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9085 TCGv_i64 fp1 = tcg_temp_new_i64();
9086 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9087 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9088 gen_load_fpr64(ctx, fp1, ft);
9089 gen_load_fpr64(ctx, fp2, fd);
9090 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9091 gen_store_fpr64(ctx, fp2, fd);
9092 tcg_temp_free_i64(fp2);
9093 tcg_temp_free_i64(fp1);
a7812ae4 9094 tcg_temp_free_i64(fp0);
e7f16abb 9095 opn = "msubf.d";
b6d96bed 9096 }
57fa1fb3 9097 break;
e7f16abb
LA
9098 case OPC_RINT_D:
9099 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9100 {
a7812ae4 9101 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9102 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9103 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9104 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9105 tcg_temp_free_i64(fp0);
e7f16abb 9106 opn = "rint.d";
b6d96bed 9107 }
57fa1fb3 9108 break;
e7f16abb
LA
9109 case OPC_CLASS_D:
9110 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9111 {
e7f16abb
LA
9112 TCGv_i64 fp0 = tcg_temp_new_i64();
9113 gen_load_fpr64(ctx, fp0, fs);
9114 gen_helper_float_class_d(fp0, fp0);
9115 gen_store_fpr64(ctx, fp0, fd);
9116 tcg_temp_free_i64(fp0);
9117 opn = "class.d";
9118 }
9119 break;
9120 case OPC_MIN_D: /* OPC_RECIP2_D */
9121 if (ctx->insn_flags & ISA_MIPS32R6) {
9122 /* OPC_MIN_D */
a7812ae4
PB
9123 TCGv_i64 fp0 = tcg_temp_new_i64();
9124 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9125 gen_load_fpr64(ctx, fp0, fs);
9126 gen_load_fpr64(ctx, fp1, ft);
9127 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9128 gen_store_fpr64(ctx, fp1, fd);
9129 tcg_temp_free_i64(fp1);
9130 tcg_temp_free_i64(fp0);
9131 opn = "min.d";
9132 } else {
9133 /* OPC_RECIP2_D */
9134 check_cp1_64bitmode(ctx);
9135 {
9136 TCGv_i64 fp0 = tcg_temp_new_i64();
9137 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9138
e7f16abb
LA
9139 gen_load_fpr64(ctx, fp0, fs);
9140 gen_load_fpr64(ctx, fp1, ft);
9141 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9142 tcg_temp_free_i64(fp1);
9143 gen_store_fpr64(ctx, fp0, fd);
9144 tcg_temp_free_i64(fp0);
9145 }
9146 opn = "recip2.d";
9147 }
9148 break;
9149 case OPC_MINA_D: /* OPC_RECIP1_D */
9150 if (ctx->insn_flags & ISA_MIPS32R6) {
9151 /* OPC_MINA_D */
9152 TCGv_i64 fp0 = tcg_temp_new_i64();
9153 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9154 gen_load_fpr64(ctx, fp0, fs);
9155 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9156 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9157 gen_store_fpr64(ctx, fp1, fd);
9158 tcg_temp_free_i64(fp1);
9159 tcg_temp_free_i64(fp0);
9160 opn = "mina.d";
9161 } else {
9162 /* OPC_RECIP1_D */
9163 check_cp1_64bitmode(ctx);
9164 {
9165 TCGv_i64 fp0 = tcg_temp_new_i64();
9166
9167 gen_load_fpr64(ctx, fp0, fs);
9168 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9169 gen_store_fpr64(ctx, fp0, fd);
9170 tcg_temp_free_i64(fp0);
9171 }
9172 opn = "recip1.d";
9173 }
9174 break;
9175 case OPC_MAX_D: /* OPC_RSQRT1_D */
9176 if (ctx->insn_flags & ISA_MIPS32R6) {
9177 /* OPC_MAX_D */
9178 TCGv_i64 fp0 = tcg_temp_new_i64();
9179 TCGv_i64 fp1 = tcg_temp_new_i64();
9180 gen_load_fpr64(ctx, fp0, fs);
9181 gen_load_fpr64(ctx, fp1, ft);
9182 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9183 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9184 tcg_temp_free_i64(fp1);
a7812ae4 9185 tcg_temp_free_i64(fp0);
e7f16abb
LA
9186 opn = "max.d";
9187 } else {
9188 /* OPC_RSQRT1_D */
9189 check_cp1_64bitmode(ctx);
9190 {
9191 TCGv_i64 fp0 = tcg_temp_new_i64();
9192
9193 gen_load_fpr64(ctx, fp0, fs);
9194 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9195 gen_store_fpr64(ctx, fp0, fd);
9196 tcg_temp_free_i64(fp0);
9197 }
9198 opn = "rsqrt1.d";
9199 }
9200 break;
9201 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9202 if (ctx->insn_flags & ISA_MIPS32R6) {
9203 /* OPC_MAXA_D */
9204 TCGv_i64 fp0 = tcg_temp_new_i64();
9205 TCGv_i64 fp1 = tcg_temp_new_i64();
9206 gen_load_fpr64(ctx, fp0, fs);
9207 gen_load_fpr64(ctx, fp1, ft);
9208 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9209 gen_store_fpr64(ctx, fp1, fd);
9210 tcg_temp_free_i64(fp1);
9211 tcg_temp_free_i64(fp0);
9212 opn = "maxa.d";
9213 } else {
9214 /* OPC_RSQRT2_D */
9215 check_cp1_64bitmode(ctx);
9216 {
9217 TCGv_i64 fp0 = tcg_temp_new_i64();
9218 TCGv_i64 fp1 = tcg_temp_new_i64();
9219
9220 gen_load_fpr64(ctx, fp0, fs);
9221 gen_load_fpr64(ctx, fp1, ft);
9222 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9223 tcg_temp_free_i64(fp1);
9224 gen_store_fpr64(ctx, fp0, fd);
9225 tcg_temp_free_i64(fp0);
9226 }
9227 opn = "rsqrt2.d";
b6d96bed 9228 }
57fa1fb3 9229 break;
bf4120ad
NF
9230 case OPC_CMP_F_D:
9231 case OPC_CMP_UN_D:
9232 case OPC_CMP_EQ_D:
9233 case OPC_CMP_UEQ_D:
9234 case OPC_CMP_OLT_D:
9235 case OPC_CMP_ULT_D:
9236 case OPC_CMP_OLE_D:
9237 case OPC_CMP_ULE_D:
9238 case OPC_CMP_SF_D:
9239 case OPC_CMP_NGLE_D:
9240 case OPC_CMP_SEQ_D:
9241 case OPC_CMP_NGL_D:
9242 case OPC_CMP_LT_D:
9243 case OPC_CMP_NGE_D:
9244 case OPC_CMP_LE_D:
9245 case OPC_CMP_NGT_D:
fecd2646 9246 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9247 if (ctx->opcode & (1 << 6)) {
9248 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9249 opn = condnames_abs[func-48];
9250 } else {
9251 gen_cmp_d(ctx, func-48, ft, fs, cc);
9252 opn = condnames[func-48];
5a1e8ffb 9253 }
6ea83fed 9254 break;
bf4120ad 9255 case OPC_CVT_S_D:
5e755519 9256 check_cp1_registers(ctx, fs);
b6d96bed 9257 {
a7812ae4
PB
9258 TCGv_i32 fp32 = tcg_temp_new_i32();
9259 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9260
9261 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9262 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9263 tcg_temp_free_i64(fp64);
b6d96bed 9264 gen_store_fpr32(fp32, fd);
a7812ae4 9265 tcg_temp_free_i32(fp32);
b6d96bed 9266 }
5a5012ec
TS
9267 opn = "cvt.s.d";
9268 break;
bf4120ad 9269 case OPC_CVT_W_D:
5e755519 9270 check_cp1_registers(ctx, fs);
b6d96bed 9271 {
a7812ae4
PB
9272 TCGv_i32 fp32 = tcg_temp_new_i32();
9273 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9274
9275 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9276 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 9277 tcg_temp_free_i64(fp64);
b6d96bed 9278 gen_store_fpr32(fp32, fd);
a7812ae4 9279 tcg_temp_free_i32(fp32);
b6d96bed 9280 }
5a5012ec
TS
9281 opn = "cvt.w.d";
9282 break;
bf4120ad 9283 case OPC_CVT_L_D:
5e755519 9284 check_cp1_64bitmode(ctx);
b6d96bed 9285 {
a7812ae4 9286 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9287
9288 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9289 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 9290 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9291 tcg_temp_free_i64(fp0);
b6d96bed 9292 }
5a5012ec
TS
9293 opn = "cvt.l.d";
9294 break;
bf4120ad 9295 case OPC_CVT_S_W:
b6d96bed 9296 {
a7812ae4 9297 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9298
9299 gen_load_fpr32(fp0, fs);
895c2d04 9300 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 9301 gen_store_fpr32(fp0, fd);
a7812ae4 9302 tcg_temp_free_i32(fp0);
b6d96bed 9303 }
5a5012ec 9304 opn = "cvt.s.w";
6ea83fed 9305 break;
bf4120ad 9306 case OPC_CVT_D_W:
5e755519 9307 check_cp1_registers(ctx, fd);
b6d96bed 9308 {
a7812ae4
PB
9309 TCGv_i32 fp32 = tcg_temp_new_i32();
9310 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9311
9312 gen_load_fpr32(fp32, fs);
895c2d04 9313 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 9314 tcg_temp_free_i32(fp32);
b6d96bed 9315 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9316 tcg_temp_free_i64(fp64);
b6d96bed 9317 }
5a5012ec
TS
9318 opn = "cvt.d.w";
9319 break;
bf4120ad 9320 case OPC_CVT_S_L:
5e755519 9321 check_cp1_64bitmode(ctx);
b6d96bed 9322 {
a7812ae4
PB
9323 TCGv_i32 fp32 = tcg_temp_new_i32();
9324 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9325
9326 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9327 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 9328 tcg_temp_free_i64(fp64);
b6d96bed 9329 gen_store_fpr32(fp32, fd);
a7812ae4 9330 tcg_temp_free_i32(fp32);
b6d96bed 9331 }
5a5012ec
TS
9332 opn = "cvt.s.l";
9333 break;
bf4120ad 9334 case OPC_CVT_D_L:
5e755519 9335 check_cp1_64bitmode(ctx);
b6d96bed 9336 {
a7812ae4 9337 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9338
9339 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9340 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 9341 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9342 tcg_temp_free_i64(fp0);
b6d96bed 9343 }
5a5012ec
TS
9344 opn = "cvt.d.l";
9345 break;
bf4120ad 9346 case OPC_CVT_PS_PW:
fecd2646 9347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 9348 check_cp1_64bitmode(ctx);
b6d96bed 9349 {
a7812ae4 9350 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9351
9352 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9353 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 9354 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9355 tcg_temp_free_i64(fp0);
b6d96bed 9356 }
5a5012ec
TS
9357 opn = "cvt.ps.pw";
9358 break;
bf4120ad 9359 case OPC_ADD_PS:
5e755519 9360 check_cp1_64bitmode(ctx);
b6d96bed 9361 {
a7812ae4
PB
9362 TCGv_i64 fp0 = tcg_temp_new_i64();
9363 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9364
9365 gen_load_fpr64(ctx, fp0, fs);
9366 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9367 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9368 tcg_temp_free_i64(fp1);
b6d96bed 9369 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9370 tcg_temp_free_i64(fp0);
b6d96bed 9371 }
5a5012ec 9372 opn = "add.ps";
6ea83fed 9373 break;
bf4120ad 9374 case OPC_SUB_PS:
5e755519 9375 check_cp1_64bitmode(ctx);
b6d96bed 9376 {
a7812ae4
PB
9377 TCGv_i64 fp0 = tcg_temp_new_i64();
9378 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9379
9380 gen_load_fpr64(ctx, fp0, fs);
9381 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9382 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9383 tcg_temp_free_i64(fp1);
b6d96bed 9384 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9385 tcg_temp_free_i64(fp0);
b6d96bed 9386 }
5a5012ec 9387 opn = "sub.ps";
6ea83fed 9388 break;
bf4120ad 9389 case OPC_MUL_PS:
5e755519 9390 check_cp1_64bitmode(ctx);
b6d96bed 9391 {
a7812ae4
PB
9392 TCGv_i64 fp0 = tcg_temp_new_i64();
9393 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9394
9395 gen_load_fpr64(ctx, fp0, fs);
9396 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9397 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9398 tcg_temp_free_i64(fp1);
b6d96bed 9399 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9400 tcg_temp_free_i64(fp0);
b6d96bed 9401 }
5a5012ec 9402 opn = "mul.ps";
6ea83fed 9403 break;
bf4120ad 9404 case OPC_ABS_PS:
5e755519 9405 check_cp1_64bitmode(ctx);
b6d96bed 9406 {
a7812ae4 9407 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9408
9409 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9410 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 9411 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9412 tcg_temp_free_i64(fp0);
b6d96bed 9413 }
5a5012ec 9414 opn = "abs.ps";
6ea83fed 9415 break;
bf4120ad 9416 case OPC_MOV_PS:
5e755519 9417 check_cp1_64bitmode(ctx);
b6d96bed 9418 {
a7812ae4 9419 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9420
9421 gen_load_fpr64(ctx, fp0, fs);
9422 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9423 tcg_temp_free_i64(fp0);
b6d96bed 9424 }
5a5012ec 9425 opn = "mov.ps";
6ea83fed 9426 break;
bf4120ad 9427 case OPC_NEG_PS:
5e755519 9428 check_cp1_64bitmode(ctx);
b6d96bed 9429 {
a7812ae4 9430 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9431
9432 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 9433 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 9434 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9435 tcg_temp_free_i64(fp0);
b6d96bed 9436 }
5a5012ec 9437 opn = "neg.ps";
6ea83fed 9438 break;
bf4120ad 9439 case OPC_MOVCF_PS:
5e755519 9440 check_cp1_64bitmode(ctx);
7f6613ce 9441 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9442 opn = "movcf.ps";
6ea83fed 9443 break;
bf4120ad 9444 case OPC_MOVZ_PS:
5e755519 9445 check_cp1_64bitmode(ctx);
a16336e4
TS
9446 {
9447 int l1 = gen_new_label();
30a3848b 9448 TCGv_i64 fp0;
a16336e4 9449
c9297f4d
AJ
9450 if (ft != 0)
9451 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9452 fp0 = tcg_temp_new_i64();
9453 gen_load_fpr64(ctx, fp0, fs);
9454 gen_store_fpr64(ctx, fp0, fd);
9455 tcg_temp_free_i64(fp0);
a16336e4
TS
9456 gen_set_label(l1);
9457 }
5a5012ec 9458 opn = "movz.ps";
6ea83fed 9459 break;
bf4120ad 9460 case OPC_MOVN_PS:
5e755519 9461 check_cp1_64bitmode(ctx);
a16336e4
TS
9462 {
9463 int l1 = gen_new_label();
30a3848b 9464 TCGv_i64 fp0;
c9297f4d
AJ
9465
9466 if (ft != 0) {
9467 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9468 fp0 = tcg_temp_new_i64();
9469 gen_load_fpr64(ctx, fp0, fs);
9470 gen_store_fpr64(ctx, fp0, fd);
9471 tcg_temp_free_i64(fp0);
9472 gen_set_label(l1);
9473 }
a16336e4 9474 }
5a5012ec 9475 opn = "movn.ps";
6ea83fed 9476 break;
bf4120ad 9477 case OPC_ADDR_PS:
5e755519 9478 check_cp1_64bitmode(ctx);
b6d96bed 9479 {
a7812ae4
PB
9480 TCGv_i64 fp0 = tcg_temp_new_i64();
9481 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9482
9483 gen_load_fpr64(ctx, fp0, ft);
9484 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9485 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9486 tcg_temp_free_i64(fp1);
b6d96bed 9487 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9488 tcg_temp_free_i64(fp0);
b6d96bed 9489 }
fbcc6828
TS
9490 opn = "addr.ps";
9491 break;
bf4120ad 9492 case OPC_MULR_PS:
5e755519 9493 check_cp1_64bitmode(ctx);
b6d96bed 9494 {
a7812ae4
PB
9495 TCGv_i64 fp0 = tcg_temp_new_i64();
9496 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9497
9498 gen_load_fpr64(ctx, fp0, ft);
9499 gen_load_fpr64(ctx, fp1, fs);
895c2d04 9500 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9501 tcg_temp_free_i64(fp1);
b6d96bed 9502 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9503 tcg_temp_free_i64(fp0);
b6d96bed 9504 }
57fa1fb3
TS
9505 opn = "mulr.ps";
9506 break;
bf4120ad 9507 case OPC_RECIP2_PS:
5e755519 9508 check_cp1_64bitmode(ctx);
b6d96bed 9509 {
a7812ae4
PB
9510 TCGv_i64 fp0 = tcg_temp_new_i64();
9511 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9512
9513 gen_load_fpr64(ctx, fp0, fs);
d22d7289 9514 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9515 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9516 tcg_temp_free_i64(fp1);
b6d96bed 9517 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9518 tcg_temp_free_i64(fp0);
b6d96bed 9519 }
57fa1fb3
TS
9520 opn = "recip2.ps";
9521 break;
bf4120ad 9522 case OPC_RECIP1_PS:
5e755519 9523 check_cp1_64bitmode(ctx);
b6d96bed 9524 {
a7812ae4 9525 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9526
9527 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9528 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 9529 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9530 tcg_temp_free_i64(fp0);
b6d96bed 9531 }
57fa1fb3
TS
9532 opn = "recip1.ps";
9533 break;
bf4120ad 9534 case OPC_RSQRT1_PS:
5e755519 9535 check_cp1_64bitmode(ctx);
b6d96bed 9536 {
a7812ae4 9537 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9538
9539 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9540 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 9541 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9542 tcg_temp_free_i64(fp0);
b6d96bed 9543 }
57fa1fb3
TS
9544 opn = "rsqrt1.ps";
9545 break;
bf4120ad 9546 case OPC_RSQRT2_PS:
5e755519 9547 check_cp1_64bitmode(ctx);
b6d96bed 9548 {
a7812ae4
PB
9549 TCGv_i64 fp0 = tcg_temp_new_i64();
9550 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9551
9552 gen_load_fpr64(ctx, fp0, fs);
9553 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9554 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 9555 tcg_temp_free_i64(fp1);
b6d96bed 9556 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9557 tcg_temp_free_i64(fp0);
b6d96bed 9558 }
57fa1fb3
TS
9559 opn = "rsqrt2.ps";
9560 break;
bf4120ad 9561 case OPC_CVT_S_PU:
5e755519 9562 check_cp1_64bitmode(ctx);
b6d96bed 9563 {
a7812ae4 9564 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9565
7f6613ce 9566 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 9567 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 9568 gen_store_fpr32(fp0, fd);
a7812ae4 9569 tcg_temp_free_i32(fp0);
b6d96bed 9570 }
5a5012ec 9571 opn = "cvt.s.pu";
dd016883 9572 break;
bf4120ad 9573 case OPC_CVT_PW_PS:
5e755519 9574 check_cp1_64bitmode(ctx);
b6d96bed 9575 {
a7812ae4 9576 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9577
9578 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9579 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 9580 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9581 tcg_temp_free_i64(fp0);
b6d96bed 9582 }
5a5012ec 9583 opn = "cvt.pw.ps";
6ea83fed 9584 break;
bf4120ad 9585 case OPC_CVT_S_PL:
5e755519 9586 check_cp1_64bitmode(ctx);
b6d96bed 9587 {
a7812ae4 9588 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9589
9590 gen_load_fpr32(fp0, fs);
895c2d04 9591 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 9592 gen_store_fpr32(fp0, fd);
a7812ae4 9593 tcg_temp_free_i32(fp0);
b6d96bed 9594 }
5a5012ec 9595 opn = "cvt.s.pl";
6ea83fed 9596 break;
bf4120ad 9597 case OPC_PLL_PS:
5e755519 9598 check_cp1_64bitmode(ctx);
b6d96bed 9599 {
a7812ae4
PB
9600 TCGv_i32 fp0 = tcg_temp_new_i32();
9601 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9602
9603 gen_load_fpr32(fp0, fs);
9604 gen_load_fpr32(fp1, ft);
7f6613ce 9605 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 9606 gen_store_fpr32(fp1, fd);
a7812ae4
PB
9607 tcg_temp_free_i32(fp0);
9608 tcg_temp_free_i32(fp1);
b6d96bed 9609 }
5a5012ec 9610 opn = "pll.ps";
6ea83fed 9611 break;
bf4120ad 9612 case OPC_PLU_PS:
5e755519 9613 check_cp1_64bitmode(ctx);
b6d96bed 9614 {
a7812ae4
PB
9615 TCGv_i32 fp0 = tcg_temp_new_i32();
9616 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
9617
9618 gen_load_fpr32(fp0, fs);
7f6613ce 9619 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 9620 gen_store_fpr32(fp1, fd);
7f6613ce 9621 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9622 tcg_temp_free_i32(fp0);
9623 tcg_temp_free_i32(fp1);
b6d96bed 9624 }
5a5012ec
TS
9625 opn = "plu.ps";
9626 break;
bf4120ad 9627 case OPC_PUL_PS:
5e755519 9628 check_cp1_64bitmode(ctx);
b6d96bed 9629 {
a7812ae4
PB
9630 TCGv_i32 fp0 = tcg_temp_new_i32();
9631 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9632
7f6613ce 9633 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
9634 gen_load_fpr32(fp1, ft);
9635 gen_store_fpr32(fp1, fd);
7f6613ce 9636 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9637 tcg_temp_free_i32(fp0);
9638 tcg_temp_free_i32(fp1);
b6d96bed 9639 }
5a5012ec
TS
9640 opn = "pul.ps";
9641 break;
bf4120ad 9642 case OPC_PUU_PS:
5e755519 9643 check_cp1_64bitmode(ctx);
b6d96bed 9644 {
a7812ae4
PB
9645 TCGv_i32 fp0 = tcg_temp_new_i32();
9646 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9647
7f6613ce
PJ
9648 gen_load_fpr32h(ctx, fp0, fs);
9649 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 9650 gen_store_fpr32(fp1, fd);
7f6613ce 9651 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
9652 tcg_temp_free_i32(fp0);
9653 tcg_temp_free_i32(fp1);
b6d96bed 9654 }
5a5012ec
TS
9655 opn = "puu.ps";
9656 break;
bf4120ad
NF
9657 case OPC_CMP_F_PS:
9658 case OPC_CMP_UN_PS:
9659 case OPC_CMP_EQ_PS:
9660 case OPC_CMP_UEQ_PS:
9661 case OPC_CMP_OLT_PS:
9662 case OPC_CMP_ULT_PS:
9663 case OPC_CMP_OLE_PS:
9664 case OPC_CMP_ULE_PS:
9665 case OPC_CMP_SF_PS:
9666 case OPC_CMP_NGLE_PS:
9667 case OPC_CMP_SEQ_PS:
9668 case OPC_CMP_NGL_PS:
9669 case OPC_CMP_LT_PS:
9670 case OPC_CMP_NGE_PS:
9671 case OPC_CMP_LE_PS:
9672 case OPC_CMP_NGT_PS:
8153667c
NF
9673 if (ctx->opcode & (1 << 6)) {
9674 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
9675 opn = condnames_abs[func-48];
9676 } else {
9677 gen_cmp_ps(ctx, func-48, ft, fs, cc);
9678 opn = condnames[func-48];
5a1e8ffb 9679 }
6ea83fed 9680 break;
5a5012ec 9681 default:
923617a3 9682 MIPS_INVAL(opn);
e397ee33 9683 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
9684 return;
9685 }
2abf314d 9686 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
9687 switch (optype) {
9688 case BINOP:
6ea83fed 9689 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
9690 break;
9691 case CMPOP:
9692 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
9693 break;
9694 default:
6ea83fed 9695 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
9696 break;
9697 }
6ea83fed 9698}
6af0bf9c 9699
5a5012ec 9700/* Coprocessor 3 (FPU) */
5e755519
TS
9701static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
9702 int fd, int fs, int base, int index)
7a387fff 9703{
923617a3 9704 const char *opn = "extended float load/store";
93b12ccc 9705 int store = 0;
4e2474d6 9706 TCGv t0 = tcg_temp_new();
7a387fff 9707
93b12ccc 9708 if (base == 0) {
6c5c1e20 9709 gen_load_gpr(t0, index);
93b12ccc 9710 } else if (index == 0) {
6c5c1e20 9711 gen_load_gpr(t0, base);
93b12ccc 9712 } else {
05168674 9713 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 9714 }
5a5012ec 9715 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 9716 memory access. */
5a5012ec
TS
9717 switch (opc) {
9718 case OPC_LWXC1:
8c0ab41f 9719 check_cop1x(ctx);
b6d96bed 9720 {
a7812ae4 9721 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9722
5f68f5ae 9723 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 9724 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 9725 gen_store_fpr32(fp0, fd);
a7812ae4 9726 tcg_temp_free_i32(fp0);
b6d96bed 9727 }
5a5012ec
TS
9728 opn = "lwxc1";
9729 break;
9730 case OPC_LDXC1:
8c0ab41f
AJ
9731 check_cop1x(ctx);
9732 check_cp1_registers(ctx, fd);
b6d96bed 9733 {
a7812ae4 9734 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 9735 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9736 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9737 tcg_temp_free_i64(fp0);
b6d96bed 9738 }
5a5012ec
TS
9739 opn = "ldxc1";
9740 break;
9741 case OPC_LUXC1:
8c0ab41f 9742 check_cp1_64bitmode(ctx);
6c5c1e20 9743 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9744 {
a7812ae4 9745 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9746
5f68f5ae 9747 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9749 tcg_temp_free_i64(fp0);
b6d96bed 9750 }
5a5012ec
TS
9751 opn = "luxc1";
9752 break;
9753 case OPC_SWXC1:
8c0ab41f 9754 check_cop1x(ctx);
b6d96bed 9755 {
a7812ae4 9756 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9757 gen_load_fpr32(fp0, fs);
5f68f5ae 9758 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 9759 tcg_temp_free_i32(fp0);
b6d96bed 9760 }
5a5012ec 9761 opn = "swxc1";
93b12ccc 9762 store = 1;
5a5012ec
TS
9763 break;
9764 case OPC_SDXC1:
8c0ab41f
AJ
9765 check_cop1x(ctx);
9766 check_cp1_registers(ctx, fs);
b6d96bed 9767 {
a7812ae4 9768 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9769 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9770 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9771 tcg_temp_free_i64(fp0);
b6d96bed 9772 }
5a5012ec 9773 opn = "sdxc1";
93b12ccc 9774 store = 1;
5a5012ec
TS
9775 break;
9776 case OPC_SUXC1:
8c0ab41f 9777 check_cp1_64bitmode(ctx);
6c5c1e20 9778 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9779 {
a7812ae4 9780 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9781 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9782 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9783 tcg_temp_free_i64(fp0);
b6d96bed 9784 }
5a5012ec 9785 opn = "suxc1";
93b12ccc 9786 store = 1;
5a5012ec 9787 break;
5a5012ec 9788 }
6c5c1e20 9789 tcg_temp_free(t0);
2abf314d 9790 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
9791 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
9792 regnames[index], regnames[base]);
5a5012ec
TS
9793}
9794
5e755519
TS
9795static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
9796 int fd, int fr, int fs, int ft)
5a5012ec 9797{
923617a3 9798 const char *opn = "flt3_arith";
5a5012ec 9799
5a5012ec
TS
9800 switch (opc) {
9801 case OPC_ALNV_PS:
b8aa4598 9802 check_cp1_64bitmode(ctx);
a16336e4 9803 {
a7812ae4 9804 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
9805 TCGv_i32 fp = tcg_temp_new_i32();
9806 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
9807 int l1 = gen_new_label();
9808 int l2 = gen_new_label();
9809
6c5c1e20
TS
9810 gen_load_gpr(t0, fr);
9811 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
9812
9813 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 9814 gen_load_fpr32(fp, fs);
7f6613ce 9815 gen_load_fpr32h(ctx, fph, fs);
c905fdac 9816 gen_store_fpr32(fp, fd);
7f6613ce 9817 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
9818 tcg_gen_br(l2);
9819 gen_set_label(l1);
6c5c1e20
TS
9820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
9821 tcg_temp_free(t0);
a16336e4 9822#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 9823 gen_load_fpr32(fp, fs);
7f6613ce
PJ
9824 gen_load_fpr32h(ctx, fph, ft);
9825 gen_store_fpr32h(ctx, fp, fd);
c905fdac 9826 gen_store_fpr32(fph, fd);
a16336e4 9827#else
7f6613ce 9828 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
9829 gen_load_fpr32(fp, ft);
9830 gen_store_fpr32(fph, fd);
7f6613ce 9831 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
9832#endif
9833 gen_set_label(l2);
c905fdac
AJ
9834 tcg_temp_free_i32(fp);
9835 tcg_temp_free_i32(fph);
a16336e4 9836 }
5a5012ec
TS
9837 opn = "alnv.ps";
9838 break;
9839 case OPC_MADD_S:
b8aa4598 9840 check_cop1x(ctx);
b6d96bed 9841 {
a7812ae4
PB
9842 TCGv_i32 fp0 = tcg_temp_new_i32();
9843 TCGv_i32 fp1 = tcg_temp_new_i32();
9844 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9845
9846 gen_load_fpr32(fp0, fs);
9847 gen_load_fpr32(fp1, ft);
9848 gen_load_fpr32(fp2, fr);
b3d6cd44 9849 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9850 tcg_temp_free_i32(fp0);
9851 tcg_temp_free_i32(fp1);
b6d96bed 9852 gen_store_fpr32(fp2, fd);
a7812ae4 9853 tcg_temp_free_i32(fp2);
b6d96bed 9854 }
5a5012ec
TS
9855 opn = "madd.s";
9856 break;
9857 case OPC_MADD_D:
b8aa4598
TS
9858 check_cop1x(ctx);
9859 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9860 {
a7812ae4
PB
9861 TCGv_i64 fp0 = tcg_temp_new_i64();
9862 TCGv_i64 fp1 = tcg_temp_new_i64();
9863 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9864
9865 gen_load_fpr64(ctx, fp0, fs);
9866 gen_load_fpr64(ctx, fp1, ft);
9867 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9868 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9869 tcg_temp_free_i64(fp0);
9870 tcg_temp_free_i64(fp1);
b6d96bed 9871 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9872 tcg_temp_free_i64(fp2);
b6d96bed 9873 }
5a5012ec
TS
9874 opn = "madd.d";
9875 break;
9876 case OPC_MADD_PS:
b8aa4598 9877 check_cp1_64bitmode(ctx);
b6d96bed 9878 {
a7812ae4
PB
9879 TCGv_i64 fp0 = tcg_temp_new_i64();
9880 TCGv_i64 fp1 = tcg_temp_new_i64();
9881 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9882
9883 gen_load_fpr64(ctx, fp0, fs);
9884 gen_load_fpr64(ctx, fp1, ft);
9885 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9886 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9887 tcg_temp_free_i64(fp0);
9888 tcg_temp_free_i64(fp1);
b6d96bed 9889 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9890 tcg_temp_free_i64(fp2);
b6d96bed 9891 }
5a5012ec
TS
9892 opn = "madd.ps";
9893 break;
9894 case OPC_MSUB_S:
b8aa4598 9895 check_cop1x(ctx);
b6d96bed 9896 {
a7812ae4
PB
9897 TCGv_i32 fp0 = tcg_temp_new_i32();
9898 TCGv_i32 fp1 = tcg_temp_new_i32();
9899 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9900
9901 gen_load_fpr32(fp0, fs);
9902 gen_load_fpr32(fp1, ft);
9903 gen_load_fpr32(fp2, fr);
b3d6cd44 9904 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9905 tcg_temp_free_i32(fp0);
9906 tcg_temp_free_i32(fp1);
b6d96bed 9907 gen_store_fpr32(fp2, fd);
a7812ae4 9908 tcg_temp_free_i32(fp2);
b6d96bed 9909 }
5a5012ec
TS
9910 opn = "msub.s";
9911 break;
9912 case OPC_MSUB_D:
b8aa4598
TS
9913 check_cop1x(ctx);
9914 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9915 {
a7812ae4
PB
9916 TCGv_i64 fp0 = tcg_temp_new_i64();
9917 TCGv_i64 fp1 = tcg_temp_new_i64();
9918 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9919
9920 gen_load_fpr64(ctx, fp0, fs);
9921 gen_load_fpr64(ctx, fp1, ft);
9922 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9923 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9924 tcg_temp_free_i64(fp0);
9925 tcg_temp_free_i64(fp1);
b6d96bed 9926 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9927 tcg_temp_free_i64(fp2);
b6d96bed 9928 }
5a5012ec
TS
9929 opn = "msub.d";
9930 break;
9931 case OPC_MSUB_PS:
b8aa4598 9932 check_cp1_64bitmode(ctx);
b6d96bed 9933 {
a7812ae4
PB
9934 TCGv_i64 fp0 = tcg_temp_new_i64();
9935 TCGv_i64 fp1 = tcg_temp_new_i64();
9936 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9937
9938 gen_load_fpr64(ctx, fp0, fs);
9939 gen_load_fpr64(ctx, fp1, ft);
9940 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9941 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9942 tcg_temp_free_i64(fp0);
9943 tcg_temp_free_i64(fp1);
b6d96bed 9944 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9945 tcg_temp_free_i64(fp2);
b6d96bed 9946 }
5a5012ec
TS
9947 opn = "msub.ps";
9948 break;
9949 case OPC_NMADD_S:
b8aa4598 9950 check_cop1x(ctx);
b6d96bed 9951 {
a7812ae4
PB
9952 TCGv_i32 fp0 = tcg_temp_new_i32();
9953 TCGv_i32 fp1 = tcg_temp_new_i32();
9954 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9955
9956 gen_load_fpr32(fp0, fs);
9957 gen_load_fpr32(fp1, ft);
9958 gen_load_fpr32(fp2, fr);
b3d6cd44 9959 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9960 tcg_temp_free_i32(fp0);
9961 tcg_temp_free_i32(fp1);
b6d96bed 9962 gen_store_fpr32(fp2, fd);
a7812ae4 9963 tcg_temp_free_i32(fp2);
b6d96bed 9964 }
5a5012ec
TS
9965 opn = "nmadd.s";
9966 break;
9967 case OPC_NMADD_D:
b8aa4598
TS
9968 check_cop1x(ctx);
9969 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9970 {
a7812ae4
PB
9971 TCGv_i64 fp0 = tcg_temp_new_i64();
9972 TCGv_i64 fp1 = tcg_temp_new_i64();
9973 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9974
9975 gen_load_fpr64(ctx, fp0, fs);
9976 gen_load_fpr64(ctx, fp1, ft);
9977 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9978 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9979 tcg_temp_free_i64(fp0);
9980 tcg_temp_free_i64(fp1);
b6d96bed 9981 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9982 tcg_temp_free_i64(fp2);
b6d96bed 9983 }
5a5012ec
TS
9984 opn = "nmadd.d";
9985 break;
9986 case OPC_NMADD_PS:
b8aa4598 9987 check_cp1_64bitmode(ctx);
b6d96bed 9988 {
a7812ae4
PB
9989 TCGv_i64 fp0 = tcg_temp_new_i64();
9990 TCGv_i64 fp1 = tcg_temp_new_i64();
9991 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9992
9993 gen_load_fpr64(ctx, fp0, fs);
9994 gen_load_fpr64(ctx, fp1, ft);
9995 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9996 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9997 tcg_temp_free_i64(fp0);
9998 tcg_temp_free_i64(fp1);
b6d96bed 9999 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10000 tcg_temp_free_i64(fp2);
b6d96bed 10001 }
5a5012ec
TS
10002 opn = "nmadd.ps";
10003 break;
10004 case OPC_NMSUB_S:
b8aa4598 10005 check_cop1x(ctx);
b6d96bed 10006 {
a7812ae4
PB
10007 TCGv_i32 fp0 = tcg_temp_new_i32();
10008 TCGv_i32 fp1 = tcg_temp_new_i32();
10009 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
10010
10011 gen_load_fpr32(fp0, fs);
10012 gen_load_fpr32(fp1, ft);
10013 gen_load_fpr32(fp2, fr);
b3d6cd44 10014 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10015 tcg_temp_free_i32(fp0);
10016 tcg_temp_free_i32(fp1);
b6d96bed 10017 gen_store_fpr32(fp2, fd);
a7812ae4 10018 tcg_temp_free_i32(fp2);
b6d96bed 10019 }
5a5012ec
TS
10020 opn = "nmsub.s";
10021 break;
10022 case OPC_NMSUB_D:
b8aa4598
TS
10023 check_cop1x(ctx);
10024 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10025 {
a7812ae4
PB
10026 TCGv_i64 fp0 = tcg_temp_new_i64();
10027 TCGv_i64 fp1 = tcg_temp_new_i64();
10028 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10029
10030 gen_load_fpr64(ctx, fp0, fs);
10031 gen_load_fpr64(ctx, fp1, ft);
10032 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10033 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10034 tcg_temp_free_i64(fp0);
10035 tcg_temp_free_i64(fp1);
b6d96bed 10036 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10037 tcg_temp_free_i64(fp2);
b6d96bed 10038 }
5a5012ec
TS
10039 opn = "nmsub.d";
10040 break;
10041 case OPC_NMSUB_PS:
b8aa4598 10042 check_cp1_64bitmode(ctx);
b6d96bed 10043 {
a7812ae4
PB
10044 TCGv_i64 fp0 = tcg_temp_new_i64();
10045 TCGv_i64 fp1 = tcg_temp_new_i64();
10046 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10047
10048 gen_load_fpr64(ctx, fp0, fs);
10049 gen_load_fpr64(ctx, fp1, ft);
10050 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10051 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10052 tcg_temp_free_i64(fp0);
10053 tcg_temp_free_i64(fp1);
b6d96bed 10054 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10055 tcg_temp_free_i64(fp2);
b6d96bed 10056 }
5a5012ec
TS
10057 opn = "nmsub.ps";
10058 break;
923617a3
TS
10059 default:
10060 MIPS_INVAL(opn);
5a5012ec
TS
10061 generate_exception (ctx, EXCP_RI);
10062 return;
10063 }
2abf314d 10064 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
10065 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10066 fregnames[fs], fregnames[ft]);
7a387fff
TS
10067}
10068
d75c135e 10069static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
10070{
10071 TCGv t0;
10072
b3167288
RH
10073#if !defined(CONFIG_USER_ONLY)
10074 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10075 Therefore only check the ISA in system mode. */
d75c135e 10076 check_insn(ctx, ISA_MIPS32R2);
b3167288 10077#endif
26ebe468
NF
10078 t0 = tcg_temp_new();
10079
10080 switch (rd) {
10081 case 0:
10082 save_cpu_state(ctx, 1);
895c2d04 10083 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10084 gen_store_gpr(t0, rt);
10085 break;
10086 case 1:
10087 save_cpu_state(ctx, 1);
895c2d04 10088 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10089 gen_store_gpr(t0, rt);
10090 break;
10091 case 2:
10092 save_cpu_state(ctx, 1);
895c2d04 10093 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
10094 gen_store_gpr(t0, rt);
10095 break;
10096 case 3:
10097 save_cpu_state(ctx, 1);
895c2d04 10098 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10099 gen_store_gpr(t0, rt);
10100 break;
10101 case 29:
10102#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10103 tcg_gen_ld_tl(t0, cpu_env,
10104 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10105 gen_store_gpr(t0, rt);
10106 break;
10107#else
d279279e
PJ
10108 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10109 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10110 tcg_gen_ld_tl(t0, cpu_env,
10111 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10112 gen_store_gpr(t0, rt);
10113 } else {
10114 generate_exception(ctx, EXCP_RI);
10115 }
10116 break;
26ebe468
NF
10117#endif
10118 default: /* Invalid */
10119 MIPS_INVAL("rdhwr");
10120 generate_exception(ctx, EXCP_RI);
10121 break;
10122 }
10123 tcg_temp_free(t0);
10124}
10125
31837be3 10126static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10127{
10128 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10129 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
10130 /* Branches completion */
10131 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10132 ctx->bstate = BS_BRANCH;
10133 save_cpu_state(ctx, 0);
10134 /* FIXME: Need to clear can_do_io. */
364d4831 10135 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
10136 case MIPS_HFLAG_B:
10137 /* unconditional branch */
10138 MIPS_DEBUG("unconditional branch");
364d4831
NF
10139 if (proc_hflags & MIPS_HFLAG_BX) {
10140 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10141 }
c9602061
NF
10142 gen_goto_tb(ctx, 0, ctx->btarget);
10143 break;
10144 case MIPS_HFLAG_BL:
10145 /* blikely taken case */
10146 MIPS_DEBUG("blikely branch taken");
10147 gen_goto_tb(ctx, 0, ctx->btarget);
10148 break;
10149 case MIPS_HFLAG_BC:
10150 /* Conditional branch */
10151 MIPS_DEBUG("conditional branch");
10152 {
10153 int l1 = gen_new_label();
10154
10155 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10156 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10157 gen_set_label(l1);
10158 gen_goto_tb(ctx, 0, ctx->btarget);
10159 }
10160 break;
10161 case MIPS_HFLAG_BR:
10162 /* unconditional branch to register */
10163 MIPS_DEBUG("branch to register");
d75c135e 10164 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10165 TCGv t0 = tcg_temp_new();
10166 TCGv_i32 t1 = tcg_temp_new_i32();
10167
10168 tcg_gen_andi_tl(t0, btarget, 0x1);
10169 tcg_gen_trunc_tl_i32(t1, t0);
10170 tcg_temp_free(t0);
10171 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10172 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10173 tcg_gen_or_i32(hflags, hflags, t1);
10174 tcg_temp_free_i32(t1);
10175
10176 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10177 } else {
10178 tcg_gen_mov_tl(cpu_PC, btarget);
10179 }
c9602061
NF
10180 if (ctx->singlestep_enabled) {
10181 save_cpu_state(ctx, 0);
895c2d04 10182 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
10183 }
10184 tcg_gen_exit_tb(0);
10185 break;
10186 default:
10187 MIPS_DEBUG("unknown branch");
10188 break;
10189 }
10190 }
10191}
10192
7a387fff 10193/* ISA extensions (ASEs) */
6af0bf9c 10194/* MIPS16 extension to MIPS32 */
6ea219d0
NF
10195
10196/* MIPS16 major opcodes */
10197enum {
10198 M16_OPC_ADDIUSP = 0x00,
10199 M16_OPC_ADDIUPC = 0x01,
10200 M16_OPC_B = 0x02,
10201 M16_OPC_JAL = 0x03,
10202 M16_OPC_BEQZ = 0x04,
10203 M16_OPC_BNEQZ = 0x05,
10204 M16_OPC_SHIFT = 0x06,
10205 M16_OPC_LD = 0x07,
10206 M16_OPC_RRIA = 0x08,
10207 M16_OPC_ADDIU8 = 0x09,
10208 M16_OPC_SLTI = 0x0a,
10209 M16_OPC_SLTIU = 0x0b,
10210 M16_OPC_I8 = 0x0c,
10211 M16_OPC_LI = 0x0d,
10212 M16_OPC_CMPI = 0x0e,
10213 M16_OPC_SD = 0x0f,
10214 M16_OPC_LB = 0x10,
10215 M16_OPC_LH = 0x11,
10216 M16_OPC_LWSP = 0x12,
10217 M16_OPC_LW = 0x13,
10218 M16_OPC_LBU = 0x14,
10219 M16_OPC_LHU = 0x15,
10220 M16_OPC_LWPC = 0x16,
10221 M16_OPC_LWU = 0x17,
10222 M16_OPC_SB = 0x18,
10223 M16_OPC_SH = 0x19,
10224 M16_OPC_SWSP = 0x1a,
10225 M16_OPC_SW = 0x1b,
10226 M16_OPC_RRR = 0x1c,
10227 M16_OPC_RR = 0x1d,
10228 M16_OPC_EXTEND = 0x1e,
10229 M16_OPC_I64 = 0x1f
10230};
10231
10232/* I8 funct field */
10233enum {
10234 I8_BTEQZ = 0x0,
10235 I8_BTNEZ = 0x1,
10236 I8_SWRASP = 0x2,
10237 I8_ADJSP = 0x3,
10238 I8_SVRS = 0x4,
10239 I8_MOV32R = 0x5,
10240 I8_MOVR32 = 0x7
10241};
10242
10243/* RRR f field */
10244enum {
10245 RRR_DADDU = 0x0,
10246 RRR_ADDU = 0x1,
10247 RRR_DSUBU = 0x2,
10248 RRR_SUBU = 0x3
10249};
10250
10251/* RR funct field */
10252enum {
10253 RR_JR = 0x00,
10254 RR_SDBBP = 0x01,
10255 RR_SLT = 0x02,
10256 RR_SLTU = 0x03,
10257 RR_SLLV = 0x04,
10258 RR_BREAK = 0x05,
10259 RR_SRLV = 0x06,
10260 RR_SRAV = 0x07,
10261 RR_DSRL = 0x08,
10262 RR_CMP = 0x0a,
10263 RR_NEG = 0x0b,
10264 RR_AND = 0x0c,
10265 RR_OR = 0x0d,
10266 RR_XOR = 0x0e,
10267 RR_NOT = 0x0f,
10268 RR_MFHI = 0x10,
10269 RR_CNVT = 0x11,
10270 RR_MFLO = 0x12,
10271 RR_DSRA = 0x13,
10272 RR_DSLLV = 0x14,
10273 RR_DSRLV = 0x16,
10274 RR_DSRAV = 0x17,
10275 RR_MULT = 0x18,
10276 RR_MULTU = 0x19,
10277 RR_DIV = 0x1a,
10278 RR_DIVU = 0x1b,
10279 RR_DMULT = 0x1c,
10280 RR_DMULTU = 0x1d,
10281 RR_DDIV = 0x1e,
10282 RR_DDIVU = 0x1f
10283};
10284
10285/* I64 funct field */
10286enum {
10287 I64_LDSP = 0x0,
10288 I64_SDSP = 0x1,
10289 I64_SDRASP = 0x2,
10290 I64_DADJSP = 0x3,
10291 I64_LDPC = 0x4,
364d4831 10292 I64_DADDIU5 = 0x5,
6ea219d0
NF
10293 I64_DADDIUPC = 0x6,
10294 I64_DADDIUSP = 0x7
10295};
10296
10297/* RR ry field for CNVT */
10298enum {
10299 RR_RY_CNVT_ZEB = 0x0,
10300 RR_RY_CNVT_ZEH = 0x1,
10301 RR_RY_CNVT_ZEW = 0x2,
10302 RR_RY_CNVT_SEB = 0x4,
10303 RR_RY_CNVT_SEH = 0x5,
10304 RR_RY_CNVT_SEW = 0x6,
10305};
10306
364d4831
NF
10307static int xlat (int r)
10308{
10309 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10310
10311 return map[r];
10312}
10313
10314static void gen_mips16_save (DisasContext *ctx,
10315 int xsregs, int aregs,
10316 int do_ra, int do_s0, int do_s1,
10317 int framesize)
10318{
10319 TCGv t0 = tcg_temp_new();
10320 TCGv t1 = tcg_temp_new();
10321 int args, astatic;
10322
10323 switch (aregs) {
10324 case 0:
10325 case 1:
10326 case 2:
10327 case 3:
10328 case 11:
10329 args = 0;
10330 break;
10331 case 4:
10332 case 5:
10333 case 6:
10334 case 7:
10335 args = 1;
10336 break;
10337 case 8:
10338 case 9:
10339 case 10:
10340 args = 2;
10341 break;
10342 case 12:
10343 case 13:
10344 args = 3;
10345 break;
10346 case 14:
10347 args = 4;
10348 break;
10349 default:
10350 generate_exception(ctx, EXCP_RI);
10351 return;
10352 }
10353
10354 switch (args) {
10355 case 4:
10356 gen_base_offset_addr(ctx, t0, 29, 12);
10357 gen_load_gpr(t1, 7);
5f68f5ae 10358 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10359 /* Fall through */
10360 case 3:
10361 gen_base_offset_addr(ctx, t0, 29, 8);
10362 gen_load_gpr(t1, 6);
5f68f5ae 10363 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10364 /* Fall through */
10365 case 2:
10366 gen_base_offset_addr(ctx, t0, 29, 4);
10367 gen_load_gpr(t1, 5);
5f68f5ae 10368 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10369 /* Fall through */
10370 case 1:
10371 gen_base_offset_addr(ctx, t0, 29, 0);
10372 gen_load_gpr(t1, 4);
5f68f5ae 10373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
10374 }
10375
10376 gen_load_gpr(t0, 29);
10377
5f68f5ae
AJ
10378#define DECR_AND_STORE(reg) do { \
10379 tcg_gen_subi_tl(t0, t0, 4); \
10380 gen_load_gpr(t1, reg); \
10381 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
10382 } while (0)
10383
10384 if (do_ra) {
10385 DECR_AND_STORE(31);
10386 }
10387
10388 switch (xsregs) {
10389 case 7:
10390 DECR_AND_STORE(30);
10391 /* Fall through */
10392 case 6:
10393 DECR_AND_STORE(23);
10394 /* Fall through */
10395 case 5:
10396 DECR_AND_STORE(22);
10397 /* Fall through */
10398 case 4:
10399 DECR_AND_STORE(21);
10400 /* Fall through */
10401 case 3:
10402 DECR_AND_STORE(20);
10403 /* Fall through */
10404 case 2:
10405 DECR_AND_STORE(19);
10406 /* Fall through */
10407 case 1:
10408 DECR_AND_STORE(18);
10409 }
10410
10411 if (do_s1) {
10412 DECR_AND_STORE(17);
10413 }
10414 if (do_s0) {
10415 DECR_AND_STORE(16);
10416 }
10417
10418 switch (aregs) {
10419 case 0:
10420 case 4:
10421 case 8:
10422 case 12:
10423 case 14:
10424 astatic = 0;
10425 break;
10426 case 1:
10427 case 5:
10428 case 9:
10429 case 13:
10430 astatic = 1;
10431 break;
10432 case 2:
10433 case 6:
10434 case 10:
10435 astatic = 2;
10436 break;
10437 case 3:
10438 case 7:
10439 astatic = 3;
10440 break;
10441 case 11:
10442 astatic = 4;
10443 break;
10444 default:
10445 generate_exception(ctx, EXCP_RI);
10446 return;
10447 }
10448
10449 if (astatic > 0) {
10450 DECR_AND_STORE(7);
10451 if (astatic > 1) {
10452 DECR_AND_STORE(6);
10453 if (astatic > 2) {
10454 DECR_AND_STORE(5);
10455 if (astatic > 3) {
10456 DECR_AND_STORE(4);
10457 }
10458 }
10459 }
10460 }
10461#undef DECR_AND_STORE
10462
10463 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10464 tcg_temp_free(t0);
10465 tcg_temp_free(t1);
10466}
10467
10468static void gen_mips16_restore (DisasContext *ctx,
10469 int xsregs, int aregs,
10470 int do_ra, int do_s0, int do_s1,
10471 int framesize)
10472{
10473 int astatic;
10474 TCGv t0 = tcg_temp_new();
10475 TCGv t1 = tcg_temp_new();
10476
10477 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
10478
5f68f5ae
AJ
10479#define DECR_AND_LOAD(reg) do { \
10480 tcg_gen_subi_tl(t0, t0, 4); \
10481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10482 gen_store_gpr(t1, reg); \
364d4831
NF
10483 } while (0)
10484
10485 if (do_ra) {
10486 DECR_AND_LOAD(31);
10487 }
10488
10489 switch (xsregs) {
10490 case 7:
10491 DECR_AND_LOAD(30);
10492 /* Fall through */
10493 case 6:
10494 DECR_AND_LOAD(23);
10495 /* Fall through */
10496 case 5:
10497 DECR_AND_LOAD(22);
10498 /* Fall through */
10499 case 4:
10500 DECR_AND_LOAD(21);
10501 /* Fall through */
10502 case 3:
10503 DECR_AND_LOAD(20);
10504 /* Fall through */
10505 case 2:
10506 DECR_AND_LOAD(19);
10507 /* Fall through */
10508 case 1:
10509 DECR_AND_LOAD(18);
10510 }
10511
10512 if (do_s1) {
10513 DECR_AND_LOAD(17);
10514 }
10515 if (do_s0) {
10516 DECR_AND_LOAD(16);
10517 }
10518
10519 switch (aregs) {
10520 case 0:
10521 case 4:
10522 case 8:
10523 case 12:
10524 case 14:
10525 astatic = 0;
10526 break;
10527 case 1:
10528 case 5:
10529 case 9:
10530 case 13:
10531 astatic = 1;
10532 break;
10533 case 2:
10534 case 6:
10535 case 10:
10536 astatic = 2;
10537 break;
10538 case 3:
10539 case 7:
10540 astatic = 3;
10541 break;
10542 case 11:
10543 astatic = 4;
10544 break;
10545 default:
10546 generate_exception(ctx, EXCP_RI);
10547 return;
10548 }
10549
10550 if (astatic > 0) {
10551 DECR_AND_LOAD(7);
10552 if (astatic > 1) {
10553 DECR_AND_LOAD(6);
10554 if (astatic > 2) {
10555 DECR_AND_LOAD(5);
10556 if (astatic > 3) {
10557 DECR_AND_LOAD(4);
10558 }
10559 }
10560 }
10561 }
10562#undef DECR_AND_LOAD
10563
10564 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10565 tcg_temp_free(t0);
10566 tcg_temp_free(t1);
10567}
10568
10569static void gen_addiupc (DisasContext *ctx, int rx, int imm,
10570 int is_64_bit, int extended)
10571{
10572 TCGv t0;
10573
10574 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10575 generate_exception(ctx, EXCP_RI);
10576 return;
10577 }
10578
10579 t0 = tcg_temp_new();
10580
10581 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
10582 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
10583 if (!is_64_bit) {
10584 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10585 }
10586
10587 tcg_temp_free(t0);
10588}
10589
10590#if defined(TARGET_MIPS64)
d75c135e 10591static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
10592 int ry, int funct, int16_t offset,
10593 int extended)
10594{
10595 switch (funct) {
10596 case I64_LDSP:
10597 check_mips_64(ctx);
10598 offset = extended ? offset : offset << 3;
d75c135e 10599 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
10600 break;
10601 case I64_SDSP:
10602 check_mips_64(ctx);
10603 offset = extended ? offset : offset << 3;
5c13fdfd 10604 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
10605 break;
10606 case I64_SDRASP:
10607 check_mips_64(ctx);
10608 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 10609 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
10610 break;
10611 case I64_DADJSP:
10612 check_mips_64(ctx);
10613 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 10614 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
10615 break;
10616 case I64_LDPC:
10617 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10618 generate_exception(ctx, EXCP_RI);
10619 } else {
10620 offset = extended ? offset : offset << 3;
d75c135e 10621 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
10622 }
10623 break;
10624 case I64_DADDIU5:
10625 check_mips_64(ctx);
10626 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 10627 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
10628 break;
10629 case I64_DADDIUPC:
10630 check_mips_64(ctx);
10631 offset = extended ? offset : offset << 2;
10632 gen_addiupc(ctx, ry, offset, 1, extended);
10633 break;
10634 case I64_DADDIUSP:
10635 check_mips_64(ctx);
10636 offset = extended ? offset : offset << 2;
d75c135e 10637 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
10638 break;
10639 }
10640}
10641#endif
10642
240ce26a 10643static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 10644{
895c2d04 10645 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
10646 int op, rx, ry, funct, sa;
10647 int16_t imm, offset;
10648
10649 ctx->opcode = (ctx->opcode << 16) | extend;
10650 op = (ctx->opcode >> 11) & 0x1f;
10651 sa = (ctx->opcode >> 22) & 0x1f;
10652 funct = (ctx->opcode >> 8) & 0x7;
10653 rx = xlat((ctx->opcode >> 8) & 0x7);
10654 ry = xlat((ctx->opcode >> 5) & 0x7);
10655 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
10656 | ((ctx->opcode >> 21) & 0x3f) << 5
10657 | (ctx->opcode & 0x1f));
10658
10659 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
10660 counterparts. */
10661 switch (op) {
10662 case M16_OPC_ADDIUSP:
d75c135e 10663 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
10664 break;
10665 case M16_OPC_ADDIUPC:
10666 gen_addiupc(ctx, rx, imm, 0, 1);
10667 break;
10668 case M16_OPC_B:
10669 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
10670 /* No delay slot, so just process as a normal instruction */
10671 break;
10672 case M16_OPC_BEQZ:
10673 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
10674 /* No delay slot, so just process as a normal instruction */
10675 break;
10676 case M16_OPC_BNEQZ:
10677 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
10678 /* No delay slot, so just process as a normal instruction */
10679 break;
10680 case M16_OPC_SHIFT:
10681 switch (ctx->opcode & 0x3) {
10682 case 0x0:
d75c135e 10683 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
10684 break;
10685 case 0x1:
10686#if defined(TARGET_MIPS64)
10687 check_mips_64(ctx);
d75c135e 10688 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10689#else
10690 generate_exception(ctx, EXCP_RI);
10691#endif
10692 break;
10693 case 0x2:
d75c135e 10694 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10695 break;
10696 case 0x3:
d75c135e 10697 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10698 break;
10699 }
10700 break;
10701#if defined(TARGET_MIPS64)
10702 case M16_OPC_LD:
10703 check_mips_64(ctx);
d75c135e 10704 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
10705 break;
10706#endif
10707 case M16_OPC_RRIA:
10708 imm = ctx->opcode & 0xf;
10709 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
10710 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
10711 imm = (int16_t) (imm << 1) >> 1;
10712 if ((ctx->opcode >> 4) & 0x1) {
10713#if defined(TARGET_MIPS64)
10714 check_mips_64(ctx);
d75c135e 10715 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10716#else
10717 generate_exception(ctx, EXCP_RI);
10718#endif
10719 } else {
d75c135e 10720 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10721 }
10722 break;
10723 case M16_OPC_ADDIU8:
d75c135e 10724 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10725 break;
10726 case M16_OPC_SLTI:
d75c135e 10727 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10728 break;
10729 case M16_OPC_SLTIU:
d75c135e 10730 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10731 break;
10732 case M16_OPC_I8:
10733 switch (funct) {
10734 case I8_BTEQZ:
10735 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
10736 break;
10737 case I8_BTNEZ:
10738 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
10739 break;
10740 case I8_SWRASP:
5c13fdfd 10741 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
10742 break;
10743 case I8_ADJSP:
d75c135e 10744 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
10745 break;
10746 case I8_SVRS:
10747 {
10748 int xsregs = (ctx->opcode >> 24) & 0x7;
10749 int aregs = (ctx->opcode >> 16) & 0xf;
10750 int do_ra = (ctx->opcode >> 6) & 0x1;
10751 int do_s0 = (ctx->opcode >> 5) & 0x1;
10752 int do_s1 = (ctx->opcode >> 4) & 0x1;
10753 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
10754 | (ctx->opcode & 0xf)) << 3;
10755
10756 if (ctx->opcode & (1 << 7)) {
10757 gen_mips16_save(ctx, xsregs, aregs,
10758 do_ra, do_s0, do_s1,
10759 framesize);
10760 } else {
10761 gen_mips16_restore(ctx, xsregs, aregs,
10762 do_ra, do_s0, do_s1,
10763 framesize);
10764 }
10765 }
10766 break;
10767 default:
10768 generate_exception(ctx, EXCP_RI);
10769 break;
10770 }
10771 break;
10772 case M16_OPC_LI:
10773 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
10774 break;
10775 case M16_OPC_CMPI:
10776 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
10777 break;
10778#if defined(TARGET_MIPS64)
10779 case M16_OPC_SD:
5c13fdfd 10780 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
10781 break;
10782#endif
10783 case M16_OPC_LB:
d75c135e 10784 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10785 break;
10786 case M16_OPC_LH:
d75c135e 10787 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
10788 break;
10789 case M16_OPC_LWSP:
d75c135e 10790 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
10791 break;
10792 case M16_OPC_LW:
d75c135e 10793 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
10794 break;
10795 case M16_OPC_LBU:
d75c135e 10796 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10797 break;
10798 case M16_OPC_LHU:
d75c135e 10799 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
10800 break;
10801 case M16_OPC_LWPC:
d75c135e 10802 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
10803 break;
10804#if defined(TARGET_MIPS64)
10805 case M16_OPC_LWU:
d75c135e 10806 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
10807 break;
10808#endif
10809 case M16_OPC_SB:
5c13fdfd 10810 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10811 break;
10812 case M16_OPC_SH:
5c13fdfd 10813 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
10814 break;
10815 case M16_OPC_SWSP:
5c13fdfd 10816 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
10817 break;
10818 case M16_OPC_SW:
5c13fdfd 10819 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
10820 break;
10821#if defined(TARGET_MIPS64)
10822 case M16_OPC_I64:
d75c135e 10823 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
10824 break;
10825#endif
10826 default:
10827 generate_exception(ctx, EXCP_RI);
10828 break;
10829 }
10830
10831 return 4;
10832}
10833
240ce26a 10834static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
10835{
10836 int rx, ry;
10837 int sa;
10838 int op, cnvt_op, op1, offset;
10839 int funct;
10840 int n_bytes;
10841
10842 op = (ctx->opcode >> 11) & 0x1f;
10843 sa = (ctx->opcode >> 2) & 0x7;
10844 sa = sa == 0 ? 8 : sa;
10845 rx = xlat((ctx->opcode >> 8) & 0x7);
10846 cnvt_op = (ctx->opcode >> 5) & 0x7;
10847 ry = xlat((ctx->opcode >> 5) & 0x7);
10848 op1 = offset = ctx->opcode & 0x1f;
10849
10850 n_bytes = 2;
10851
10852 switch (op) {
10853 case M16_OPC_ADDIUSP:
10854 {
10855 int16_t imm = ((uint8_t) ctx->opcode) << 2;
10856
d75c135e 10857 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
10858 }
10859 break;
10860 case M16_OPC_ADDIUPC:
10861 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
10862 break;
10863 case M16_OPC_B:
10864 offset = (ctx->opcode & 0x7ff) << 1;
10865 offset = (int16_t)(offset << 4) >> 4;
10866 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
10867 /* No delay slot, so just process as a normal instruction */
10868 break;
10869 case M16_OPC_JAL:
895c2d04 10870 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
10871 offset = (((ctx->opcode & 0x1f) << 21)
10872 | ((ctx->opcode >> 5) & 0x1f) << 16
10873 | offset) << 2;
620e48f6 10874 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
10875 gen_compute_branch(ctx, op, 4, rx, ry, offset);
10876 n_bytes = 4;
364d4831
NF
10877 break;
10878 case M16_OPC_BEQZ:
10879 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10880 /* No delay slot, so just process as a normal instruction */
10881 break;
10882 case M16_OPC_BNEQZ:
10883 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10884 /* No delay slot, so just process as a normal instruction */
10885 break;
10886 case M16_OPC_SHIFT:
10887 switch (ctx->opcode & 0x3) {
10888 case 0x0:
d75c135e 10889 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
10890 break;
10891 case 0x1:
10892#if defined(TARGET_MIPS64)
10893 check_mips_64(ctx);
d75c135e 10894 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10895#else
10896 generate_exception(ctx, EXCP_RI);
10897#endif
10898 break;
10899 case 0x2:
d75c135e 10900 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10901 break;
10902 case 0x3:
d75c135e 10903 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10904 break;
10905 }
10906 break;
10907#if defined(TARGET_MIPS64)
10908 case M16_OPC_LD:
10909 check_mips_64(ctx);
d75c135e 10910 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
10911 break;
10912#endif
10913 case M16_OPC_RRIA:
10914 {
10915 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
10916
10917 if ((ctx->opcode >> 4) & 1) {
10918#if defined(TARGET_MIPS64)
10919 check_mips_64(ctx);
d75c135e 10920 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10921#else
10922 generate_exception(ctx, EXCP_RI);
10923#endif
10924 } else {
d75c135e 10925 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10926 }
10927 }
10928 break;
10929 case M16_OPC_ADDIU8:
10930 {
10931 int16_t imm = (int8_t) ctx->opcode;
10932
d75c135e 10933 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10934 }
10935 break;
10936 case M16_OPC_SLTI:
10937 {
10938 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10939 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10940 }
10941 break;
10942 case M16_OPC_SLTIU:
10943 {
10944 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10945 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10946 }
10947 break;
10948 case M16_OPC_I8:
10949 {
10950 int reg32;
10951
10952 funct = (ctx->opcode >> 8) & 0x7;
10953 switch (funct) {
10954 case I8_BTEQZ:
10955 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
10956 ((int8_t)ctx->opcode) << 1);
10957 break;
10958 case I8_BTNEZ:
10959 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
10960 ((int8_t)ctx->opcode) << 1);
10961 break;
10962 case I8_SWRASP:
5c13fdfd 10963 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
10964 break;
10965 case I8_ADJSP:
d75c135e 10966 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
10967 ((int8_t)ctx->opcode) << 3);
10968 break;
10969 case I8_SVRS:
10970 {
10971 int do_ra = ctx->opcode & (1 << 6);
10972 int do_s0 = ctx->opcode & (1 << 5);
10973 int do_s1 = ctx->opcode & (1 << 4);
10974 int framesize = ctx->opcode & 0xf;
10975
10976 if (framesize == 0) {
10977 framesize = 128;
10978 } else {
10979 framesize = framesize << 3;
10980 }
10981
10982 if (ctx->opcode & (1 << 7)) {
10983 gen_mips16_save(ctx, 0, 0,
10984 do_ra, do_s0, do_s1, framesize);
10985 } else {
10986 gen_mips16_restore(ctx, 0, 0,
10987 do_ra, do_s0, do_s1, framesize);
10988 }
10989 }
10990 break;
10991 case I8_MOV32R:
10992 {
10993 int rz = xlat(ctx->opcode & 0x7);
10994
10995 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10996 ((ctx->opcode >> 5) & 0x7);
d75c135e 10997 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
10998 }
10999 break;
11000 case I8_MOVR32:
11001 reg32 = ctx->opcode & 0x1f;
d75c135e 11002 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11003 break;
11004 default:
11005 generate_exception(ctx, EXCP_RI);
11006 break;
11007 }
11008 }
11009 break;
11010 case M16_OPC_LI:
11011 {
11012 int16_t imm = (uint8_t) ctx->opcode;
11013
d75c135e 11014 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11015 }
11016 break;
11017 case M16_OPC_CMPI:
11018 {
11019 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11020 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
11021 }
11022 break;
11023#if defined(TARGET_MIPS64)
11024 case M16_OPC_SD:
11025 check_mips_64(ctx);
5c13fdfd 11026 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
11027 break;
11028#endif
11029 case M16_OPC_LB:
d75c135e 11030 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11031 break;
11032 case M16_OPC_LH:
d75c135e 11033 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
11034 break;
11035 case M16_OPC_LWSP:
d75c135e 11036 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11037 break;
11038 case M16_OPC_LW:
d75c135e 11039 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
11040 break;
11041 case M16_OPC_LBU:
d75c135e 11042 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11043 break;
11044 case M16_OPC_LHU:
d75c135e 11045 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
11046 break;
11047 case M16_OPC_LWPC:
d75c135e 11048 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11049 break;
11050#if defined (TARGET_MIPS64)
11051 case M16_OPC_LWU:
11052 check_mips_64(ctx);
d75c135e 11053 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
11054 break;
11055#endif
11056 case M16_OPC_SB:
5c13fdfd 11057 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11058 break;
11059 case M16_OPC_SH:
5c13fdfd 11060 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
11061 break;
11062 case M16_OPC_SWSP:
5c13fdfd 11063 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
11064 break;
11065 case M16_OPC_SW:
5c13fdfd 11066 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
11067 break;
11068 case M16_OPC_RRR:
11069 {
11070 int rz = xlat((ctx->opcode >> 2) & 0x7);
11071 int mips32_op;
11072
11073 switch (ctx->opcode & 0x3) {
11074 case RRR_ADDU:
11075 mips32_op = OPC_ADDU;
11076 break;
11077 case RRR_SUBU:
11078 mips32_op = OPC_SUBU;
11079 break;
11080#if defined(TARGET_MIPS64)
11081 case RRR_DADDU:
11082 mips32_op = OPC_DADDU;
11083 check_mips_64(ctx);
11084 break;
11085 case RRR_DSUBU:
11086 mips32_op = OPC_DSUBU;
11087 check_mips_64(ctx);
11088 break;
11089#endif
11090 default:
11091 generate_exception(ctx, EXCP_RI);
11092 goto done;
11093 }
11094
d75c135e 11095 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
11096 done:
11097 ;
11098 }
11099 break;
11100 case M16_OPC_RR:
11101 switch (op1) {
11102 case RR_JR:
11103 {
11104 int nd = (ctx->opcode >> 7) & 0x1;
11105 int link = (ctx->opcode >> 6) & 0x1;
11106 int ra = (ctx->opcode >> 5) & 0x1;
11107
11108 if (link) {
620e48f6 11109 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
11110 } else {
11111 op = OPC_JR;
11112 }
11113
11114 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
11115 }
11116 break;
11117 case RR_SDBBP:
11118 /* XXX: not clear which exception should be raised
11119 * when in debug mode...
11120 */
d75c135e 11121 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11122 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11123 generate_exception(ctx, EXCP_DBp);
11124 } else {
11125 generate_exception(ctx, EXCP_DBp);
11126 }
11127 break;
11128 case RR_SLT:
d75c135e 11129 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
11130 break;
11131 case RR_SLTU:
d75c135e 11132 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
11133 break;
11134 case RR_BREAK:
11135 generate_exception(ctx, EXCP_BREAK);
11136 break;
11137 case RR_SLLV:
d75c135e 11138 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
11139 break;
11140 case RR_SRLV:
d75c135e 11141 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
11142 break;
11143 case RR_SRAV:
d75c135e 11144 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
11145 break;
11146#if defined (TARGET_MIPS64)
11147 case RR_DSRL:
11148 check_mips_64(ctx);
d75c135e 11149 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
11150 break;
11151#endif
11152 case RR_CMP:
d75c135e 11153 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
11154 break;
11155 case RR_NEG:
d75c135e 11156 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
11157 break;
11158 case RR_AND:
d75c135e 11159 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
11160 break;
11161 case RR_OR:
d75c135e 11162 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
11163 break;
11164 case RR_XOR:
d75c135e 11165 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
11166 break;
11167 case RR_NOT:
d75c135e 11168 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
11169 break;
11170 case RR_MFHI:
26135ead 11171 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
11172 break;
11173 case RR_CNVT:
11174 switch (cnvt_op) {
11175 case RR_RY_CNVT_ZEB:
11176 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11177 break;
11178 case RR_RY_CNVT_ZEH:
11179 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11180 break;
11181 case RR_RY_CNVT_SEB:
11182 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11183 break;
11184 case RR_RY_CNVT_SEH:
11185 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11186 break;
11187#if defined (TARGET_MIPS64)
11188 case RR_RY_CNVT_ZEW:
11189 check_mips_64(ctx);
11190 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11191 break;
11192 case RR_RY_CNVT_SEW:
11193 check_mips_64(ctx);
11194 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11195 break;
11196#endif
11197 default:
11198 generate_exception(ctx, EXCP_RI);
11199 break;
11200 }
11201 break;
11202 case RR_MFLO:
26135ead 11203 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
11204 break;
11205#if defined (TARGET_MIPS64)
11206 case RR_DSRA:
11207 check_mips_64(ctx);
d75c135e 11208 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
11209 break;
11210 case RR_DSLLV:
11211 check_mips_64(ctx);
d75c135e 11212 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
11213 break;
11214 case RR_DSRLV:
11215 check_mips_64(ctx);
d75c135e 11216 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
11217 break;
11218 case RR_DSRAV:
11219 check_mips_64(ctx);
d75c135e 11220 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
11221 break;
11222#endif
11223 case RR_MULT:
26135ead 11224 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
11225 break;
11226 case RR_MULTU:
26135ead 11227 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
11228 break;
11229 case RR_DIV:
26135ead 11230 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
11231 break;
11232 case RR_DIVU:
26135ead 11233 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
11234 break;
11235#if defined (TARGET_MIPS64)
11236 case RR_DMULT:
11237 check_mips_64(ctx);
26135ead 11238 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
11239 break;
11240 case RR_DMULTU:
11241 check_mips_64(ctx);
26135ead 11242 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
11243 break;
11244 case RR_DDIV:
11245 check_mips_64(ctx);
26135ead 11246 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
11247 break;
11248 case RR_DDIVU:
11249 check_mips_64(ctx);
26135ead 11250 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
11251 break;
11252#endif
11253 default:
11254 generate_exception(ctx, EXCP_RI);
11255 break;
11256 }
11257 break;
11258 case M16_OPC_EXTEND:
240ce26a 11259 decode_extended_mips16_opc(env, ctx);
364d4831
NF
11260 n_bytes = 4;
11261 break;
11262#if defined(TARGET_MIPS64)
11263 case M16_OPC_I64:
11264 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 11265 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
11266 break;
11267#endif
11268 default:
11269 generate_exception(ctx, EXCP_RI);
11270 break;
11271 }
11272
11273 return n_bytes;
11274}
11275
211da992 11276/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 11277
211da992
CWR
11278/*
11279 * microMIPS32/microMIPS64 major opcodes
11280 *
11281 * 1. MIPS Architecture for Programmers Volume II-B:
11282 * The microMIPS32 Instruction Set (Revision 3.05)
11283 *
11284 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11285 *
11286 * 2. MIPS Architecture For Programmers Volume II-A:
11287 * The MIPS64 Instruction Set (Revision 3.51)
11288 */
6af0bf9c 11289
3c824109
NF
11290enum {
11291 POOL32A = 0x00,
11292 POOL16A = 0x01,
11293 LBU16 = 0x02,
11294 MOVE16 = 0x03,
11295 ADDI32 = 0x04,
11296 LBU32 = 0x05,
11297 SB32 = 0x06,
11298 LB32 = 0x07,
11299
11300 POOL32B = 0x08,
11301 POOL16B = 0x09,
11302 LHU16 = 0x0a,
11303 ANDI16 = 0x0b,
11304 ADDIU32 = 0x0c,
11305 LHU32 = 0x0d,
11306 SH32 = 0x0e,
11307 LH32 = 0x0f,
11308
11309 POOL32I = 0x10,
11310 POOL16C = 0x11,
11311 LWSP16 = 0x12,
11312 POOL16D = 0x13,
11313 ORI32 = 0x14,
11314 POOL32F = 0x15,
211da992
CWR
11315 POOL32S = 0x16, /* MIPS64 */
11316 DADDIU32 = 0x17, /* MIPS64 */
3c824109 11317
211da992 11318 /* 0x1f is reserved */
3c824109
NF
11319 POOL32C = 0x18,
11320 LWGP16 = 0x19,
11321 LW16 = 0x1a,
11322 POOL16E = 0x1b,
11323 XORI32 = 0x1c,
11324 JALS32 = 0x1d,
11325 ADDIUPC = 0x1e,
3c824109
NF
11326
11327 /* 0x20 is reserved */
11328 RES_20 = 0x20,
11329 POOL16F = 0x21,
11330 SB16 = 0x22,
11331 BEQZ16 = 0x23,
11332 SLTI32 = 0x24,
11333 BEQ32 = 0x25,
11334 SWC132 = 0x26,
11335 LWC132 = 0x27,
11336
11337 /* 0x28 and 0x29 are reserved */
11338 RES_28 = 0x28,
11339 RES_29 = 0x29,
11340 SH16 = 0x2a,
11341 BNEZ16 = 0x2b,
11342 SLTIU32 = 0x2c,
11343 BNE32 = 0x2d,
11344 SDC132 = 0x2e,
11345 LDC132 = 0x2f,
11346
11347 /* 0x30 and 0x31 are reserved */
11348 RES_30 = 0x30,
11349 RES_31 = 0x31,
11350 SWSP16 = 0x32,
11351 B16 = 0x33,
11352 ANDI32 = 0x34,
11353 J32 = 0x35,
211da992
CWR
11354 SD32 = 0x36, /* MIPS64 */
11355 LD32 = 0x37, /* MIPS64 */
3c824109
NF
11356
11357 /* 0x38 and 0x39 are reserved */
11358 RES_38 = 0x38,
11359 RES_39 = 0x39,
11360 SW16 = 0x3a,
11361 LI16 = 0x3b,
11362 JALX32 = 0x3c,
11363 JAL32 = 0x3d,
11364 SW32 = 0x3e,
11365 LW32 = 0x3f
11366};
11367
11368/* POOL32A encoding of minor opcode field */
11369
11370enum {
11371 /* These opcodes are distinguished only by bits 9..6; those bits are
11372 * what are recorded below. */
11373 SLL32 = 0x0,
11374 SRL32 = 0x1,
11375 SRA = 0x2,
11376 ROTR = 0x3,
11377
11378 SLLV = 0x0,
11379 SRLV = 0x1,
11380 SRAV = 0x2,
11381 ROTRV = 0x3,
11382 ADD = 0x4,
11383 ADDU32 = 0x5,
11384 SUB = 0x6,
11385 SUBU32 = 0x7,
11386 MUL = 0x8,
11387 AND = 0x9,
11388 OR32 = 0xa,
11389 NOR = 0xb,
11390 XOR32 = 0xc,
11391 SLT = 0xd,
11392 SLTU = 0xe,
11393
11394 MOVN = 0x0,
11395 MOVZ = 0x1,
11396 LWXS = 0x4,
11397
11398 /* The following can be distinguished by their lower 6 bits. */
11399 INS = 0x0c,
11400 EXT = 0x2c,
11401 POOL32AXF = 0x3c
11402};
11403
11404/* POOL32AXF encoding of minor opcode field extension */
11405
d132c79f
CWR
11406/*
11407 * 1. MIPS Architecture for Programmers Volume II-B:
11408 * The microMIPS32 Instruction Set (Revision 3.05)
11409 *
11410 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11411 *
11412 * 2. MIPS Architecture for Programmers VolumeIV-e:
11413 * The MIPS DSP Application-Specific Extension
11414 * to the microMIPS32 Architecture (Revision 2.34)
11415 *
11416 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11417 */
11418
3c824109
NF
11419enum {
11420 /* bits 11..6 */
11421 TEQ = 0x00,
11422 TGE = 0x08,
11423 TGEU = 0x10,
11424 TLT = 0x20,
11425 TLTU = 0x28,
11426 TNE = 0x30,
11427
11428 MFC0 = 0x03,
11429 MTC0 = 0x0b,
11430
d132c79f
CWR
11431 /* begin of microMIPS32 DSP */
11432
3c824109
NF
11433 /* bits 13..12 for 0x01 */
11434 MFHI_ACC = 0x0,
11435 MFLO_ACC = 0x1,
11436 MTHI_ACC = 0x2,
11437 MTLO_ACC = 0x3,
11438
11439 /* bits 13..12 for 0x2a */
11440 MADD_ACC = 0x0,
11441 MADDU_ACC = 0x1,
11442 MSUB_ACC = 0x2,
11443 MSUBU_ACC = 0x3,
11444
11445 /* bits 13..12 for 0x32 */
11446 MULT_ACC = 0x0,
6801038b 11447 MULTU_ACC = 0x1,
3c824109 11448
d132c79f
CWR
11449 /* end of microMIPS32 DSP */
11450
3c824109
NF
11451 /* bits 15..12 for 0x2c */
11452 SEB = 0x2,
11453 SEH = 0x3,
11454 CLO = 0x4,
11455 CLZ = 0x5,
11456 RDHWR = 0x6,
11457 WSBH = 0x7,
11458 MULT = 0x8,
11459 MULTU = 0x9,
11460 DIV = 0xa,
11461 DIVU = 0xb,
11462 MADD = 0xc,
11463 MADDU = 0xd,
11464 MSUB = 0xe,
11465 MSUBU = 0xf,
11466
11467 /* bits 15..12 for 0x34 */
11468 MFC2 = 0x4,
11469 MTC2 = 0x5,
11470 MFHC2 = 0x8,
11471 MTHC2 = 0x9,
11472 CFC2 = 0xc,
11473 CTC2 = 0xd,
11474
11475 /* bits 15..12 for 0x3c */
11476 JALR = 0x0,
11477 JR = 0x0, /* alias */
11478 JALR_HB = 0x1,
11479 JALRS = 0x4,
11480 JALRS_HB = 0x5,
11481
11482 /* bits 15..12 for 0x05 */
11483 RDPGPR = 0xe,
11484 WRPGPR = 0xf,
11485
11486 /* bits 15..12 for 0x0d */
11487 TLBP = 0x0,
11488 TLBR = 0x1,
11489 TLBWI = 0x2,
11490 TLBWR = 0x3,
11491 WAIT = 0x9,
11492 IRET = 0xd,
11493 DERET = 0xe,
11494 ERET = 0xf,
11495
11496 /* bits 15..12 for 0x15 */
11497 DMT = 0x0,
11498 DVPE = 0x1,
11499 EMT = 0x2,
11500 EVPE = 0x3,
11501
11502 /* bits 15..12 for 0x1d */
11503 DI = 0x4,
11504 EI = 0x5,
11505
11506 /* bits 15..12 for 0x2d */
11507 SYNC = 0x6,
11508 SYSCALL = 0x8,
11509 SDBBP = 0xd,
11510
11511 /* bits 15..12 for 0x35 */
11512 MFHI32 = 0x0,
11513 MFLO32 = 0x1,
11514 MTHI32 = 0x2,
11515 MTLO32 = 0x3,
11516};
11517
11518/* POOL32B encoding of minor opcode field (bits 15..12) */
11519
11520enum {
11521 LWC2 = 0x0,
11522 LWP = 0x1,
11523 LDP = 0x4,
11524 LWM32 = 0x5,
11525 CACHE = 0x6,
11526 LDM = 0x7,
11527 SWC2 = 0x8,
11528 SWP = 0x9,
11529 SDP = 0xc,
11530 SWM32 = 0xd,
11531 SDM = 0xf
11532};
11533
11534/* POOL32C encoding of minor opcode field (bits 15..12) */
11535
11536enum {
11537 LWL = 0x0,
11538 SWL = 0x8,
11539 LWR = 0x1,
11540 SWR = 0x9,
11541 PREF = 0x2,
11542 /* 0xa is reserved */
11543 LL = 0x3,
11544 SC = 0xb,
11545 LDL = 0x4,
11546 SDL = 0xc,
11547 LDR = 0x5,
11548 SDR = 0xd,
11549 /* 0x6 is reserved */
11550 LWU = 0xe,
11551 LLD = 0x7,
11552 SCD = 0xf
11553};
11554
11555/* POOL32F encoding of minor opcode field (bits 5..0) */
11556
11557enum {
11558 /* These are the bit 7..6 values */
11559 ADD_FMT = 0x0,
11560 MOVN_FMT = 0x0,
11561
11562 SUB_FMT = 0x1,
11563 MOVZ_FMT = 0x1,
11564
11565 MUL_FMT = 0x2,
11566
11567 DIV_FMT = 0x3,
11568
11569 /* These are the bit 8..6 values */
11570 RSQRT2_FMT = 0x0,
11571 MOVF_FMT = 0x0,
11572
11573 LWXC1 = 0x1,
11574 MOVT_FMT = 0x1,
11575
11576 PLL_PS = 0x2,
11577 SWXC1 = 0x2,
11578
11579 PLU_PS = 0x3,
11580 LDXC1 = 0x3,
11581
11582 PUL_PS = 0x4,
11583 SDXC1 = 0x4,
11584 RECIP2_FMT = 0x4,
11585
11586 PUU_PS = 0x5,
11587 LUXC1 = 0x5,
11588
11589 CVT_PS_S = 0x6,
11590 SUXC1 = 0x6,
11591 ADDR_PS = 0x6,
11592 PREFX = 0x6,
11593
11594 MULR_PS = 0x7,
11595
11596 MADD_S = 0x01,
11597 MADD_D = 0x09,
11598 MADD_PS = 0x11,
11599 ALNV_PS = 0x19,
11600 MSUB_S = 0x21,
11601 MSUB_D = 0x29,
11602 MSUB_PS = 0x31,
11603
11604 NMADD_S = 0x02,
11605 NMADD_D = 0x0a,
11606 NMADD_PS = 0x12,
11607 NMSUB_S = 0x22,
11608 NMSUB_D = 0x2a,
11609 NMSUB_PS = 0x32,
11610
11611 POOL32FXF = 0x3b,
11612
11613 CABS_COND_FMT = 0x1c, /* MIPS3D */
11614 C_COND_FMT = 0x3c
11615};
11616
11617/* POOL32Fxf encoding of minor opcode extension field */
11618
11619enum {
11620 CVT_L = 0x04,
11621 RSQRT_FMT = 0x08,
11622 FLOOR_L = 0x0c,
11623 CVT_PW_PS = 0x1c,
11624 CVT_W = 0x24,
11625 SQRT_FMT = 0x28,
11626 FLOOR_W = 0x2c,
11627 CVT_PS_PW = 0x3c,
11628 CFC1 = 0x40,
11629 RECIP_FMT = 0x48,
11630 CEIL_L = 0x4c,
11631 CTC1 = 0x60,
11632 CEIL_W = 0x6c,
11633 MFC1 = 0x80,
11634 CVT_S_PL = 0x84,
11635 TRUNC_L = 0x8c,
11636 MTC1 = 0xa0,
11637 CVT_S_PU = 0xa4,
11638 TRUNC_W = 0xac,
11639 MFHC1 = 0xc0,
11640 ROUND_L = 0xcc,
11641 MTHC1 = 0xe0,
11642 ROUND_W = 0xec,
11643
11644 MOV_FMT = 0x01,
11645 MOVF = 0x05,
11646 ABS_FMT = 0x0d,
11647 RSQRT1_FMT = 0x1d,
11648 MOVT = 0x25,
11649 NEG_FMT = 0x2d,
11650 CVT_D = 0x4d,
11651 RECIP1_FMT = 0x5d,
11652 CVT_S = 0x6d
11653};
11654
11655/* POOL32I encoding of minor opcode field (bits 25..21) */
11656
11657enum {
11658 BLTZ = 0x00,
11659 BLTZAL = 0x01,
11660 BGEZ = 0x02,
11661 BGEZAL = 0x03,
11662 BLEZ = 0x04,
11663 BNEZC = 0x05,
11664 BGTZ = 0x06,
11665 BEQZC = 0x07,
11666 TLTI = 0x08,
11667 TGEI = 0x09,
11668 TLTIU = 0x0a,
11669 TGEIU = 0x0b,
11670 TNEI = 0x0c,
11671 LUI = 0x0d,
11672 TEQI = 0x0e,
11673 SYNCI = 0x10,
11674 BLTZALS = 0x11,
11675 BGEZALS = 0x13,
11676 BC2F = 0x14,
11677 BC2T = 0x15,
11678 BPOSGE64 = 0x1a,
11679 BPOSGE32 = 0x1b,
11680 /* These overlap and are distinguished by bit16 of the instruction */
11681 BC1F = 0x1c,
11682 BC1T = 0x1d,
11683 BC1ANY2F = 0x1c,
11684 BC1ANY2T = 0x1d,
11685 BC1ANY4F = 0x1e,
11686 BC1ANY4T = 0x1f
11687};
11688
11689/* POOL16A encoding of minor opcode field */
11690
11691enum {
11692 ADDU16 = 0x0,
11693 SUBU16 = 0x1
11694};
11695
11696/* POOL16B encoding of minor opcode field */
11697
11698enum {
11699 SLL16 = 0x0,
11700 SRL16 = 0x1
11701};
11702
11703/* POOL16C encoding of minor opcode field */
11704
11705enum {
11706 NOT16 = 0x00,
11707 XOR16 = 0x04,
11708 AND16 = 0x08,
11709 OR16 = 0x0c,
11710 LWM16 = 0x10,
11711 SWM16 = 0x14,
11712 JR16 = 0x18,
11713 JRC16 = 0x1a,
11714 JALR16 = 0x1c,
11715 JALR16S = 0x1e,
11716 MFHI16 = 0x20,
11717 MFLO16 = 0x24,
11718 BREAK16 = 0x28,
11719 SDBBP16 = 0x2c,
11720 JRADDIUSP = 0x30
11721};
11722
11723/* POOL16D encoding of minor opcode field */
11724
11725enum {
11726 ADDIUS5 = 0x0,
11727 ADDIUSP = 0x1
11728};
11729
11730/* POOL16E encoding of minor opcode field */
11731
11732enum {
11733 ADDIUR2 = 0x0,
11734 ADDIUR1SP = 0x1
11735};
11736
11737static int mmreg (int r)
11738{
11739 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11740
11741 return map[r];
11742}
11743
11744/* Used for 16-bit store instructions. */
11745static int mmreg2 (int r)
11746{
11747 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11748
11749 return map[r];
11750}
11751
11752#define uMIPS_RD(op) ((op >> 7) & 0x7)
11753#define uMIPS_RS(op) ((op >> 4) & 0x7)
11754#define uMIPS_RS2(op) uMIPS_RS(op)
11755#define uMIPS_RS1(op) ((op >> 1) & 0x7)
11756#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11757#define uMIPS_RS5(op) (op & 0x1f)
11758
11759/* Signed immediate */
11760#define SIMM(op, start, width) \
11761 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11762 << (32-width)) \
11763 >> (32-width))
11764/* Zero-extended immediate */
11765#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11766
d75c135e 11767static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
11768{
11769 int rd = mmreg(uMIPS_RD(ctx->opcode));
11770
d75c135e 11771 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
11772}
11773
d75c135e 11774static void gen_addiur2(DisasContext *ctx)
3c824109
NF
11775{
11776 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11777 int rd = mmreg(uMIPS_RD(ctx->opcode));
11778 int rs = mmreg(uMIPS_RS(ctx->opcode));
11779
d75c135e 11780 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
11781}
11782
d75c135e 11783static void gen_addiusp(DisasContext *ctx)
3c824109
NF
11784{
11785 int encoded = ZIMM(ctx->opcode, 1, 9);
11786 int decoded;
11787
11788 if (encoded <= 1) {
11789 decoded = 256 + encoded;
11790 } else if (encoded <= 255) {
11791 decoded = encoded;
11792 } else if (encoded <= 509) {
11793 decoded = encoded - 512;
11794 } else {
11795 decoded = encoded - 768;
11796 }
11797
d75c135e 11798 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
11799}
11800
d75c135e 11801static void gen_addius5(DisasContext *ctx)
3c824109
NF
11802{
11803 int imm = SIMM(ctx->opcode, 1, 4);
11804 int rd = (ctx->opcode >> 5) & 0x1f;
11805
d75c135e 11806 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
11807}
11808
d75c135e 11809static void gen_andi16(DisasContext *ctx)
3c824109
NF
11810{
11811 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11812 31, 32, 63, 64, 255, 32768, 65535 };
11813 int rd = mmreg(uMIPS_RD(ctx->opcode));
11814 int rs = mmreg(uMIPS_RS(ctx->opcode));
11815 int encoded = ZIMM(ctx->opcode, 0, 4);
11816
d75c135e 11817 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
11818}
11819
11820static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
11821 int base, int16_t offset)
11822{
e1050a76 11823 const char *opn = "ldst_multiple";
3c824109
NF
11824 TCGv t0, t1;
11825 TCGv_i32 t2;
11826
11827 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11828 generate_exception(ctx, EXCP_RI);
11829 return;
11830 }
11831
11832 t0 = tcg_temp_new();
11833
11834 gen_base_offset_addr(ctx, t0, base, offset);
11835
11836 t1 = tcg_const_tl(reglist);
11837 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 11838
3c824109
NF
11839 save_cpu_state(ctx, 1);
11840 switch (opc) {
11841 case LWM32:
895c2d04 11842 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 11843 opn = "lwm";
3c824109
NF
11844 break;
11845 case SWM32:
895c2d04 11846 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 11847 opn = "swm";
3c824109
NF
11848 break;
11849#ifdef TARGET_MIPS64
11850 case LDM:
895c2d04 11851 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 11852 opn = "ldm";
3c824109
NF
11853 break;
11854 case SDM:
895c2d04 11855 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 11856 opn = "sdm";
3c824109 11857 break;
6af0bf9c 11858#endif
3c824109 11859 }
e1050a76 11860 (void)opn;
3c824109
NF
11861 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
11862 tcg_temp_free(t0);
33087598 11863 tcg_temp_free(t1);
3c824109
NF
11864 tcg_temp_free_i32(t2);
11865}
6af0bf9c 11866
3c824109 11867
240ce26a 11868static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 11869{
3c824109
NF
11870 int rd = mmreg((ctx->opcode >> 3) & 0x7);
11871 int rs = mmreg(ctx->opcode & 0x7);
11872 int opc;
6af0bf9c 11873
3c824109
NF
11874 switch (((ctx->opcode) >> 4) & 0x3f) {
11875 case NOT16 + 0:
11876 case NOT16 + 1:
11877 case NOT16 + 2:
11878 case NOT16 + 3:
d75c135e 11879 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
11880 break;
11881 case XOR16 + 0:
11882 case XOR16 + 1:
11883 case XOR16 + 2:
11884 case XOR16 + 3:
d75c135e 11885 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
11886 break;
11887 case AND16 + 0:
11888 case AND16 + 1:
11889 case AND16 + 2:
11890 case AND16 + 3:
d75c135e 11891 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
11892 break;
11893 case OR16 + 0:
11894 case OR16 + 1:
11895 case OR16 + 2:
11896 case OR16 + 3:
d75c135e 11897 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
11898 break;
11899 case LWM16 + 0:
11900 case LWM16 + 1:
11901 case LWM16 + 2:
11902 case LWM16 + 3:
11903 {
11904 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11905 int offset = ZIMM(ctx->opcode, 0, 4);
11906
11907 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
11908 29, offset << 2);
11909 }
11910 break;
11911 case SWM16 + 0:
11912 case SWM16 + 1:
11913 case SWM16 + 2:
11914 case SWM16 + 3:
11915 {
11916 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11917 int offset = ZIMM(ctx->opcode, 0, 4);
11918
11919 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
11920 29, offset << 2);
11921 }
11922 break;
11923 case JR16 + 0:
11924 case JR16 + 1:
11925 {
11926 int reg = ctx->opcode & 0x1f;
11927
11928 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11929 }
3c824109
NF
11930 break;
11931 case JRC16 + 0:
11932 case JRC16 + 1:
11933 {
11934 int reg = ctx->opcode & 0x1f;
11935
11936 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11937 /* Let normal delay slot handling in our caller take us
11938 to the branch target. */
11939 }
11940 break;
11941 case JALR16 + 0:
11942 case JALR16 + 1:
11943 opc = OPC_JALR;
11944 goto do_jalr;
11945 case JALR16S + 0:
11946 case JALR16S + 1:
11947 opc = OPC_JALRS;
11948 do_jalr:
11949 {
11950 int reg = ctx->opcode & 0x1f;
11951
11952 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
11953 }
3c824109
NF
11954 break;
11955 case MFHI16 + 0:
11956 case MFHI16 + 1:
26135ead 11957 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11958 break;
11959 case MFLO16 + 0:
11960 case MFLO16 + 1:
26135ead 11961 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11962 break;
11963 case BREAK16:
11964 generate_exception(ctx, EXCP_BREAK);
11965 break;
11966 case SDBBP16:
11967 /* XXX: not clear which exception should be raised
11968 * when in debug mode...
11969 */
d75c135e 11970 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11971 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11972 generate_exception(ctx, EXCP_DBp);
11973 } else {
11974 generate_exception(ctx, EXCP_DBp);
11975 }
11976 break;
11977 case JRADDIUSP + 0:
11978 case JRADDIUSP + 1:
11979 {
11980 int imm = ZIMM(ctx->opcode, 0, 5);
11981
11982 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 11983 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
11984 /* Let normal delay slot handling in our caller take us
11985 to the branch target. */
11986 }
11987 break;
11988 default:
11989 generate_exception(ctx, EXCP_RI);
11990 break;
11991 }
11992}
11993
11994static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
11995{
11996 TCGv t0 = tcg_temp_new();
11997 TCGv t1 = tcg_temp_new();
11998
11999 gen_load_gpr(t0, base);
12000
12001 if (index != 0) {
12002 gen_load_gpr(t1, index);
12003 tcg_gen_shli_tl(t1, t1, 2);
12004 gen_op_addr_add(ctx, t0, t1, t0);
12005 }
12006
5f68f5ae 12007 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12008 gen_store_gpr(t1, rd);
12009
12010 tcg_temp_free(t0);
12011 tcg_temp_free(t1);
12012}
12013
12014static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12015 int base, int16_t offset)
12016{
12017 const char *opn = "ldst_pair";
12018 TCGv t0, t1;
12019
36c6711b 12020 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 12021 generate_exception(ctx, EXCP_RI);
d796321b
FB
12022 return;
12023 }
12024
3c824109
NF
12025 t0 = tcg_temp_new();
12026 t1 = tcg_temp_new();
8e9ade68 12027
3c824109
NF
12028 gen_base_offset_addr(ctx, t0, base, offset);
12029
12030 switch (opc) {
12031 case LWP:
36c6711b
EJ
12032 if (rd == base) {
12033 generate_exception(ctx, EXCP_RI);
12034 return;
12035 }
5f68f5ae 12036 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12037 gen_store_gpr(t1, rd);
12038 tcg_gen_movi_tl(t1, 4);
12039 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12040 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
12041 gen_store_gpr(t1, rd+1);
12042 opn = "lwp";
12043 break;
12044 case SWP:
3c824109 12045 gen_load_gpr(t1, rd);
5f68f5ae 12046 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12047 tcg_gen_movi_tl(t1, 4);
12048 gen_op_addr_add(ctx, t0, t0, t1);
12049 gen_load_gpr(t1, rd+1);
5f68f5ae 12050 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
12051 opn = "swp";
12052 break;
12053#ifdef TARGET_MIPS64
12054 case LDP:
36c6711b
EJ
12055 if (rd == base) {
12056 generate_exception(ctx, EXCP_RI);
12057 return;
12058 }
5f68f5ae 12059 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12060 gen_store_gpr(t1, rd);
12061 tcg_gen_movi_tl(t1, 8);
12062 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 12063 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12064 gen_store_gpr(t1, rd+1);
12065 opn = "ldp";
12066 break;
12067 case SDP:
3c824109 12068 gen_load_gpr(t1, rd);
5f68f5ae 12069 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12070 tcg_gen_movi_tl(t1, 8);
12071 gen_op_addr_add(ctx, t0, t0, t1);
12072 gen_load_gpr(t1, rd+1);
5f68f5ae 12073 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
12074 opn = "sdp";
12075 break;
12076#endif
6af0bf9c 12077 }
2abf314d 12078 (void)opn; /* avoid a compiler warning */
3c824109
NF
12079 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12080 tcg_temp_free(t0);
12081 tcg_temp_free(t1);
12082}
618b0fe9 12083
240ce26a 12084static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
12085{
12086 int extension = (ctx->opcode >> 6) & 0x3f;
12087 int minor = (ctx->opcode >> 12) & 0xf;
12088 uint32_t mips32_op;
12089
12090 switch (extension) {
12091 case TEQ:
12092 mips32_op = OPC_TEQ;
12093 goto do_trap;
12094 case TGE:
12095 mips32_op = OPC_TGE;
12096 goto do_trap;
12097 case TGEU:
12098 mips32_op = OPC_TGEU;
12099 goto do_trap;
12100 case TLT:
12101 mips32_op = OPC_TLT;
12102 goto do_trap;
12103 case TLTU:
12104 mips32_op = OPC_TLTU;
12105 goto do_trap;
12106 case TNE:
12107 mips32_op = OPC_TNE;
12108 do_trap:
12109 gen_trap(ctx, mips32_op, rs, rt, -1);
12110 break;
12111#ifndef CONFIG_USER_ONLY
12112 case MFC0:
12113 case MFC0 + 32:
2e15497c 12114 check_cp0_enabled(ctx);
3c824109
NF
12115 if (rt == 0) {
12116 /* Treat as NOP. */
12117 break;
12118 }
d75c135e 12119 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12120 break;
12121 case MTC0:
12122 case MTC0 + 32:
2e15497c 12123 check_cp0_enabled(ctx);
3c824109
NF
12124 {
12125 TCGv t0 = tcg_temp_new();
618b0fe9 12126
3c824109 12127 gen_load_gpr(t0, rt);
d75c135e 12128 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
12129 tcg_temp_free(t0);
12130 }
12131 break;
12132#endif
a1fc6246
LA
12133 case 0x2a:
12134 switch (minor & 3) {
12135 case MADD_ACC:
12136 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12137 break;
12138 case MADDU_ACC:
12139 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12140 break;
12141 case MSUB_ACC:
12142 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12143 break;
12144 case MSUBU_ACC:
12145 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12146 break;
12147 default:
12148 goto pool32axf_invalid;
12149 }
12150 break;
12151 case 0x32:
12152 switch (minor & 3) {
12153 case MULT_ACC:
12154 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12155 break;
12156 case MULTU_ACC:
12157 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12158 break;
12159 default:
12160 goto pool32axf_invalid;
12161 }
12162 break;
3c824109
NF
12163 case 0x2c:
12164 switch (minor) {
12165 case SEB:
12166 gen_bshfl(ctx, OPC_SEB, rs, rt);
12167 break;
12168 case SEH:
12169 gen_bshfl(ctx, OPC_SEH, rs, rt);
12170 break;
12171 case CLO:
12172 mips32_op = OPC_CLO;
12173 goto do_cl;
12174 case CLZ:
12175 mips32_op = OPC_CLZ;
12176 do_cl:
d75c135e 12177 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12178 gen_cl(ctx, mips32_op, rt, rs);
12179 break;
12180 case RDHWR:
d75c135e 12181 gen_rdhwr(ctx, rt, rs);
3c824109
NF
12182 break;
12183 case WSBH:
12184 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12185 break;
12186 case MULT:
12187 mips32_op = OPC_MULT;
26135ead 12188 goto do_mul;
3c824109
NF
12189 case MULTU:
12190 mips32_op = OPC_MULTU;
26135ead 12191 goto do_mul;
3c824109
NF
12192 case DIV:
12193 mips32_op = OPC_DIV;
26135ead 12194 goto do_div;
3c824109
NF
12195 case DIVU:
12196 mips32_op = OPC_DIVU;
26135ead
RS
12197 goto do_div;
12198 do_div:
12199 check_insn(ctx, ISA_MIPS32);
12200 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12201 break;
3c824109
NF
12202 case MADD:
12203 mips32_op = OPC_MADD;
26135ead 12204 goto do_mul;
3c824109
NF
12205 case MADDU:
12206 mips32_op = OPC_MADDU;
26135ead 12207 goto do_mul;
3c824109
NF
12208 case MSUB:
12209 mips32_op = OPC_MSUB;
26135ead 12210 goto do_mul;
3c824109
NF
12211 case MSUBU:
12212 mips32_op = OPC_MSUBU;
26135ead 12213 do_mul:
d75c135e 12214 check_insn(ctx, ISA_MIPS32);
a1fc6246 12215 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
12216 break;
12217 default:
12218 goto pool32axf_invalid;
12219 }
12220 break;
12221 case 0x34:
12222 switch (minor) {
12223 case MFC2:
12224 case MTC2:
12225 case MFHC2:
12226 case MTHC2:
12227 case CFC2:
12228 case CTC2:
12229 generate_exception_err(ctx, EXCP_CpU, 2);
12230 break;
12231 default:
12232 goto pool32axf_invalid;
12233 }
12234 break;
12235 case 0x3c:
12236 switch (minor) {
12237 case JALR:
12238 case JALR_HB:
12239 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
12240 break;
12241 case JALRS:
12242 case JALRS_HB:
12243 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
12244 break;
12245 default:
12246 goto pool32axf_invalid;
12247 }
12248 break;
12249 case 0x05:
12250 switch (minor) {
12251 case RDPGPR:
2e15497c 12252 check_cp0_enabled(ctx);
d75c135e 12253 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12254 gen_load_srsgpr(rt, rs);
12255 break;
12256 case WRPGPR:
2e15497c 12257 check_cp0_enabled(ctx);
d75c135e 12258 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
12259 gen_store_srsgpr(rt, rs);
12260 break;
12261 default:
12262 goto pool32axf_invalid;
12263 }
12264 break;
12265#ifndef CONFIG_USER_ONLY
12266 case 0x0d:
12267 switch (minor) {
12268 case TLBP:
12269 mips32_op = OPC_TLBP;
12270 goto do_cp0;
12271 case TLBR:
12272 mips32_op = OPC_TLBR;
12273 goto do_cp0;
12274 case TLBWI:
12275 mips32_op = OPC_TLBWI;
12276 goto do_cp0;
12277 case TLBWR:
12278 mips32_op = OPC_TLBWR;
12279 goto do_cp0;
12280 case WAIT:
12281 mips32_op = OPC_WAIT;
12282 goto do_cp0;
12283 case DERET:
12284 mips32_op = OPC_DERET;
12285 goto do_cp0;
12286 case ERET:
12287 mips32_op = OPC_ERET;
12288 do_cp0:
12289 gen_cp0(env, ctx, mips32_op, rt, rs);
12290 break;
12291 default:
12292 goto pool32axf_invalid;
12293 }
12294 break;
12295 case 0x1d:
12296 switch (minor) {
12297 case DI:
2e15497c 12298 check_cp0_enabled(ctx);
3c824109
NF
12299 {
12300 TCGv t0 = tcg_temp_new();
12301
12302 save_cpu_state(ctx, 1);
895c2d04 12303 gen_helper_di(t0, cpu_env);
3c824109
NF
12304 gen_store_gpr(t0, rs);
12305 /* Stop translation as we may have switched the execution mode */
12306 ctx->bstate = BS_STOP;
12307 tcg_temp_free(t0);
12308 }
12309 break;
12310 case EI:
2e15497c 12311 check_cp0_enabled(ctx);
3c824109
NF
12312 {
12313 TCGv t0 = tcg_temp_new();
12314
12315 save_cpu_state(ctx, 1);
895c2d04 12316 gen_helper_ei(t0, cpu_env);
3c824109
NF
12317 gen_store_gpr(t0, rs);
12318 /* Stop translation as we may have switched the execution mode */
12319 ctx->bstate = BS_STOP;
12320 tcg_temp_free(t0);
12321 }
12322 break;
12323 default:
12324 goto pool32axf_invalid;
12325 }
12326 break;
12327#endif
12328 case 0x2d:
12329 switch (minor) {
12330 case SYNC:
12331 /* NOP */
12332 break;
12333 case SYSCALL:
12334 generate_exception(ctx, EXCP_SYSCALL);
12335 ctx->bstate = BS_STOP;
12336 break;
12337 case SDBBP:
d75c135e 12338 check_insn(ctx, ISA_MIPS32);
3c824109
NF
12339 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12340 generate_exception(ctx, EXCP_DBp);
12341 } else {
12342 generate_exception(ctx, EXCP_DBp);
12343 }
12344 break;
12345 default:
12346 goto pool32axf_invalid;
12347 }
12348 break;
a1fc6246 12349 case 0x01:
26135ead 12350 switch (minor & 3) {
a1fc6246 12351 case MFHI_ACC:
26135ead 12352 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 12353 break;
a1fc6246 12354 case MFLO_ACC:
26135ead 12355 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 12356 break;
a1fc6246 12357 case MTHI_ACC:
26135ead 12358 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 12359 break;
a1fc6246 12360 case MTLO_ACC:
26135ead 12361 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
12362 break;
12363 default:
12364 goto pool32axf_invalid;
12365 }
12366 break;
a1fc6246
LA
12367 case 0x35:
12368 switch (minor) {
12369 case MFHI32:
12370 gen_HILO(ctx, OPC_MFHI, 0, rs);
12371 break;
12372 case MFLO32:
12373 gen_HILO(ctx, OPC_MFLO, 0, rs);
12374 break;
12375 case MTHI32:
12376 gen_HILO(ctx, OPC_MTHI, 0, rs);
12377 break;
12378 case MTLO32:
12379 gen_HILO(ctx, OPC_MTLO, 0, rs);
12380 break;
12381 default:
12382 goto pool32axf_invalid;
12383 }
12384 break;
3c824109
NF
12385 default:
12386 pool32axf_invalid:
12387 MIPS_INVAL("pool32axf");
12388 generate_exception(ctx, EXCP_RI);
12389 break;
12390 }
12391}
12392
12393/* Values for microMIPS fmt field. Variable-width, depending on which
12394 formats the instruction supports. */
12395
12396enum {
12397 FMT_SD_S = 0,
12398 FMT_SD_D = 1,
12399
12400 FMT_SDPS_S = 0,
12401 FMT_SDPS_D = 1,
12402 FMT_SDPS_PS = 2,
12403
12404 FMT_SWL_S = 0,
12405 FMT_SWL_W = 1,
12406 FMT_SWL_L = 2,
12407
12408 FMT_DWL_D = 0,
12409 FMT_DWL_W = 1,
12410 FMT_DWL_L = 2
12411};
12412
d75c135e 12413static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
12414{
12415 int extension = (ctx->opcode >> 6) & 0x3ff;
12416 uint32_t mips32_op;
12417
12418#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12419#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12420#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12421
12422 switch (extension) {
12423 case FLOAT_1BIT_FMT(CFC1, 0):
12424 mips32_op = OPC_CFC1;
12425 goto do_cp1;
12426 case FLOAT_1BIT_FMT(CTC1, 0):
12427 mips32_op = OPC_CTC1;
12428 goto do_cp1;
12429 case FLOAT_1BIT_FMT(MFC1, 0):
12430 mips32_op = OPC_MFC1;
12431 goto do_cp1;
12432 case FLOAT_1BIT_FMT(MTC1, 0):
12433 mips32_op = OPC_MTC1;
12434 goto do_cp1;
12435 case FLOAT_1BIT_FMT(MFHC1, 0):
12436 mips32_op = OPC_MFHC1;
12437 goto do_cp1;
12438 case FLOAT_1BIT_FMT(MTHC1, 0):
12439 mips32_op = OPC_MTHC1;
12440 do_cp1:
12441 gen_cp1(ctx, mips32_op, rt, rs);
12442 break;
12443
12444 /* Reciprocal square root */
12445 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12446 mips32_op = OPC_RSQRT_S;
12447 goto do_unaryfp;
12448 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12449 mips32_op = OPC_RSQRT_D;
12450 goto do_unaryfp;
12451
12452 /* Square root */
12453 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12454 mips32_op = OPC_SQRT_S;
12455 goto do_unaryfp;
12456 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12457 mips32_op = OPC_SQRT_D;
12458 goto do_unaryfp;
12459
12460 /* Reciprocal */
12461 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12462 mips32_op = OPC_RECIP_S;
12463 goto do_unaryfp;
12464 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12465 mips32_op = OPC_RECIP_D;
12466 goto do_unaryfp;
12467
12468 /* Floor */
12469 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12470 mips32_op = OPC_FLOOR_L_S;
12471 goto do_unaryfp;
12472 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12473 mips32_op = OPC_FLOOR_L_D;
12474 goto do_unaryfp;
12475 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12476 mips32_op = OPC_FLOOR_W_S;
12477 goto do_unaryfp;
12478 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12479 mips32_op = OPC_FLOOR_W_D;
12480 goto do_unaryfp;
12481
12482 /* Ceiling */
12483 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12484 mips32_op = OPC_CEIL_L_S;
12485 goto do_unaryfp;
12486 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12487 mips32_op = OPC_CEIL_L_D;
12488 goto do_unaryfp;
12489 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12490 mips32_op = OPC_CEIL_W_S;
12491 goto do_unaryfp;
12492 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12493 mips32_op = OPC_CEIL_W_D;
12494 goto do_unaryfp;
12495
12496 /* Truncation */
12497 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12498 mips32_op = OPC_TRUNC_L_S;
12499 goto do_unaryfp;
12500 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12501 mips32_op = OPC_TRUNC_L_D;
12502 goto do_unaryfp;
12503 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12504 mips32_op = OPC_TRUNC_W_S;
12505 goto do_unaryfp;
12506 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12507 mips32_op = OPC_TRUNC_W_D;
12508 goto do_unaryfp;
12509
12510 /* Round */
12511 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12512 mips32_op = OPC_ROUND_L_S;
12513 goto do_unaryfp;
12514 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12515 mips32_op = OPC_ROUND_L_D;
12516 goto do_unaryfp;
12517 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12518 mips32_op = OPC_ROUND_W_S;
12519 goto do_unaryfp;
12520 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12521 mips32_op = OPC_ROUND_W_D;
12522 goto do_unaryfp;
12523
12524 /* Integer to floating-point conversion */
12525 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12526 mips32_op = OPC_CVT_L_S;
12527 goto do_unaryfp;
12528 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12529 mips32_op = OPC_CVT_L_D;
12530 goto do_unaryfp;
12531 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
12532 mips32_op = OPC_CVT_W_S;
12533 goto do_unaryfp;
12534 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
12535 mips32_op = OPC_CVT_W_D;
12536 goto do_unaryfp;
12537
12538 /* Paired-foo conversions */
12539 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
12540 mips32_op = OPC_CVT_S_PL;
12541 goto do_unaryfp;
12542 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
12543 mips32_op = OPC_CVT_S_PU;
12544 goto do_unaryfp;
12545 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
12546 mips32_op = OPC_CVT_PW_PS;
12547 goto do_unaryfp;
12548 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
12549 mips32_op = OPC_CVT_PS_PW;
12550 goto do_unaryfp;
12551
12552 /* Floating-point moves */
12553 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
12554 mips32_op = OPC_MOV_S;
12555 goto do_unaryfp;
12556 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
12557 mips32_op = OPC_MOV_D;
12558 goto do_unaryfp;
12559 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
12560 mips32_op = OPC_MOV_PS;
12561 goto do_unaryfp;
12562
12563 /* Absolute value */
12564 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
12565 mips32_op = OPC_ABS_S;
12566 goto do_unaryfp;
12567 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
12568 mips32_op = OPC_ABS_D;
12569 goto do_unaryfp;
12570 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
12571 mips32_op = OPC_ABS_PS;
12572 goto do_unaryfp;
12573
12574 /* Negation */
12575 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
12576 mips32_op = OPC_NEG_S;
12577 goto do_unaryfp;
12578 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
12579 mips32_op = OPC_NEG_D;
12580 goto do_unaryfp;
12581 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
12582 mips32_op = OPC_NEG_PS;
12583 goto do_unaryfp;
12584
12585 /* Reciprocal square root step */
12586 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
12587 mips32_op = OPC_RSQRT1_S;
12588 goto do_unaryfp;
12589 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
12590 mips32_op = OPC_RSQRT1_D;
12591 goto do_unaryfp;
12592 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
12593 mips32_op = OPC_RSQRT1_PS;
12594 goto do_unaryfp;
12595
12596 /* Reciprocal step */
12597 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
12598 mips32_op = OPC_RECIP1_S;
12599 goto do_unaryfp;
12600 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
12601 mips32_op = OPC_RECIP1_S;
12602 goto do_unaryfp;
12603 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
12604 mips32_op = OPC_RECIP1_PS;
12605 goto do_unaryfp;
12606
12607 /* Conversions from double */
12608 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
12609 mips32_op = OPC_CVT_D_S;
12610 goto do_unaryfp;
12611 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
12612 mips32_op = OPC_CVT_D_W;
12613 goto do_unaryfp;
12614 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
12615 mips32_op = OPC_CVT_D_L;
12616 goto do_unaryfp;
12617
12618 /* Conversions from single */
12619 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
12620 mips32_op = OPC_CVT_S_D;
12621 goto do_unaryfp;
12622 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
12623 mips32_op = OPC_CVT_S_W;
12624 goto do_unaryfp;
12625 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
12626 mips32_op = OPC_CVT_S_L;
12627 do_unaryfp:
12628 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
12629 break;
12630
12631 /* Conditional moves on floating-point codes */
12632 case COND_FLOAT_MOV(MOVT, 0):
12633 case COND_FLOAT_MOV(MOVT, 1):
12634 case COND_FLOAT_MOV(MOVT, 2):
12635 case COND_FLOAT_MOV(MOVT, 3):
12636 case COND_FLOAT_MOV(MOVT, 4):
12637 case COND_FLOAT_MOV(MOVT, 5):
12638 case COND_FLOAT_MOV(MOVT, 6):
12639 case COND_FLOAT_MOV(MOVT, 7):
12640 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
12641 break;
12642 case COND_FLOAT_MOV(MOVF, 0):
12643 case COND_FLOAT_MOV(MOVF, 1):
12644 case COND_FLOAT_MOV(MOVF, 2):
12645 case COND_FLOAT_MOV(MOVF, 3):
12646 case COND_FLOAT_MOV(MOVF, 4):
12647 case COND_FLOAT_MOV(MOVF, 5):
12648 case COND_FLOAT_MOV(MOVF, 6):
12649 case COND_FLOAT_MOV(MOVF, 7):
12650 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
12651 break;
12652 default:
12653 MIPS_INVAL("pool32fxf");
12654 generate_exception(ctx, EXCP_RI);
12655 break;
12656 }
12657}
12658
7db13fae 12659static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 12660 uint16_t insn_hw1)
3c824109
NF
12661{
12662 int32_t offset;
12663 uint16_t insn;
12664 int rt, rs, rd, rr;
12665 int16_t imm;
12666 uint32_t op, minor, mips32_op;
12667 uint32_t cond, fmt, cc;
12668
895c2d04 12669 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
12670 ctx->opcode = (ctx->opcode << 16) | insn;
12671
12672 rt = (ctx->opcode >> 21) & 0x1f;
12673 rs = (ctx->opcode >> 16) & 0x1f;
12674 rd = (ctx->opcode >> 11) & 0x1f;
12675 rr = (ctx->opcode >> 6) & 0x1f;
12676 imm = (int16_t) ctx->opcode;
12677
12678 op = (ctx->opcode >> 26) & 0x3f;
12679 switch (op) {
12680 case POOL32A:
12681 minor = ctx->opcode & 0x3f;
12682 switch (minor) {
12683 case 0x00:
12684 minor = (ctx->opcode >> 6) & 0xf;
12685 switch (minor) {
12686 case SLL32:
12687 mips32_op = OPC_SLL;
12688 goto do_shifti;
12689 case SRA:
12690 mips32_op = OPC_SRA;
12691 goto do_shifti;
12692 case SRL32:
12693 mips32_op = OPC_SRL;
12694 goto do_shifti;
12695 case ROTR:
12696 mips32_op = OPC_ROTR;
12697 do_shifti:
d75c135e 12698 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
12699 break;
12700 default:
12701 goto pool32a_invalid;
12702 }
12703 break;
12704 case 0x10:
12705 minor = (ctx->opcode >> 6) & 0xf;
12706 switch (minor) {
12707 /* Arithmetic */
12708 case ADD:
12709 mips32_op = OPC_ADD;
12710 goto do_arith;
12711 case ADDU32:
12712 mips32_op = OPC_ADDU;
12713 goto do_arith;
12714 case SUB:
12715 mips32_op = OPC_SUB;
12716 goto do_arith;
12717 case SUBU32:
12718 mips32_op = OPC_SUBU;
12719 goto do_arith;
12720 case MUL:
12721 mips32_op = OPC_MUL;
12722 do_arith:
d75c135e 12723 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12724 break;
12725 /* Shifts */
12726 case SLLV:
12727 mips32_op = OPC_SLLV;
12728 goto do_shift;
12729 case SRLV:
12730 mips32_op = OPC_SRLV;
12731 goto do_shift;
12732 case SRAV:
12733 mips32_op = OPC_SRAV;
12734 goto do_shift;
12735 case ROTRV:
12736 mips32_op = OPC_ROTRV;
12737 do_shift:
d75c135e 12738 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12739 break;
12740 /* Logical operations */
12741 case AND:
12742 mips32_op = OPC_AND;
12743 goto do_logic;
12744 case OR32:
12745 mips32_op = OPC_OR;
12746 goto do_logic;
12747 case NOR:
12748 mips32_op = OPC_NOR;
12749 goto do_logic;
12750 case XOR32:
12751 mips32_op = OPC_XOR;
12752 do_logic:
d75c135e 12753 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12754 break;
12755 /* Set less than */
12756 case SLT:
12757 mips32_op = OPC_SLT;
12758 goto do_slt;
12759 case SLTU:
12760 mips32_op = OPC_SLTU;
12761 do_slt:
d75c135e 12762 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12763 break;
12764 default:
12765 goto pool32a_invalid;
12766 }
12767 break;
12768 case 0x18:
12769 minor = (ctx->opcode >> 6) & 0xf;
12770 switch (minor) {
12771 /* Conditional moves */
12772 case MOVN:
12773 mips32_op = OPC_MOVN;
12774 goto do_cmov;
12775 case MOVZ:
12776 mips32_op = OPC_MOVZ;
12777 do_cmov:
d75c135e 12778 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12779 break;
12780 case LWXS:
12781 gen_ldxs(ctx, rs, rt, rd);
12782 break;
12783 default:
12784 goto pool32a_invalid;
12785 }
12786 break;
12787 case INS:
12788 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
12789 return;
12790 case EXT:
12791 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
12792 return;
12793 case POOL32AXF:
240ce26a 12794 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
12795 break;
12796 case 0x07:
12797 generate_exception(ctx, EXCP_BREAK);
12798 break;
12799 default:
12800 pool32a_invalid:
12801 MIPS_INVAL("pool32a");
12802 generate_exception(ctx, EXCP_RI);
12803 break;
12804 }
12805 break;
12806 case POOL32B:
12807 minor = (ctx->opcode >> 12) & 0xf;
12808 switch (minor) {
12809 case CACHE:
2e15497c 12810 check_cp0_enabled(ctx);
3c824109
NF
12811 /* Treat as no-op. */
12812 break;
12813 case LWC2:
12814 case SWC2:
12815 /* COP2: Not implemented. */
12816 generate_exception_err(ctx, EXCP_CpU, 2);
12817 break;
12818 case LWP:
12819 case SWP:
12820#ifdef TARGET_MIPS64
12821 case LDP:
12822 case SDP:
12823#endif
12824 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12825 break;
12826 case LWM32:
12827 case SWM32:
12828#ifdef TARGET_MIPS64
12829 case LDM:
12830 case SDM:
12831#endif
12832 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12833 break;
12834 default:
12835 MIPS_INVAL("pool32b");
12836 generate_exception(ctx, EXCP_RI);
12837 break;
12838 }
12839 break;
12840 case POOL32F:
5ab5c041 12841 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
12842 minor = ctx->opcode & 0x3f;
12843 check_cp1_enabled(ctx);
12844 switch (minor) {
12845 case ALNV_PS:
12846 mips32_op = OPC_ALNV_PS;
12847 goto do_madd;
12848 case MADD_S:
12849 mips32_op = OPC_MADD_S;
12850 goto do_madd;
12851 case MADD_D:
12852 mips32_op = OPC_MADD_D;
12853 goto do_madd;
12854 case MADD_PS:
12855 mips32_op = OPC_MADD_PS;
12856 goto do_madd;
12857 case MSUB_S:
12858 mips32_op = OPC_MSUB_S;
12859 goto do_madd;
12860 case MSUB_D:
12861 mips32_op = OPC_MSUB_D;
12862 goto do_madd;
12863 case MSUB_PS:
12864 mips32_op = OPC_MSUB_PS;
12865 goto do_madd;
12866 case NMADD_S:
12867 mips32_op = OPC_NMADD_S;
12868 goto do_madd;
12869 case NMADD_D:
12870 mips32_op = OPC_NMADD_D;
12871 goto do_madd;
12872 case NMADD_PS:
12873 mips32_op = OPC_NMADD_PS;
12874 goto do_madd;
12875 case NMSUB_S:
12876 mips32_op = OPC_NMSUB_S;
12877 goto do_madd;
12878 case NMSUB_D:
12879 mips32_op = OPC_NMSUB_D;
12880 goto do_madd;
12881 case NMSUB_PS:
12882 mips32_op = OPC_NMSUB_PS;
12883 do_madd:
12884 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
12885 break;
12886 case CABS_COND_FMT:
12887 cond = (ctx->opcode >> 6) & 0xf;
12888 cc = (ctx->opcode >> 13) & 0x7;
12889 fmt = (ctx->opcode >> 10) & 0x3;
12890 switch (fmt) {
12891 case 0x0:
12892 gen_cmpabs_s(ctx, cond, rt, rs, cc);
12893 break;
12894 case 0x1:
12895 gen_cmpabs_d(ctx, cond, rt, rs, cc);
12896 break;
12897 case 0x2:
12898 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
12899 break;
12900 default:
12901 goto pool32f_invalid;
12902 }
12903 break;
12904 case C_COND_FMT:
12905 cond = (ctx->opcode >> 6) & 0xf;
12906 cc = (ctx->opcode >> 13) & 0x7;
12907 fmt = (ctx->opcode >> 10) & 0x3;
12908 switch (fmt) {
12909 case 0x0:
12910 gen_cmp_s(ctx, cond, rt, rs, cc);
12911 break;
12912 case 0x1:
12913 gen_cmp_d(ctx, cond, rt, rs, cc);
12914 break;
12915 case 0x2:
12916 gen_cmp_ps(ctx, cond, rt, rs, cc);
12917 break;
12918 default:
12919 goto pool32f_invalid;
12920 }
12921 break;
12922 case POOL32FXF:
d75c135e 12923 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
12924 break;
12925 case 0x00:
12926 /* PLL foo */
12927 switch ((ctx->opcode >> 6) & 0x7) {
12928 case PLL_PS:
12929 mips32_op = OPC_PLL_PS;
12930 goto do_ps;
12931 case PLU_PS:
12932 mips32_op = OPC_PLU_PS;
12933 goto do_ps;
12934 case PUL_PS:
12935 mips32_op = OPC_PUL_PS;
12936 goto do_ps;
12937 case PUU_PS:
12938 mips32_op = OPC_PUU_PS;
12939 goto do_ps;
12940 case CVT_PS_S:
12941 mips32_op = OPC_CVT_PS_S;
12942 do_ps:
12943 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12944 break;
12945 default:
12946 goto pool32f_invalid;
12947 }
12948 break;
12949 case 0x08:
12950 /* [LS][WDU]XC1 */
12951 switch ((ctx->opcode >> 6) & 0x7) {
12952 case LWXC1:
12953 mips32_op = OPC_LWXC1;
12954 goto do_ldst_cp1;
12955 case SWXC1:
12956 mips32_op = OPC_SWXC1;
12957 goto do_ldst_cp1;
12958 case LDXC1:
12959 mips32_op = OPC_LDXC1;
12960 goto do_ldst_cp1;
12961 case SDXC1:
12962 mips32_op = OPC_SDXC1;
12963 goto do_ldst_cp1;
12964 case LUXC1:
12965 mips32_op = OPC_LUXC1;
12966 goto do_ldst_cp1;
12967 case SUXC1:
12968 mips32_op = OPC_SUXC1;
12969 do_ldst_cp1:
12970 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
12971 break;
12972 default:
12973 goto pool32f_invalid;
12974 }
12975 break;
12976 case 0x18:
12977 /* 3D insns */
12978 fmt = (ctx->opcode >> 9) & 0x3;
12979 switch ((ctx->opcode >> 6) & 0x7) {
12980 case RSQRT2_FMT:
12981 switch (fmt) {
12982 case FMT_SDPS_S:
12983 mips32_op = OPC_RSQRT2_S;
12984 goto do_3d;
12985 case FMT_SDPS_D:
12986 mips32_op = OPC_RSQRT2_D;
12987 goto do_3d;
12988 case FMT_SDPS_PS:
12989 mips32_op = OPC_RSQRT2_PS;
12990 goto do_3d;
12991 default:
12992 goto pool32f_invalid;
12993 }
12994 break;
12995 case RECIP2_FMT:
12996 switch (fmt) {
12997 case FMT_SDPS_S:
12998 mips32_op = OPC_RECIP2_S;
12999 goto do_3d;
13000 case FMT_SDPS_D:
13001 mips32_op = OPC_RECIP2_D;
13002 goto do_3d;
13003 case FMT_SDPS_PS:
13004 mips32_op = OPC_RECIP2_PS;
13005 goto do_3d;
13006 default:
13007 goto pool32f_invalid;
13008 }
13009 break;
13010 case ADDR_PS:
13011 mips32_op = OPC_ADDR_PS;
13012 goto do_3d;
13013 case MULR_PS:
13014 mips32_op = OPC_MULR_PS;
13015 do_3d:
13016 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13017 break;
13018 default:
13019 goto pool32f_invalid;
13020 }
13021 break;
13022 case 0x20:
13023 /* MOV[FT].fmt and PREFX */
13024 cc = (ctx->opcode >> 13) & 0x7;
13025 fmt = (ctx->opcode >> 9) & 0x3;
13026 switch ((ctx->opcode >> 6) & 0x7) {
13027 case MOVF_FMT:
13028 switch (fmt) {
13029 case FMT_SDPS_S:
13030 gen_movcf_s(rs, rt, cc, 0);
13031 break;
13032 case FMT_SDPS_D:
13033 gen_movcf_d(ctx, rs, rt, cc, 0);
13034 break;
13035 case FMT_SDPS_PS:
7f6613ce 13036 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
13037 break;
13038 default:
13039 goto pool32f_invalid;
13040 }
13041 break;
13042 case MOVT_FMT:
13043 switch (fmt) {
13044 case FMT_SDPS_S:
13045 gen_movcf_s(rs, rt, cc, 1);
13046 break;
13047 case FMT_SDPS_D:
13048 gen_movcf_d(ctx, rs, rt, cc, 1);
13049 break;
13050 case FMT_SDPS_PS:
7f6613ce 13051 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
13052 break;
13053 default:
13054 goto pool32f_invalid;
13055 }
13056 break;
13057 case PREFX:
13058 break;
13059 default:
13060 goto pool32f_invalid;
13061 }
13062 break;
13063#define FINSN_3ARG_SDPS(prfx) \
13064 switch ((ctx->opcode >> 8) & 0x3) { \
13065 case FMT_SDPS_S: \
13066 mips32_op = OPC_##prfx##_S; \
13067 goto do_fpop; \
13068 case FMT_SDPS_D: \
13069 mips32_op = OPC_##prfx##_D; \
13070 goto do_fpop; \
13071 case FMT_SDPS_PS: \
13072 mips32_op = OPC_##prfx##_PS; \
13073 goto do_fpop; \
13074 default: \
13075 goto pool32f_invalid; \
13076 }
13077 case 0x30:
13078 /* regular FP ops */
13079 switch ((ctx->opcode >> 6) & 0x3) {
13080 case ADD_FMT:
13081 FINSN_3ARG_SDPS(ADD);
13082 break;
13083 case SUB_FMT:
13084 FINSN_3ARG_SDPS(SUB);
13085 break;
13086 case MUL_FMT:
13087 FINSN_3ARG_SDPS(MUL);
13088 break;
13089 case DIV_FMT:
13090 fmt = (ctx->opcode >> 8) & 0x3;
13091 if (fmt == 1) {
13092 mips32_op = OPC_DIV_D;
13093 } else if (fmt == 0) {
13094 mips32_op = OPC_DIV_S;
13095 } else {
13096 goto pool32f_invalid;
13097 }
13098 goto do_fpop;
13099 default:
13100 goto pool32f_invalid;
13101 }
13102 break;
13103 case 0x38:
13104 /* cmovs */
13105 switch ((ctx->opcode >> 6) & 0x3) {
13106 case MOVN_FMT:
13107 FINSN_3ARG_SDPS(MOVN);
13108 break;
13109 case MOVZ_FMT:
13110 FINSN_3ARG_SDPS(MOVZ);
13111 break;
13112 default:
13113 goto pool32f_invalid;
13114 }
13115 break;
13116 do_fpop:
13117 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13118 break;
13119 default:
13120 pool32f_invalid:
13121 MIPS_INVAL("pool32f");
13122 generate_exception(ctx, EXCP_RI);
13123 break;
13124 }
13125 } else {
13126 generate_exception_err(ctx, EXCP_CpU, 1);
13127 }
13128 break;
13129 case POOL32I:
13130 minor = (ctx->opcode >> 21) & 0x1f;
13131 switch (minor) {
13132 case BLTZ:
13133 mips32_op = OPC_BLTZ;
13134 goto do_branch;
13135 case BLTZAL:
13136 mips32_op = OPC_BLTZAL;
13137 goto do_branch;
13138 case BLTZALS:
13139 mips32_op = OPC_BLTZALS;
13140 goto do_branch;
13141 case BGEZ:
13142 mips32_op = OPC_BGEZ;
13143 goto do_branch;
13144 case BGEZAL:
13145 mips32_op = OPC_BGEZAL;
13146 goto do_branch;
13147 case BGEZALS:
13148 mips32_op = OPC_BGEZALS;
13149 goto do_branch;
13150 case BLEZ:
13151 mips32_op = OPC_BLEZ;
13152 goto do_branch;
13153 case BGTZ:
13154 mips32_op = OPC_BGTZ;
13155 do_branch:
13156 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
13157 break;
13158
13159 /* Traps */
13160 case TLTI:
13161 mips32_op = OPC_TLTI;
13162 goto do_trapi;
13163 case TGEI:
13164 mips32_op = OPC_TGEI;
13165 goto do_trapi;
13166 case TLTIU:
13167 mips32_op = OPC_TLTIU;
13168 goto do_trapi;
13169 case TGEIU:
13170 mips32_op = OPC_TGEIU;
13171 goto do_trapi;
13172 case TNEI:
13173 mips32_op = OPC_TNEI;
13174 goto do_trapi;
13175 case TEQI:
13176 mips32_op = OPC_TEQI;
13177 do_trapi:
13178 gen_trap(ctx, mips32_op, rs, -1, imm);
13179 break;
13180
13181 case BNEZC:
13182 case BEQZC:
13183 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
13184 4, rs, 0, imm << 1);
13185 /* Compact branches don't have a delay slot, so just let
13186 the normal delay slot handling take us to the branch
13187 target. */
13188 break;
13189 case LUI:
d75c135e 13190 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
13191 break;
13192 case SYNCI:
13193 break;
13194 case BC2F:
13195 case BC2T:
13196 /* COP2: Not implemented. */
13197 generate_exception_err(ctx, EXCP_CpU, 2);
13198 break;
13199 case BC1F:
13200 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13201 goto do_cp1branch;
13202 case BC1T:
13203 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13204 goto do_cp1branch;
13205 case BC1ANY4F:
13206 mips32_op = OPC_BC1FANY4;
13207 goto do_cp1mips3d;
13208 case BC1ANY4T:
13209 mips32_op = OPC_BC1TANY4;
13210 do_cp1mips3d:
13211 check_cop1x(ctx);
d75c135e 13212 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
13213 /* Fall through */
13214 do_cp1branch:
d75c135e 13215 gen_compute_branch1(ctx, mips32_op,
3c824109 13216 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
13217 break;
13218 case BPOSGE64:
13219 case BPOSGE32:
13220 /* MIPS DSP: not implemented */
13221 /* Fall through */
13222 default:
13223 MIPS_INVAL("pool32i");
13224 generate_exception(ctx, EXCP_RI);
13225 break;
13226 }
13227 break;
13228 case POOL32C:
13229 minor = (ctx->opcode >> 12) & 0xf;
13230 switch (minor) {
13231 case LWL:
13232 mips32_op = OPC_LWL;
5c13fdfd 13233 goto do_ld_lr;
3c824109
NF
13234 case SWL:
13235 mips32_op = OPC_SWL;
5c13fdfd 13236 goto do_st_lr;
3c824109
NF
13237 case LWR:
13238 mips32_op = OPC_LWR;
5c13fdfd 13239 goto do_ld_lr;
3c824109
NF
13240 case SWR:
13241 mips32_op = OPC_SWR;
5c13fdfd 13242 goto do_st_lr;
3c824109
NF
13243#if defined(TARGET_MIPS64)
13244 case LDL:
13245 mips32_op = OPC_LDL;
5c13fdfd 13246 goto do_ld_lr;
3c824109
NF
13247 case SDL:
13248 mips32_op = OPC_SDL;
5c13fdfd 13249 goto do_st_lr;
3c824109
NF
13250 case LDR:
13251 mips32_op = OPC_LDR;
5c13fdfd 13252 goto do_ld_lr;
3c824109
NF
13253 case SDR:
13254 mips32_op = OPC_SDR;
5c13fdfd 13255 goto do_st_lr;
3c824109
NF
13256 case LWU:
13257 mips32_op = OPC_LWU;
5c13fdfd 13258 goto do_ld_lr;
3c824109
NF
13259 case LLD:
13260 mips32_op = OPC_LLD;
5c13fdfd 13261 goto do_ld_lr;
3c824109
NF
13262#endif
13263 case LL:
13264 mips32_op = OPC_LL;
5c13fdfd
AJ
13265 goto do_ld_lr;
13266 do_ld_lr:
d75c135e 13267 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
13268 break;
13269 do_st_lr:
13270 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
13271 break;
13272 case SC:
13273 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13274 break;
13275#if defined(TARGET_MIPS64)
13276 case SCD:
13277 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13278 break;
13279#endif
13280 case PREF:
13281 /* Treat as no-op */
13282 break;
13283 default:
13284 MIPS_INVAL("pool32c");
13285 generate_exception(ctx, EXCP_RI);
13286 break;
13287 }
13288 break;
13289 case ADDI32:
13290 mips32_op = OPC_ADDI;
13291 goto do_addi;
13292 case ADDIU32:
13293 mips32_op = OPC_ADDIU;
13294 do_addi:
d75c135e 13295 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13296 break;
13297
13298 /* Logical operations */
13299 case ORI32:
13300 mips32_op = OPC_ORI;
13301 goto do_logici;
13302 case XORI32:
13303 mips32_op = OPC_XORI;
13304 goto do_logici;
13305 case ANDI32:
13306 mips32_op = OPC_ANDI;
13307 do_logici:
d75c135e 13308 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13309 break;
13310
13311 /* Set less than immediate */
13312 case SLTI32:
13313 mips32_op = OPC_SLTI;
13314 goto do_slti;
13315 case SLTIU32:
13316 mips32_op = OPC_SLTIU;
13317 do_slti:
d75c135e 13318 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13319 break;
13320 case JALX32:
13321 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
13322 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
13323 break;
13324 case JALS32:
13325 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
13326 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
13327 break;
13328 case BEQ32:
13329 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
13330 break;
13331 case BNE32:
13332 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
13333 break;
13334 case J32:
13335 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
13336 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
13337 break;
13338 case JAL32:
13339 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
13340 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
13341 break;
13342 /* Floating point (COP1) */
13343 case LWC132:
13344 mips32_op = OPC_LWC1;
13345 goto do_cop1;
13346 case LDC132:
13347 mips32_op = OPC_LDC1;
13348 goto do_cop1;
13349 case SWC132:
13350 mips32_op = OPC_SWC1;
13351 goto do_cop1;
13352 case SDC132:
13353 mips32_op = OPC_SDC1;
13354 do_cop1:
5ab5c041 13355 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13356 break;
13357 case ADDIUPC:
13358 {
13359 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13360 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13361
13362 gen_addiupc(ctx, reg, offset, 0, 0);
13363 }
13364 break;
13365 /* Loads and stores */
13366 case LB32:
13367 mips32_op = OPC_LB;
5c13fdfd 13368 goto do_ld;
3c824109
NF
13369 case LBU32:
13370 mips32_op = OPC_LBU;
5c13fdfd 13371 goto do_ld;
3c824109
NF
13372 case LH32:
13373 mips32_op = OPC_LH;
5c13fdfd 13374 goto do_ld;
3c824109
NF
13375 case LHU32:
13376 mips32_op = OPC_LHU;
5c13fdfd 13377 goto do_ld;
3c824109
NF
13378 case LW32:
13379 mips32_op = OPC_LW;
5c13fdfd 13380 goto do_ld;
3c824109
NF
13381#ifdef TARGET_MIPS64
13382 case LD32:
13383 mips32_op = OPC_LD;
5c13fdfd 13384 goto do_ld;
3c824109
NF
13385 case SD32:
13386 mips32_op = OPC_SD;
5c13fdfd 13387 goto do_st;
3c824109
NF
13388#endif
13389 case SB32:
13390 mips32_op = OPC_SB;
5c13fdfd 13391 goto do_st;
3c824109
NF
13392 case SH32:
13393 mips32_op = OPC_SH;
5c13fdfd 13394 goto do_st;
3c824109
NF
13395 case SW32:
13396 mips32_op = OPC_SW;
5c13fdfd
AJ
13397 goto do_st;
13398 do_ld:
d75c135e 13399 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
13400 break;
13401 do_st:
13402 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
13403 break;
13404 default:
13405 generate_exception(ctx, EXCP_RI);
13406 break;
13407 }
13408}
13409
240ce26a 13410static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13411{
13412 uint32_t op;
13413
13414 /* make sure instructions are on a halfword boundary */
13415 if (ctx->pc & 0x1) {
13416 env->CP0_BadVAddr = ctx->pc;
13417 generate_exception(ctx, EXCP_AdEL);
13418 ctx->bstate = BS_STOP;
13419 return 2;
13420 }
13421
13422 op = (ctx->opcode >> 10) & 0x3f;
13423 /* Enforce properly-sized instructions in a delay slot */
13424 if (ctx->hflags & MIPS_HFLAG_BMASK) {
13425 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
13426
13427 switch (op) {
13428 case POOL32A:
13429 case POOL32B:
13430 case POOL32I:
13431 case POOL32C:
13432 case ADDI32:
13433 case ADDIU32:
13434 case ORI32:
13435 case XORI32:
13436 case SLTI32:
13437 case SLTIU32:
13438 case ANDI32:
13439 case JALX32:
13440 case LBU32:
13441 case LHU32:
13442 case POOL32F:
13443 case JALS32:
13444 case BEQ32:
13445 case BNE32:
13446 case J32:
13447 case JAL32:
13448 case SB32:
13449 case SH32:
13450 case POOL32S:
13451 case ADDIUPC:
13452 case SWC132:
13453 case SDC132:
13454 case SD32:
13455 case SW32:
13456 case LB32:
13457 case LH32:
13458 case DADDIU32:
3c824109
NF
13459 case LWC132:
13460 case LDC132:
13461 case LD32:
13462 case LW32:
13463 if (bits & MIPS_HFLAG_BDS16) {
13464 generate_exception(ctx, EXCP_RI);
13465 /* Just stop translation; the user is confused. */
13466 ctx->bstate = BS_STOP;
13467 return 2;
13468 }
13469 break;
13470 case POOL16A:
13471 case POOL16B:
13472 case POOL16C:
13473 case LWGP16:
13474 case POOL16F:
13475 case LBU16:
13476 case LHU16:
13477 case LWSP16:
13478 case LW16:
13479 case SB16:
13480 case SH16:
13481 case SWSP16:
13482 case SW16:
13483 case MOVE16:
13484 case ANDI16:
13485 case POOL16D:
13486 case POOL16E:
13487 case BEQZ16:
13488 case BNEZ16:
13489 case B16:
13490 case LI16:
13491 if (bits & MIPS_HFLAG_BDS32) {
13492 generate_exception(ctx, EXCP_RI);
13493 /* Just stop translation; the user is confused. */
13494 ctx->bstate = BS_STOP;
13495 return 2;
13496 }
13497 break;
13498 default:
13499 break;
13500 }
13501 }
13502 switch (op) {
13503 case POOL16A:
13504 {
13505 int rd = mmreg(uMIPS_RD(ctx->opcode));
13506 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13507 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13508 uint32_t opc = 0;
13509
13510 switch (ctx->opcode & 0x1) {
13511 case ADDU16:
13512 opc = OPC_ADDU;
13513 break;
13514 case SUBU16:
13515 opc = OPC_SUBU;
13516 break;
13517 }
13518
d75c135e 13519 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
13520 }
13521 break;
13522 case POOL16B:
13523 {
13524 int rd = mmreg(uMIPS_RD(ctx->opcode));
13525 int rs = mmreg(uMIPS_RS(ctx->opcode));
13526 int amount = (ctx->opcode >> 1) & 0x7;
13527 uint32_t opc = 0;
13528 amount = amount == 0 ? 8 : amount;
13529
13530 switch (ctx->opcode & 0x1) {
13531 case SLL16:
13532 opc = OPC_SLL;
13533 break;
13534 case SRL16:
13535 opc = OPC_SRL;
13536 break;
13537 }
13538
d75c135e 13539 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
13540 }
13541 break;
13542 case POOL16C:
240ce26a 13543 gen_pool16c_insn(ctx);
3c824109
NF
13544 break;
13545 case LWGP16:
13546 {
13547 int rd = mmreg(uMIPS_RD(ctx->opcode));
13548 int rb = 28; /* GP */
13549 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
13550
d75c135e 13551 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13552 }
13553 break;
13554 case POOL16F:
13555 if (ctx->opcode & 1) {
13556 generate_exception(ctx, EXCP_RI);
13557 } else {
13558 /* MOVEP */
13559 int enc_dest = uMIPS_RD(ctx->opcode);
13560 int enc_rt = uMIPS_RS2(ctx->opcode);
13561 int enc_rs = uMIPS_RS1(ctx->opcode);
13562 int rd, rs, re, rt;
13563 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13564 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13565 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13566
13567 rd = rd_enc[enc_dest];
13568 re = re_enc[enc_dest];
13569 rs = rs_rt_enc[enc_rs];
13570 rt = rs_rt_enc[enc_rt];
13571
d75c135e
AJ
13572 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
13573 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
13574 }
13575 break;
13576 case LBU16:
13577 {
13578 int rd = mmreg(uMIPS_RD(ctx->opcode));
13579 int rb = mmreg(uMIPS_RS(ctx->opcode));
13580 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13581 offset = (offset == 0xf ? -1 : offset);
13582
d75c135e 13583 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
13584 }
13585 break;
13586 case LHU16:
13587 {
13588 int rd = mmreg(uMIPS_RD(ctx->opcode));
13589 int rb = mmreg(uMIPS_RS(ctx->opcode));
13590 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13591
d75c135e 13592 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
13593 }
13594 break;
13595 case LWSP16:
13596 {
13597 int rd = (ctx->opcode >> 5) & 0x1f;
13598 int rb = 29; /* SP */
13599 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13600
d75c135e 13601 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13602 }
13603 break;
13604 case LW16:
13605 {
13606 int rd = mmreg(uMIPS_RD(ctx->opcode));
13607 int rb = mmreg(uMIPS_RS(ctx->opcode));
13608 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13609
d75c135e 13610 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
13611 }
13612 break;
13613 case SB16:
13614 {
13615 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13616 int rb = mmreg(uMIPS_RS(ctx->opcode));
13617 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13618
5c13fdfd 13619 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
13620 }
13621 break;
13622 case SH16:
13623 {
13624 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13625 int rb = mmreg(uMIPS_RS(ctx->opcode));
13626 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13627
5c13fdfd 13628 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
13629 }
13630 break;
13631 case SWSP16:
13632 {
13633 int rd = (ctx->opcode >> 5) & 0x1f;
13634 int rb = 29; /* SP */
13635 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13636
5c13fdfd 13637 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13638 }
13639 break;
13640 case SW16:
13641 {
13642 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13643 int rb = mmreg(uMIPS_RS(ctx->opcode));
13644 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13645
5c13fdfd 13646 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
13647 }
13648 break;
13649 case MOVE16:
13650 {
13651 int rd = uMIPS_RD5(ctx->opcode);
13652 int rs = uMIPS_RS5(ctx->opcode);
13653
d75c135e 13654 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
13655 }
13656 break;
13657 case ANDI16:
d75c135e 13658 gen_andi16(ctx);
3c824109
NF
13659 break;
13660 case POOL16D:
13661 switch (ctx->opcode & 0x1) {
13662 case ADDIUS5:
d75c135e 13663 gen_addius5(ctx);
3c824109
NF
13664 break;
13665 case ADDIUSP:
d75c135e 13666 gen_addiusp(ctx);
3c824109
NF
13667 break;
13668 }
13669 break;
13670 case POOL16E:
13671 switch (ctx->opcode & 0x1) {
13672 case ADDIUR2:
d75c135e 13673 gen_addiur2(ctx);
3c824109
NF
13674 break;
13675 case ADDIUR1SP:
d75c135e 13676 gen_addiur1sp(ctx);
3c824109
NF
13677 break;
13678 }
13679 break;
13680 case B16:
13681 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
13682 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
13683 break;
13684 case BNEZ16:
13685 case BEQZ16:
13686 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
13687 mmreg(uMIPS_RD(ctx->opcode)),
13688 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
13689 break;
13690 case LI16:
13691 {
13692 int reg = mmreg(uMIPS_RD(ctx->opcode));
13693 int imm = ZIMM(ctx->opcode, 0, 7);
13694
13695 imm = (imm == 0x7f ? -1 : imm);
13696 tcg_gen_movi_tl(cpu_gpr[reg], imm);
13697 }
13698 break;
13699 case RES_20:
13700 case RES_28:
13701 case RES_29:
13702 case RES_30:
13703 case RES_31:
13704 case RES_38:
13705 case RES_39:
13706 generate_exception(ctx, EXCP_RI);
13707 break;
13708 default:
240ce26a 13709 decode_micromips32_opc (env, ctx, op);
3c824109
NF
13710 return 4;
13711 }
13712
13713 return 2;
13714}
13715
13716/* SmartMIPS extension to MIPS32 */
13717
13718#if defined(TARGET_MIPS64)
13719
13720/* MDMX extension to MIPS64 */
13721
13722#endif
13723
9b1a1d68 13724/* MIPSDSP functions. */
d75c135e 13725static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
13726 int rd, int base, int offset)
13727{
13728 const char *opn = "ldx";
13729 TCGv t0;
13730
9b1a1d68
JL
13731 check_dsp(ctx);
13732 t0 = tcg_temp_new();
13733
13734 if (base == 0) {
13735 gen_load_gpr(t0, offset);
13736 } else if (offset == 0) {
13737 gen_load_gpr(t0, base);
13738 } else {
13739 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
13740 }
13741
9b1a1d68
JL
13742 switch (opc) {
13743 case OPC_LBUX:
5f68f5ae 13744 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
13745 gen_store_gpr(t0, rd);
13746 opn = "lbux";
13747 break;
13748 case OPC_LHX:
5f68f5ae 13749 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
13750 gen_store_gpr(t0, rd);
13751 opn = "lhx";
13752 break;
13753 case OPC_LWX:
5f68f5ae 13754 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
13755 gen_store_gpr(t0, rd);
13756 opn = "lwx";
13757 break;
13758#if defined(TARGET_MIPS64)
13759 case OPC_LDX:
5f68f5ae 13760 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
13761 gen_store_gpr(t0, rd);
13762 opn = "ldx";
13763 break;
13764#endif
13765 }
13766 (void)opn; /* avoid a compiler warning */
13767 MIPS_DEBUG("%s %s, %s(%s)", opn,
13768 regnames[rd], regnames[offset], regnames[base]);
13769 tcg_temp_free(t0);
13770}
13771
461c08df
JL
13772static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
13773 int ret, int v1, int v2)
13774{
13775 const char *opn = "mipsdsp arith";
13776 TCGv v1_t;
13777 TCGv v2_t;
13778
13779 if (ret == 0) {
13780 /* Treat as NOP. */
13781 MIPS_DEBUG("NOP");
13782 return;
13783 }
13784
13785 v1_t = tcg_temp_new();
13786 v2_t = tcg_temp_new();
13787
13788 gen_load_gpr(v1_t, v1);
13789 gen_load_gpr(v2_t, v2);
13790
13791 switch (op1) {
13792 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13793 case OPC_MULT_G_2E:
13794 check_dspr2(ctx);
13795 switch (op2) {
13796 case OPC_ADDUH_QB:
13797 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
13798 break;
13799 case OPC_ADDUH_R_QB:
13800 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13801 break;
13802 case OPC_ADDQH_PH:
13803 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
13804 break;
13805 case OPC_ADDQH_R_PH:
13806 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13807 break;
13808 case OPC_ADDQH_W:
13809 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
13810 break;
13811 case OPC_ADDQH_R_W:
13812 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13813 break;
13814 case OPC_SUBUH_QB:
13815 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
13816 break;
13817 case OPC_SUBUH_R_QB:
13818 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13819 break;
13820 case OPC_SUBQH_PH:
13821 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
13822 break;
13823 case OPC_SUBQH_R_PH:
13824 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13825 break;
13826 case OPC_SUBQH_W:
13827 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
13828 break;
13829 case OPC_SUBQH_R_W:
13830 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13831 break;
13832 }
13833 break;
13834 case OPC_ABSQ_S_PH_DSP:
13835 switch (op2) {
13836 case OPC_ABSQ_S_QB:
13837 check_dspr2(ctx);
13838 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
13839 break;
13840 case OPC_ABSQ_S_PH:
13841 check_dsp(ctx);
13842 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
13843 break;
13844 case OPC_ABSQ_S_W:
13845 check_dsp(ctx);
13846 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
13847 break;
13848 case OPC_PRECEQ_W_PHL:
13849 check_dsp(ctx);
13850 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
13851 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13852 break;
13853 case OPC_PRECEQ_W_PHR:
13854 check_dsp(ctx);
13855 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
13856 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
13857 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13858 break;
13859 case OPC_PRECEQU_PH_QBL:
13860 check_dsp(ctx);
13861 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
13862 break;
13863 case OPC_PRECEQU_PH_QBR:
13864 check_dsp(ctx);
13865 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
13866 break;
13867 case OPC_PRECEQU_PH_QBLA:
13868 check_dsp(ctx);
13869 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
13870 break;
13871 case OPC_PRECEQU_PH_QBRA:
13872 check_dsp(ctx);
13873 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
13874 break;
13875 case OPC_PRECEU_PH_QBL:
13876 check_dsp(ctx);
13877 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
13878 break;
13879 case OPC_PRECEU_PH_QBR:
13880 check_dsp(ctx);
13881 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
13882 break;
13883 case OPC_PRECEU_PH_QBLA:
13884 check_dsp(ctx);
13885 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
13886 break;
13887 case OPC_PRECEU_PH_QBRA:
13888 check_dsp(ctx);
13889 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
13890 break;
13891 }
13892 break;
13893 case OPC_ADDU_QB_DSP:
13894 switch (op2) {
13895 case OPC_ADDQ_PH:
13896 check_dsp(ctx);
13897 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13898 break;
13899 case OPC_ADDQ_S_PH:
13900 check_dsp(ctx);
13901 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13902 break;
13903 case OPC_ADDQ_S_W:
13904 check_dsp(ctx);
13905 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13906 break;
13907 case OPC_ADDU_QB:
13908 check_dsp(ctx);
13909 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13910 break;
13911 case OPC_ADDU_S_QB:
13912 check_dsp(ctx);
13913 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13914 break;
13915 case OPC_ADDU_PH:
13916 check_dspr2(ctx);
13917 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_ADDU_S_PH:
13920 check_dspr2(ctx);
13921 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_SUBQ_PH:
13924 check_dsp(ctx);
13925 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13926 break;
13927 case OPC_SUBQ_S_PH:
13928 check_dsp(ctx);
13929 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13930 break;
13931 case OPC_SUBQ_S_W:
13932 check_dsp(ctx);
13933 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13934 break;
13935 case OPC_SUBU_QB:
13936 check_dsp(ctx);
13937 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13938 break;
13939 case OPC_SUBU_S_QB:
13940 check_dsp(ctx);
13941 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13942 break;
13943 case OPC_SUBU_PH:
13944 check_dspr2(ctx);
13945 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13946 break;
13947 case OPC_SUBU_S_PH:
13948 check_dspr2(ctx);
13949 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13950 break;
13951 case OPC_ADDSC:
13952 check_dsp(ctx);
13953 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13954 break;
13955 case OPC_ADDWC:
13956 check_dsp(ctx);
13957 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13958 break;
13959 case OPC_MODSUB:
13960 check_dsp(ctx);
13961 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
13962 break;
13963 case OPC_RADDU_W_QB:
13964 check_dsp(ctx);
13965 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
13966 break;
13967 }
13968 break;
13969 case OPC_CMPU_EQ_QB_DSP:
13970 switch (op2) {
13971 case OPC_PRECR_QB_PH:
13972 check_dspr2(ctx);
13973 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13974 break;
13975 case OPC_PRECRQ_QB_PH:
13976 check_dsp(ctx);
13977 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13978 break;
13979 case OPC_PRECR_SRA_PH_W:
13980 check_dspr2(ctx);
13981 {
13982 TCGv_i32 sa_t = tcg_const_i32(v2);
13983 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
13984 cpu_gpr[ret]);
13985 tcg_temp_free_i32(sa_t);
13986 break;
13987 }
13988 case OPC_PRECR_SRA_R_PH_W:
13989 check_dspr2(ctx);
13990 {
13991 TCGv_i32 sa_t = tcg_const_i32(v2);
13992 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
13993 cpu_gpr[ret]);
13994 tcg_temp_free_i32(sa_t);
13995 break;
13996 }
13997 case OPC_PRECRQ_PH_W:
13998 check_dsp(ctx);
13999 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14000 break;
14001 case OPC_PRECRQ_RS_PH_W:
14002 check_dsp(ctx);
14003 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14004 break;
14005 case OPC_PRECRQU_S_QB_PH:
14006 check_dsp(ctx);
14007 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14008 break;
14009 }
14010 break;
14011#ifdef TARGET_MIPS64
14012 case OPC_ABSQ_S_QH_DSP:
14013 switch (op2) {
14014 case OPC_PRECEQ_L_PWL:
14015 check_dsp(ctx);
14016 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14017 break;
14018 case OPC_PRECEQ_L_PWR:
14019 check_dsp(ctx);
14020 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14021 break;
14022 case OPC_PRECEQ_PW_QHL:
14023 check_dsp(ctx);
14024 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14025 break;
14026 case OPC_PRECEQ_PW_QHR:
14027 check_dsp(ctx);
14028 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14029 break;
14030 case OPC_PRECEQ_PW_QHLA:
14031 check_dsp(ctx);
14032 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14033 break;
14034 case OPC_PRECEQ_PW_QHRA:
14035 check_dsp(ctx);
14036 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14037 break;
14038 case OPC_PRECEQU_QH_OBL:
14039 check_dsp(ctx);
14040 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14041 break;
14042 case OPC_PRECEQU_QH_OBR:
14043 check_dsp(ctx);
14044 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14045 break;
14046 case OPC_PRECEQU_QH_OBLA:
14047 check_dsp(ctx);
14048 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14049 break;
14050 case OPC_PRECEQU_QH_OBRA:
14051 check_dsp(ctx);
14052 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14053 break;
14054 case OPC_PRECEU_QH_OBL:
14055 check_dsp(ctx);
14056 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14057 break;
14058 case OPC_PRECEU_QH_OBR:
14059 check_dsp(ctx);
14060 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14061 break;
14062 case OPC_PRECEU_QH_OBLA:
14063 check_dsp(ctx);
14064 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14065 break;
14066 case OPC_PRECEU_QH_OBRA:
14067 check_dsp(ctx);
14068 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14069 break;
14070 case OPC_ABSQ_S_OB:
14071 check_dspr2(ctx);
14072 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14073 break;
14074 case OPC_ABSQ_S_PW:
14075 check_dsp(ctx);
14076 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14077 break;
14078 case OPC_ABSQ_S_QH:
14079 check_dsp(ctx);
14080 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14081 break;
14082 }
14083 break;
14084 case OPC_ADDU_OB_DSP:
14085 switch (op2) {
14086 case OPC_RADDU_L_OB:
14087 check_dsp(ctx);
14088 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14089 break;
14090 case OPC_SUBQ_PW:
14091 check_dsp(ctx);
14092 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14093 break;
14094 case OPC_SUBQ_S_PW:
14095 check_dsp(ctx);
14096 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14097 break;
14098 case OPC_SUBQ_QH:
14099 check_dsp(ctx);
14100 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14101 break;
14102 case OPC_SUBQ_S_QH:
14103 check_dsp(ctx);
14104 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14105 break;
14106 case OPC_SUBU_OB:
14107 check_dsp(ctx);
14108 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14109 break;
14110 case OPC_SUBU_S_OB:
14111 check_dsp(ctx);
14112 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14113 break;
14114 case OPC_SUBU_QH:
14115 check_dspr2(ctx);
14116 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14117 break;
14118 case OPC_SUBU_S_QH:
14119 check_dspr2(ctx);
14120 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14121 break;
14122 case OPC_SUBUH_OB:
14123 check_dspr2(ctx);
14124 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14125 break;
14126 case OPC_SUBUH_R_OB:
14127 check_dspr2(ctx);
14128 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14129 break;
14130 case OPC_ADDQ_PW:
14131 check_dsp(ctx);
14132 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14133 break;
14134 case OPC_ADDQ_S_PW:
14135 check_dsp(ctx);
14136 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14137 break;
14138 case OPC_ADDQ_QH:
14139 check_dsp(ctx);
14140 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14141 break;
14142 case OPC_ADDQ_S_QH:
14143 check_dsp(ctx);
14144 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14145 break;
14146 case OPC_ADDU_OB:
14147 check_dsp(ctx);
14148 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14149 break;
14150 case OPC_ADDU_S_OB:
14151 check_dsp(ctx);
14152 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14153 break;
14154 case OPC_ADDU_QH:
14155 check_dspr2(ctx);
14156 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14157 break;
14158 case OPC_ADDU_S_QH:
14159 check_dspr2(ctx);
14160 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14161 break;
14162 case OPC_ADDUH_OB:
14163 check_dspr2(ctx);
14164 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14165 break;
14166 case OPC_ADDUH_R_OB:
14167 check_dspr2(ctx);
14168 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14169 break;
14170 }
14171 break;
14172 case OPC_CMPU_EQ_OB_DSP:
14173 switch (op2) {
14174 case OPC_PRECR_OB_QH:
14175 check_dspr2(ctx);
14176 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14177 break;
14178 case OPC_PRECR_SRA_QH_PW:
14179 check_dspr2(ctx);
14180 {
14181 TCGv_i32 ret_t = tcg_const_i32(ret);
14182 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14183 tcg_temp_free_i32(ret_t);
14184 break;
14185 }
14186 case OPC_PRECR_SRA_R_QH_PW:
14187 check_dspr2(ctx);
14188 {
14189 TCGv_i32 sa_v = tcg_const_i32(ret);
14190 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14191 tcg_temp_free_i32(sa_v);
14192 break;
14193 }
14194 case OPC_PRECRQ_OB_QH:
14195 check_dsp(ctx);
14196 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14197 break;
14198 case OPC_PRECRQ_PW_L:
14199 check_dsp(ctx);
14200 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14201 break;
14202 case OPC_PRECRQ_QH_PW:
14203 check_dsp(ctx);
14204 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14205 break;
14206 case OPC_PRECRQ_RS_QH_PW:
14207 check_dsp(ctx);
14208 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14209 break;
14210 case OPC_PRECRQU_S_OB_QH:
14211 check_dsp(ctx);
14212 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14213 break;
14214 }
14215 break;
14216#endif
14217 }
14218
14219 tcg_temp_free(v1_t);
14220 tcg_temp_free(v2_t);
14221
14222 (void)opn; /* avoid a compiler warning */
14223 MIPS_DEBUG("%s", opn);
14224}
9b1a1d68 14225
77c5fa8b
JL
14226static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14227 int ret, int v1, int v2)
14228{
14229 uint32_t op2;
14230 const char *opn = "mipsdsp shift";
14231 TCGv t0;
14232 TCGv v1_t;
14233 TCGv v2_t;
14234
14235 if (ret == 0) {
14236 /* Treat as NOP. */
14237 MIPS_DEBUG("NOP");
14238 return;
14239 }
14240
14241 t0 = tcg_temp_new();
14242 v1_t = tcg_temp_new();
14243 v2_t = tcg_temp_new();
14244
14245 tcg_gen_movi_tl(t0, v1);
14246 gen_load_gpr(v1_t, v1);
14247 gen_load_gpr(v2_t, v2);
14248
14249 switch (opc) {
14250 case OPC_SHLL_QB_DSP:
14251 {
14252 op2 = MASK_SHLL_QB(ctx->opcode);
14253 switch (op2) {
14254 case OPC_SHLL_QB:
14255 check_dsp(ctx);
14256 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14257 break;
14258 case OPC_SHLLV_QB:
14259 check_dsp(ctx);
14260 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14261 break;
14262 case OPC_SHLL_PH:
14263 check_dsp(ctx);
14264 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14265 break;
14266 case OPC_SHLLV_PH:
14267 check_dsp(ctx);
14268 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14269 break;
14270 case OPC_SHLL_S_PH:
14271 check_dsp(ctx);
14272 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14273 break;
14274 case OPC_SHLLV_S_PH:
14275 check_dsp(ctx);
14276 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14277 break;
14278 case OPC_SHLL_S_W:
14279 check_dsp(ctx);
14280 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14281 break;
14282 case OPC_SHLLV_S_W:
14283 check_dsp(ctx);
14284 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14285 break;
14286 case OPC_SHRL_QB:
14287 check_dsp(ctx);
14288 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14289 break;
14290 case OPC_SHRLV_QB:
14291 check_dsp(ctx);
14292 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14293 break;
14294 case OPC_SHRL_PH:
14295 check_dspr2(ctx);
14296 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14297 break;
14298 case OPC_SHRLV_PH:
14299 check_dspr2(ctx);
14300 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14301 break;
14302 case OPC_SHRA_QB:
14303 check_dspr2(ctx);
14304 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14305 break;
14306 case OPC_SHRA_R_QB:
14307 check_dspr2(ctx);
14308 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14309 break;
14310 case OPC_SHRAV_QB:
14311 check_dspr2(ctx);
14312 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14313 break;
14314 case OPC_SHRAV_R_QB:
14315 check_dspr2(ctx);
14316 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14317 break;
14318 case OPC_SHRA_PH:
14319 check_dsp(ctx);
14320 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14321 break;
14322 case OPC_SHRA_R_PH:
14323 check_dsp(ctx);
14324 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14325 break;
14326 case OPC_SHRAV_PH:
14327 check_dsp(ctx);
14328 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14329 break;
14330 case OPC_SHRAV_R_PH:
14331 check_dsp(ctx);
14332 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14333 break;
14334 case OPC_SHRA_R_W:
14335 check_dsp(ctx);
14336 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14337 break;
14338 case OPC_SHRAV_R_W:
14339 check_dsp(ctx);
14340 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14341 break;
14342 default: /* Invalid */
14343 MIPS_INVAL("MASK SHLL.QB");
14344 generate_exception(ctx, EXCP_RI);
14345 break;
14346 }
14347 break;
14348 }
14349#ifdef TARGET_MIPS64
14350 case OPC_SHLL_OB_DSP:
14351 op2 = MASK_SHLL_OB(ctx->opcode);
14352 switch (op2) {
14353 case OPC_SHLL_PW:
14354 check_dsp(ctx);
14355 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14356 break;
14357 case OPC_SHLLV_PW:
14358 check_dsp(ctx);
14359 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14360 break;
14361 case OPC_SHLL_S_PW:
14362 check_dsp(ctx);
14363 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14364 break;
14365 case OPC_SHLLV_S_PW:
14366 check_dsp(ctx);
14367 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14368 break;
14369 case OPC_SHLL_OB:
14370 check_dsp(ctx);
14371 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14372 break;
14373 case OPC_SHLLV_OB:
14374 check_dsp(ctx);
14375 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14376 break;
14377 case OPC_SHLL_QH:
14378 check_dsp(ctx);
14379 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14380 break;
14381 case OPC_SHLLV_QH:
14382 check_dsp(ctx);
14383 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14384 break;
14385 case OPC_SHLL_S_QH:
14386 check_dsp(ctx);
14387 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14388 break;
14389 case OPC_SHLLV_S_QH:
14390 check_dsp(ctx);
14391 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14392 break;
14393 case OPC_SHRA_OB:
14394 check_dspr2(ctx);
14395 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14396 break;
14397 case OPC_SHRAV_OB:
14398 check_dspr2(ctx);
14399 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14400 break;
14401 case OPC_SHRA_R_OB:
14402 check_dspr2(ctx);
14403 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14404 break;
14405 case OPC_SHRAV_R_OB:
14406 check_dspr2(ctx);
14407 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14408 break;
14409 case OPC_SHRA_PW:
14410 check_dsp(ctx);
14411 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14412 break;
14413 case OPC_SHRAV_PW:
14414 check_dsp(ctx);
14415 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14416 break;
14417 case OPC_SHRA_R_PW:
14418 check_dsp(ctx);
14419 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14420 break;
14421 case OPC_SHRAV_R_PW:
14422 check_dsp(ctx);
14423 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14424 break;
14425 case OPC_SHRA_QH:
14426 check_dsp(ctx);
14427 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14428 break;
14429 case OPC_SHRAV_QH:
14430 check_dsp(ctx);
14431 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14432 break;
14433 case OPC_SHRA_R_QH:
14434 check_dsp(ctx);
14435 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14436 break;
14437 case OPC_SHRAV_R_QH:
14438 check_dsp(ctx);
14439 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14440 break;
14441 case OPC_SHRL_OB:
14442 check_dsp(ctx);
14443 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14444 break;
14445 case OPC_SHRLV_OB:
14446 check_dsp(ctx);
14447 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14448 break;
14449 case OPC_SHRL_QH:
14450 check_dspr2(ctx);
14451 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14452 break;
14453 case OPC_SHRLV_QH:
14454 check_dspr2(ctx);
14455 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14456 break;
14457 default: /* Invalid */
14458 MIPS_INVAL("MASK SHLL.OB");
14459 generate_exception(ctx, EXCP_RI);
14460 break;
14461 }
14462 break;
14463#endif
14464 }
14465
14466 tcg_temp_free(t0);
14467 tcg_temp_free(v1_t);
14468 tcg_temp_free(v2_t);
14469 (void)opn; /* avoid a compiler warning */
14470 MIPS_DEBUG("%s", opn);
14471}
14472
a22260ae
JL
14473static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14474 int ret, int v1, int v2, int check_ret)
14475{
14476 const char *opn = "mipsdsp multiply";
14477 TCGv_i32 t0;
14478 TCGv v1_t;
14479 TCGv v2_t;
14480
14481 if ((ret == 0) && (check_ret == 1)) {
14482 /* Treat as NOP. */
14483 MIPS_DEBUG("NOP");
14484 return;
14485 }
14486
14487 t0 = tcg_temp_new_i32();
14488 v1_t = tcg_temp_new();
14489 v2_t = tcg_temp_new();
14490
14491 tcg_gen_movi_i32(t0, ret);
14492 gen_load_gpr(v1_t, v1);
14493 gen_load_gpr(v2_t, v2);
14494
14495 switch (op1) {
14496 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14497 * the same mask and op1. */
14498 case OPC_MULT_G_2E:
639eadb9 14499 check_dspr2(ctx);
a22260ae
JL
14500 switch (op2) {
14501 case OPC_MUL_PH:
14502 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14503 break;
14504 case OPC_MUL_S_PH:
14505 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14506 break;
14507 case OPC_MULQ_S_W:
14508 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14509 break;
14510 case OPC_MULQ_RS_W:
14511 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14512 break;
14513 }
14514 break;
14515 case OPC_DPA_W_PH_DSP:
14516 switch (op2) {
14517 case OPC_DPAU_H_QBL:
14518 check_dsp(ctx);
14519 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14520 break;
14521 case OPC_DPAU_H_QBR:
14522 check_dsp(ctx);
14523 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14524 break;
14525 case OPC_DPSU_H_QBL:
14526 check_dsp(ctx);
14527 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14528 break;
14529 case OPC_DPSU_H_QBR:
14530 check_dsp(ctx);
14531 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14532 break;
14533 case OPC_DPA_W_PH:
14534 check_dspr2(ctx);
14535 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14536 break;
14537 case OPC_DPAX_W_PH:
14538 check_dspr2(ctx);
14539 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
14540 break;
14541 case OPC_DPAQ_S_W_PH:
14542 check_dsp(ctx);
14543 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14544 break;
14545 case OPC_DPAQX_S_W_PH:
14546 check_dspr2(ctx);
14547 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14548 break;
14549 case OPC_DPAQX_SA_W_PH:
14550 check_dspr2(ctx);
14551 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14552 break;
14553 case OPC_DPS_W_PH:
14554 check_dspr2(ctx);
14555 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
14556 break;
14557 case OPC_DPSX_W_PH:
14558 check_dspr2(ctx);
14559 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
14560 break;
14561 case OPC_DPSQ_S_W_PH:
14562 check_dsp(ctx);
14563 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14564 break;
14565 case OPC_DPSQX_S_W_PH:
14566 check_dspr2(ctx);
14567 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14568 break;
14569 case OPC_DPSQX_SA_W_PH:
14570 check_dspr2(ctx);
14571 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14572 break;
14573 case OPC_MULSAQ_S_W_PH:
14574 check_dsp(ctx);
14575 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14576 break;
14577 case OPC_DPAQ_SA_L_W:
14578 check_dsp(ctx);
14579 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14580 break;
14581 case OPC_DPSQ_SA_L_W:
14582 check_dsp(ctx);
14583 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14584 break;
14585 case OPC_MAQ_S_W_PHL:
14586 check_dsp(ctx);
14587 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
14588 break;
14589 case OPC_MAQ_S_W_PHR:
14590 check_dsp(ctx);
14591 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
14592 break;
14593 case OPC_MAQ_SA_W_PHL:
14594 check_dsp(ctx);
14595 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
14596 break;
14597 case OPC_MAQ_SA_W_PHR:
14598 check_dsp(ctx);
14599 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
14600 break;
14601 case OPC_MULSA_W_PH:
14602 check_dspr2(ctx);
14603 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
14604 break;
14605 }
14606 break;
14607#ifdef TARGET_MIPS64
14608 case OPC_DPAQ_W_QH_DSP:
14609 {
14610 int ac = ret & 0x03;
14611 tcg_gen_movi_i32(t0, ac);
14612
14613 switch (op2) {
14614 case OPC_DMADD:
14615 check_dsp(ctx);
14616 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
14617 break;
14618 case OPC_DMADDU:
14619 check_dsp(ctx);
14620 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
14621 break;
14622 case OPC_DMSUB:
14623 check_dsp(ctx);
14624 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
14625 break;
14626 case OPC_DMSUBU:
14627 check_dsp(ctx);
14628 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
14629 break;
14630 case OPC_DPA_W_QH:
14631 check_dspr2(ctx);
14632 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
14633 break;
14634 case OPC_DPAQ_S_W_QH:
14635 check_dsp(ctx);
14636 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14637 break;
14638 case OPC_DPAQ_SA_L_PW:
14639 check_dsp(ctx);
14640 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14641 break;
14642 case OPC_DPAU_H_OBL:
14643 check_dsp(ctx);
14644 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
14645 break;
14646 case OPC_DPAU_H_OBR:
14647 check_dsp(ctx);
14648 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
14649 break;
14650 case OPC_DPS_W_QH:
14651 check_dspr2(ctx);
14652 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
14653 break;
14654 case OPC_DPSQ_S_W_QH:
14655 check_dsp(ctx);
14656 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14657 break;
14658 case OPC_DPSQ_SA_L_PW:
14659 check_dsp(ctx);
14660 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14661 break;
14662 case OPC_DPSU_H_OBL:
14663 check_dsp(ctx);
14664 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
14665 break;
14666 case OPC_DPSU_H_OBR:
14667 check_dsp(ctx);
14668 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
14669 break;
14670 case OPC_MAQ_S_L_PWL:
14671 check_dsp(ctx);
14672 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
14673 break;
14674 case OPC_MAQ_S_L_PWR:
14675 check_dsp(ctx);
14676 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
14677 break;
14678 case OPC_MAQ_S_W_QHLL:
14679 check_dsp(ctx);
14680 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
14681 break;
14682 case OPC_MAQ_SA_W_QHLL:
14683 check_dsp(ctx);
14684 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
14685 break;
14686 case OPC_MAQ_S_W_QHLR:
14687 check_dsp(ctx);
14688 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
14689 break;
14690 case OPC_MAQ_SA_W_QHLR:
14691 check_dsp(ctx);
14692 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
14693 break;
14694 case OPC_MAQ_S_W_QHRL:
14695 check_dsp(ctx);
14696 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
14697 break;
14698 case OPC_MAQ_SA_W_QHRL:
14699 check_dsp(ctx);
14700 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
14701 break;
14702 case OPC_MAQ_S_W_QHRR:
14703 check_dsp(ctx);
14704 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
14705 break;
14706 case OPC_MAQ_SA_W_QHRR:
14707 check_dsp(ctx);
14708 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
14709 break;
14710 case OPC_MULSAQ_S_L_PW:
14711 check_dsp(ctx);
14712 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
14713 break;
14714 case OPC_MULSAQ_S_W_QH:
14715 check_dsp(ctx);
14716 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14717 break;
14718 }
14719 }
14720 break;
14721#endif
14722 case OPC_ADDU_QB_DSP:
14723 switch (op2) {
14724 case OPC_MULEU_S_PH_QBL:
14725 check_dsp(ctx);
14726 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14727 break;
14728 case OPC_MULEU_S_PH_QBR:
14729 check_dsp(ctx);
14730 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14731 break;
14732 case OPC_MULQ_RS_PH:
14733 check_dsp(ctx);
14734 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14735 break;
14736 case OPC_MULEQ_S_W_PHL:
14737 check_dsp(ctx);
14738 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14739 break;
14740 case OPC_MULEQ_S_W_PHR:
14741 check_dsp(ctx);
14742 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14743 break;
14744 case OPC_MULQ_S_PH:
14745 check_dspr2(ctx);
14746 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14747 break;
14748 }
14749 break;
14750#ifdef TARGET_MIPS64
14751 case OPC_ADDU_OB_DSP:
14752 switch (op2) {
14753 case OPC_MULEQ_S_PW_QHL:
14754 check_dsp(ctx);
14755 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14756 break;
14757 case OPC_MULEQ_S_PW_QHR:
14758 check_dsp(ctx);
14759 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14760 break;
14761 case OPC_MULEU_S_QH_OBL:
14762 check_dsp(ctx);
14763 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14764 break;
14765 case OPC_MULEU_S_QH_OBR:
14766 check_dsp(ctx);
14767 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14768 break;
14769 case OPC_MULQ_RS_QH:
14770 check_dsp(ctx);
14771 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14772 break;
14773 }
14774 break;
14775#endif
14776 }
14777
14778 tcg_temp_free_i32(t0);
14779 tcg_temp_free(v1_t);
14780 tcg_temp_free(v2_t);
14781
14782 (void)opn; /* avoid a compiler warning */
14783 MIPS_DEBUG("%s", opn);
14784
14785}
14786
d75c135e 14787static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
14788 int ret, int val)
14789{
14790 const char *opn = "mipsdsp Bit/ Manipulation";
14791 int16_t imm;
14792 TCGv t0;
14793 TCGv val_t;
14794
14795 if (ret == 0) {
14796 /* Treat as NOP. */
14797 MIPS_DEBUG("NOP");
14798 return;
14799 }
14800
14801 t0 = tcg_temp_new();
14802 val_t = tcg_temp_new();
14803 gen_load_gpr(val_t, val);
14804
14805 switch (op1) {
14806 case OPC_ABSQ_S_PH_DSP:
14807 switch (op2) {
14808 case OPC_BITREV:
14809 check_dsp(ctx);
14810 gen_helper_bitrev(cpu_gpr[ret], val_t);
14811 break;
14812 case OPC_REPL_QB:
14813 check_dsp(ctx);
14814 {
14815 target_long result;
14816 imm = (ctx->opcode >> 16) & 0xFF;
14817 result = (uint32_t)imm << 24 |
14818 (uint32_t)imm << 16 |
14819 (uint32_t)imm << 8 |
14820 (uint32_t)imm;
14821 result = (int32_t)result;
14822 tcg_gen_movi_tl(cpu_gpr[ret], result);
14823 }
14824 break;
14825 case OPC_REPLV_QB:
14826 check_dsp(ctx);
14827 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14832 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14833 break;
14834 case OPC_REPL_PH:
14835 check_dsp(ctx);
14836 {
14837 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 14838 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
14839 tcg_gen_movi_tl(cpu_gpr[ret], \
14840 (target_long)((int32_t)imm << 16 | \
c4aaba92 14841 (uint16_t)imm));
1cb6686c
JL
14842 }
14843 break;
14844 case OPC_REPLV_PH:
14845 check_dsp(ctx);
14846 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14847 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14848 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14849 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14850 break;
14851 }
14852 break;
14853#ifdef TARGET_MIPS64
14854 case OPC_ABSQ_S_QH_DSP:
14855 switch (op2) {
14856 case OPC_REPL_OB:
14857 check_dsp(ctx);
14858 {
14859 target_long temp;
14860
14861 imm = (ctx->opcode >> 16) & 0xFF;
14862 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
14863 temp = (temp << 16) | temp;
14864 temp = (temp << 32) | temp;
14865 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14866 break;
14867 }
14868 case OPC_REPL_PW:
14869 check_dsp(ctx);
14870 {
14871 target_long temp;
14872
14873 imm = (ctx->opcode >> 16) & 0x03FF;
14874 imm = (int16_t)(imm << 6) >> 6;
14875 temp = ((target_long)imm << 32) \
14876 | ((target_long)imm & 0xFFFFFFFF);
14877 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14878 break;
14879 }
14880 case OPC_REPL_QH:
14881 check_dsp(ctx);
14882 {
14883 target_long temp;
14884
14885 imm = (ctx->opcode >> 16) & 0x03FF;
14886 imm = (int16_t)(imm << 6) >> 6;
14887
14888 temp = ((uint64_t)(uint16_t)imm << 48) |
14889 ((uint64_t)(uint16_t)imm << 32) |
14890 ((uint64_t)(uint16_t)imm << 16) |
14891 (uint64_t)(uint16_t)imm;
14892 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14893 break;
14894 }
14895 case OPC_REPLV_OB:
14896 check_dsp(ctx);
14897 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14898 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14899 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14900 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14901 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14902 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14903 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14904 break;
14905 case OPC_REPLV_PW:
14906 check_dsp(ctx);
14907 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
14908 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14909 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14910 break;
14911 case OPC_REPLV_QH:
14912 check_dsp(ctx);
14913 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14914 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14915 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14916 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14917 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14918 break;
14919 }
14920 break;
14921#endif
14922 }
14923 tcg_temp_free(t0);
14924 tcg_temp_free(val_t);
14925
14926 (void)opn; /* avoid a compiler warning */
14927 MIPS_DEBUG("%s", opn);
14928}
14929
26690560
JL
14930static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
14931 uint32_t op1, uint32_t op2,
14932 int ret, int v1, int v2, int check_ret)
14933{
14934 const char *opn = "mipsdsp add compare pick";
26690560
JL
14935 TCGv t1;
14936 TCGv v1_t;
14937 TCGv v2_t;
14938
14939 if ((ret == 0) && (check_ret == 1)) {
14940 /* Treat as NOP. */
14941 MIPS_DEBUG("NOP");
14942 return;
14943 }
14944
26690560
JL
14945 t1 = tcg_temp_new();
14946 v1_t = tcg_temp_new();
14947 v2_t = tcg_temp_new();
14948
14949 gen_load_gpr(v1_t, v1);
14950 gen_load_gpr(v2_t, v2);
14951
14952 switch (op1) {
26690560
JL
14953 case OPC_CMPU_EQ_QB_DSP:
14954 switch (op2) {
14955 case OPC_CMPU_EQ_QB:
14956 check_dsp(ctx);
14957 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
14958 break;
14959 case OPC_CMPU_LT_QB:
14960 check_dsp(ctx);
14961 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
14962 break;
14963 case OPC_CMPU_LE_QB:
14964 check_dsp(ctx);
14965 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
14966 break;
14967 case OPC_CMPGU_EQ_QB:
14968 check_dsp(ctx);
14969 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
14970 break;
14971 case OPC_CMPGU_LT_QB:
14972 check_dsp(ctx);
14973 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
14974 break;
14975 case OPC_CMPGU_LE_QB:
14976 check_dsp(ctx);
14977 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
14978 break;
14979 case OPC_CMPGDU_EQ_QB:
14980 check_dspr2(ctx);
14981 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
14982 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14983 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14984 tcg_gen_shli_tl(t1, t1, 24);
14985 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14986 break;
14987 case OPC_CMPGDU_LT_QB:
14988 check_dspr2(ctx);
14989 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
14990 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14991 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14992 tcg_gen_shli_tl(t1, t1, 24);
14993 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14994 break;
14995 case OPC_CMPGDU_LE_QB:
14996 check_dspr2(ctx);
14997 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14998 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14999 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15000 tcg_gen_shli_tl(t1, t1, 24);
15001 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15002 break;
15003 case OPC_CMP_EQ_PH:
15004 check_dsp(ctx);
15005 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15006 break;
15007 case OPC_CMP_LT_PH:
15008 check_dsp(ctx);
15009 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15010 break;
15011 case OPC_CMP_LE_PH:
15012 check_dsp(ctx);
15013 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15014 break;
15015 case OPC_PICK_QB:
15016 check_dsp(ctx);
15017 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15018 break;
15019 case OPC_PICK_PH:
15020 check_dsp(ctx);
15021 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15022 break;
15023 case OPC_PACKRL_PH:
15024 check_dsp(ctx);
15025 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15026 break;
15027 }
15028 break;
15029#ifdef TARGET_MIPS64
15030 case OPC_CMPU_EQ_OB_DSP:
15031 switch (op2) {
15032 case OPC_CMP_EQ_PW:
15033 check_dsp(ctx);
15034 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15035 break;
15036 case OPC_CMP_LT_PW:
15037 check_dsp(ctx);
15038 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15039 break;
15040 case OPC_CMP_LE_PW:
15041 check_dsp(ctx);
15042 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15043 break;
15044 case OPC_CMP_EQ_QH:
15045 check_dsp(ctx);
15046 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15047 break;
15048 case OPC_CMP_LT_QH:
15049 check_dsp(ctx);
15050 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15051 break;
15052 case OPC_CMP_LE_QH:
15053 check_dsp(ctx);
15054 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15055 break;
15056 case OPC_CMPGDU_EQ_OB:
15057 check_dspr2(ctx);
15058 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15059 break;
15060 case OPC_CMPGDU_LT_OB:
15061 check_dspr2(ctx);
15062 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15063 break;
15064 case OPC_CMPGDU_LE_OB:
15065 check_dspr2(ctx);
15066 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15067 break;
15068 case OPC_CMPGU_EQ_OB:
15069 check_dsp(ctx);
15070 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15071 break;
15072 case OPC_CMPGU_LT_OB:
15073 check_dsp(ctx);
15074 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15075 break;
15076 case OPC_CMPGU_LE_OB:
15077 check_dsp(ctx);
15078 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15079 break;
15080 case OPC_CMPU_EQ_OB:
15081 check_dsp(ctx);
15082 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15083 break;
15084 case OPC_CMPU_LT_OB:
15085 check_dsp(ctx);
15086 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15087 break;
15088 case OPC_CMPU_LE_OB:
15089 check_dsp(ctx);
15090 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15091 break;
15092 case OPC_PACKRL_PW:
15093 check_dsp(ctx);
15094 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15095 break;
15096 case OPC_PICK_OB:
15097 check_dsp(ctx);
15098 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15099 break;
15100 case OPC_PICK_PW:
15101 check_dsp(ctx);
15102 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15103 break;
15104 case OPC_PICK_QH:
15105 check_dsp(ctx);
15106 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15107 break;
15108 }
15109 break;
df6126a7
AJ
15110#endif
15111 }
15112
15113 tcg_temp_free(t1);
15114 tcg_temp_free(v1_t);
15115 tcg_temp_free(v2_t);
15116
15117 (void)opn; /* avoid a compiler warning */
15118 MIPS_DEBUG("%s", opn);
15119}
15120
15121static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15122 uint32_t op1, int rt, int rs, int sa)
15123{
15124 const char *opn = "mipsdsp append/dappend";
15125 TCGv t0;
15126
15127 check_dspr2(ctx);
15128
15129 if (rt == 0) {
15130 /* Treat as NOP. */
15131 MIPS_DEBUG("NOP");
15132 return;
15133 }
15134
15135 t0 = tcg_temp_new();
15136 gen_load_gpr(t0, rs);
15137
15138 switch (op1) {
15139 case OPC_APPEND_DSP:
15140 switch (MASK_APPEND(ctx->opcode)) {
15141 case OPC_APPEND:
15142 if (sa != 0) {
15143 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15144 }
15145 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15146 break;
15147 case OPC_PREPEND:
15148 if (sa != 0) {
15149 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15150 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15151 tcg_gen_shli_tl(t0, t0, 32 - sa);
15152 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15153 }
15154 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15155 break;
15156 case OPC_BALIGN:
15157 sa &= 3;
15158 if (sa != 0 && sa != 2) {
15159 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15160 tcg_gen_ext32u_tl(t0, t0);
15161 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15162 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15163 }
15164 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15165 break;
15166 default: /* Invalid */
15167 MIPS_INVAL("MASK APPEND");
15168 generate_exception(ctx, EXCP_RI);
15169 break;
15170 }
15171 break;
15172#ifdef TARGET_MIPS64
26690560 15173 case OPC_DAPPEND_DSP:
df6126a7 15174 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 15175 case OPC_DAPPEND:
df6126a7
AJ
15176 if (sa != 0) {
15177 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15178 }
26690560
JL
15179 break;
15180 case OPC_PREPENDD:
df6126a7
AJ
15181 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15182 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15183 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
15184 break;
15185 case OPC_PREPENDW:
df6126a7
AJ
15186 if (sa != 0) {
15187 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15188 tcg_gen_shli_tl(t0, t0, 64 - sa);
15189 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15190 }
26690560
JL
15191 break;
15192 case OPC_DBALIGN:
df6126a7
AJ
15193 sa &= 7;
15194 if (sa != 0 && sa != 2 && sa != 4) {
15195 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15196 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15197 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15198 }
26690560
JL
15199 break;
15200 default: /* Invalid */
15201 MIPS_INVAL("MASK DAPPEND");
15202 generate_exception(ctx, EXCP_RI);
15203 break;
15204 }
15205 break;
15206#endif
15207 }
df6126a7 15208 tcg_temp_free(t0);
26690560
JL
15209 (void)opn; /* avoid a compiler warning */
15210 MIPS_DEBUG("%s", opn);
15211}
15212
b53371ed
JL
15213static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15214 int ret, int v1, int v2, int check_ret)
15215
15216{
15217 const char *opn = "mipsdsp accumulator";
15218 TCGv t0;
15219 TCGv t1;
15220 TCGv v1_t;
15221 TCGv v2_t;
15222 int16_t imm;
15223
15224 if ((ret == 0) && (check_ret == 1)) {
15225 /* Treat as NOP. */
15226 MIPS_DEBUG("NOP");
15227 return;
15228 }
15229
15230 t0 = tcg_temp_new();
15231 t1 = tcg_temp_new();
15232 v1_t = tcg_temp_new();
15233 v2_t = tcg_temp_new();
15234
15235 gen_load_gpr(v1_t, v1);
15236 gen_load_gpr(v2_t, v2);
15237
15238 switch (op1) {
15239 case OPC_EXTR_W_DSP:
15240 check_dsp(ctx);
15241 switch (op2) {
15242 case OPC_EXTR_W:
15243 tcg_gen_movi_tl(t0, v2);
15244 tcg_gen_movi_tl(t1, v1);
15245 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15246 break;
15247 case OPC_EXTR_R_W:
15248 tcg_gen_movi_tl(t0, v2);
15249 tcg_gen_movi_tl(t1, v1);
15250 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15251 break;
15252 case OPC_EXTR_RS_W:
15253 tcg_gen_movi_tl(t0, v2);
15254 tcg_gen_movi_tl(t1, v1);
15255 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15256 break;
15257 case OPC_EXTR_S_H:
15258 tcg_gen_movi_tl(t0, v2);
15259 tcg_gen_movi_tl(t1, v1);
15260 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15261 break;
15262 case OPC_EXTRV_S_H:
15263 tcg_gen_movi_tl(t0, v2);
15264 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15265 break;
15266 case OPC_EXTRV_W:
15267 tcg_gen_movi_tl(t0, v2);
15268 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15269 break;
15270 case OPC_EXTRV_R_W:
15271 tcg_gen_movi_tl(t0, v2);
15272 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15273 break;
15274 case OPC_EXTRV_RS_W:
15275 tcg_gen_movi_tl(t0, v2);
15276 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15277 break;
15278 case OPC_EXTP:
15279 tcg_gen_movi_tl(t0, v2);
15280 tcg_gen_movi_tl(t1, v1);
15281 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15282 break;
15283 case OPC_EXTPV:
15284 tcg_gen_movi_tl(t0, v2);
15285 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15286 break;
15287 case OPC_EXTPDP:
15288 tcg_gen_movi_tl(t0, v2);
15289 tcg_gen_movi_tl(t1, v1);
15290 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15291 break;
15292 case OPC_EXTPDPV:
15293 tcg_gen_movi_tl(t0, v2);
15294 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15295 break;
15296 case OPC_SHILO:
15297 imm = (ctx->opcode >> 20) & 0x3F;
15298 tcg_gen_movi_tl(t0, ret);
15299 tcg_gen_movi_tl(t1, imm);
15300 gen_helper_shilo(t0, t1, cpu_env);
15301 break;
15302 case OPC_SHILOV:
15303 tcg_gen_movi_tl(t0, ret);
15304 gen_helper_shilo(t0, v1_t, cpu_env);
15305 break;
15306 case OPC_MTHLIP:
15307 tcg_gen_movi_tl(t0, ret);
15308 gen_helper_mthlip(t0, v1_t, cpu_env);
15309 break;
15310 case OPC_WRDSP:
15311 imm = (ctx->opcode >> 11) & 0x3FF;
15312 tcg_gen_movi_tl(t0, imm);
15313 gen_helper_wrdsp(v1_t, t0, cpu_env);
15314 break;
15315 case OPC_RDDSP:
15316 imm = (ctx->opcode >> 16) & 0x03FF;
15317 tcg_gen_movi_tl(t0, imm);
15318 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15319 break;
15320 }
15321 break;
15322#ifdef TARGET_MIPS64
15323 case OPC_DEXTR_W_DSP:
15324 check_dsp(ctx);
15325 switch (op2) {
15326 case OPC_DMTHLIP:
15327 tcg_gen_movi_tl(t0, ret);
15328 gen_helper_dmthlip(v1_t, t0, cpu_env);
15329 break;
15330 case OPC_DSHILO:
15331 {
15332 int shift = (ctx->opcode >> 19) & 0x7F;
15333 int ac = (ctx->opcode >> 11) & 0x03;
15334 tcg_gen_movi_tl(t0, shift);
15335 tcg_gen_movi_tl(t1, ac);
15336 gen_helper_dshilo(t0, t1, cpu_env);
15337 break;
15338 }
15339 case OPC_DSHILOV:
15340 {
15341 int ac = (ctx->opcode >> 11) & 0x03;
15342 tcg_gen_movi_tl(t0, ac);
15343 gen_helper_dshilo(v1_t, t0, cpu_env);
15344 break;
15345 }
15346 case OPC_DEXTP:
15347 tcg_gen_movi_tl(t0, v2);
15348 tcg_gen_movi_tl(t1, v1);
15349
15350 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15351 break;
15352 case OPC_DEXTPV:
15353 tcg_gen_movi_tl(t0, v2);
15354 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15355 break;
15356 case OPC_DEXTPDP:
15357 tcg_gen_movi_tl(t0, v2);
15358 tcg_gen_movi_tl(t1, v1);
15359 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15360 break;
15361 case OPC_DEXTPDPV:
15362 tcg_gen_movi_tl(t0, v2);
15363 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15364 break;
15365 case OPC_DEXTR_L:
15366 tcg_gen_movi_tl(t0, v2);
15367 tcg_gen_movi_tl(t1, v1);
15368 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15369 break;
15370 case OPC_DEXTR_R_L:
15371 tcg_gen_movi_tl(t0, v2);
15372 tcg_gen_movi_tl(t1, v1);
15373 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15374 break;
15375 case OPC_DEXTR_RS_L:
15376 tcg_gen_movi_tl(t0, v2);
15377 tcg_gen_movi_tl(t1, v1);
15378 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15379 break;
15380 case OPC_DEXTR_W:
15381 tcg_gen_movi_tl(t0, v2);
15382 tcg_gen_movi_tl(t1, v1);
15383 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15384 break;
15385 case OPC_DEXTR_R_W:
15386 tcg_gen_movi_tl(t0, v2);
15387 tcg_gen_movi_tl(t1, v1);
15388 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15389 break;
15390 case OPC_DEXTR_RS_W:
15391 tcg_gen_movi_tl(t0, v2);
15392 tcg_gen_movi_tl(t1, v1);
15393 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15394 break;
15395 case OPC_DEXTR_S_H:
15396 tcg_gen_movi_tl(t0, v2);
15397 tcg_gen_movi_tl(t1, v1);
15398 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15399 break;
15400 case OPC_DEXTRV_S_H:
15401 tcg_gen_movi_tl(t0, v2);
15402 tcg_gen_movi_tl(t1, v1);
15403 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15404 break;
15405 case OPC_DEXTRV_L:
15406 tcg_gen_movi_tl(t0, v2);
15407 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15408 break;
15409 case OPC_DEXTRV_R_L:
15410 tcg_gen_movi_tl(t0, v2);
15411 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15412 break;
15413 case OPC_DEXTRV_RS_L:
15414 tcg_gen_movi_tl(t0, v2);
15415 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15416 break;
15417 case OPC_DEXTRV_W:
15418 tcg_gen_movi_tl(t0, v2);
15419 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15420 break;
15421 case OPC_DEXTRV_R_W:
15422 tcg_gen_movi_tl(t0, v2);
15423 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15424 break;
15425 case OPC_DEXTRV_RS_W:
15426 tcg_gen_movi_tl(t0, v2);
15427 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15428 break;
15429 }
15430 break;
15431#endif
15432 }
15433
15434 tcg_temp_free(t0);
15435 tcg_temp_free(t1);
15436 tcg_temp_free(v1_t);
15437 tcg_temp_free(v2_t);
15438
15439 (void)opn; /* avoid a compiler warning */
15440 MIPS_DEBUG("%s", opn);
15441}
15442
9b1a1d68
JL
15443/* End MIPSDSP functions. */
15444
31837be3
YK
15445/* Compact Branches */
15446static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15447 int rs, int rt, int32_t offset)
15448{
15449 int bcond_compute = 0;
15450 TCGv t0 = tcg_temp_new();
15451 TCGv t1 = tcg_temp_new();
15452
15453 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15454#ifdef MIPS_DEBUG_DISAS
15455 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
15456#endif
15457 generate_exception(ctx, EXCP_RI);
15458 goto out;
15459 }
15460
15461 /* Load needed operands and calculate btarget */
15462 switch (opc) {
15463 /* compact branch */
15464 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15465 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15466 gen_load_gpr(t0, rs);
15467 gen_load_gpr(t1, rt);
15468 bcond_compute = 1;
15469 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15470 if (rs <= rt && rs == 0) {
15471 /* OPC_BEQZALC, OPC_BNEZALC */
15472 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15473 }
15474 break;
15475 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15476 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15477 gen_load_gpr(t0, rs);
15478 gen_load_gpr(t1, rt);
15479 bcond_compute = 1;
15480 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15481 break;
15482 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15483 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15484 if (rs == 0 || rs == rt) {
15485 /* OPC_BLEZALC, OPC_BGEZALC */
15486 /* OPC_BGTZALC, OPC_BLTZALC */
15487 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15488 }
15489 gen_load_gpr(t0, rs);
15490 gen_load_gpr(t1, rt);
15491 bcond_compute = 1;
15492 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15493 break;
15494 case OPC_BC:
15495 case OPC_BALC:
15496 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15497 break;
15498 case OPC_BEQZC:
15499 case OPC_BNEZC:
15500 if (rs != 0) {
15501 /* OPC_BEQZC, OPC_BNEZC */
15502 gen_load_gpr(t0, rs);
15503 bcond_compute = 1;
15504 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15505 } else {
15506 /* OPC_JIC, OPC_JIALC */
15507 TCGv tbase = tcg_temp_new();
15508 TCGv toffset = tcg_temp_new();
15509
15510 gen_load_gpr(tbase, rt);
15511 tcg_gen_movi_tl(toffset, offset);
15512 gen_op_addr_add(ctx, btarget, tbase, toffset);
15513 tcg_temp_free(tbase);
15514 tcg_temp_free(toffset);
15515 }
15516 break;
15517 default:
15518 MIPS_INVAL("Compact branch/jump");
15519 generate_exception(ctx, EXCP_RI);
15520 goto out;
15521 }
15522
15523 if (bcond_compute == 0) {
15524 /* Uncoditional compact branch */
15525 switch (opc) {
15526 case OPC_JIALC:
15527 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15528 /* Fallthrough */
15529 case OPC_JIC:
15530 ctx->hflags |= MIPS_HFLAG_BR;
15531 break;
15532 case OPC_BALC:
15533 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15534 /* Fallthrough */
15535 case OPC_BC:
15536 ctx->hflags |= MIPS_HFLAG_B;
15537 break;
15538 default:
15539 MIPS_INVAL("Compact branch/jump");
15540 generate_exception(ctx, EXCP_RI);
15541 goto out;
15542 }
15543
15544 /* Generating branch here as compact branches don't have delay slot */
15545 gen_branch(ctx, 4);
15546 } else {
15547 /* Conditional compact branch */
15548 int l1 = gen_new_label();
15549 save_cpu_state(ctx, 0);
15550
15551 switch (opc) {
15552 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15553 if (rs == 0 && rt != 0) {
15554 /* OPC_BLEZALC */
15555 tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
15556 } else if (rs != 0 && rt != 0 && rs == rt) {
15557 /* OPC_BGEZALC */
15558 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
15559 } else {
15560 /* OPC_BGEUC */
15561 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
15562 }
15563 break;
15564 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15565 if (rs == 0 && rt != 0) {
15566 /* OPC_BGTZALC */
15567 tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
15568 } else if (rs != 0 && rt != 0 && rs == rt) {
15569 /* OPC_BLTZALC */
15570 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
15571 } else {
15572 /* OPC_BLTUC */
15573 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
15574 }
15575 break;
15576 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15577 if (rs == 0 && rt != 0) {
15578 /* OPC_BLEZC */
15579 tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
15580 } else if (rs != 0 && rt != 0 && rs == rt) {
15581 /* OPC_BGEZC */
15582 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
15583 } else {
15584 /* OPC_BGEC */
15585 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
15586 }
15587 break;
15588 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15589 if (rs == 0 && rt != 0) {
15590 /* OPC_BGTZC */
15591 tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
15592 } else if (rs != 0 && rt != 0 && rs == rt) {
15593 /* OPC_BLTZC */
15594 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
15595 } else {
15596 /* OPC_BLTC */
15597 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
15598 }
15599 break;
15600 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15601 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15602 if (rs >= rt) {
15603 /* OPC_BOVC, OPC_BNVC */
15604 TCGv t2 = tcg_temp_new();
15605 TCGv t3 = tcg_temp_new();
15606 TCGv t4 = tcg_temp_new();
15607 TCGv input_overflow = tcg_temp_new();
15608
15609 gen_load_gpr(t0, rs);
15610 gen_load_gpr(t1, rt);
15611 tcg_gen_ext32s_tl(t2, t0);
15612 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
15613 tcg_gen_ext32s_tl(t3, t1);
15614 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
15615 tcg_gen_or_tl(input_overflow, input_overflow, t4);
15616
15617 tcg_gen_add_tl(t4, t2, t3);
15618 tcg_gen_ext32s_tl(t4, t4);
15619 tcg_gen_xor_tl(t2, t2, t3);
15620 tcg_gen_xor_tl(t3, t4, t3);
15621 tcg_gen_andc_tl(t2, t3, t2);
15622 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
15623 tcg_gen_or_tl(t4, t4, input_overflow);
15624 if (opc == OPC_BOVC) {
15625 /* OPC_BOVC */
15626 tcg_gen_brcondi_tl(TCG_COND_NE, t4, 0, l1);
15627 } else {
15628 /* OPC_BNVC */
15629 tcg_gen_brcondi_tl(TCG_COND_EQ, t4, 0, l1);
15630 }
15631 tcg_temp_free(input_overflow);
15632 tcg_temp_free(t4);
15633 tcg_temp_free(t3);
15634 tcg_temp_free(t2);
15635 } else if (rs < rt && rs == 0) {
15636 /* OPC_BEQZALC, OPC_BNEZALC */
15637 if (opc == OPC_BEQZALC) {
15638 /* OPC_BEQZALC */
15639 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
15640 } else {
15641 /* OPC_BNEZALC */
15642 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
15643 }
15644 } else {
15645 /* OPC_BEQC, OPC_BNEC */
15646 if (opc == OPC_BEQC) {
15647 /* OPC_BEQC */
15648 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
15649 } else {
15650 /* OPC_BNEC */
15651 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
15652 }
15653 }
15654 break;
15655 case OPC_BEQZC:
15656 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
15657 break;
15658 case OPC_BNEZC:
15659 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
15660 break;
15661 default:
15662 MIPS_INVAL("Compact conditional branch/jump");
15663 generate_exception(ctx, EXCP_RI);
15664 goto out;
15665 }
15666
15667 /* Generating branch here as compact branches don't have delay slot */
15668 /* TODO: implement forbidden slot */
15669 gen_goto_tb(ctx, 1, ctx->pc + 4);
15670 gen_set_label(l1);
15671 gen_goto_tb(ctx, 0, ctx->btarget);
15672 MIPS_DEBUG("Compact conditional branch");
15673 ctx->bstate = BS_BRANCH;
15674 }
15675
15676out:
15677 tcg_temp_free(t0);
15678 tcg_temp_free(t1);
15679}
15680
10dc65db
LA
15681static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
15682{
4267d3e6 15683 int rs, rt, rd, sa;
b42ee5e1 15684 uint32_t op1, op2;
10dc65db
LA
15685
15686 rs = (ctx->opcode >> 21) & 0x1f;
15687 rt = (ctx->opcode >> 16) & 0x1f;
15688 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 15689 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
15690
15691 op1 = MASK_SPECIAL(ctx->opcode);
15692 switch (op1) {
d4ea6acd
LA
15693 case OPC_LSA:
15694 if (rd != 0) {
15695 int imm2 = extract32(ctx->opcode, 6, 3);
15696 TCGv t0 = tcg_temp_new();
15697 TCGv t1 = tcg_temp_new();
15698 gen_load_gpr(t0, rs);
15699 gen_load_gpr(t1, rt);
15700 tcg_gen_shli_tl(t0, t0, imm2 + 1);
15701 tcg_gen_add_tl(t0, t0, t1);
15702 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
15703 tcg_temp_free(t1);
15704 tcg_temp_free(t0);
15705 }
15706 break;
b42ee5e1
LA
15707 case OPC_MULT ... OPC_DIVU:
15708 op2 = MASK_R6_MULDIV(ctx->opcode);
15709 switch (op2) {
15710 case R6_OPC_MUL:
15711 case R6_OPC_MUH:
15712 case R6_OPC_MULU:
15713 case R6_OPC_MUHU:
15714 case R6_OPC_DIV:
15715 case R6_OPC_MOD:
15716 case R6_OPC_DIVU:
15717 case R6_OPC_MODU:
15718 gen_r6_muldiv(ctx, op2, rd, rs, rt);
15719 break;
15720 default:
15721 MIPS_INVAL("special_r6 muldiv");
15722 generate_exception(ctx, EXCP_RI);
15723 break;
15724 }
15725 break;
10dc65db
LA
15726 case OPC_SELEQZ:
15727 case OPC_SELNEZ:
15728 gen_cond_move(ctx, op1, rd, rs, rt);
15729 break;
4267d3e6
LA
15730 case R6_OPC_CLO:
15731 case R6_OPC_CLZ:
15732 if (rt == 0 && sa == 1) {
15733 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15734 We need additionally to check other fields */
15735 gen_cl(ctx, op1, rd, rs);
15736 } else {
15737 generate_exception(ctx, EXCP_RI);
15738 }
15739 break;
15740 case R6_OPC_SDBBP:
15741 generate_exception(ctx, EXCP_DBp);
15742 break;
b42ee5e1 15743#if defined(TARGET_MIPS64)
d4ea6acd
LA
15744 case OPC_DLSA:
15745 check_mips_64(ctx);
15746 if (rd != 0) {
15747 int imm2 = extract32(ctx->opcode, 6, 3);
15748 TCGv t0 = tcg_temp_new();
15749 TCGv t1 = tcg_temp_new();
15750 gen_load_gpr(t0, rs);
15751 gen_load_gpr(t1, rt);
15752 tcg_gen_shli_tl(t0, t0, imm2 + 1);
15753 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
15754 tcg_temp_free(t1);
15755 tcg_temp_free(t0);
15756 }
15757 break;
4267d3e6
LA
15758 case R6_OPC_DCLO:
15759 case R6_OPC_DCLZ:
15760 if (rt == 0 && sa == 1) {
15761 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15762 We need additionally to check other fields */
15763 check_mips_64(ctx);
15764 gen_cl(ctx, op1, rd, rs);
15765 } else {
15766 generate_exception(ctx, EXCP_RI);
15767 }
15768 break;
b42ee5e1
LA
15769 case OPC_DMULT ... OPC_DDIVU:
15770 op2 = MASK_R6_MULDIV(ctx->opcode);
15771 switch (op2) {
15772 case R6_OPC_DMUL:
15773 case R6_OPC_DMUH:
15774 case R6_OPC_DMULU:
15775 case R6_OPC_DMUHU:
15776 case R6_OPC_DDIV:
15777 case R6_OPC_DMOD:
15778 case R6_OPC_DDIVU:
15779 case R6_OPC_DMODU:
15780 check_mips_64(ctx);
15781 gen_r6_muldiv(ctx, op2, rd, rs, rt);
15782 break;
15783 default:
15784 MIPS_INVAL("special_r6 muldiv");
15785 generate_exception(ctx, EXCP_RI);
15786 break;
15787 }
15788 break;
15789#endif
10dc65db
LA
15790 default: /* Invalid */
15791 MIPS_INVAL("special_r6");
15792 generate_exception(ctx, EXCP_RI);
15793 break;
15794 }
15795}
15796
15797static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
15798{
b42ee5e1 15799 int rs, rt, rd, sa;
10dc65db
LA
15800 uint32_t op1;
15801
15802 rs = (ctx->opcode >> 21) & 0x1f;
15803 rt = (ctx->opcode >> 16) & 0x1f;
15804 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 15805 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
15806
15807 op1 = MASK_SPECIAL(ctx->opcode);
15808 switch (op1) {
15809 case OPC_MOVN: /* Conditional move */
15810 case OPC_MOVZ:
15811 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
15812 INSN_LOONGSON2E | INSN_LOONGSON2F);
15813 gen_cond_move(ctx, op1, rd, rs, rt);
15814 break;
15815 case OPC_MFHI: /* Move from HI/LO */
15816 case OPC_MFLO:
15817 gen_HILO(ctx, op1, rs & 3, rd);
15818 break;
15819 case OPC_MTHI:
15820 case OPC_MTLO: /* Move to HI/LO */
15821 gen_HILO(ctx, op1, rd & 3, rs);
15822 break;
15823 case OPC_MOVCI:
15824 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15825 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15826 check_cp1_enabled(ctx);
15827 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
15828 (ctx->opcode >> 16) & 1);
15829 } else {
15830 generate_exception_err(ctx, EXCP_CpU, 1);
15831 }
15832 break;
b42ee5e1
LA
15833 case OPC_MULT:
15834 case OPC_MULTU:
15835 if (sa) {
15836 check_insn(ctx, INSN_VR54XX);
15837 op1 = MASK_MUL_VR54XX(ctx->opcode);
15838 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
15839 } else {
15840 gen_muldiv(ctx, op1, rd & 3, rs, rt);
15841 }
15842 break;
15843 case OPC_DIV:
15844 case OPC_DIVU:
15845 gen_muldiv(ctx, op1, 0, rs, rt);
15846 break;
15847#if defined(TARGET_MIPS64)
15848 case OPC_DMULT ... OPC_DDIVU:
15849 check_insn(ctx, ISA_MIPS3);
15850 check_mips_64(ctx);
15851 gen_muldiv(ctx, op1, 0, rs, rt);
15852 break;
15853#endif
0aefa333
YK
15854 case OPC_JR:
15855 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
15856 break;
4267d3e6
LA
15857 case OPC_SPIM:
15858#ifdef MIPS_STRICT_STANDARD
15859 MIPS_INVAL("SPIM");
15860 generate_exception(ctx, EXCP_RI);
15861#else
15862 /* Implemented as RI exception for now. */
15863 MIPS_INVAL("spim (unofficial)");
15864 generate_exception(ctx, EXCP_RI);
15865#endif
15866 break;
10dc65db
LA
15867 default: /* Invalid */
15868 MIPS_INVAL("special_legacy");
15869 generate_exception(ctx, EXCP_RI);
15870 break;
15871 }
15872}
15873
099e5b4d 15874static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 15875{
3c824109 15876 int rs, rt, rd, sa;
099e5b4d 15877 uint32_t op1;
3c824109 15878
3c824109
NF
15879 rs = (ctx->opcode >> 21) & 0x1f;
15880 rt = (ctx->opcode >> 16) & 0x1f;
15881 rd = (ctx->opcode >> 11) & 0x1f;
15882 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
15883
15884 op1 = MASK_SPECIAL(ctx->opcode);
15885 switch (op1) {
15886 case OPC_SLL: /* Shift with immediate */
15887 case OPC_SRA:
15888 gen_shift_imm(ctx, op1, rd, rt, sa);
15889 break;
15890 case OPC_SRL:
15891 switch ((ctx->opcode >> 21) & 0x1f) {
15892 case 1:
15893 /* rotr is decoded as srl on non-R2 CPUs */
15894 if (ctx->insn_flags & ISA_MIPS32R2) {
15895 op1 = OPC_ROTR;
ea63e2c3 15896 }
099e5b4d
LA
15897 /* Fallthrough */
15898 case 0:
15899 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 15900 break;
099e5b4d
LA
15901 default:
15902 generate_exception(ctx, EXCP_RI);
ea63e2c3 15903 break;
099e5b4d
LA
15904 }
15905 break;
099e5b4d
LA
15906 case OPC_ADD ... OPC_SUBU:
15907 gen_arith(ctx, op1, rd, rs, rt);
15908 break;
15909 case OPC_SLLV: /* Shifts */
15910 case OPC_SRAV:
15911 gen_shift(ctx, op1, rd, rs, rt);
15912 break;
15913 case OPC_SRLV:
15914 switch ((ctx->opcode >> 6) & 0x1f) {
15915 case 1:
15916 /* rotrv is decoded as srlv on non-R2 CPUs */
15917 if (ctx->insn_flags & ISA_MIPS32R2) {
15918 op1 = OPC_ROTRV;
26135ead 15919 }
099e5b4d
LA
15920 /* Fallthrough */
15921 case 0:
15922 gen_shift(ctx, op1, rd, rs, rt);
26135ead 15923 break;
099e5b4d
LA
15924 default:
15925 generate_exception(ctx, EXCP_RI);
6af0bf9c 15926 break;
099e5b4d
LA
15927 }
15928 break;
15929 case OPC_SLT: /* Set on less than */
15930 case OPC_SLTU:
15931 gen_slt(ctx, op1, rd, rs, rt);
15932 break;
15933 case OPC_AND: /* Logic*/
15934 case OPC_OR:
15935 case OPC_NOR:
15936 case OPC_XOR:
15937 gen_logic(ctx, op1, rd, rs, rt);
15938 break;
0aefa333 15939 case OPC_JALR:
099e5b4d
LA
15940 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
15941 break;
15942 case OPC_TGE ... OPC_TEQ: /* Traps */
15943 case OPC_TNE:
15944 gen_trap(ctx, op1, rs, rt, -1);
15945 break;
d4ea6acd
LA
15946 case OPC_LSA: /* OPC_PMON */
15947 if (ctx->insn_flags & ISA_MIPS32R6) {
15948 decode_opc_special_r6(env, ctx);
15949 } else {
15950 /* Pmon entry point, also R4010 selsl */
b48cfdff 15951#ifdef MIPS_STRICT_STANDARD
d4ea6acd
LA
15952 MIPS_INVAL("PMON / selsl");
15953 generate_exception(ctx, EXCP_RI);
b48cfdff 15954#else
d4ea6acd 15955 gen_helper_0e0i(pmon, sa);
b48cfdff 15956#endif
d4ea6acd 15957 }
099e5b4d
LA
15958 break;
15959 case OPC_SYSCALL:
15960 generate_exception(ctx, EXCP_SYSCALL);
15961 ctx->bstate = BS_STOP;
15962 break;
15963 case OPC_BREAK:
15964 generate_exception(ctx, EXCP_BREAK);
15965 break;
099e5b4d
LA
15966 case OPC_SYNC:
15967 /* Treat as NOP. */
15968 break;
4ad40f36 15969
d26bc211 15970#if defined(TARGET_MIPS64)
099e5b4d
LA
15971 /* MIPS64 specific opcodes */
15972 case OPC_DSLL:
15973 case OPC_DSRA:
15974 case OPC_DSLL32:
15975 case OPC_DSRA32:
15976 check_insn(ctx, ISA_MIPS3);
15977 check_mips_64(ctx);
15978 gen_shift_imm(ctx, op1, rd, rt, sa);
15979 break;
15980 case OPC_DSRL:
15981 switch ((ctx->opcode >> 21) & 0x1f) {
15982 case 1:
15983 /* drotr is decoded as dsrl on non-R2 CPUs */
15984 if (ctx->insn_flags & ISA_MIPS32R2) {
15985 op1 = OPC_DROTR;
ea63e2c3 15986 }
099e5b4d
LA
15987 /* Fallthrough */
15988 case 0:
d75c135e 15989 check_insn(ctx, ISA_MIPS3);
e189e748 15990 check_mips_64(ctx);
099e5b4d 15991 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 15992 break;
099e5b4d
LA
15993 default:
15994 generate_exception(ctx, EXCP_RI);
460f00c4 15995 break;
099e5b4d
LA
15996 }
15997 break;
15998 case OPC_DSRL32:
15999 switch ((ctx->opcode >> 21) & 0x1f) {
16000 case 1:
16001 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16002 if (ctx->insn_flags & ISA_MIPS32R2) {
16003 op1 = OPC_DROTR32;
ea63e2c3 16004 }
099e5b4d
LA
16005 /* Fallthrough */
16006 case 0:
d75c135e 16007 check_insn(ctx, ISA_MIPS3);
e189e748 16008 check_mips_64(ctx);
099e5b4d 16009 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 16010 break;
099e5b4d 16011 default:
6af0bf9c
FB
16012 generate_exception(ctx, EXCP_RI);
16013 break;
16014 }
16015 break;
099e5b4d
LA
16016 case OPC_DADD ... OPC_DSUBU:
16017 check_insn(ctx, ISA_MIPS3);
16018 check_mips_64(ctx);
16019 gen_arith(ctx, op1, rd, rs, rt);
16020 break;
16021 case OPC_DSLLV:
16022 case OPC_DSRAV:
16023 check_insn(ctx, ISA_MIPS3);
16024 check_mips_64(ctx);
16025 gen_shift(ctx, op1, rd, rs, rt);
16026 break;
16027 case OPC_DSRLV:
16028 switch ((ctx->opcode >> 6) & 0x1f) {
16029 case 1:
16030 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16031 if (ctx->insn_flags & ISA_MIPS32R2) {
16032 op1 = OPC_DROTRV;
6af0bf9c 16033 }
099e5b4d
LA
16034 /* Fallthrough */
16035 case 0:
16036 check_insn(ctx, ISA_MIPS3);
e189e748 16037 check_mips_64(ctx);
099e5b4d 16038 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 16039 break;
099e5b4d 16040 default:
6af0bf9c
FB
16041 generate_exception(ctx, EXCP_RI);
16042 break;
16043 }
16044 break;
099e5b4d 16045#endif
10dc65db
LA
16046 default:
16047 if (ctx->insn_flags & ISA_MIPS32R6) {
16048 decode_opc_special_r6(env, ctx);
16049 } else {
16050 decode_opc_special_legacy(env, ctx);
16051 }
16052 }
16053}
16054
10dc65db 16055static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
16056{
16057 int rs, rt, rd;
16058 uint32_t op1;
6c5c1e20 16059
4267d3e6
LA
16060 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16061
099e5b4d
LA
16062 rs = (ctx->opcode >> 21) & 0x1f;
16063 rt = (ctx->opcode >> 16) & 0x1f;
16064 rd = (ctx->opcode >> 11) & 0x1f;
16065
16066 op1 = MASK_SPECIAL2(ctx->opcode);
16067 switch (op1) {
16068 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16069 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
16070 check_insn(ctx, ISA_MIPS32);
16071 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16072 break;
16073 case OPC_MUL:
099e5b4d
LA
16074 gen_arith(ctx, op1, rd, rs, rt);
16075 break;
fac5a073
LA
16076 case OPC_DIV_G_2F:
16077 case OPC_DIVU_G_2F:
16078 case OPC_MULT_G_2F:
16079 case OPC_MULTU_G_2F:
16080 case OPC_MOD_G_2F:
16081 case OPC_MODU_G_2F:
16082 check_insn(ctx, INSN_LOONGSON2F);
16083 gen_loongson_integer(ctx, op1, rd, rs, rt);
16084 break;
099e5b4d
LA
16085 case OPC_CLO:
16086 case OPC_CLZ:
16087 check_insn(ctx, ISA_MIPS32);
16088 gen_cl(ctx, op1, rd, rs);
16089 break;
16090 case OPC_SDBBP:
16091 /* XXX: not clear which exception should be raised
16092 * when in debug mode...
16093 */
16094 check_insn(ctx, ISA_MIPS32);
16095 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16096 generate_exception(ctx, EXCP_DBp);
16097 } else {
16098 generate_exception(ctx, EXCP_DBp);
16099 }
16100 /* Treat as NOP. */
16101 break;
9b1a1d68 16102#if defined(TARGET_MIPS64)
099e5b4d
LA
16103 case OPC_DCLO:
16104 case OPC_DCLZ:
16105 check_insn(ctx, ISA_MIPS64);
16106 check_mips_64(ctx);
16107 gen_cl(ctx, op1, rd, rs);
16108 break;
4267d3e6
LA
16109 case OPC_DMULT_G_2F:
16110 case OPC_DMULTU_G_2F:
16111 case OPC_DDIV_G_2F:
16112 case OPC_DDIVU_G_2F:
16113 case OPC_DMOD_G_2F:
16114 case OPC_DMODU_G_2F:
16115 check_insn(ctx, INSN_LOONGSON2F);
16116 gen_loongson_integer(ctx, op1, rd, rs, rt);
16117 break;
10dc65db 16118#endif
4267d3e6
LA
16119 default: /* Invalid */
16120 MIPS_INVAL("special2_legacy");
16121 generate_exception(ctx, EXCP_RI);
16122 break;
10dc65db
LA
16123 }
16124}
16125
16126static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16127{
15eacb9b
YK
16128 int rs, rt, rd, sa;
16129 uint32_t op1, op2;
10dc65db
LA
16130 int16_t imm;
16131
16132 rs = (ctx->opcode >> 21) & 0x1f;
16133 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
16134 rd = (ctx->opcode >> 11) & 0x1f;
16135 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
16136 imm = (int16_t)ctx->opcode >> 7;
16137
16138 op1 = MASK_SPECIAL3(ctx->opcode);
16139 switch (op1) {
bf7910c6
LA
16140 case R6_OPC_PREF:
16141 if (rt >= 24) {
16142 /* hint codes 24-31 are reserved and signal RI */
16143 generate_exception(ctx, EXCP_RI);
16144 }
16145 /* Treat as NOP. */
16146 break;
16147 case R6_OPC_CACHE:
16148 /* Treat as NOP. */
16149 break;
10dc65db
LA
16150 case R6_OPC_SC:
16151 gen_st_cond(ctx, op1, rt, rs, imm);
16152 break;
16153 case R6_OPC_LL:
16154 gen_ld(ctx, op1, rt, rs, imm);
16155 break;
15eacb9b
YK
16156 case OPC_BSHFL:
16157 {
16158 if (rd == 0) {
16159 /* Treat as NOP. */
16160 break;
16161 }
16162 TCGv t0 = tcg_temp_new();
16163 gen_load_gpr(t0, rt);
16164
16165 op2 = MASK_BSHFL(ctx->opcode);
16166 switch (op2) {
16167 case OPC_ALIGN ... OPC_ALIGN_END:
16168 sa &= 3;
16169 if (sa == 0) {
16170 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16171 } else {
16172 TCGv t1 = tcg_temp_new();
16173 TCGv_i64 t2 = tcg_temp_new_i64();
16174 gen_load_gpr(t1, rs);
16175 tcg_gen_concat_tl_i64(t2, t1, t0);
16176 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16177#if defined(TARGET_MIPS64)
16178 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16179#else
16180 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16181#endif
16182 tcg_temp_free_i64(t2);
16183 tcg_temp_free(t1);
16184 }
16185 break;
16186 case OPC_BITSWAP:
16187 gen_helper_bitswap(cpu_gpr[rd], t0);
16188 break;
16189 }
16190 tcg_temp_free(t0);
16191 }
16192 break;
bf7910c6
LA
16193#if defined(TARGET_MIPS64)
16194 case R6_OPC_SCD:
16195 gen_st_cond(ctx, op1, rt, rs, imm);
16196 break;
16197 case R6_OPC_LLD:
16198 gen_ld(ctx, op1, rt, rs, imm);
16199 break;
15eacb9b
YK
16200 case OPC_DBSHFL:
16201 check_mips_64(ctx);
16202 {
16203 if (rd == 0) {
16204 /* Treat as NOP. */
16205 break;
16206 }
16207 TCGv t0 = tcg_temp_new();
16208 gen_load_gpr(t0, rt);
16209
16210 op2 = MASK_DBSHFL(ctx->opcode);
16211 switch (op2) {
16212 case OPC_DALIGN ... OPC_DALIGN_END:
16213 sa &= 7;
16214 if (sa == 0) {
16215 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16216 } else {
16217 TCGv t1 = tcg_temp_new();
16218 gen_load_gpr(t1, rs);
16219 tcg_gen_shli_tl(t0, t0, 8 * sa);
16220 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16221 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16222 tcg_temp_free(t1);
16223 }
16224 break;
16225 case OPC_DBITSWAP:
16226 gen_helper_dbitswap(cpu_gpr[rd], t0);
16227 break;
16228 }
16229 tcg_temp_free(t0);
16230 }
16231 break;
bf7910c6 16232#endif
10dc65db
LA
16233 default: /* Invalid */
16234 MIPS_INVAL("special3_r6");
16235 generate_exception(ctx, EXCP_RI);
16236 break;
16237 }
16238}
16239
16240static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16241{
fac5a073 16242 int rs, rt, rd;
099e5b4d 16243 uint32_t op1, op2;
099e5b4d
LA
16244
16245 rs = (ctx->opcode >> 21) & 0x1f;
16246 rt = (ctx->opcode >> 16) & 0x1f;
16247 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
16248
16249 op1 = MASK_SPECIAL3(ctx->opcode);
16250 switch (op1) {
099e5b4d
LA
16251 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16252 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16253 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16254 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16255 * the same mask and op1. */
16256 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16257 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 16258 switch (op2) {
099e5b4d
LA
16259 case OPC_ADDUH_QB:
16260 case OPC_ADDUH_R_QB:
16261 case OPC_ADDQH_PH:
16262 case OPC_ADDQH_R_PH:
16263 case OPC_ADDQH_W:
16264 case OPC_ADDQH_R_W:
16265 case OPC_SUBUH_QB:
16266 case OPC_SUBUH_R_QB:
16267 case OPC_SUBQH_PH:
16268 case OPC_SUBQH_R_PH:
16269 case OPC_SUBQH_W:
16270 case OPC_SUBQH_R_W:
461c08df
JL
16271 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16272 break;
099e5b4d
LA
16273 case OPC_MUL_PH:
16274 case OPC_MUL_S_PH:
16275 case OPC_MULQ_S_W:
16276 case OPC_MULQ_RS_W:
16277 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16278 break;
461c08df 16279 default:
099e5b4d 16280 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
16281 generate_exception(ctx, EXCP_RI);
16282 break;
16283 }
099e5b4d
LA
16284 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16285 gen_loongson_integer(ctx, op1, rd, rs, rt);
16286 } else {
16287 generate_exception(ctx, EXCP_RI);
16288 }
16289 break;
16290 case OPC_LX_DSP:
16291 op2 = MASK_LX(ctx->opcode);
16292 switch (op2) {
16293#if defined(TARGET_MIPS64)
16294 case OPC_LDX:
16295#endif
16296 case OPC_LBUX:
16297 case OPC_LHX:
16298 case OPC_LWX:
16299 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16300 break;
16301 default: /* Invalid */
16302 MIPS_INVAL("MASK LX");
16303 generate_exception(ctx, EXCP_RI);
16304 break;
16305 }
16306 break;
16307 case OPC_ABSQ_S_PH_DSP:
16308 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16309 switch (op2) {
16310 case OPC_ABSQ_S_QB:
16311 case OPC_ABSQ_S_PH:
16312 case OPC_ABSQ_S_W:
16313 case OPC_PRECEQ_W_PHL:
16314 case OPC_PRECEQ_W_PHR:
16315 case OPC_PRECEQU_PH_QBL:
16316 case OPC_PRECEQU_PH_QBR:
16317 case OPC_PRECEQU_PH_QBLA:
16318 case OPC_PRECEQU_PH_QBRA:
16319 case OPC_PRECEU_PH_QBL:
16320 case OPC_PRECEU_PH_QBR:
16321 case OPC_PRECEU_PH_QBLA:
16322 case OPC_PRECEU_PH_QBRA:
16323 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16324 break;
16325 case OPC_BITREV:
16326 case OPC_REPL_QB:
16327 case OPC_REPLV_QB:
16328 case OPC_REPL_PH:
16329 case OPC_REPLV_PH:
16330 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16331 break;
16332 default:
16333 MIPS_INVAL("MASK ABSQ_S.PH");
16334 generate_exception(ctx, EXCP_RI);
16335 break;
16336 }
16337 break;
16338 case OPC_ADDU_QB_DSP:
16339 op2 = MASK_ADDU_QB(ctx->opcode);
16340 switch (op2) {
16341 case OPC_ADDQ_PH:
16342 case OPC_ADDQ_S_PH:
16343 case OPC_ADDQ_S_W:
16344 case OPC_ADDU_QB:
16345 case OPC_ADDU_S_QB:
16346 case OPC_ADDU_PH:
16347 case OPC_ADDU_S_PH:
16348 case OPC_SUBQ_PH:
16349 case OPC_SUBQ_S_PH:
16350 case OPC_SUBQ_S_W:
16351 case OPC_SUBU_QB:
16352 case OPC_SUBU_S_QB:
16353 case OPC_SUBU_PH:
16354 case OPC_SUBU_S_PH:
16355 case OPC_ADDSC:
16356 case OPC_ADDWC:
16357 case OPC_MODSUB:
16358 case OPC_RADDU_W_QB:
16359 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16360 break;
16361 case OPC_MULEU_S_PH_QBL:
16362 case OPC_MULEU_S_PH_QBR:
16363 case OPC_MULQ_RS_PH:
16364 case OPC_MULEQ_S_W_PHL:
16365 case OPC_MULEQ_S_W_PHR:
16366 case OPC_MULQ_S_PH:
16367 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16368 break;
16369 default: /* Invalid */
16370 MIPS_INVAL("MASK ADDU.QB");
16371 generate_exception(ctx, EXCP_RI);
461c08df 16372 break;
461c08df 16373
099e5b4d
LA
16374 }
16375 break;
16376 case OPC_CMPU_EQ_QB_DSP:
16377 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16378 switch (op2) {
16379 case OPC_PRECR_SRA_PH_W:
16380 case OPC_PRECR_SRA_R_PH_W:
16381 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 16382 break;
099e5b4d
LA
16383 case OPC_PRECR_QB_PH:
16384 case OPC_PRECRQ_QB_PH:
16385 case OPC_PRECRQ_PH_W:
16386 case OPC_PRECRQ_RS_PH_W:
16387 case OPC_PRECRQU_S_QB_PH:
16388 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 16389 break;
099e5b4d
LA
16390 case OPC_CMPU_EQ_QB:
16391 case OPC_CMPU_LT_QB:
16392 case OPC_CMPU_LE_QB:
16393 case OPC_CMP_EQ_PH:
16394 case OPC_CMP_LT_PH:
16395 case OPC_CMP_LE_PH:
16396 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 16397 break;
099e5b4d
LA
16398 case OPC_CMPGU_EQ_QB:
16399 case OPC_CMPGU_LT_QB:
16400 case OPC_CMPGU_LE_QB:
16401 case OPC_CMPGDU_EQ_QB:
16402 case OPC_CMPGDU_LT_QB:
16403 case OPC_CMPGDU_LE_QB:
16404 case OPC_PICK_QB:
16405 case OPC_PICK_PH:
16406 case OPC_PACKRL_PH:
16407 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16408 break;
16409 default: /* Invalid */
16410 MIPS_INVAL("MASK CMPU.EQ.QB");
16411 generate_exception(ctx, EXCP_RI);
16412 break;
16413 }
16414 break;
16415 case OPC_SHLL_QB_DSP:
16416 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16417 break;
16418 case OPC_DPA_W_PH_DSP:
16419 op2 = MASK_DPA_W_PH(ctx->opcode);
16420 switch (op2) {
16421 case OPC_DPAU_H_QBL:
16422 case OPC_DPAU_H_QBR:
16423 case OPC_DPSU_H_QBL:
16424 case OPC_DPSU_H_QBR:
16425 case OPC_DPA_W_PH:
16426 case OPC_DPAX_W_PH:
16427 case OPC_DPAQ_S_W_PH:
16428 case OPC_DPAQX_S_W_PH:
16429 case OPC_DPAQX_SA_W_PH:
16430 case OPC_DPS_W_PH:
16431 case OPC_DPSX_W_PH:
16432 case OPC_DPSQ_S_W_PH:
16433 case OPC_DPSQX_S_W_PH:
16434 case OPC_DPSQX_SA_W_PH:
16435 case OPC_MULSAQ_S_W_PH:
16436 case OPC_DPAQ_SA_L_W:
16437 case OPC_DPSQ_SA_L_W:
16438 case OPC_MAQ_S_W_PHL:
16439 case OPC_MAQ_S_W_PHR:
16440 case OPC_MAQ_SA_W_PHL:
16441 case OPC_MAQ_SA_W_PHR:
16442 case OPC_MULSA_W_PH:
16443 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16444 break;
16445 default: /* Invalid */
16446 MIPS_INVAL("MASK DPAW.PH");
16447 generate_exception(ctx, EXCP_RI);
16448 break;
16449 }
16450 break;
16451 case OPC_INSV_DSP:
16452 op2 = MASK_INSV(ctx->opcode);
16453 switch (op2) {
16454 case OPC_INSV:
16455 check_dsp(ctx);
16456 {
16457 TCGv t0, t1;
16458
16459 if (rt == 0) {
16460 MIPS_DEBUG("NOP");
16461 break;
16462 }
16463
16464 t0 = tcg_temp_new();
16465 t1 = tcg_temp_new();
16466
16467 gen_load_gpr(t0, rt);
16468 gen_load_gpr(t1, rs);
16469
16470 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16471
16472 tcg_temp_free(t0);
16473 tcg_temp_free(t1);
a22260ae
JL
16474 break;
16475 }
099e5b4d
LA
16476 default: /* Invalid */
16477 MIPS_INVAL("MASK INSV");
16478 generate_exception(ctx, EXCP_RI);
16479 break;
16480 }
16481 break;
16482 case OPC_APPEND_DSP:
16483 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16484 break;
16485 case OPC_EXTR_W_DSP:
16486 op2 = MASK_EXTR_W(ctx->opcode);
16487 switch (op2) {
16488 case OPC_EXTR_W:
16489 case OPC_EXTR_R_W:
16490 case OPC_EXTR_RS_W:
16491 case OPC_EXTR_S_H:
16492 case OPC_EXTRV_S_H:
16493 case OPC_EXTRV_W:
16494 case OPC_EXTRV_R_W:
16495 case OPC_EXTRV_RS_W:
16496 case OPC_EXTP:
16497 case OPC_EXTPV:
16498 case OPC_EXTPDP:
16499 case OPC_EXTPDPV:
16500 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16501 break;
16502 case OPC_RDDSP:
16503 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16504 break;
16505 case OPC_SHILO:
16506 case OPC_SHILOV:
16507 case OPC_MTHLIP:
16508 case OPC_WRDSP:
16509 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16510 break;
16511 default: /* Invalid */
16512 MIPS_INVAL("MASK EXTR.W");
16513 generate_exception(ctx, EXCP_RI);
16514 break;
16515 }
16516 break;
099e5b4d 16517#if defined(TARGET_MIPS64)
fac5a073
LA
16518 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
16519 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
16520 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
16521 check_insn(ctx, INSN_LOONGSON2E);
16522 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 16523 break;
099e5b4d
LA
16524 case OPC_ABSQ_S_QH_DSP:
16525 op2 = MASK_ABSQ_S_QH(ctx->opcode);
16526 switch (op2) {
16527 case OPC_PRECEQ_L_PWL:
16528 case OPC_PRECEQ_L_PWR:
16529 case OPC_PRECEQ_PW_QHL:
16530 case OPC_PRECEQ_PW_QHR:
16531 case OPC_PRECEQ_PW_QHLA:
16532 case OPC_PRECEQ_PW_QHRA:
16533 case OPC_PRECEQU_QH_OBL:
16534 case OPC_PRECEQU_QH_OBR:
16535 case OPC_PRECEQU_QH_OBLA:
16536 case OPC_PRECEQU_QH_OBRA:
16537 case OPC_PRECEU_QH_OBL:
16538 case OPC_PRECEU_QH_OBR:
16539 case OPC_PRECEU_QH_OBLA:
16540 case OPC_PRECEU_QH_OBRA:
16541 case OPC_ABSQ_S_OB:
16542 case OPC_ABSQ_S_PW:
16543 case OPC_ABSQ_S_QH:
16544 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16545 break;
16546 case OPC_REPL_OB:
16547 case OPC_REPL_PW:
16548 case OPC_REPL_QH:
16549 case OPC_REPLV_OB:
16550 case OPC_REPLV_PW:
16551 case OPC_REPLV_QH:
16552 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16553 break;
16554 default: /* Invalid */
16555 MIPS_INVAL("MASK ABSQ_S.QH");
16556 generate_exception(ctx, EXCP_RI);
16557 break;
16558 }
16559 break;
16560 case OPC_ADDU_OB_DSP:
16561 op2 = MASK_ADDU_OB(ctx->opcode);
16562 switch (op2) {
16563 case OPC_RADDU_L_OB:
16564 case OPC_SUBQ_PW:
16565 case OPC_SUBQ_S_PW:
16566 case OPC_SUBQ_QH:
16567 case OPC_SUBQ_S_QH:
16568 case OPC_SUBU_OB:
16569 case OPC_SUBU_S_OB:
16570 case OPC_SUBU_QH:
16571 case OPC_SUBU_S_QH:
16572 case OPC_SUBUH_OB:
16573 case OPC_SUBUH_R_OB:
16574 case OPC_ADDQ_PW:
16575 case OPC_ADDQ_S_PW:
16576 case OPC_ADDQ_QH:
16577 case OPC_ADDQ_S_QH:
16578 case OPC_ADDU_OB:
16579 case OPC_ADDU_S_OB:
16580 case OPC_ADDU_QH:
16581 case OPC_ADDU_S_QH:
16582 case OPC_ADDUH_OB:
16583 case OPC_ADDUH_R_OB:
16584 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 16585 break;
099e5b4d
LA
16586 case OPC_MULEQ_S_PW_QHL:
16587 case OPC_MULEQ_S_PW_QHR:
16588 case OPC_MULEU_S_QH_OBL:
16589 case OPC_MULEU_S_QH_OBR:
16590 case OPC_MULQ_RS_QH:
16591 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 16592 break;
099e5b4d
LA
16593 default: /* Invalid */
16594 MIPS_INVAL("MASK ADDU.OB");
16595 generate_exception(ctx, EXCP_RI);
26690560 16596 break;
099e5b4d
LA
16597 }
16598 break;
16599 case OPC_CMPU_EQ_OB_DSP:
16600 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
16601 switch (op2) {
16602 case OPC_PRECR_SRA_QH_PW:
16603 case OPC_PRECR_SRA_R_QH_PW:
16604 /* Return value is rt. */
16605 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 16606 break;
099e5b4d
LA
16607 case OPC_PRECR_OB_QH:
16608 case OPC_PRECRQ_OB_QH:
16609 case OPC_PRECRQ_PW_L:
16610 case OPC_PRECRQ_QH_PW:
16611 case OPC_PRECRQ_RS_QH_PW:
16612 case OPC_PRECRQU_S_OB_QH:
16613 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 16614 break;
099e5b4d
LA
16615 case OPC_CMPU_EQ_OB:
16616 case OPC_CMPU_LT_OB:
16617 case OPC_CMPU_LE_OB:
16618 case OPC_CMP_EQ_QH:
16619 case OPC_CMP_LT_QH:
16620 case OPC_CMP_LE_QH:
16621 case OPC_CMP_EQ_PW:
16622 case OPC_CMP_LT_PW:
16623 case OPC_CMP_LE_PW:
16624 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 16625 break;
099e5b4d
LA
16626 case OPC_CMPGDU_EQ_OB:
16627 case OPC_CMPGDU_LT_OB:
16628 case OPC_CMPGDU_LE_OB:
16629 case OPC_CMPGU_EQ_OB:
16630 case OPC_CMPGU_LT_OB:
16631 case OPC_CMPGU_LE_OB:
16632 case OPC_PACKRL_PW:
16633 case OPC_PICK_OB:
16634 case OPC_PICK_PW:
16635 case OPC_PICK_QH:
16636 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 16637 break;
099e5b4d
LA
16638 default: /* Invalid */
16639 MIPS_INVAL("MASK CMPU_EQ.OB");
16640 generate_exception(ctx, EXCP_RI);
161f85e6 16641 break;
099e5b4d
LA
16642 }
16643 break;
16644 case OPC_DAPPEND_DSP:
16645 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16646 break;
16647 case OPC_DEXTR_W_DSP:
16648 op2 = MASK_DEXTR_W(ctx->opcode);
16649 switch (op2) {
16650 case OPC_DEXTP:
16651 case OPC_DEXTPDP:
16652 case OPC_DEXTPDPV:
16653 case OPC_DEXTPV:
16654 case OPC_DEXTR_L:
16655 case OPC_DEXTR_R_L:
16656 case OPC_DEXTR_RS_L:
16657 case OPC_DEXTR_W:
16658 case OPC_DEXTR_R_W:
16659 case OPC_DEXTR_RS_W:
16660 case OPC_DEXTR_S_H:
16661 case OPC_DEXTRV_L:
16662 case OPC_DEXTRV_R_L:
16663 case OPC_DEXTRV_RS_L:
16664 case OPC_DEXTRV_S_H:
16665 case OPC_DEXTRV_W:
16666 case OPC_DEXTRV_R_W:
16667 case OPC_DEXTRV_RS_W:
16668 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 16669 break;
099e5b4d
LA
16670 case OPC_DMTHLIP:
16671 case OPC_DSHILO:
16672 case OPC_DSHILOV:
16673 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 16674 break;
099e5b4d
LA
16675 default: /* Invalid */
16676 MIPS_INVAL("MASK EXTR.W");
16677 generate_exception(ctx, EXCP_RI);
461c08df 16678 break;
099e5b4d
LA
16679 }
16680 break;
16681 case OPC_DPAQ_W_QH_DSP:
16682 op2 = MASK_DPAQ_W_QH(ctx->opcode);
16683 switch (op2) {
16684 case OPC_DPAU_H_OBL:
16685 case OPC_DPAU_H_OBR:
16686 case OPC_DPSU_H_OBL:
16687 case OPC_DPSU_H_OBR:
16688 case OPC_DPA_W_QH:
16689 case OPC_DPAQ_S_W_QH:
16690 case OPC_DPS_W_QH:
16691 case OPC_DPSQ_S_W_QH:
16692 case OPC_MULSAQ_S_W_QH:
16693 case OPC_DPAQ_SA_L_PW:
16694 case OPC_DPSQ_SA_L_PW:
16695 case OPC_MULSAQ_S_L_PW:
16696 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16697 break;
16698 case OPC_MAQ_S_W_QHLL:
16699 case OPC_MAQ_S_W_QHLR:
16700 case OPC_MAQ_S_W_QHRL:
16701 case OPC_MAQ_S_W_QHRR:
16702 case OPC_MAQ_SA_W_QHLL:
16703 case OPC_MAQ_SA_W_QHLR:
16704 case OPC_MAQ_SA_W_QHRL:
16705 case OPC_MAQ_SA_W_QHRR:
16706 case OPC_MAQ_S_L_PWL:
16707 case OPC_MAQ_S_L_PWR:
16708 case OPC_DMADD:
16709 case OPC_DMADDU:
16710 case OPC_DMSUB:
16711 case OPC_DMSUBU:
16712 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 16713 break;
099e5b4d
LA
16714 default: /* Invalid */
16715 MIPS_INVAL("MASK DPAQ.W.QH");
16716 generate_exception(ctx, EXCP_RI);
b53371ed 16717 break;
099e5b4d
LA
16718 }
16719 break;
16720 case OPC_DINSV_DSP:
16721 op2 = MASK_INSV(ctx->opcode);
16722 switch (op2) {
16723 case OPC_DINSV:
16724 {
16725 TCGv t0, t1;
16726
16727 if (rt == 0) {
16728 MIPS_DEBUG("NOP");
a22260ae
JL
16729 break;
16730 }
099e5b4d 16731 check_dsp(ctx);
1cb6686c 16732
099e5b4d
LA
16733 t0 = tcg_temp_new();
16734 t1 = tcg_temp_new();
1cb6686c 16735
099e5b4d
LA
16736 gen_load_gpr(t0, rt);
16737 gen_load_gpr(t1, rs);
1cb6686c 16738
099e5b4d 16739 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 16740
099e5b4d
LA
16741 tcg_temp_free(t0);
16742 tcg_temp_free(t1);
77c5fa8b 16743 break;
099e5b4d 16744 }
7a387fff 16745 default: /* Invalid */
099e5b4d 16746 MIPS_INVAL("MASK DINSV");
7a387fff
TS
16747 generate_exception(ctx, EXCP_RI);
16748 break;
16749 }
16750 break;
099e5b4d
LA
16751 case OPC_SHLL_OB_DSP:
16752 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16753 break;
16754#endif
fac5a073
LA
16755 default: /* Invalid */
16756 MIPS_INVAL("special3_legacy");
16757 generate_exception(ctx, EXCP_RI);
16758 break;
16759 }
16760}
16761
16762static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
16763{
16764 int rs, rt, rd, sa;
16765 uint32_t op1, op2;
16766
16767 rs = (ctx->opcode >> 21) & 0x1f;
16768 rt = (ctx->opcode >> 16) & 0x1f;
16769 rd = (ctx->opcode >> 11) & 0x1f;
16770 sa = (ctx->opcode >> 6) & 0x1f;
16771
16772 op1 = MASK_SPECIAL3(ctx->opcode);
16773 switch (op1) {
16774 case OPC_EXT:
16775 case OPC_INS:
16776 check_insn(ctx, ISA_MIPS32R2);
16777 gen_bitops(ctx, op1, rt, rs, sa, rd);
16778 break;
16779 case OPC_BSHFL:
fac5a073 16780 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
16781 switch (op2) {
16782 case OPC_ALIGN ... OPC_ALIGN_END:
16783 case OPC_BITSWAP:
16784 check_insn(ctx, ISA_MIPS32R6);
16785 decode_opc_special3_r6(env, ctx);
16786 break;
16787 default:
16788 check_insn(ctx, ISA_MIPS32R2);
16789 gen_bshfl(ctx, op2, rt, rd);
16790 break;
16791 }
fac5a073
LA
16792 break;
16793#if defined(TARGET_MIPS64)
16794 case OPC_DEXTM ... OPC_DEXT:
16795 case OPC_DINSM ... OPC_DINS:
16796 check_insn(ctx, ISA_MIPS64R2);
16797 check_mips_64(ctx);
16798 gen_bitops(ctx, op1, rt, rs, sa, rd);
16799 break;
16800 case OPC_DBSHFL:
fac5a073 16801 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
16802 switch (op2) {
16803 case OPC_DALIGN ... OPC_DALIGN_END:
16804 case OPC_DBITSWAP:
16805 check_insn(ctx, ISA_MIPS32R6);
16806 decode_opc_special3_r6(env, ctx);
16807 break;
16808 default:
16809 check_insn(ctx, ISA_MIPS64R2);
16810 check_mips_64(ctx);
16811 op2 = MASK_DBSHFL(ctx->opcode);
16812 gen_bshfl(ctx, op2, rt, rd);
16813 break;
16814 }
fac5a073
LA
16815 break;
16816#endif
16817 case OPC_RDHWR:
16818 gen_rdhwr(ctx, rt, rd);
16819 break;
16820 case OPC_FORK:
16821 check_insn(ctx, ASE_MT);
16822 {
16823 TCGv t0 = tcg_temp_new();
16824 TCGv t1 = tcg_temp_new();
16825
16826 gen_load_gpr(t0, rt);
16827 gen_load_gpr(t1, rs);
16828 gen_helper_fork(t0, t1);
16829 tcg_temp_free(t0);
16830 tcg_temp_free(t1);
16831 }
16832 break;
16833 case OPC_YIELD:
16834 check_insn(ctx, ASE_MT);
16835 {
16836 TCGv t0 = tcg_temp_new();
16837
16838 save_cpu_state(ctx, 1);
16839 gen_load_gpr(t0, rs);
16840 gen_helper_yield(t0, cpu_env, t0);
16841 gen_store_gpr(t0, rd);
16842 tcg_temp_free(t0);
16843 }
16844 break;
10dc65db
LA
16845 default:
16846 if (ctx->insn_flags & ISA_MIPS32R6) {
16847 decode_opc_special3_r6(env, ctx);
16848 } else {
16849 decode_opc_special3_legacy(env, ctx);
16850 }
099e5b4d
LA
16851 }
16852}
16853
16854static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
16855{
16856 int32_t offset;
16857 int rs, rt, rd, sa;
16858 uint32_t op, op1;
16859 int16_t imm;
16860
16861 /* make sure instructions are on a word boundary */
16862 if (ctx->pc & 0x3) {
16863 env->CP0_BadVAddr = ctx->pc;
16864 generate_exception(ctx, EXCP_AdEL);
16865 return;
16866 }
16867
16868 /* Handle blikely not taken case */
16869 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
16870 int l1 = gen_new_label();
16871
16872 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
16873 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
16874 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
16875 gen_goto_tb(ctx, 1, ctx->pc + 4);
16876 gen_set_label(l1);
16877 }
16878
16879 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
16880 tcg_gen_debug_insn_start(ctx->pc);
16881 }
16882
16883 op = MASK_OP_MAJOR(ctx->opcode);
16884 rs = (ctx->opcode >> 21) & 0x1f;
16885 rt = (ctx->opcode >> 16) & 0x1f;
16886 rd = (ctx->opcode >> 11) & 0x1f;
16887 sa = (ctx->opcode >> 6) & 0x1f;
16888 imm = (int16_t)ctx->opcode;
16889 switch (op) {
16890 case OPC_SPECIAL:
16891 decode_opc_special(env, ctx);
16892 break;
16893 case OPC_SPECIAL2:
4267d3e6 16894 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
16895 break;
16896 case OPC_SPECIAL3:
16897 decode_opc_special3(env, ctx);
16898 break;
7a387fff
TS
16899 case OPC_REGIMM:
16900 op1 = MASK_REGIMM(ctx->opcode);
16901 switch (op1) {
fecd2646
LA
16902 case OPC_BLTZL: /* REGIMM branches */
16903 case OPC_BGEZL:
16904 case OPC_BLTZALL:
16905 case OPC_BGEZALL:
16906 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16907 case OPC_BLTZ:
16908 case OPC_BGEZ:
0aefa333
YK
16909 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
16910 break;
fecd2646
LA
16911 case OPC_BLTZAL:
16912 case OPC_BGEZAL:
0aefa333
YK
16913 if (ctx->insn_flags & ISA_MIPS32R6) {
16914 if (rs == 0) {
16915 /* OPC_NAL, OPC_BAL */
16916 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2);
16917 } else {
16918 generate_exception(ctx, EXCP_RI);
16919 }
16920 } else {
16921 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
16922 }
c9602061 16923 break;
7a387fff
TS
16924 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
16925 case OPC_TNEI:
fecd2646 16926 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
16927 gen_trap(ctx, op1, rs, -1, imm);
16928 break;
16929 case OPC_SYNCI:
d75c135e 16930 check_insn(ctx, ISA_MIPS32R2);
ead9360e 16931 /* Treat as NOP. */
6af0bf9c 16932 break;
e45a93e2
JL
16933 case OPC_BPOSGE32: /* MIPS DSP branch */
16934#if defined(TARGET_MIPS64)
16935 case OPC_BPOSGE64:
16936#endif
16937 check_dsp(ctx);
16938 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 16939 break;
d4ea6acd
LA
16940#if defined(TARGET_MIPS64)
16941 case OPC_DAHI:
16942 check_insn(ctx, ISA_MIPS32R6);
16943 check_mips_64(ctx);
16944 if (rs != 0) {
16945 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
16946 }
16947 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
16948 break;
16949 case OPC_DATI:
16950 check_insn(ctx, ISA_MIPS32R6);
16951 check_mips_64(ctx);
16952 if (rs != 0) {
16953 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
16954 }
16955 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
16956 break;
16957#endif
6af0bf9c 16958 default: /* Invalid */
923617a3 16959 MIPS_INVAL("regimm");
6af0bf9c
FB
16960 generate_exception(ctx, EXCP_RI);
16961 break;
16962 }
16963 break;
7a387fff 16964 case OPC_CP0:
387a8fe5 16965 check_cp0_enabled(ctx);
7a387fff 16966 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 16967 switch (op1) {
7a387fff
TS
16968 case OPC_MFC0:
16969 case OPC_MTC0:
ead9360e
TS
16970 case OPC_MFTR:
16971 case OPC_MTTR:
d26bc211 16972#if defined(TARGET_MIPS64)
7a387fff
TS
16973 case OPC_DMFC0:
16974 case OPC_DMTC0:
16975#endif
f1aa6320 16976#ifndef CONFIG_USER_ONLY
932e71cd 16977 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 16978#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
16979 break;
16980 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 16981#ifndef CONFIG_USER_ONLY
932e71cd 16982 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 16983#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
16984 break;
16985 case OPC_MFMC0:
8706c382 16986#ifndef CONFIG_USER_ONLY
932e71cd 16987 {
099e5b4d 16988 uint32_t op2;
35fbce2c 16989 TCGv t0 = tcg_temp_new();
6c5c1e20 16990
0eaef5aa 16991 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
16992 switch (op2) {
16993 case OPC_DMT:
d75c135e 16994 check_insn(ctx, ASE_MT);
9ed5726c 16995 gen_helper_dmt(t0);
35fbce2c 16996 gen_store_gpr(t0, rt);
6c5c1e20
TS
16997 break;
16998 case OPC_EMT:
d75c135e 16999 check_insn(ctx, ASE_MT);
9ed5726c 17000 gen_helper_emt(t0);
35fbce2c 17001 gen_store_gpr(t0, rt);
da80682b 17002 break;
6c5c1e20 17003 case OPC_DVPE:
d75c135e 17004 check_insn(ctx, ASE_MT);
895c2d04 17005 gen_helper_dvpe(t0, cpu_env);
35fbce2c 17006 gen_store_gpr(t0, rt);
6c5c1e20
TS
17007 break;
17008 case OPC_EVPE:
d75c135e 17009 check_insn(ctx, ASE_MT);
895c2d04 17010 gen_helper_evpe(t0, cpu_env);
35fbce2c 17011 gen_store_gpr(t0, rt);
6c5c1e20
TS
17012 break;
17013 case OPC_DI:
d75c135e 17014 check_insn(ctx, ISA_MIPS32R2);
867abc7e 17015 save_cpu_state(ctx, 1);
895c2d04 17016 gen_helper_di(t0, cpu_env);
35fbce2c 17017 gen_store_gpr(t0, rt);
6c5c1e20
TS
17018 /* Stop translation as we may have switched the execution mode */
17019 ctx->bstate = BS_STOP;
17020 break;
17021 case OPC_EI:
d75c135e 17022 check_insn(ctx, ISA_MIPS32R2);
867abc7e 17023 save_cpu_state(ctx, 1);
895c2d04 17024 gen_helper_ei(t0, cpu_env);
35fbce2c 17025 gen_store_gpr(t0, rt);
6c5c1e20
TS
17026 /* Stop translation as we may have switched the execution mode */
17027 ctx->bstate = BS_STOP;
17028 break;
17029 default: /* Invalid */
17030 MIPS_INVAL("mfmc0");
17031 generate_exception(ctx, EXCP_RI);
17032 break;
17033 }
6c5c1e20 17034 tcg_temp_free(t0);
7a387fff 17035 }
0eaef5aa 17036#endif /* !CONFIG_USER_ONLY */
6af0bf9c 17037 break;
7a387fff 17038 case OPC_RDPGPR:
d75c135e 17039 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 17040 gen_load_srsgpr(rt, rd);
ead9360e 17041 break;
7a387fff 17042 case OPC_WRPGPR:
d75c135e 17043 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 17044 gen_store_srsgpr(rt, rd);
38121543 17045 break;
6af0bf9c 17046 default:
923617a3 17047 MIPS_INVAL("cp0");
7a387fff 17048 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
17049 break;
17050 }
17051 break;
31837be3
YK
17052 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
17053 if (ctx->insn_flags & ISA_MIPS32R6) {
17054 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
17055 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17056 } else {
17057 /* OPC_ADDI */
17058 /* Arithmetic with immediate opcode */
17059 gen_arith_imm(ctx, op, rt, rs, imm);
17060 }
17061 break;
324d9e32 17062 case OPC_ADDIU:
d75c135e 17063 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 17064 break;
324d9e32
AJ
17065 case OPC_SLTI: /* Set on less than with immediate opcode */
17066 case OPC_SLTIU:
d75c135e 17067 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
17068 break;
17069 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 17070 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
17071 case OPC_ORI:
17072 case OPC_XORI:
d75c135e 17073 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 17074 break;
7a387fff
TS
17075 case OPC_J ... OPC_JAL: /* Jump */
17076 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 17077 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 17078 break;
31837be3
YK
17079 /* Branch */
17080 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17081 if (ctx->insn_flags & ISA_MIPS32R6) {
17082 if (rt == 0) {
17083 generate_exception(ctx, EXCP_RI);
17084 break;
17085 }
17086 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17087 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17088 } else {
17089 /* OPC_BLEZL */
17090 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17091 }
17092 break;
17093 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17094 if (ctx->insn_flags & ISA_MIPS32R6) {
17095 if (rt == 0) {
17096 generate_exception(ctx, EXCP_RI);
17097 break;
17098 }
17099 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17100 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17101 } else {
17102 /* OPC_BGTZL */
17103 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17104 }
17105 break;
17106 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17107 if (rt == 0) {
17108 /* OPC_BLEZ */
17109 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17110 } else {
17111 check_insn(ctx, ISA_MIPS32R6);
17112 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17113 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17114 }
17115 break;
17116 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17117 if (rt == 0) {
17118 /* OPC_BGTZ */
17119 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17120 } else {
17121 check_insn(ctx, ISA_MIPS32R6);
17122 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17123 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17124 }
17125 break;
17126 case OPC_BEQL:
17127 case OPC_BNEL:
fecd2646 17128 check_insn_opc_removed(ctx, ISA_MIPS32R6);
31837be3
YK
17129 case OPC_BEQ:
17130 case OPC_BNE:
7dca4ad0 17131 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 17132 break;
fecd2646
LA
17133 case OPC_LWL: /* Load and stores */
17134 case OPC_LWR:
4368b29a 17135 case OPC_LL:
fecd2646
LA
17136 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17137 case OPC_LB ... OPC_LH:
17138 case OPC_LW ... OPC_LHU:
d75c135e 17139 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 17140 break;
fecd2646 17141 case OPC_SWL:
7a387fff 17142 case OPC_SWR:
fecd2646
LA
17143 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17144 case OPC_SB ... OPC_SH:
17145 case OPC_SW:
5c13fdfd 17146 gen_st(ctx, op, rt, rs, imm);
7a387fff 17147 break;
d66c7132 17148 case OPC_SC:
4368b29a 17149 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
17150 gen_st_cond(ctx, op, rt, rs, imm);
17151 break;
7a387fff 17152 case OPC_CACHE:
bf7910c6 17153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 17154 check_cp0_enabled(ctx);
d75c135e 17155 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 17156 /* Treat as NOP. */
34ae7b51 17157 break;
7a387fff 17158 case OPC_PREF:
bf7910c6 17159 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17160 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 17161 /* Treat as NOP. */
6af0bf9c 17162 break;
4ad40f36 17163
923617a3 17164 /* Floating point (COP1). */
7a387fff
TS
17165 case OPC_LWC1:
17166 case OPC_LDC1:
17167 case OPC_SWC1:
17168 case OPC_SDC1:
5ab5c041 17169 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
17170 break;
17171
7a387fff 17172 case OPC_CP1:
5ab5c041 17173 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 17174 check_cp1_enabled(ctx);
36d23958
TS
17175 op1 = MASK_CP1(ctx->opcode);
17176 switch (op1) {
3a95e3a7
TS
17177 case OPC_MFHC1:
17178 case OPC_MTHC1:
d75c135e 17179 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
17180 case OPC_MFC1:
17181 case OPC_CFC1:
17182 case OPC_MTC1:
17183 case OPC_CTC1:
e189e748
TS
17184 gen_cp1(ctx, op1, rt, rd);
17185 break;
d26bc211 17186#if defined(TARGET_MIPS64)
36d23958
TS
17187 case OPC_DMFC1:
17188 case OPC_DMTC1:
d75c135e 17189 check_insn(ctx, ISA_MIPS3);
36d23958
TS
17190 gen_cp1(ctx, op1, rt, rd);
17191 break;
e189e748 17192#endif
31837be3
YK
17193 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
17194 if (ctx->insn_flags & ISA_MIPS32R6) {
17195 /* OPC_BC1EQZ */
17196 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17197 rt, imm << 2);
17198 } else {
17199 /* OPC_BC1ANY2 */
17200 check_cop1x(ctx);
17201 check_insn(ctx, ASE_MIPS3D);
17202 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
17203 (rt >> 2) & 0x7, imm << 2);
17204 }
17205 break;
17206 case OPC_BC1NEZ:
17207 check_insn(ctx, ISA_MIPS32R6);
17208 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17209 rt, imm << 2);
17210 break;
fbcc6828 17211 case OPC_BC1ANY4:
fecd2646 17212 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b8aa4598 17213 check_cop1x(ctx);
d75c135e 17214 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
17215 /* fall through */
17216 case OPC_BC1:
fecd2646 17217 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17218 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 17219 (rt >> 2) & 0x7, imm << 2);
c9602061 17220 break;
fecd2646
LA
17221 case OPC_PS_FMT:
17222 check_insn_opc_removed(ctx, ISA_MIPS32R6);
36d23958
TS
17223 case OPC_S_FMT:
17224 case OPC_D_FMT:
bf4120ad 17225 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 17226 (imm >> 8) & 0x7);
36d23958 17227 break;
3f493883
YK
17228 case OPC_W_FMT:
17229 case OPC_L_FMT:
17230 {
17231 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
17232 if (ctx->insn_flags & ISA_MIPS32R6) {
17233 switch (r6_op) {
17234 case R6_OPC_CMP_AF_S:
17235 case R6_OPC_CMP_UN_S:
17236 case R6_OPC_CMP_EQ_S:
17237 case R6_OPC_CMP_UEQ_S:
17238 case R6_OPC_CMP_LT_S:
17239 case R6_OPC_CMP_ULT_S:
17240 case R6_OPC_CMP_LE_S:
17241 case R6_OPC_CMP_ULE_S:
17242 case R6_OPC_CMP_SAF_S:
17243 case R6_OPC_CMP_SUN_S:
17244 case R6_OPC_CMP_SEQ_S:
17245 case R6_OPC_CMP_SEUQ_S:
17246 case R6_OPC_CMP_SLT_S:
17247 case R6_OPC_CMP_SULT_S:
17248 case R6_OPC_CMP_SLE_S:
17249 case R6_OPC_CMP_SULE_S:
17250 case R6_OPC_CMP_OR_S:
17251 case R6_OPC_CMP_UNE_S:
17252 case R6_OPC_CMP_NE_S:
17253 case R6_OPC_CMP_SOR_S:
17254 case R6_OPC_CMP_SUNE_S:
17255 case R6_OPC_CMP_SNE_S:
17256 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17257 break;
17258 case R6_OPC_CMP_AF_D:
17259 case R6_OPC_CMP_UN_D:
17260 case R6_OPC_CMP_EQ_D:
17261 case R6_OPC_CMP_UEQ_D:
17262 case R6_OPC_CMP_LT_D:
17263 case R6_OPC_CMP_ULT_D:
17264 case R6_OPC_CMP_LE_D:
17265 case R6_OPC_CMP_ULE_D:
17266 case R6_OPC_CMP_SAF_D:
17267 case R6_OPC_CMP_SUN_D:
17268 case R6_OPC_CMP_SEQ_D:
17269 case R6_OPC_CMP_SEUQ_D:
17270 case R6_OPC_CMP_SLT_D:
17271 case R6_OPC_CMP_SULT_D:
17272 case R6_OPC_CMP_SLE_D:
17273 case R6_OPC_CMP_SULE_D:
17274 case R6_OPC_CMP_OR_D:
17275 case R6_OPC_CMP_UNE_D:
17276 case R6_OPC_CMP_NE_D:
17277 case R6_OPC_CMP_SOR_D:
17278 case R6_OPC_CMP_SUNE_D:
17279 case R6_OPC_CMP_SNE_D:
17280 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17281 break;
17282 default:
17283 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17284 (imm >> 8) & 0x7);
17285 break;
17286 }
17287 } else {
17288 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17289 (imm >> 8) & 0x7);
17290 }
17291 break;
17292 }
36d23958 17293 default:
923617a3 17294 MIPS_INVAL("cp1");
e397ee33 17295 generate_exception (ctx, EXCP_RI);
36d23958
TS
17296 break;
17297 }
17298 } else {
17299 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 17300 }
4ad40f36
FB
17301 break;
17302
31837be3
YK
17303 /* Compact branches [R6] and COP2 [non-R6] */
17304 case OPC_BC: /* OPC_LWC2 */
17305 case OPC_BALC: /* OPC_SWC2 */
17306 if (ctx->insn_flags & ISA_MIPS32R6) {
17307 /* OPC_BC, OPC_BALC */
17308 gen_compute_compact_branch(ctx, op, 0, 0,
17309 sextract32(ctx->opcode << 2, 0, 28));
17310 } else {
17311 /* OPC_LWC2, OPC_SWC2 */
17312 /* COP2: Not implemented. */
17313 generate_exception_err(ctx, EXCP_CpU, 2);
17314 }
17315 break;
17316 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
17317 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
17318 if (ctx->insn_flags & ISA_MIPS32R6) {
17319 if (rs != 0) {
17320 /* OPC_BEQZC, OPC_BNEZC */
17321 gen_compute_compact_branch(ctx, op, rs, 0,
17322 sextract32(ctx->opcode << 2, 0, 23));
17323 } else {
17324 /* OPC_JIC, OPC_JIALC */
17325 gen_compute_compact_branch(ctx, op, 0, rt, imm);
17326 }
17327 } else {
17328 /* OPC_LWC2, OPC_SWC2 */
17329 /* COP2: Not implemented. */
17330 generate_exception_err(ctx, EXCP_CpU, 2);
17331 }
4ad40f36 17332 break;
bd277fa1 17333 case OPC_CP2:
d75c135e 17334 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
17335 /* Note that these instructions use different fields. */
17336 gen_loongson_multimedia(ctx, sa, rd, rt);
17337 break;
4ad40f36 17338
7a387fff 17339 case OPC_CP3:
fecd2646 17340 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 17341 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 17342 check_cp1_enabled(ctx);
36d23958
TS
17343 op1 = MASK_CP3(ctx->opcode);
17344 switch (op1) {
5a5012ec
TS
17345 case OPC_LWXC1:
17346 case OPC_LDXC1:
17347 case OPC_LUXC1:
17348 case OPC_SWXC1:
17349 case OPC_SDXC1:
17350 case OPC_SUXC1:
93b12ccc 17351 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 17352 break;
e0c84da7 17353 case OPC_PREFX:
ead9360e 17354 /* Treat as NOP. */
e0c84da7 17355 break;
5a5012ec
TS
17356 case OPC_ALNV_PS:
17357 case OPC_MADD_S:
17358 case OPC_MADD_D:
17359 case OPC_MADD_PS:
17360 case OPC_MSUB_S:
17361 case OPC_MSUB_D:
17362 case OPC_MSUB_PS:
17363 case OPC_NMADD_S:
17364 case OPC_NMADD_D:
17365 case OPC_NMADD_PS:
17366 case OPC_NMSUB_S:
17367 case OPC_NMSUB_D:
17368 case OPC_NMSUB_PS:
17369 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
17370 break;
36d23958 17371 default:
923617a3 17372 MIPS_INVAL("cp3");
e397ee33 17373 generate_exception (ctx, EXCP_RI);
36d23958
TS
17374 break;
17375 }
17376 } else {
e397ee33 17377 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 17378 }
4ad40f36
FB
17379 break;
17380
d26bc211 17381#if defined(TARGET_MIPS64)
7a387fff 17382 /* MIPS64 opcodes */
7a387fff 17383 case OPC_LDL ... OPC_LDR:
bf7910c6 17384 case OPC_LLD:
fecd2646
LA
17385 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17386 case OPC_LWU:
7a387fff 17387 case OPC_LD:
d75c135e 17388 check_insn(ctx, ISA_MIPS3);
5c13fdfd 17389 check_mips_64(ctx);
d75c135e 17390 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
17391 break;
17392 case OPC_SDL ... OPC_SDR:
fecd2646 17393 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 17394 case OPC_SD:
d75c135e 17395 check_insn(ctx, ISA_MIPS3);
e189e748 17396 check_mips_64(ctx);
5c13fdfd 17397 gen_st(ctx, op, rt, rs, imm);
7a387fff 17398 break;
d66c7132 17399 case OPC_SCD:
bf7910c6 17400 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 17401 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
17402 check_mips_64(ctx);
17403 gen_st_cond(ctx, op, rt, rs, imm);
17404 break;
31837be3
YK
17405 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17406 if (ctx->insn_flags & ISA_MIPS32R6) {
17407 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17408 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17409 } else {
17410 /* OPC_DADDI */
17411 check_insn(ctx, ISA_MIPS3);
17412 check_mips_64(ctx);
17413 gen_arith_imm(ctx, op, rt, rs, imm);
17414 }
17415 break;
324d9e32 17416 case OPC_DADDIU:
d75c135e 17417 check_insn(ctx, ISA_MIPS3);
e189e748 17418 check_mips_64(ctx);
d75c135e 17419 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 17420 break;
31837be3
YK
17421#else
17422 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
17423 if (ctx->insn_flags & ISA_MIPS32R6) {
17424 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17425 } else {
17426 MIPS_INVAL("major opcode");
17427 generate_exception(ctx, EXCP_RI);
17428 }
17429 break;
6af0bf9c 17430#endif
d4ea6acd
LA
17431 case OPC_DAUI: /* OPC_JALX */
17432 if (ctx->insn_flags & ISA_MIPS32R6) {
17433#if defined(TARGET_MIPS64)
17434 /* OPC_DAUI */
17435 check_mips_64(ctx);
17436 if (rt != 0) {
17437 TCGv t0 = tcg_temp_new();
17438 gen_load_gpr(t0, rs);
17439 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
17440 tcg_temp_free(t0);
17441 }
17442 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
17443#else
17444 generate_exception(ctx, EXCP_RI);
17445 MIPS_INVAL("major opcode");
17446#endif
17447 } else {
17448 /* OPC_JALX */
17449 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
17450 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17451 gen_compute_branch(ctx, op, 4, rs, rt, offset);
17452 }
364d4831 17453 break;
7a387fff 17454 case OPC_MDMX:
d75c135e 17455 check_insn(ctx, ASE_MDMX);
7a387fff 17456 /* MDMX: Not implemented. */
d4ea6acd
LA
17457 break;
17458 case OPC_PCREL:
17459 check_insn(ctx, ISA_MIPS32R6);
17460 gen_pcrel(ctx, rs, imm);
17461 break;
6af0bf9c 17462 default: /* Invalid */
923617a3 17463 MIPS_INVAL("major opcode");
6af0bf9c
FB
17464 generate_exception(ctx, EXCP_RI);
17465 break;
17466 }
6af0bf9c
FB
17467}
17468
2cfc5f17 17469static inline void
6429db34
AF
17470gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
17471 bool search_pc)
6af0bf9c 17472{
ed2803da 17473 CPUState *cs = CPU(cpu);
6429db34 17474 CPUMIPSState *env = &cpu->env;
278d0702 17475 DisasContext ctx;
6af0bf9c
FB
17476 target_ulong pc_start;
17477 uint16_t *gen_opc_end;
a1d1bb31 17478 CPUBreakpoint *bp;
6af0bf9c 17479 int j, lj = -1;
2e70f6ef
PB
17480 int num_insns;
17481 int max_insns;
c9602061 17482 int insn_bytes;
240ce26a 17483 int is_delay;
6af0bf9c 17484
93fcfe39
AL
17485 if (search_pc)
17486 qemu_log("search pc %d\n", search_pc);
4ad40f36 17487
6af0bf9c 17488 pc_start = tb->pc;
92414b31 17489 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 17490 ctx.pc = pc_start;
4ad40f36 17491 ctx.saved_pc = -1;
ed2803da 17492 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 17493 ctx.insn_flags = env->insn_flags;
5ab5c041 17494 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
17495 ctx.tb = tb;
17496 ctx.bstate = BS_NONE;
4ad40f36 17497 /* Restore delay slot state from the tb context. */
c068688b 17498 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 17499 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 17500 restore_cpu_state(env, &ctx);
932e71cd 17501#ifdef CONFIG_USER_ONLY
0eaef5aa 17502 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 17503#else
0eaef5aa 17504 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 17505#endif
2e70f6ef
PB
17506 num_insns = 0;
17507 max_insns = tb->cflags & CF_COUNT_MASK;
17508 if (max_insns == 0)
17509 max_insns = CF_COUNT_MASK;
d12d51d5 17510 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 17511 gen_tb_start();
faf7aaa9 17512 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
17513 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
17514 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 17515 if (bp->pc == ctx.pc) {
278d0702 17516 save_cpu_state(&ctx, 1);
4ad40f36 17517 ctx.bstate = BS_BRANCH;
895c2d04 17518 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
17519 /* Include the breakpoint location or the tb won't
17520 * be flushed when it must be. */
17521 ctx.pc += 4;
4ad40f36
FB
17522 goto done_generating;
17523 }
17524 }
17525 }
17526
6af0bf9c 17527 if (search_pc) {
92414b31 17528 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
17529 if (lj < j) {
17530 lj++;
17531 while (lj < j)
ab1103de 17532 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 17533 }
25983cad 17534 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 17535 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 17536 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 17537 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 17538 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 17539 }
2e70f6ef
PB
17540 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
17541 gen_io_start();
c9602061 17542
240ce26a 17543 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 17544 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 17545 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 17546 insn_bytes = 4;
240ce26a 17547 decode_opc(env, &ctx);
d75c135e 17548 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 17549 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 17550 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 17551 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 17552 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 17553 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
17554 } else {
17555 generate_exception(&ctx, EXCP_RI);
3c824109 17556 ctx.bstate = BS_STOP;
c9602061
NF
17557 break;
17558 }
31837be3 17559
240ce26a 17560 if (is_delay) {
31837be3 17561 gen_branch(&ctx, insn_bytes);
c9602061
NF
17562 }
17563 ctx.pc += insn_bytes;
17564
2e70f6ef 17565 num_insns++;
4ad40f36 17566
7b270ef2
NF
17567 /* Execute a branch and its delay slot as a single instruction.
17568 This is what GDB expects and is consistent with what the
17569 hardware does (e.g. if a delay slot instruction faults, the
17570 reported PC is the PC of the branch). */
ed2803da 17571 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 17572 break;
ed2803da 17573 }
4ad40f36 17574
6af0bf9c
FB
17575 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
17576 break;
4ad40f36 17577
efd7f486 17578 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 17579 break;
efd7f486 17580 }
faf7aaa9 17581
2e70f6ef
PB
17582 if (num_insns >= max_insns)
17583 break;
1b530a6d
AJ
17584
17585 if (singlestep)
17586 break;
6af0bf9c 17587 }
ed2803da 17588 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 17589 gen_io_end();
ed2803da
AF
17590 }
17591 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 17592 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 17593 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 17594 } else {
6958549d 17595 switch (ctx.bstate) {
16c00cb2 17596 case BS_STOP:
df1561e2
TS
17597 gen_goto_tb(&ctx, 0, ctx.pc);
17598 break;
16c00cb2 17599 case BS_NONE:
278d0702 17600 save_cpu_state(&ctx, 0);
16c00cb2
TS
17601 gen_goto_tb(&ctx, 0, ctx.pc);
17602 break;
5a5012ec 17603 case BS_EXCP:
57fec1fe 17604 tcg_gen_exit_tb(0);
16c00cb2 17605 break;
5a5012ec
TS
17606 case BS_BRANCH:
17607 default:
17608 break;
6958549d 17609 }
6af0bf9c 17610 }
4ad40f36 17611done_generating:
806f352d 17612 gen_tb_end(tb, num_insns);
efd7f486 17613 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 17614 if (search_pc) {
92414b31 17615 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
17616 lj++;
17617 while (lj <= j)
ab1103de 17618 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
17619 } else {
17620 tb->size = ctx.pc - pc_start;
2e70f6ef 17621 tb->icount = num_insns;
6af0bf9c
FB
17622 }
17623#ifdef DEBUG_DISAS
d12d51d5 17624 LOG_DISAS("\n");
8fec2b8c 17625 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 17626 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 17627 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 17628 qemu_log("\n");
6af0bf9c
FB
17629 }
17630#endif
6af0bf9c
FB
17631}
17632
7db13fae 17633void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 17634{
6429db34 17635 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
17636}
17637
7db13fae 17638void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 17639{
6429db34 17640 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
17641}
17642
7db13fae 17643static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 17644 int flags)
6ea83fed
FB
17645{
17646 int i;
5e755519 17647 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 17648
2a5612e6
SW
17649#define printfpr(fp) \
17650 do { \
17651 if (is_fpu64) \
17652 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17653 " fd:%13g fs:%13g psu: %13g\n", \
17654 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
17655 (double)(fp)->fd, \
17656 (double)(fp)->fs[FP_ENDIAN_IDX], \
17657 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
17658 else { \
17659 fpr_t tmp; \
17660 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
17661 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
17662 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17663 " fd:%13g fs:%13g psu:%13g\n", \
17664 tmp.w[FP_ENDIAN_IDX], tmp.d, \
17665 (double)tmp.fd, \
17666 (double)tmp.fs[FP_ENDIAN_IDX], \
17667 (double)tmp.fs[!FP_ENDIAN_IDX]); \
17668 } \
6ea83fed
FB
17669 } while(0)
17670
5a5012ec 17671
9a78eead
SW
17672 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
17673 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 17674 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
17675 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
17676 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 17677 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
17678 }
17679
17680#undef printfpr
17681}
17682
d26bc211 17683#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 17684/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 17685 sign-extended values on 64bit machines. */
c570fd16
TS
17686
17687#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
17688
8706c382 17689static void
7db13fae 17690cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 17691 fprintf_function cpu_fprintf,
8706c382 17692 int flags)
c570fd16
TS
17693{
17694 int i;
17695
b5dc7732
TS
17696 if (!SIGN_EXT_P(env->active_tc.PC))
17697 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
17698 if (!SIGN_EXT_P(env->active_tc.HI[0]))
17699 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
17700 if (!SIGN_EXT_P(env->active_tc.LO[0]))
17701 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 17702 if (!SIGN_EXT_P(env->btarget))
3594c774 17703 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
17704
17705 for (i = 0; i < 32; i++) {
b5dc7732
TS
17706 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
17707 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
17708 }
17709
17710 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 17711 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
17712 if (!SIGN_EXT_P(env->lladdr))
17713 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
17714}
17715#endif
17716
878096ee
AF
17717void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
17718 int flags)
6af0bf9c 17719{
878096ee
AF
17720 MIPSCPU *cpu = MIPS_CPU(cs);
17721 CPUMIPSState *env = &cpu->env;
6af0bf9c 17722 int i;
3b46e624 17723
a7200c9f
SW
17724 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
17725 " LO=0x" TARGET_FMT_lx " ds %04x "
17726 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
17727 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
17728 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
17729 for (i = 0; i < 32; i++) {
17730 if ((i & 3) == 0)
17731 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 17732 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
17733 if ((i & 3) == 3)
17734 cpu_fprintf(f, "\n");
17735 }
568b600d 17736
3594c774 17737 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 17738 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 17739 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 17740 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 17741 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 17742 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 17743#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
17744 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
17745#endif
6af0bf9c
FB
17746}
17747
78ce64f4 17748void mips_tcg_init(void)
39454628 17749{
f01be154 17750 int i;
39454628
TS
17751 static int inited;
17752
17753 /* Initialize various static tables. */
17754 if (inited)
6958549d 17755 return;
39454628 17756
a7812ae4 17757 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 17758 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 17759 for (i = 1; i < 32; i++)
a7812ae4 17760 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17761 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 17762 regnames[i]);
d73ee8a2
RH
17763
17764 for (i = 0; i < 32; i++) {
17765 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
17766 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
17767 }
17768
a7812ae4 17769 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 17770 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 17771 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 17772 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17773 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 17774 regnames_HI[i]);
a7812ae4 17775 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17776 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 17777 regnames_LO[i]);
a7812ae4 17778 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 17779 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
17780 regnames_ACX[i]);
17781 }
a7812ae4 17782 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 17783 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 17784 "DSPControl");
1ba74fb8 17785 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 17786 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 17787 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 17788 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 17789 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 17790 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 17791
a7812ae4 17792 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 17793 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
17794 "fcr0");
17795 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 17796 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 17797 "fcr31");
39454628
TS
17798
17799 inited = 1;
17800}
17801
aaed909a
FB
17802#include "translate_init.c"
17803
30bf942d 17804MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 17805{
0f71a709 17806 MIPSCPU *cpu;
6af0bf9c 17807 CPUMIPSState *env;
c227f099 17808 const mips_def_t *def;
6af0bf9c 17809
aaed909a
FB
17810 def = cpu_mips_find_by_name(cpu_model);
17811 if (!def)
17812 return NULL;
0f71a709
AF
17813 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
17814 env = &cpu->env;
aaed909a
FB
17815 env->cpu_model = def;
17816
51cc2e78
BS
17817#ifndef CONFIG_USER_ONLY
17818 mmu_init(env, def);
17819#endif
17820 fpu_init(env, def);
17821 mvp_init(env, def);
c1caf1d9
AF
17822
17823 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
17824
30bf942d 17825 return cpu;
6ae81775
TS
17826}
17827
1bba0dc9 17828void cpu_state_reset(CPUMIPSState *env)
6ae81775 17829{
55e5c285
AF
17830 MIPSCPU *cpu = mips_env_get_cpu(env);
17831 CPUState *cs = CPU(cpu);
6ae81775 17832
51cc2e78
BS
17833 /* Reset registers to their default values */
17834 env->CP0_PRid = env->cpu_model->CP0_PRid;
17835 env->CP0_Config0 = env->cpu_model->CP0_Config0;
17836#ifdef TARGET_WORDS_BIGENDIAN
17837 env->CP0_Config0 |= (1 << CP0C0_BE);
17838#endif
17839 env->CP0_Config1 = env->cpu_model->CP0_Config1;
17840 env->CP0_Config2 = env->cpu_model->CP0_Config2;
17841 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
17842 env->CP0_Config4 = env->cpu_model->CP0_Config4;
17843 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
17844 env->CP0_Config5 = env->cpu_model->CP0_Config5;
17845 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
17846 env->CP0_Config6 = env->cpu_model->CP0_Config6;
17847 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
17848 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
17849 << env->cpu_model->CP0_LLAddr_shift;
17850 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
17851 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
17852 env->CCRes = env->cpu_model->CCRes;
17853 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
17854 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
17855 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
17856 env->current_tc = 0;
17857 env->SEGBITS = env->cpu_model->SEGBITS;
17858 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
17859#if defined(TARGET_MIPS64)
17860 if (env->cpu_model->insn_flags & ISA_MIPS3) {
17861 env->SEGMask |= 3ULL << 62;
17862 }
17863#endif
17864 env->PABITS = env->cpu_model->PABITS;
17865 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
17866 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
17867 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
17868 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
17869 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
17870 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
17871 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
17872 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
17873 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
17874 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
17875 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 17876 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
17877 env->insn_flags = env->cpu_model->insn_flags;
17878
0eaef5aa 17879#if defined(CONFIG_USER_ONLY)
03e6e501 17880 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
17881# ifdef TARGET_MIPS64
17882 /* Enable 64-bit register mode. */
17883 env->CP0_Status |= (1 << CP0St_PX);
17884# endif
17885# ifdef TARGET_ABI_MIPSN64
17886 /* Enable 64-bit address mode. */
17887 env->CP0_Status |= (1 << CP0St_UX);
17888# endif
94159135
MI
17889 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
17890 hardware registers. */
17891 env->CP0_HWREna |= 0x0000000F;
91a75935 17892 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 17893 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 17894 }
6f0af304
PJ
17895 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
17896 env->CP0_Status |= (1 << CP0St_MX);
853c3240 17897 }
4d66261f
PJ
17898# if defined(TARGET_MIPS64)
17899 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
17900 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
17901 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
17902 env->CP0_Status |= (1 << CP0St_FR);
17903 }
4d66261f 17904# endif
932e71cd
AJ
17905#else
17906 if (env->hflags & MIPS_HFLAG_BMASK) {
17907 /* If the exception was raised from a delay slot,
17908 come back to the jump. */
17909 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 17910 } else {
932e71cd
AJ
17911 env->CP0_ErrorEPC = env->active_tc.PC;
17912 }
17913 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
17914 env->CP0_Random = env->tlb->nb_tlb - 1;
17915 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 17916 env->CP0_Wired = 0;
0a2672b7
JH
17917 env->CP0_EBase = (cs->cpu_index & 0x3FF);
17918 if (kvm_enabled()) {
17919 env->CP0_EBase |= 0x40000000;
17920 } else {
17921 env->CP0_EBase |= 0x80000000;
17922 }
932e71cd
AJ
17923 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
17924 /* vectored interrupts not implemented, timer on int 7,
17925 no performance counters. */
17926 env->CP0_IntCtl = 0xe0000000;
17927 {
17928 int i;
17929
17930 for (i = 0; i < 7; i++) {
17931 env->CP0_WatchLo[i] = 0;
17932 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 17933 }
932e71cd
AJ
17934 env->CP0_WatchLo[7] = 0;
17935 env->CP0_WatchHi[7] = 0;
fd88b6ab 17936 }
932e71cd
AJ
17937 /* Count register increments in debug mode, EJTAG version 1 */
17938 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 17939
4b69c7e2
JH
17940 cpu_mips_store_count(env, 1);
17941
9e56e756
EI
17942 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
17943 int i;
17944
17945 /* Only TC0 on VPE 0 starts as active. */
17946 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 17947 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
17948 env->tcs[i].CP0_TCHalt = 1;
17949 }
17950 env->active_tc.CP0_TCHalt = 1;
259186a7 17951 cs->halted = 1;
9e56e756 17952
55e5c285 17953 if (cs->cpu_index == 0) {
9e56e756
EI
17954 /* VPE0 starts up enabled. */
17955 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
17956 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
17957
17958 /* TC0 starts up unhalted. */
259186a7 17959 cs->halted = 0;
9e56e756
EI
17960 env->active_tc.CP0_TCHalt = 0;
17961 env->tcs[0].CP0_TCHalt = 0;
17962 /* With thread 0 active. */
17963 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
17964 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
17965 }
17966 }
51cc2e78 17967#endif
ddc584bd
LA
17968 if ((env->insn_flags & ISA_MIPS32R6) &&
17969 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
17970 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
17971 env->CP0_Status |= (1 << CP0St_FR);
17972 }
17973
03e6e501 17974 compute_hflags(env);
27103424 17975 cs->exception_index = EXCP_NONE;
6af0bf9c 17976}
d2856f1a 17977
7db13fae 17978void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 17979{
25983cad 17980 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
17981 env->hflags &= ~MIPS_HFLAG_BMASK;
17982 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
17983 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
17984 case MIPS_HFLAG_BR:
17985 break;
17986 case MIPS_HFLAG_BC:
17987 case MIPS_HFLAG_BL:
17988 case MIPS_HFLAG_B:
17989 env->btarget = gen_opc_btarget[pc_pos];
17990 break;
17991 }
d2856f1a 17992}
This page took 3.843765 seconds and 4 git commands to generate.