]> Git Repo - qemu.git/blame - target-mips/translate.c
target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6
[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 */
620e48f6 78 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 79 /* Load and stores */
7a387fff
TS
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
364d4831 86 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
364d4831 101 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
102 OPC_SC = (0x38 << 26),
103 OPC_SCD = (0x3C << 26),
104 OPC_SD = (0x3F << 26),
e37e863f 105 /* Floating point load/store */
7a387fff
TS
106 OPC_LWC1 = (0x31 << 26),
107 OPC_LWC2 = (0x32 << 26),
108 OPC_LDC1 = (0x35 << 26),
109 OPC_LDC2 = (0x36 << 26),
110 OPC_SWC1 = (0x39 << 26),
111 OPC_SWC2 = (0x3A << 26),
112 OPC_SDC1 = (0x3D << 26),
113 OPC_SDC2 = (0x3E << 26),
114 /* MDMX ASE specific */
115 OPC_MDMX = (0x1E << 26),
e37e863f 116 /* Cache and prefetch */
7a387fff
TS
117 OPC_CACHE = (0x2F << 26),
118 OPC_PREF = (0x33 << 26),
119 /* Reserved major opcode */
120 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
121};
122
123/* MIPS special opcodes */
7a387fff
TS
124#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
125
e37e863f
FB
126enum {
127 /* Shifts */
7a387fff 128 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
129 /* NOP is SLL r0, r0, 0 */
130 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
131 /* EHB is SLL r0, r0, 3 */
132 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 133 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
134 OPC_SRA = 0x03 | OPC_SPECIAL,
135 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 136 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 137 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
138 OPC_SRAV = 0x07 | OPC_SPECIAL,
139 OPC_DSLLV = 0x14 | OPC_SPECIAL,
140 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 141 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
142 OPC_DSRAV = 0x17 | OPC_SPECIAL,
143 OPC_DSLL = 0x38 | OPC_SPECIAL,
144 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 145 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
146 OPC_DSRA = 0x3B | OPC_SPECIAL,
147 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
148 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 149 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 150 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 151 /* Multiplication / division */
7a387fff
TS
152 OPC_MULT = 0x18 | OPC_SPECIAL,
153 OPC_MULTU = 0x19 | OPC_SPECIAL,
154 OPC_DIV = 0x1A | OPC_SPECIAL,
155 OPC_DIVU = 0x1B | OPC_SPECIAL,
156 OPC_DMULT = 0x1C | OPC_SPECIAL,
157 OPC_DMULTU = 0x1D | OPC_SPECIAL,
158 OPC_DDIV = 0x1E | OPC_SPECIAL,
159 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 160
e37e863f 161 /* 2 registers arithmetic / logic */
7a387fff
TS
162 OPC_ADD = 0x20 | OPC_SPECIAL,
163 OPC_ADDU = 0x21 | OPC_SPECIAL,
164 OPC_SUB = 0x22 | OPC_SPECIAL,
165 OPC_SUBU = 0x23 | OPC_SPECIAL,
166 OPC_AND = 0x24 | OPC_SPECIAL,
167 OPC_OR = 0x25 | OPC_SPECIAL,
168 OPC_XOR = 0x26 | OPC_SPECIAL,
169 OPC_NOR = 0x27 | OPC_SPECIAL,
170 OPC_SLT = 0x2A | OPC_SPECIAL,
171 OPC_SLTU = 0x2B | OPC_SPECIAL,
172 OPC_DADD = 0x2C | OPC_SPECIAL,
173 OPC_DADDU = 0x2D | OPC_SPECIAL,
174 OPC_DSUB = 0x2E | OPC_SPECIAL,
175 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 176 /* Jumps */
7a387fff
TS
177 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
178 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 179 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 180 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 181 /* Traps */
7a387fff
TS
182 OPC_TGE = 0x30 | OPC_SPECIAL,
183 OPC_TGEU = 0x31 | OPC_SPECIAL,
184 OPC_TLT = 0x32 | OPC_SPECIAL,
185 OPC_TLTU = 0x33 | OPC_SPECIAL,
186 OPC_TEQ = 0x34 | OPC_SPECIAL,
187 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 188 /* HI / LO registers load & stores */
7a387fff
TS
189 OPC_MFHI = 0x10 | OPC_SPECIAL,
190 OPC_MTHI = 0x11 | OPC_SPECIAL,
191 OPC_MFLO = 0x12 | OPC_SPECIAL,
192 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 193 /* Conditional moves */
7a387fff
TS
194 OPC_MOVZ = 0x0A | OPC_SPECIAL,
195 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 196
b691d9d2
LA
197 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
198 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
199
7a387fff 200 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
201
202 /* Special */
a0d700e4 203 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
204 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
205 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 206 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
207 OPC_SYNC = 0x0F | OPC_SPECIAL,
208
209 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
210 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
211 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
212 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
213 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
214};
215
b42ee5e1
LA
216/* R6 Multiply and Divide instructions have the same Opcode
217 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
218#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
219
220enum {
221 R6_OPC_MUL = OPC_MULT | (2 << 6),
222 R6_OPC_MUH = OPC_MULT | (3 << 6),
223 R6_OPC_MULU = OPC_MULTU | (2 << 6),
224 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
225 R6_OPC_DIV = OPC_DIV | (2 << 6),
226 R6_OPC_MOD = OPC_DIV | (3 << 6),
227 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
228 R6_OPC_MODU = OPC_DIVU | (3 << 6),
229
230 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
231 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
232 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
233 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
234 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
235 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
236 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
237 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
238
239 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
240 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
241 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
242 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
243 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
b42ee5e1
LA
244};
245
e9c71dd1
TS
246/* Multiplication variants of the vr54xx. */
247#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
248
249enum {
250 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
251 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
252 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
253 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
254 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
255 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
256 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
257 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
258 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
259 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
260 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
261 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
262 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
263 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
264};
265
7a387fff
TS
266/* REGIMM (rt field) opcodes */
267#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
268
269enum {
270 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
271 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
272 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
273 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
274 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 275 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
276 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
277 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 278 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
279 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
280 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
281 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
282 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
283 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
284 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
285 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
286 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
287};
288
7a387fff
TS
289/* Special2 opcodes */
290#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
291
e37e863f 292enum {
7a387fff
TS
293 /* Multiply & xxx operations */
294 OPC_MADD = 0x00 | OPC_SPECIAL2,
295 OPC_MADDU = 0x01 | OPC_SPECIAL2,
296 OPC_MUL = 0x02 | OPC_SPECIAL2,
297 OPC_MSUB = 0x04 | OPC_SPECIAL2,
298 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
299 /* Loongson 2F */
300 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
301 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
302 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
303 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
304 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
305 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
306 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
307 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
308 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
309 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
310 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
311 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 312 /* Misc */
7a387fff
TS
313 OPC_CLZ = 0x20 | OPC_SPECIAL2,
314 OPC_CLO = 0x21 | OPC_SPECIAL2,
315 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
316 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 317 /* Special */
7a387fff
TS
318 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
319};
320
321/* Special3 opcodes */
322#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
323
324enum {
325 OPC_EXT = 0x00 | OPC_SPECIAL3,
326 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
327 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
328 OPC_DEXT = 0x03 | OPC_SPECIAL3,
329 OPC_INS = 0x04 | OPC_SPECIAL3,
330 OPC_DINSM = 0x05 | OPC_SPECIAL3,
331 OPC_DINSU = 0x06 | OPC_SPECIAL3,
332 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
333 OPC_FORK = 0x08 | OPC_SPECIAL3,
334 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
335 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
336 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
337 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
338
339 /* Loongson 2E */
340 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
341 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
342 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
343 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
344 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
345 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
346 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
347 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
348 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
349 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
350 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
351 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
352
353 /* MIPS DSP Load */
354 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
355 /* MIPS DSP Arithmetic */
356 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 357 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 358 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 359 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
360 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
361 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
362 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 363 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
364 /* MIPS DSP GPR-Based Shift Sub-class */
365 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 366 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
367 /* MIPS DSP Multiply Sub-class insns */
368 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
369 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
370 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 371 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
372 /* DSP Bit/Manipulation Sub-class */
373 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 374 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 375 /* MIPS DSP Append Sub-class */
26690560 376 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 377 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
378 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
379 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 380 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a
LA
381
382 /* R6 */
bf7910c6
LA
383 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
384 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
385 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
386 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
387 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
388 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
389};
390
7a387fff
TS
391/* BSHFL opcodes */
392#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
393
e37e863f 394enum {
7a387fff
TS
395 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
396 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
397 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
398};
399
7a387fff
TS
400/* DBSHFL opcodes */
401#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
402
e37e863f 403enum {
7a387fff
TS
404 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
405 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
406};
407
e45a93e2
JL
408/* MIPS DSP REGIMM opcodes */
409enum {
410 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 411 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
412};
413
9b1a1d68
JL
414#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
415/* MIPS DSP Load */
416enum {
417 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
418 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
419 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 420 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
421};
422
461c08df
JL
423#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
424enum {
425 /* MIPS DSP Arithmetic Sub-class */
426 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
427 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
428 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
429 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
430 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
431 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
432 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
433 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
434 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
435 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
436 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
437 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
438 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
439 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
440 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
441 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
442 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
443 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
444 /* MIPS DSP Multiply Sub-class insns */
445 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
446 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
447 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
448 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
449 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
450 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
451};
452
453#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
454#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
455enum {
456 /* MIPS DSP Arithmetic Sub-class */
457 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
458 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
459 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
460 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
461 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
462 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
463 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
464 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
465 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
466 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
467 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
468 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
469 /* MIPS DSP Multiply Sub-class insns */
470 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
471 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
472 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
473 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
474};
475
476#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
477enum {
478 /* MIPS DSP Arithmetic Sub-class */
479 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
480 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
481 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
482 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
483 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
484 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
485 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
486 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
487 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
488 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
489 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
490 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
491 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
492 /* DSP Bit/Manipulation Sub-class */
493 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
494 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
495 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
496 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
497 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
498};
499
500#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501enum {
502 /* MIPS DSP Arithmetic Sub-class */
503 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
504 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
505 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
506 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
507 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
508 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
509 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
510 /* DSP Compare-Pick Sub-class */
511 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
512 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
513 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
514 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
515 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
516 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
517 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
518 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
519 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
520 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
521 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
522 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
523 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
524 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
525 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 526};
a22260ae 527
77c5fa8b
JL
528#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529enum {
530 /* MIPS DSP GPR-Based Shift Sub-class */
531 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
532 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
533 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
534 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
535 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
536 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
537 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
538 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
539 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
540 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
541 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
542 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
543 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
544 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
545 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
546 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
547 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
548 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
549 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
550 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
551 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
552 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
553};
461c08df 554
a22260ae
JL
555#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
556enum {
557 /* MIPS DSP Multiply Sub-class insns */
558 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
559 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
560 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
561 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
562 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
563 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
564 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
565 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
566 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
567 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
568 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
569 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
570 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
571 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
572 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
573 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
574 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
575 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
576 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
577 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
578 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
579 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
580};
581
1cb6686c
JL
582#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583enum {
584 /* DSP Bit/Manipulation Sub-class */
585 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
586};
587
26690560
JL
588#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
589enum {
df6126a7 590 /* MIPS DSP Append Sub-class */
26690560
JL
591 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
592 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
593 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
594};
595
b53371ed
JL
596#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
597enum {
598 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
599 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
600 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
601 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
602 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
603 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
604 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
605 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
606 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
607 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
608 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
609 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
610 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
611 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
612 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
613 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
614 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
615 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
616};
617
461c08df
JL
618#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
619enum {
620 /* MIPS DSP Arithmetic Sub-class */
621 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
622 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
623 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
624 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
625 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
626 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
627 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
628 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
629 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
630 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
631 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
632 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
633 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
634 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
635 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
636 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
637 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
638 /* DSP Bit/Manipulation Sub-class */
639 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
640 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
641 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
642 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
643 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
644 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 645};
461c08df 646
461c08df
JL
647#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
648enum {
a22260ae
JL
649 /* MIPS DSP Multiply Sub-class insns */
650 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
651 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
652 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
653 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
654 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
655 /* MIPS DSP Arithmetic Sub-class */
656 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
657 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
658 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
659 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
660 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
661 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
662 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
663 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
664 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
665 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
666 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
667 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
668 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
669 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
670 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
671 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
672 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
673 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
674 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
675 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
676 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
677};
461c08df 678
461c08df
JL
679#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
680enum {
26690560
JL
681 /* DSP Compare-Pick Sub-class */
682 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
683 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
684 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
685 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
686 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
687 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
688 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
689 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
690 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
691 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
692 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
693 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
694 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
695 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
696 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
697 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
698 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
699 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
700 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
701 /* MIPS DSP Arithmetic Sub-class */
702 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
703 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
704 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
705 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
706 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
707 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
708 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
709 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
710};
461c08df 711
26690560
JL
712#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
713enum {
df6126a7 714 /* DSP Append Sub-class */
26690560
JL
715 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
716 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
717 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
718 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
719};
26690560 720
b53371ed
JL
721#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722enum {
723 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
724 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
725 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
726 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
727 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
728 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
729 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
730 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
731 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
732 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
733 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
734 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
735 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
736 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
737 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
738 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
739 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
740 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
741 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
742 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
743 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
744 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
745};
746
1cb6686c
JL
747#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
748enum {
749 /* DSP Bit/Manipulation Sub-class */
750 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
751};
1cb6686c 752
a22260ae
JL
753#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754enum {
755 /* MIPS DSP Multiply Sub-class insns */
756 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
757 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
758 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
759 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
760 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
761 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
762 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
763 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
764 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
765 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
766 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
767 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
768 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
769 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
770 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
771 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
772 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
773 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
774 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
775 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
776 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
777 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
778 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
779 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
780 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
781 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
782};
a22260ae 783
77c5fa8b
JL
784#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
785enum {
786 /* MIPS DSP GPR-Based Shift Sub-class */
787 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
788 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
789 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
790 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
791 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
792 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
793 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
794 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
795 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
796 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
797 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
798 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
799 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
800 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
801 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
802 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
803 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
804 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
805 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
806 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
807 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
808 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
809 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
810 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
811 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
812 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
813};
77c5fa8b 814
7a387fff
TS
815/* Coprocessor 0 (rs field) */
816#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
6ea83fed 818enum {
7a387fff
TS
819 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
820 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
821 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
822 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 823 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
824 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
825 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 826 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
827 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
828 OPC_C0 = (0x10 << 21) | OPC_CP0,
829 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
830 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 831};
7a387fff
TS
832
833/* MFMC0 opcodes */
b48cfdff 834#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
835
836enum {
ead9360e
TS
837 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
838 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
839 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
840 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
841 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
842 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
843};
844
845/* Coprocessor 0 (with rs == C0) */
846#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
847
848enum {
849 OPC_TLBR = 0x01 | OPC_C0,
850 OPC_TLBWI = 0x02 | OPC_C0,
851 OPC_TLBWR = 0x06 | OPC_C0,
852 OPC_TLBP = 0x08 | OPC_C0,
853 OPC_RFE = 0x10 | OPC_C0,
854 OPC_ERET = 0x18 | OPC_C0,
855 OPC_DERET = 0x1F | OPC_C0,
856 OPC_WAIT = 0x20 | OPC_C0,
857};
858
859/* Coprocessor 1 (rs field) */
860#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
861
bf4120ad
NF
862/* Values for the fmt field in FP instructions */
863enum {
864 /* 0 - 15 are reserved */
e459440a
AJ
865 FMT_S = 16, /* single fp */
866 FMT_D = 17, /* double fp */
867 FMT_E = 18, /* extended fp */
868 FMT_Q = 19, /* quad fp */
869 FMT_W = 20, /* 32-bit fixed */
870 FMT_L = 21, /* 64-bit fixed */
871 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
872 /* 23 - 31 are reserved */
873};
874
7a387fff
TS
875enum {
876 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
877 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
878 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 879 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
880 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
881 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
882 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 883 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 884 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
885 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
886 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
887 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
888 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
889 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
890 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
891 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
892 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
893 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
894};
895
5a5012ec
TS
896#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
897#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
898
7a387fff
TS
899enum {
900 OPC_BC1F = (0x00 << 16) | OPC_BC1,
901 OPC_BC1T = (0x01 << 16) | OPC_BC1,
902 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
903 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
904};
905
5a5012ec
TS
906enum {
907 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
908 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
909};
910
911enum {
912 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
913 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
914};
7a387fff
TS
915
916#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
917
918enum {
919 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
920 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
921 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
922 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
923 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
924 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
925 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
926 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
927 OPC_BC2 = (0x08 << 21) | OPC_CP2,
928};
929
bd277fa1
RH
930#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
931
932enum {
933 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
934 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
935 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
936 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
937 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
938 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
939 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
940 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
941
942 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
943 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
944 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
945 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
946 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
947 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
948 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
949 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
950
951 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
952 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
953 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
954 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
955 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
956 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
957 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
958 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
959
960 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
961 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
962 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
963 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
964 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
965 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
966 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
967 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
968
969 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
970 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
971 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
972 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
973 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
974 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
975
976 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
977 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
978 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
979 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
980 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
981 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
982
983 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
984 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
985 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
986 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
987 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
988 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
989
990 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
991 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
992 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
993 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
994 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
995 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
996
997 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
998 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
999 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1000 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1001 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1002 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1003
1004 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1005 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1006 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1007 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1008 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1009 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1010
1011 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1012 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1013 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1014 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1015 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1016 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1017
1018 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1019 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1020 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1021 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1022 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1023 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1024};
1025
1026
e0c84da7
TS
1027#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1028
1029enum {
1030 OPC_LWXC1 = 0x00 | OPC_CP3,
1031 OPC_LDXC1 = 0x01 | OPC_CP3,
1032 OPC_LUXC1 = 0x05 | OPC_CP3,
1033 OPC_SWXC1 = 0x08 | OPC_CP3,
1034 OPC_SDXC1 = 0x09 | OPC_CP3,
1035 OPC_SUXC1 = 0x0D | OPC_CP3,
1036 OPC_PREFX = 0x0F | OPC_CP3,
1037 OPC_ALNV_PS = 0x1E | OPC_CP3,
1038 OPC_MADD_S = 0x20 | OPC_CP3,
1039 OPC_MADD_D = 0x21 | OPC_CP3,
1040 OPC_MADD_PS = 0x26 | OPC_CP3,
1041 OPC_MSUB_S = 0x28 | OPC_CP3,
1042 OPC_MSUB_D = 0x29 | OPC_CP3,
1043 OPC_MSUB_PS = 0x2E | OPC_CP3,
1044 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1045 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1046 OPC_NMADD_PS= 0x36 | OPC_CP3,
1047 OPC_NMSUB_S = 0x38 | OPC_CP3,
1048 OPC_NMSUB_D = 0x39 | OPC_CP3,
1049 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1050};
1051
39454628 1052/* global register indices */
a7812ae4
PB
1053static TCGv_ptr cpu_env;
1054static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1055static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1056static TCGv cpu_dspctrl, btarget, bcond;
1057static TCGv_i32 hflags;
a7812ae4 1058static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1059static TCGv_i64 fpu_f64[32];
aa0bf00b 1060
1a7ff922 1061static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1062static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1063
022c62cb 1064#include "exec/gen-icount.h"
2e70f6ef 1065
895c2d04 1066#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1067 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1068 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1069 tcg_temp_free_i32(helper_tmp); \
1070 } while(0)
be24bb4f 1071
895c2d04 1072#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1073 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1074 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1075 tcg_temp_free_i32(helper_tmp); \
1076 } while(0)
be24bb4f 1077
895c2d04
BS
1078#define gen_helper_1e0i(name, ret, arg1) do { \
1079 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1080 gen_helper_##name(ret, cpu_env, helper_tmp); \
1081 tcg_temp_free_i32(helper_tmp); \
1082 } while(0)
1083
1084#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1085 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1086 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1087 tcg_temp_free_i32(helper_tmp); \
1088 } while(0)
1089
1090#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1091 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1092 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1093 tcg_temp_free_i32(helper_tmp); \
1094 } while(0)
1095
1096#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1097 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1098 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1099 tcg_temp_free_i32(helper_tmp); \
1100 } while(0)
be24bb4f 1101
895c2d04 1102#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1103 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1104 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1105 tcg_temp_free_i32(helper_tmp); \
1106 } while(0)
c239529e 1107
8e9ade68
TS
1108typedef struct DisasContext {
1109 struct TranslationBlock *tb;
1110 target_ulong pc, saved_pc;
1111 uint32_t opcode;
7b270ef2 1112 int singlestep_enabled;
d75c135e 1113 int insn_flags;
5ab5c041 1114 int32_t CP0_Config1;
8e9ade68
TS
1115 /* Routine used to access memory */
1116 int mem_idx;
1117 uint32_t hflags, saved_hflags;
1118 int bstate;
1119 target_ulong btarget;
d279279e 1120 bool ulri;
8e9ade68
TS
1121} DisasContext;
1122
1123enum {
1124 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1125 * exception condition */
8e9ade68
TS
1126 BS_STOP = 1, /* We want to stop translation for any reason */
1127 BS_BRANCH = 2, /* We reached a branch condition */
1128 BS_EXCP = 3, /* We reached an exception condition */
1129};
1130
d73ee8a2
RH
1131static const char * const regnames[] = {
1132 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1133 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1134 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1135 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1136};
6af0bf9c 1137
d73ee8a2
RH
1138static const char * const regnames_HI[] = {
1139 "HI0", "HI1", "HI2", "HI3",
1140};
4b2eb8d2 1141
d73ee8a2
RH
1142static const char * const regnames_LO[] = {
1143 "LO0", "LO1", "LO2", "LO3",
1144};
4b2eb8d2 1145
d73ee8a2
RH
1146static const char * const regnames_ACX[] = {
1147 "ACX0", "ACX1", "ACX2", "ACX3",
1148};
4b2eb8d2 1149
d73ee8a2
RH
1150static const char * const fregnames[] = {
1151 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1152 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1153 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1154 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1155};
958fb4a9 1156
fb7729e2
RH
1157#define MIPS_DEBUG(fmt, ...) \
1158 do { \
1159 if (MIPS_DEBUG_DISAS) { \
1160 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1161 TARGET_FMT_lx ": %08x " fmt "\n", \
1162 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1163 } \
1164 } while (0)
1165
1166#define LOG_DISAS(...) \
1167 do { \
1168 if (MIPS_DEBUG_DISAS) { \
1169 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1170 } \
1171 } while (0)
958fb4a9 1172
8e9ade68 1173#define MIPS_INVAL(op) \
8e9ade68 1174 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1175 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1176
8e9ade68
TS
1177/* General purpose registers moves. */
1178static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1179{
8e9ade68
TS
1180 if (reg == 0)
1181 tcg_gen_movi_tl(t, 0);
1182 else
4b2eb8d2 1183 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1184}
1185
8e9ade68 1186static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1187{
8e9ade68 1188 if (reg != 0)
4b2eb8d2 1189 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1190}
1191
b10fa3c9 1192/* Moves to/from ACX register. */
4b2eb8d2 1193static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1194{
4b2eb8d2 1195 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1196}
1197
4b2eb8d2 1198static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1199{
4b2eb8d2 1200 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1201}
1202
8e9ade68 1203/* Moves to/from shadow registers. */
be24bb4f 1204static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1205{
d9bea114 1206 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1207
1208 if (from == 0)
d9bea114 1209 tcg_gen_movi_tl(t0, 0);
8e9ade68 1210 else {
d9bea114 1211 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1212 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1213
7db13fae 1214 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1215 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1216 tcg_gen_andi_i32(t2, t2, 0xf);
1217 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1218 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1219 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1220
d9bea114 1221 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1222 tcg_temp_free_ptr(addr);
d9bea114 1223 tcg_temp_free_i32(t2);
8e9ade68 1224 }
d9bea114
AJ
1225 gen_store_gpr(t0, to);
1226 tcg_temp_free(t0);
aaa9128a
TS
1227}
1228
be24bb4f 1229static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1230{
be24bb4f 1231 if (to != 0) {
d9bea114
AJ
1232 TCGv t0 = tcg_temp_new();
1233 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1234 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1235
d9bea114 1236 gen_load_gpr(t0, from);
7db13fae 1237 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1238 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1239 tcg_gen_andi_i32(t2, t2, 0xf);
1240 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1241 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1242 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1243
d9bea114 1244 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1245 tcg_temp_free_ptr(addr);
d9bea114
AJ
1246 tcg_temp_free_i32(t2);
1247 tcg_temp_free(t0);
8e9ade68 1248 }
aaa9128a
TS
1249}
1250
aaa9128a 1251/* Floating point register moves. */
d73ee8a2 1252static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1253{
d73ee8a2 1254 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1255}
1256
d73ee8a2 1257static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1258{
d73ee8a2
RH
1259 TCGv_i64 t64 = tcg_temp_new_i64();
1260 tcg_gen_extu_i32_i64(t64, t);
1261 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1262 tcg_temp_free_i64(t64);
6d066274
AJ
1263}
1264
7f6613ce 1265static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1266{
7f6613ce
PJ
1267 if (ctx->hflags & MIPS_HFLAG_F64) {
1268 TCGv_i64 t64 = tcg_temp_new_i64();
1269 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1270 tcg_gen_trunc_i64_i32(t, t64);
1271 tcg_temp_free_i64(t64);
1272 } else {
1273 gen_load_fpr32(t, reg | 1);
1274 }
6d066274
AJ
1275}
1276
7f6613ce 1277static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1278{
7f6613ce
PJ
1279 if (ctx->hflags & MIPS_HFLAG_F64) {
1280 TCGv_i64 t64 = tcg_temp_new_i64();
1281 tcg_gen_extu_i32_i64(t64, t);
1282 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1283 tcg_temp_free_i64(t64);
1284 } else {
1285 gen_store_fpr32(t, reg | 1);
1286 }
aa0bf00b 1287}
6ea83fed 1288
d73ee8a2 1289static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1290{
f364515c 1291 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1292 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1293 } else {
d73ee8a2 1294 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1295 }
1296}
6ea83fed 1297
d73ee8a2 1298static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1299{
f364515c 1300 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1301 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1302 } else {
d73ee8a2
RH
1303 TCGv_i64 t0;
1304 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1305 t0 = tcg_temp_new_i64();
6d066274 1306 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1307 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1308 tcg_temp_free_i64(t0);
aa0bf00b
TS
1309 }
1310}
6ea83fed 1311
d94536f4 1312static inline int get_fp_bit (int cc)
a16336e4 1313{
d94536f4
AJ
1314 if (cc)
1315 return 24 + cc;
1316 else
1317 return 23;
a16336e4
TS
1318}
1319
30898801 1320/* Tests */
8e9ade68
TS
1321static inline void gen_save_pc(target_ulong pc)
1322{
1eb75d4a 1323 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1324}
30898801 1325
356265ae 1326static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1327{
d12d51d5 1328 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1329 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1330 gen_save_pc(ctx->pc);
6af0bf9c
FB
1331 ctx->saved_pc = ctx->pc;
1332 }
1333 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1334 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1335 ctx->saved_hflags = ctx->hflags;
364d4831 1336 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1337 case MIPS_HFLAG_BR:
5a5012ec
TS
1338 break;
1339 case MIPS_HFLAG_BC:
5a5012ec 1340 case MIPS_HFLAG_BL:
5a5012ec 1341 case MIPS_HFLAG_B:
d077b6f7 1342 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1343 break;
6af0bf9c
FB
1344 }
1345 }
1346}
1347
7db13fae 1348static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1349{
fd4a04eb 1350 ctx->saved_hflags = ctx->hflags;
364d4831 1351 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1352 case MIPS_HFLAG_BR:
fd4a04eb
TS
1353 break;
1354 case MIPS_HFLAG_BC:
1355 case MIPS_HFLAG_BL:
39454628 1356 case MIPS_HFLAG_B:
fd4a04eb 1357 ctx->btarget = env->btarget;
fd4a04eb 1358 break;
5a5012ec
TS
1359 }
1360}
1361
356265ae 1362static inline void
48d38ca5 1363generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1364{
a7812ae4
PB
1365 TCGv_i32 texcp = tcg_const_i32(excp);
1366 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1367 save_cpu_state(ctx, 1);
895c2d04 1368 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1369 tcg_temp_free_i32(terr);
1370 tcg_temp_free_i32(texcp);
aaa9128a
TS
1371}
1372
356265ae 1373static inline void
48d38ca5 1374generate_exception (DisasContext *ctx, int excp)
aaa9128a 1375{
6af0bf9c 1376 save_cpu_state(ctx, 1);
895c2d04 1377 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1378}
1379
48d38ca5 1380/* Addresses computation */
941694d0 1381static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1382{
941694d0 1383 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1384
1385#if defined(TARGET_MIPS64)
1386 /* For compatibility with 32-bit code, data reference in user mode
1387 with Status_UX = 0 should be casted to 32-bit and sign extended.
1388 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1389 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1390 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1391 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1392 }
1393#endif
4ad40f36
FB
1394}
1395
356265ae 1396static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1397{
fe253235 1398 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1399 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1400}
1401
356265ae 1402static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1403{
fe253235 1404 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1405 generate_exception_err(ctx, EXCP_CpU, 1);
1406}
1407
b8aa4598
TS
1408/* Verify that the processor is running with COP1X instructions enabled.
1409 This is associated with the nabla symbol in the MIPS32 and MIPS64
1410 opcode tables. */
1411
356265ae 1412static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1413{
1414 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1415 generate_exception(ctx, EXCP_RI);
1416}
1417
1418/* Verify that the processor is running with 64-bit floating-point
1419 operations enabled. */
1420
356265ae 1421static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1422{
b8aa4598 1423 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1424 generate_exception(ctx, EXCP_RI);
1425}
1426
1427/*
1428 * Verify if floating point register is valid; an operation is not defined
1429 * if bit 0 of any register specification is set and the FR bit in the
1430 * Status register equals zero, since the register numbers specify an
1431 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1432 * in the Status register equals one, both even and odd register numbers
1433 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1434 *
1435 * Multiple 64 bit wide registers can be checked by calling
1436 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1437 */
356265ae 1438static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1439{
fe253235 1440 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1441 generate_exception(ctx, EXCP_RI);
1442}
1443
853c3240
JL
1444/* Verify that the processor is running with DSP instructions enabled.
1445 This is enabled by CP0 Status register MX(24) bit.
1446 */
1447
1448static inline void check_dsp(DisasContext *ctx)
1449{
1450 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15
AJ
1451 if (ctx->insn_flags & ASE_DSP) {
1452 generate_exception(ctx, EXCP_DSPDIS);
1453 } else {
1454 generate_exception(ctx, EXCP_RI);
1455 }
853c3240
JL
1456 }
1457}
1458
1459static inline void check_dspr2(DisasContext *ctx)
1460{
1461 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15
AJ
1462 if (ctx->insn_flags & ASE_DSP) {
1463 generate_exception(ctx, EXCP_DSPDIS);
1464 } else {
1465 generate_exception(ctx, EXCP_RI);
1466 }
853c3240
JL
1467 }
1468}
1469
3a95e3a7 1470/* This code generates a "reserved instruction" exception if the
e189e748 1471 CPU does not support the instruction set corresponding to flags. */
d75c135e 1472static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1473{
d75c135e 1474 if (unlikely(!(ctx->insn_flags & flags))) {
3a95e3a7 1475 generate_exception(ctx, EXCP_RI);
d75c135e 1476 }
3a95e3a7
TS
1477}
1478
fecd2646
LA
1479/* This code generates a "reserved instruction" exception if the
1480 CPU has corresponding flag set which indicates that the instruction
1481 has been removed. */
1482static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1483{
1484 if (unlikely(ctx->insn_flags & flags)) {
1485 generate_exception(ctx, EXCP_RI);
1486 }
1487}
1488
e189e748
TS
1489/* This code generates a "reserved instruction" exception if 64-bit
1490 instructions are not enabled. */
356265ae 1491static inline void check_mips_64(DisasContext *ctx)
e189e748 1492{
fe253235 1493 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1494 generate_exception(ctx, EXCP_RI);
1495}
1496
8153667c
NF
1497/* Define small wrappers for gen_load_fpr* so that we have a uniform
1498 calling interface for 32 and 64-bit FPRs. No sense in changing
1499 all callers for gen_load_fpr32 when we need the CTX parameter for
1500 this one use. */
1501#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1502#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1503#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1504static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1505 int ft, int fs, int cc) \
1506{ \
1507 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1508 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1509 switch (ifmt) { \
1510 case FMT_PS: \
1511 check_cp1_64bitmode(ctx); \
1512 break; \
1513 case FMT_D: \
1514 if (abs) { \
1515 check_cop1x(ctx); \
1516 } \
1517 check_cp1_registers(ctx, fs | ft); \
1518 break; \
1519 case FMT_S: \
1520 if (abs) { \
1521 check_cop1x(ctx); \
1522 } \
1523 break; \
1524 } \
1525 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1526 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1527 switch (n) { \
895c2d04
BS
1528 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1529 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1530 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1531 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1532 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1533 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1534 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1535 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1536 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1537 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1538 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1539 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1540 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1541 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1542 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1543 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1544 default: abort(); \
1545 } \
1546 tcg_temp_free_i##bits (fp0); \
1547 tcg_temp_free_i##bits (fp1); \
1548}
1549
1550FOP_CONDS(, 0, d, FMT_D, 64)
1551FOP_CONDS(abs, 1, d, FMT_D, 64)
1552FOP_CONDS(, 0, s, FMT_S, 32)
1553FOP_CONDS(abs, 1, s, FMT_S, 32)
1554FOP_CONDS(, 0, ps, FMT_PS, 64)
1555FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1556#undef FOP_CONDS
1557#undef gen_ldcmp_fpr32
1558#undef gen_ldcmp_fpr64
1559
958fb4a9 1560/* load/store instructions. */
e7139c44 1561#ifdef CONFIG_USER_ONLY
d9bea114 1562#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1563static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1564{ \
1565 TCGv t0 = tcg_temp_new(); \
1566 tcg_gen_mov_tl(t0, arg1); \
1567 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1568 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1569 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1570 tcg_temp_free(t0); \
aaa9128a 1571}
e7139c44
AJ
1572#else
1573#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1574static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1575{ \
895c2d04 1576 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1577}
1578#endif
aaa9128a
TS
1579OP_LD_ATOMIC(ll,ld32s);
1580#if defined(TARGET_MIPS64)
1581OP_LD_ATOMIC(lld,ld64);
1582#endif
1583#undef OP_LD_ATOMIC
1584
590bc601
PB
1585#ifdef CONFIG_USER_ONLY
1586#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1587static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1588{ \
1589 TCGv t0 = tcg_temp_new(); \
1590 int l1 = gen_new_label(); \
1591 int l2 = gen_new_label(); \
1592 \
1593 tcg_gen_andi_tl(t0, arg2, almask); \
1594 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1595 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1596 generate_exception(ctx, EXCP_AdES); \
1597 gen_set_label(l1); \
7db13fae 1598 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1599 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1600 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1601 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1602 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1603 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1604 gen_set_label(l2); \
1605 tcg_gen_movi_tl(t0, 0); \
1606 gen_store_gpr(t0, rt); \
1607 tcg_temp_free(t0); \
1608}
1609#else
1610#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1611static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1612{ \
1613 TCGv t0 = tcg_temp_new(); \
895c2d04 1614 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1615 gen_store_gpr(t0, rt); \
590bc601
PB
1616 tcg_temp_free(t0); \
1617}
1618#endif
590bc601 1619OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1620#if defined(TARGET_MIPS64)
590bc601 1621OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1622#endif
1623#undef OP_ST_ATOMIC
1624
662d7485
NF
1625static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1626 int base, int16_t offset)
1627{
1628 if (base == 0) {
1629 tcg_gen_movi_tl(addr, offset);
1630 } else if (offset == 0) {
1631 gen_load_gpr(addr, base);
1632 } else {
1633 tcg_gen_movi_tl(addr, offset);
1634 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1635 }
1636}
1637
364d4831
NF
1638static target_ulong pc_relative_pc (DisasContext *ctx)
1639{
1640 target_ulong pc = ctx->pc;
1641
1642 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1643 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1644
1645 pc -= branch_bytes;
1646 }
1647
1648 pc &= ~(target_ulong)3;
1649 return pc;
1650}
1651
5c13fdfd 1652/* Load */
d75c135e
AJ
1653static void gen_ld(DisasContext *ctx, uint32_t opc,
1654 int rt, int base, int16_t offset)
6af0bf9c 1655{
5c13fdfd 1656 const char *opn = "ld";
fc40787a 1657 TCGv t0, t1, t2;
afa88c3a 1658
d75c135e 1659 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
1660 /* Loongson CPU uses a load to zero register for prefetch.
1661 We emulate it as a NOP. On other CPU we must perform the
1662 actual memory access. */
1663 MIPS_DEBUG("NOP");
1664 return;
1665 }
6af0bf9c 1666
afa88c3a 1667 t0 = tcg_temp_new();
662d7485 1668 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1669
6af0bf9c 1670 switch (opc) {
d26bc211 1671#if defined(TARGET_MIPS64)
6e473128 1672 case OPC_LWU:
5f68f5ae 1673 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
78723684 1674 gen_store_gpr(t0, rt);
6e473128
TS
1675 opn = "lwu";
1676 break;
6af0bf9c 1677 case OPC_LD:
5f68f5ae 1678 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
78723684 1679 gen_store_gpr(t0, rt);
6af0bf9c
FB
1680 opn = "ld";
1681 break;
7a387fff 1682 case OPC_LLD:
bf7910c6 1683 case R6_OPC_LLD:
b835e919 1684 save_cpu_state(ctx, 1);
5c13fdfd 1685 op_ld_lld(t0, t0, ctx);
78723684 1686 gen_store_gpr(t0, rt);
7a387fff
TS
1687 opn = "lld";
1688 break;
6af0bf9c 1689 case OPC_LDL:
3cee3050 1690 t1 = tcg_temp_new();
fc40787a
AJ
1691 tcg_gen_andi_tl(t1, t0, 7);
1692#ifndef TARGET_WORDS_BIGENDIAN
1693 tcg_gen_xori_tl(t1, t1, 7);
1694#endif
1695 tcg_gen_shli_tl(t1, t1, 3);
1696 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1697 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1698 tcg_gen_shl_tl(t0, t0, t1);
1699 tcg_gen_xori_tl(t1, t1, 63);
1700 t2 = tcg_const_tl(0x7fffffffffffffffull);
1701 tcg_gen_shr_tl(t2, t2, t1);
78723684 1702 gen_load_gpr(t1, rt);
fc40787a
AJ
1703 tcg_gen_and_tl(t1, t1, t2);
1704 tcg_temp_free(t2);
1705 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1706 tcg_temp_free(t1);
fc40787a 1707 gen_store_gpr(t0, rt);
6af0bf9c
FB
1708 opn = "ldl";
1709 break;
6af0bf9c 1710 case OPC_LDR:
3cee3050 1711 t1 = tcg_temp_new();
fc40787a
AJ
1712 tcg_gen_andi_tl(t1, t0, 7);
1713#ifdef TARGET_WORDS_BIGENDIAN
1714 tcg_gen_xori_tl(t1, t1, 7);
1715#endif
1716 tcg_gen_shli_tl(t1, t1, 3);
1717 tcg_gen_andi_tl(t0, t0, ~7);
5f68f5ae 1718 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
fc40787a
AJ
1719 tcg_gen_shr_tl(t0, t0, t1);
1720 tcg_gen_xori_tl(t1, t1, 63);
1721 t2 = tcg_const_tl(0xfffffffffffffffeull);
1722 tcg_gen_shl_tl(t2, t2, t1);
78723684 1723 gen_load_gpr(t1, rt);
fc40787a
AJ
1724 tcg_gen_and_tl(t1, t1, t2);
1725 tcg_temp_free(t2);
1726 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1727 tcg_temp_free(t1);
fc40787a 1728 gen_store_gpr(t0, rt);
6af0bf9c
FB
1729 opn = "ldr";
1730 break;
364d4831 1731 case OPC_LDPC:
3cee3050 1732 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1733 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1734 tcg_temp_free(t1);
5f68f5ae 1735 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
364d4831 1736 gen_store_gpr(t0, rt);
5c13fdfd 1737 opn = "ldpc";
364d4831 1738 break;
6af0bf9c 1739#endif
364d4831 1740 case OPC_LWPC:
3cee3050 1741 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 1742 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 1743 tcg_temp_free(t1);
5f68f5ae 1744 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
364d4831 1745 gen_store_gpr(t0, rt);
5c13fdfd 1746 opn = "lwpc";
364d4831 1747 break;
6af0bf9c 1748 case OPC_LW:
5f68f5ae 1749 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
78723684 1750 gen_store_gpr(t0, rt);
6af0bf9c
FB
1751 opn = "lw";
1752 break;
6af0bf9c 1753 case OPC_LH:
5f68f5ae 1754 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
78723684 1755 gen_store_gpr(t0, rt);
6af0bf9c
FB
1756 opn = "lh";
1757 break;
6af0bf9c 1758 case OPC_LHU:
5f68f5ae 1759 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
78723684 1760 gen_store_gpr(t0, rt);
6af0bf9c
FB
1761 opn = "lhu";
1762 break;
1763 case OPC_LB:
5f68f5ae 1764 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
78723684 1765 gen_store_gpr(t0, rt);
6af0bf9c
FB
1766 opn = "lb";
1767 break;
6af0bf9c 1768 case OPC_LBU:
5f68f5ae 1769 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
78723684 1770 gen_store_gpr(t0, rt);
6af0bf9c
FB
1771 opn = "lbu";
1772 break;
1773 case OPC_LWL:
3cee3050 1774 t1 = tcg_temp_new();
fc40787a
AJ
1775 tcg_gen_andi_tl(t1, t0, 3);
1776#ifndef TARGET_WORDS_BIGENDIAN
1777 tcg_gen_xori_tl(t1, t1, 3);
1778#endif
1779 tcg_gen_shli_tl(t1, t1, 3);
1780 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1781 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1782 tcg_gen_shl_tl(t0, t0, t1);
1783 tcg_gen_xori_tl(t1, t1, 31);
1784 t2 = tcg_const_tl(0x7fffffffull);
1785 tcg_gen_shr_tl(t2, t2, t1);
6958549d 1786 gen_load_gpr(t1, rt);
fc40787a
AJ
1787 tcg_gen_and_tl(t1, t1, t2);
1788 tcg_temp_free(t2);
1789 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1790 tcg_temp_free(t1);
fc40787a
AJ
1791 tcg_gen_ext32s_tl(t0, t0);
1792 gen_store_gpr(t0, rt);
6af0bf9c
FB
1793 opn = "lwl";
1794 break;
6af0bf9c 1795 case OPC_LWR:
3cee3050 1796 t1 = tcg_temp_new();
fc40787a
AJ
1797 tcg_gen_andi_tl(t1, t0, 3);
1798#ifdef TARGET_WORDS_BIGENDIAN
1799 tcg_gen_xori_tl(t1, t1, 3);
1800#endif
1801 tcg_gen_shli_tl(t1, t1, 3);
1802 tcg_gen_andi_tl(t0, t0, ~3);
5f68f5ae 1803 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
fc40787a
AJ
1804 tcg_gen_shr_tl(t0, t0, t1);
1805 tcg_gen_xori_tl(t1, t1, 31);
1806 t2 = tcg_const_tl(0xfffffffeull);
1807 tcg_gen_shl_tl(t2, t2, t1);
6958549d 1808 gen_load_gpr(t1, rt);
fc40787a
AJ
1809 tcg_gen_and_tl(t1, t1, t2);
1810 tcg_temp_free(t2);
1811 tcg_gen_or_tl(t0, t0, t1);
3cee3050 1812 tcg_temp_free(t1);
c728154b 1813 tcg_gen_ext32s_tl(t0, t0);
fc40787a 1814 gen_store_gpr(t0, rt);
6af0bf9c
FB
1815 opn = "lwr";
1816 break;
6af0bf9c 1817 case OPC_LL:
4368b29a 1818 case R6_OPC_LL:
e7139c44 1819 save_cpu_state(ctx, 1);
5c13fdfd 1820 op_ld_ll(t0, t0, ctx);
78723684 1821 gen_store_gpr(t0, rt);
6af0bf9c
FB
1822 opn = "ll";
1823 break;
d66c7132 1824 }
2abf314d 1825 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1826 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1827 tcg_temp_free(t0);
d66c7132
AJ
1828}
1829
5c13fdfd
AJ
1830/* Store */
1831static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1832 int base, int16_t offset)
1833{
1834 const char *opn = "st";
1835 TCGv t0 = tcg_temp_new();
1836 TCGv t1 = tcg_temp_new();
1837
1838 gen_base_offset_addr(ctx, t0, base, offset);
1839 gen_load_gpr(t1, rt);
1840 switch (opc) {
1841#if defined(TARGET_MIPS64)
1842 case OPC_SD:
5f68f5ae 1843 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
5c13fdfd
AJ
1844 opn = "sd";
1845 break;
1846 case OPC_SDL:
1847 save_cpu_state(ctx, 1);
895c2d04 1848 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1849 opn = "sdl";
1850 break;
1851 case OPC_SDR:
1852 save_cpu_state(ctx, 1);
895c2d04 1853 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1854 opn = "sdr";
1855 break;
1856#endif
1857 case OPC_SW:
5f68f5ae 1858 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
5c13fdfd
AJ
1859 opn = "sw";
1860 break;
1861 case OPC_SH:
5f68f5ae 1862 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
5c13fdfd
AJ
1863 opn = "sh";
1864 break;
1865 case OPC_SB:
5f68f5ae 1866 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
5c13fdfd
AJ
1867 opn = "sb";
1868 break;
1869 case OPC_SWL:
1870 save_cpu_state(ctx, 1);
895c2d04 1871 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1872 opn = "swl";
1873 break;
1874 case OPC_SWR:
1875 save_cpu_state(ctx, 1);
895c2d04 1876 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1877 opn = "swr";
1878 break;
1879 }
2abf314d 1880 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1881 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1882 tcg_temp_free(t0);
1883 tcg_temp_free(t1);
1884}
1885
1886
d66c7132
AJ
1887/* Store conditional */
1888static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1889 int base, int16_t offset)
1890{
1891 const char *opn = "st_cond";
1892 TCGv t0, t1;
1893
2d2826b9 1894#ifdef CONFIG_USER_ONLY
d66c7132 1895 t0 = tcg_temp_local_new();
d66c7132 1896 t1 = tcg_temp_local_new();
2d2826b9
AJ
1897#else
1898 t0 = tcg_temp_new();
1899 t1 = tcg_temp_new();
1900#endif
1901 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1902 gen_load_gpr(t1, rt);
1903 switch (opc) {
1904#if defined(TARGET_MIPS64)
1905 case OPC_SCD:
bf7910c6 1906 case R6_OPC_SCD:
b835e919 1907 save_cpu_state(ctx, 1);
5c13fdfd 1908 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1909 opn = "scd";
1910 break;
1911#endif
6af0bf9c 1912 case OPC_SC:
4368b29a 1913 case R6_OPC_SC:
e7139c44 1914 save_cpu_state(ctx, 1);
5c13fdfd 1915 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1916 opn = "sc";
1917 break;
6af0bf9c 1918 }
2abf314d 1919 (void)opn; /* avoid a compiler warning */
6af0bf9c 1920 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1921 tcg_temp_free(t1);
d66c7132 1922 tcg_temp_free(t0);
6af0bf9c
FB
1923}
1924
6ea83fed 1925/* Load and store */
7a387fff 1926static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1927 int base, int16_t offset)
6ea83fed 1928{
923617a3 1929 const char *opn = "flt_ldst";
4e2474d6 1930 TCGv t0 = tcg_temp_new();
6ea83fed 1931
662d7485 1932 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1933 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1934 memory access. */
6ea83fed
FB
1935 switch (opc) {
1936 case OPC_LWC1:
b6d96bed 1937 {
a7812ae4 1938 TCGv_i32 fp0 = tcg_temp_new_i32();
5f68f5ae 1939 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
b6d96bed 1940 gen_store_fpr32(fp0, ft);
a7812ae4 1941 tcg_temp_free_i32(fp0);
b6d96bed 1942 }
6ea83fed
FB
1943 opn = "lwc1";
1944 break;
1945 case OPC_SWC1:
b6d96bed 1946 {
a7812ae4 1947 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1948 gen_load_fpr32(fp0, ft);
5f68f5ae 1949 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 1950 tcg_temp_free_i32(fp0);
b6d96bed 1951 }
6ea83fed
FB
1952 opn = "swc1";
1953 break;
1954 case OPC_LDC1:
b6d96bed 1955 {
a7812ae4 1956 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 1957 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 1958 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1959 tcg_temp_free_i64(fp0);
b6d96bed 1960 }
6ea83fed
FB
1961 opn = "ldc1";
1962 break;
1963 case OPC_SDC1:
b6d96bed 1964 {
a7812ae4 1965 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 1966 gen_load_fpr64(ctx, fp0, ft);
5f68f5ae 1967 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 1968 tcg_temp_free_i64(fp0);
b6d96bed 1969 }
6ea83fed
FB
1970 opn = "sdc1";
1971 break;
1972 default:
923617a3 1973 MIPS_INVAL(opn);
e397ee33 1974 generate_exception(ctx, EXCP_RI);
78723684 1975 goto out;
6ea83fed 1976 }
2abf314d 1977 (void)opn; /* avoid a compiler warning */
6ea83fed 1978 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1979 out:
1980 tcg_temp_free(t0);
6ea83fed 1981}
6ea83fed 1982
5ab5c041
AJ
1983static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
1984 int rs, int16_t imm)
26ebe468 1985{
5ab5c041 1986 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468
NF
1987 check_cp1_enabled(ctx);
1988 gen_flt_ldst(ctx, op, rt, rs, imm);
1989 } else {
1990 generate_exception_err(ctx, EXCP_CpU, 1);
1991 }
1992}
1993
6af0bf9c 1994/* Arithmetic with immediate operand */
d75c135e
AJ
1995static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1996 int rt, int rs, int16_t imm)
6af0bf9c 1997{
324d9e32 1998 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1999 const char *opn = "imm arith";
6af0bf9c 2000
7a387fff 2001 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2002 /* If no destination, treat it as a NOP.
2003 For addi, we must generate the overflow exception when needed. */
6af0bf9c 2004 MIPS_DEBUG("NOP");
324d9e32 2005 return;
6af0bf9c
FB
2006 }
2007 switch (opc) {
2008 case OPC_ADDI:
48d38ca5 2009 {
324d9e32
AJ
2010 TCGv t0 = tcg_temp_local_new();
2011 TCGv t1 = tcg_temp_new();
2012 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2013 int l1 = gen_new_label();
2014
324d9e32
AJ
2015 gen_load_gpr(t1, rs);
2016 tcg_gen_addi_tl(t0, t1, uimm);
2017 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2018
324d9e32
AJ
2019 tcg_gen_xori_tl(t1, t1, ~uimm);
2020 tcg_gen_xori_tl(t2, t0, uimm);
2021 tcg_gen_and_tl(t1, t1, t2);
2022 tcg_temp_free(t2);
2023 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2024 tcg_temp_free(t1);
48d38ca5
TS
2025 /* operands of same sign, result different sign */
2026 generate_exception(ctx, EXCP_OVERFLOW);
2027 gen_set_label(l1);
78723684 2028 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2029 gen_store_gpr(t0, rt);
2030 tcg_temp_free(t0);
48d38ca5 2031 }
6af0bf9c
FB
2032 opn = "addi";
2033 break;
2034 case OPC_ADDIU:
324d9e32
AJ
2035 if (rs != 0) {
2036 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2037 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2038 } else {
2039 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2040 }
6af0bf9c
FB
2041 opn = "addiu";
2042 break;
d26bc211 2043#if defined(TARGET_MIPS64)
7a387fff 2044 case OPC_DADDI:
48d38ca5 2045 {
324d9e32
AJ
2046 TCGv t0 = tcg_temp_local_new();
2047 TCGv t1 = tcg_temp_new();
2048 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2049 int l1 = gen_new_label();
2050
324d9e32
AJ
2051 gen_load_gpr(t1, rs);
2052 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2053
324d9e32
AJ
2054 tcg_gen_xori_tl(t1, t1, ~uimm);
2055 tcg_gen_xori_tl(t2, t0, uimm);
2056 tcg_gen_and_tl(t1, t1, t2);
2057 tcg_temp_free(t2);
2058 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2059 tcg_temp_free(t1);
48d38ca5
TS
2060 /* operands of same sign, result different sign */
2061 generate_exception(ctx, EXCP_OVERFLOW);
2062 gen_set_label(l1);
324d9e32
AJ
2063 gen_store_gpr(t0, rt);
2064 tcg_temp_free(t0);
48d38ca5 2065 }
7a387fff
TS
2066 opn = "daddi";
2067 break;
2068 case OPC_DADDIU:
324d9e32
AJ
2069 if (rs != 0) {
2070 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2071 } else {
2072 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2073 }
7a387fff
TS
2074 opn = "daddiu";
2075 break;
2076#endif
324d9e32 2077 }
2abf314d 2078 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2079 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2080}
2081
2082/* Logic with immediate operand */
d75c135e 2083static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2084 int rt, int rs, int16_t imm)
324d9e32
AJ
2085{
2086 target_ulong uimm;
324d9e32
AJ
2087
2088 if (rt == 0) {
2089 /* If no destination, treat it as a NOP. */
2090 MIPS_DEBUG("NOP");
2091 return;
2092 }
2093 uimm = (uint16_t)imm;
2094 switch (opc) {
6af0bf9c 2095 case OPC_ANDI:
324d9e32
AJ
2096 if (likely(rs != 0))
2097 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2098 else
2099 tcg_gen_movi_tl(cpu_gpr[rt], 0);
7c2c3ea3
EJ
2100 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2101 regnames[rs], uimm);
6af0bf9c
FB
2102 break;
2103 case OPC_ORI:
324d9e32
AJ
2104 if (rs != 0)
2105 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2106 else
2107 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2108 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2109 regnames[rs], uimm);
6af0bf9c
FB
2110 break;
2111 case OPC_XORI:
324d9e32
AJ
2112 if (likely(rs != 0))
2113 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2114 else
2115 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
7c2c3ea3
EJ
2116 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2117 regnames[rs], uimm);
6af0bf9c
FB
2118 break;
2119 case OPC_LUI:
324d9e32 2120 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
7c2c3ea3
EJ
2121 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2122 break;
2123
2124 default:
2125 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
6af0bf9c 2126 break;
324d9e32 2127 }
324d9e32
AJ
2128}
2129
2130/* Set on less than with immediate operand */
d75c135e 2131static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2132 int rt, int rs, int16_t imm)
324d9e32
AJ
2133{
2134 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2135 const char *opn = "imm arith";
2136 TCGv t0;
2137
2138 if (rt == 0) {
2139 /* If no destination, treat it as a NOP. */
2140 MIPS_DEBUG("NOP");
2141 return;
2142 }
2143 t0 = tcg_temp_new();
2144 gen_load_gpr(t0, rs);
2145 switch (opc) {
2146 case OPC_SLTI:
e68dd28f 2147 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2148 opn = "slti";
2149 break;
2150 case OPC_SLTIU:
e68dd28f 2151 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2152 opn = "sltiu";
2153 break;
2154 }
2abf314d 2155 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2156 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2157 tcg_temp_free(t0);
2158}
2159
2160/* Shifts with immediate operand */
d75c135e 2161static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2162 int rt, int rs, int16_t imm)
2163{
2164 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2165 const char *opn = "imm shift";
2166 TCGv t0;
2167
2168 if (rt == 0) {
2169 /* If no destination, treat it as a NOP. */
2170 MIPS_DEBUG("NOP");
2171 return;
2172 }
2173
2174 t0 = tcg_temp_new();
2175 gen_load_gpr(t0, rs);
2176 switch (opc) {
6af0bf9c 2177 case OPC_SLL:
78723684 2178 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2179 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2180 opn = "sll";
2181 break;
2182 case OPC_SRA:
324d9e32 2183 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2184 opn = "sra";
2185 break;
2186 case OPC_SRL:
ea63e2c3
NF
2187 if (uimm != 0) {
2188 tcg_gen_ext32u_tl(t0, t0);
2189 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2190 } else {
2191 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2192 }
ea63e2c3
NF
2193 opn = "srl";
2194 break;
2195 case OPC_ROTR:
2196 if (uimm != 0) {
2197 TCGv_i32 t1 = tcg_temp_new_i32();
2198
2199 tcg_gen_trunc_tl_i32(t1, t0);
2200 tcg_gen_rotri_i32(t1, t1, uimm);
2201 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2202 tcg_temp_free_i32(t1);
3399e30f
NF
2203 } else {
2204 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2205 }
2206 opn = "rotr";
7a387fff 2207 break;
d26bc211 2208#if defined(TARGET_MIPS64)
7a387fff 2209 case OPC_DSLL:
324d9e32 2210 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2211 opn = "dsll";
2212 break;
2213 case OPC_DSRA:
324d9e32 2214 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2215 opn = "dsra";
2216 break;
2217 case OPC_DSRL:
ea63e2c3
NF
2218 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2219 opn = "dsrl";
2220 break;
2221 case OPC_DROTR:
2222 if (uimm != 0) {
2223 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2224 } else {
2225 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2226 }
ea63e2c3 2227 opn = "drotr";
7a387fff
TS
2228 break;
2229 case OPC_DSLL32:
324d9e32 2230 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2231 opn = "dsll32";
2232 break;
2233 case OPC_DSRA32:
324d9e32 2234 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2235 opn = "dsra32";
2236 break;
2237 case OPC_DSRL32:
ea63e2c3
NF
2238 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2239 opn = "dsrl32";
2240 break;
2241 case OPC_DROTR32:
2242 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2243 opn = "drotr32";
6af0bf9c 2244 break;
7a387fff 2245#endif
6af0bf9c 2246 }
2abf314d 2247 (void)opn; /* avoid a compiler warning */
93b12ccc 2248 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2249 tcg_temp_free(t0);
6af0bf9c
FB
2250}
2251
2252/* Arithmetic */
d75c135e
AJ
2253static void gen_arith(DisasContext *ctx, uint32_t opc,
2254 int rd, int rs, int rt)
6af0bf9c 2255{
923617a3 2256 const char *opn = "arith";
6af0bf9c 2257
7a387fff
TS
2258 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2259 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2260 /* If no destination, treat it as a NOP.
2261 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2262 MIPS_DEBUG("NOP");
460f00c4 2263 return;
185f0762 2264 }
460f00c4 2265
6af0bf9c
FB
2266 switch (opc) {
2267 case OPC_ADD:
48d38ca5 2268 {
460f00c4
AJ
2269 TCGv t0 = tcg_temp_local_new();
2270 TCGv t1 = tcg_temp_new();
2271 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2272 int l1 = gen_new_label();
2273
460f00c4
AJ
2274 gen_load_gpr(t1, rs);
2275 gen_load_gpr(t2, rt);
2276 tcg_gen_add_tl(t0, t1, t2);
2277 tcg_gen_ext32s_tl(t0, t0);
2278 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2279 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2280 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2281 tcg_temp_free(t2);
2282 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2283 tcg_temp_free(t1);
48d38ca5
TS
2284 /* operands of same sign, result different sign */
2285 generate_exception(ctx, EXCP_OVERFLOW);
2286 gen_set_label(l1);
460f00c4
AJ
2287 gen_store_gpr(t0, rd);
2288 tcg_temp_free(t0);
48d38ca5 2289 }
6af0bf9c
FB
2290 opn = "add";
2291 break;
2292 case OPC_ADDU:
460f00c4
AJ
2293 if (rs != 0 && rt != 0) {
2294 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2295 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2296 } else if (rs == 0 && rt != 0) {
2297 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2298 } else if (rs != 0 && rt == 0) {
2299 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2300 } else {
2301 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2302 }
6af0bf9c
FB
2303 opn = "addu";
2304 break;
2305 case OPC_SUB:
48d38ca5 2306 {
460f00c4
AJ
2307 TCGv t0 = tcg_temp_local_new();
2308 TCGv t1 = tcg_temp_new();
2309 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2310 int l1 = gen_new_label();
2311
460f00c4
AJ
2312 gen_load_gpr(t1, rs);
2313 gen_load_gpr(t2, rt);
2314 tcg_gen_sub_tl(t0, t1, t2);
2315 tcg_gen_ext32s_tl(t0, t0);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2319 tcg_temp_free(t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2321 tcg_temp_free(t1);
31e3104f 2322 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2323 generate_exception(ctx, EXCP_OVERFLOW);
2324 gen_set_label(l1);
460f00c4
AJ
2325 gen_store_gpr(t0, rd);
2326 tcg_temp_free(t0);
48d38ca5 2327 }
6af0bf9c
FB
2328 opn = "sub";
2329 break;
2330 case OPC_SUBU:
460f00c4
AJ
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2334 } else if (rs == 0 && rt != 0) {
2335 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2336 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2337 } else if (rs != 0 && rt == 0) {
2338 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2339 } else {
2340 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2341 }
6af0bf9c
FB
2342 opn = "subu";
2343 break;
d26bc211 2344#if defined(TARGET_MIPS64)
7a387fff 2345 case OPC_DADD:
48d38ca5 2346 {
460f00c4
AJ
2347 TCGv t0 = tcg_temp_local_new();
2348 TCGv t1 = tcg_temp_new();
2349 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2350 int l1 = gen_new_label();
2351
460f00c4
AJ
2352 gen_load_gpr(t1, rs);
2353 gen_load_gpr(t2, rt);
2354 tcg_gen_add_tl(t0, t1, t2);
2355 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2356 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2357 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2358 tcg_temp_free(t2);
2359 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2360 tcg_temp_free(t1);
48d38ca5
TS
2361 /* operands of same sign, result different sign */
2362 generate_exception(ctx, EXCP_OVERFLOW);
2363 gen_set_label(l1);
460f00c4
AJ
2364 gen_store_gpr(t0, rd);
2365 tcg_temp_free(t0);
48d38ca5 2366 }
7a387fff
TS
2367 opn = "dadd";
2368 break;
2369 case OPC_DADDU:
460f00c4
AJ
2370 if (rs != 0 && rt != 0) {
2371 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2372 } else if (rs == 0 && rt != 0) {
2373 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2374 } else if (rs != 0 && rt == 0) {
2375 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2376 } else {
2377 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2378 }
7a387fff
TS
2379 opn = "daddu";
2380 break;
2381 case OPC_DSUB:
48d38ca5 2382 {
460f00c4
AJ
2383 TCGv t0 = tcg_temp_local_new();
2384 TCGv t1 = tcg_temp_new();
2385 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2386 int l1 = gen_new_label();
2387
460f00c4
AJ
2388 gen_load_gpr(t1, rs);
2389 gen_load_gpr(t2, rt);
2390 tcg_gen_sub_tl(t0, t1, t2);
2391 tcg_gen_xor_tl(t2, t1, t2);
2392 tcg_gen_xor_tl(t1, t0, t1);
2393 tcg_gen_and_tl(t1, t1, t2);
2394 tcg_temp_free(t2);
2395 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2396 tcg_temp_free(t1);
31e3104f 2397 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2398 generate_exception(ctx, EXCP_OVERFLOW);
2399 gen_set_label(l1);
460f00c4
AJ
2400 gen_store_gpr(t0, rd);
2401 tcg_temp_free(t0);
48d38ca5 2402 }
7a387fff
TS
2403 opn = "dsub";
2404 break;
2405 case OPC_DSUBU:
460f00c4
AJ
2406 if (rs != 0 && rt != 0) {
2407 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2408 } else if (rs == 0 && rt != 0) {
2409 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2410 } else if (rs != 0 && rt == 0) {
2411 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2412 } else {
2413 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2414 }
7a387fff
TS
2415 opn = "dsubu";
2416 break;
2417#endif
460f00c4
AJ
2418 case OPC_MUL:
2419 if (likely(rs != 0 && rt != 0)) {
2420 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2421 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2422 } else {
2423 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2424 }
2425 opn = "mul";
6af0bf9c 2426 break;
460f00c4 2427 }
2abf314d 2428 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2429 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2430}
2431
2432/* Conditional move */
d75c135e 2433static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2434 int rd, int rs, int rt)
460f00c4
AJ
2435{
2436 const char *opn = "cond move";
acf12465 2437 TCGv t0, t1, t2;
460f00c4
AJ
2438
2439 if (rd == 0) {
acf12465 2440 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2441 MIPS_DEBUG("NOP");
2442 return;
2443 }
2444
acf12465
AJ
2445 t0 = tcg_temp_new();
2446 gen_load_gpr(t0, rt);
2447 t1 = tcg_const_tl(0);
2448 t2 = tcg_temp_new();
2449 gen_load_gpr(t2, rs);
460f00c4
AJ
2450 switch (opc) {
2451 case OPC_MOVN:
acf12465 2452 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2453 opn = "movn";
6af0bf9c 2454 break;
460f00c4 2455 case OPC_MOVZ:
acf12465 2456 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4
AJ
2457 opn = "movz";
2458 break;
b691d9d2
LA
2459 case OPC_SELNEZ:
2460 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2461 opn = "selnez";
2462 break;
2463 case OPC_SELEQZ:
2464 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2465 opn = "seleqz";
2466 break;
460f00c4 2467 }
acf12465
AJ
2468 tcg_temp_free(t2);
2469 tcg_temp_free(t1);
2470 tcg_temp_free(t0);
460f00c4 2471
2abf314d 2472 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2473 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2474}
2475
2476/* Logic */
d75c135e 2477static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2478 int rd, int rs, int rt)
460f00c4
AJ
2479{
2480 const char *opn = "logic";
2481
2482 if (rd == 0) {
2483 /* If no destination, treat it as a NOP. */
2484 MIPS_DEBUG("NOP");
2485 return;
2486 }
2487
2488 switch (opc) {
6af0bf9c 2489 case OPC_AND:
460f00c4
AJ
2490 if (likely(rs != 0 && rt != 0)) {
2491 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2492 } else {
2493 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2494 }
6af0bf9c
FB
2495 opn = "and";
2496 break;
2497 case OPC_NOR:
460f00c4
AJ
2498 if (rs != 0 && rt != 0) {
2499 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2500 } else if (rs == 0 && rt != 0) {
2501 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2502 } else if (rs != 0 && rt == 0) {
2503 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2504 } else {
2505 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2506 }
6af0bf9c
FB
2507 opn = "nor";
2508 break;
2509 case OPC_OR:
460f00c4
AJ
2510 if (likely(rs != 0 && rt != 0)) {
2511 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2512 } else if (rs == 0 && rt != 0) {
2513 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2514 } else if (rs != 0 && rt == 0) {
2515 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2516 } else {
2517 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2518 }
6af0bf9c
FB
2519 opn = "or";
2520 break;
2521 case OPC_XOR:
460f00c4
AJ
2522 if (likely(rs != 0 && rt != 0)) {
2523 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2524 } else if (rs == 0 && rt != 0) {
2525 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2526 } else if (rs != 0 && rt == 0) {
2527 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2528 } else {
2529 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2530 }
6af0bf9c
FB
2531 opn = "xor";
2532 break;
460f00c4 2533 }
2abf314d 2534 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2535 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2536}
2537
2538/* Set on lower than */
d75c135e 2539static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2540 int rd, int rs, int rt)
460f00c4
AJ
2541{
2542 const char *opn = "slt";
2543 TCGv t0, t1;
2544
2545 if (rd == 0) {
2546 /* If no destination, treat it as a NOP. */
2547 MIPS_DEBUG("NOP");
2548 return;
2549 }
2550
2551 t0 = tcg_temp_new();
2552 t1 = tcg_temp_new();
2553 gen_load_gpr(t0, rs);
2554 gen_load_gpr(t1, rt);
2555 switch (opc) {
2556 case OPC_SLT:
e68dd28f 2557 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2558 opn = "slt";
6af0bf9c 2559 break;
460f00c4 2560 case OPC_SLTU:
e68dd28f 2561 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2562 opn = "sltu";
2563 break;
2564 }
2abf314d 2565 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2566 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2567 tcg_temp_free(t0);
2568 tcg_temp_free(t1);
2569}
20c4c97c 2570
460f00c4 2571/* Shifts */
d75c135e
AJ
2572static void gen_shift(DisasContext *ctx, uint32_t opc,
2573 int rd, int rs, int rt)
460f00c4
AJ
2574{
2575 const char *opn = "shifts";
2576 TCGv t0, t1;
20c4c97c 2577
460f00c4
AJ
2578 if (rd == 0) {
2579 /* If no destination, treat it as a NOP.
2580 For add & sub, we must generate the overflow exception when needed. */
2581 MIPS_DEBUG("NOP");
2582 return;
2583 }
2584
2585 t0 = tcg_temp_new();
2586 t1 = tcg_temp_new();
2587 gen_load_gpr(t0, rs);
2588 gen_load_gpr(t1, rt);
2589 switch (opc) {
6af0bf9c 2590 case OPC_SLLV:
78723684
TS
2591 tcg_gen_andi_tl(t0, t0, 0x1f);
2592 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2593 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2594 opn = "sllv";
2595 break;
2596 case OPC_SRAV:
78723684 2597 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2598 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2599 opn = "srav";
2600 break;
2601 case OPC_SRLV:
ea63e2c3
NF
2602 tcg_gen_ext32u_tl(t1, t1);
2603 tcg_gen_andi_tl(t0, t0, 0x1f);
2604 tcg_gen_shr_tl(t0, t1, t0);
2605 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2606 opn = "srlv";
2607 break;
2608 case OPC_ROTRV:
2609 {
2610 TCGv_i32 t2 = tcg_temp_new_i32();
2611 TCGv_i32 t3 = tcg_temp_new_i32();
2612
2613 tcg_gen_trunc_tl_i32(t2, t0);
2614 tcg_gen_trunc_tl_i32(t3, t1);
2615 tcg_gen_andi_i32(t2, t2, 0x1f);
2616 tcg_gen_rotr_i32(t2, t3, t2);
2617 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2618 tcg_temp_free_i32(t2);
2619 tcg_temp_free_i32(t3);
2620 opn = "rotrv";
5a63bcb2 2621 }
7a387fff 2622 break;
d26bc211 2623#if defined(TARGET_MIPS64)
7a387fff 2624 case OPC_DSLLV:
78723684 2625 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2626 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2627 opn = "dsllv";
2628 break;
2629 case OPC_DSRAV:
78723684 2630 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2631 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2632 opn = "dsrav";
2633 break;
2634 case OPC_DSRLV:
ea63e2c3
NF
2635 tcg_gen_andi_tl(t0, t0, 0x3f);
2636 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2637 opn = "dsrlv";
2638 break;
2639 case OPC_DROTRV:
2640 tcg_gen_andi_tl(t0, t0, 0x3f);
2641 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2642 opn = "drotrv";
6af0bf9c 2643 break;
7a387fff 2644#endif
6af0bf9c 2645 }
2abf314d 2646 (void)opn; /* avoid a compiler warning */
6af0bf9c 2647 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2648 tcg_temp_free(t0);
2649 tcg_temp_free(t1);
6af0bf9c
FB
2650}
2651
2652/* Arithmetic on HI/LO registers */
26135ead 2653static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 2654{
923617a3 2655 const char *opn = "hilo";
6af0bf9c
FB
2656
2657 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2658 /* Treat as NOP. */
6af0bf9c 2659 MIPS_DEBUG("NOP");
a1f6684d 2660 return;
6af0bf9c 2661 }
4133498f 2662
4133498f
JL
2663 if (acc != 0) {
2664 check_dsp(ctx);
2665 }
2666
6af0bf9c
FB
2667 switch (opc) {
2668 case OPC_MFHI:
4133498f
JL
2669#if defined(TARGET_MIPS64)
2670 if (acc != 0) {
2671 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2672 } else
2673#endif
2674 {
2675 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2676 }
6af0bf9c
FB
2677 opn = "mfhi";
2678 break;
2679 case OPC_MFLO:
4133498f
JL
2680#if defined(TARGET_MIPS64)
2681 if (acc != 0) {
2682 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2683 } else
2684#endif
2685 {
2686 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2687 }
6af0bf9c
FB
2688 opn = "mflo";
2689 break;
2690 case OPC_MTHI:
4133498f
JL
2691 if (reg != 0) {
2692#if defined(TARGET_MIPS64)
2693 if (acc != 0) {
2694 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2695 } else
2696#endif
2697 {
2698 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2699 }
2700 } else {
2701 tcg_gen_movi_tl(cpu_HI[acc], 0);
2702 }
6af0bf9c
FB
2703 opn = "mthi";
2704 break;
2705 case OPC_MTLO:
4133498f
JL
2706 if (reg != 0) {
2707#if defined(TARGET_MIPS64)
2708 if (acc != 0) {
2709 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2710 } else
2711#endif
2712 {
2713 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2714 }
2715 } else {
2716 tcg_gen_movi_tl(cpu_LO[acc], 0);
2717 }
6af0bf9c
FB
2718 opn = "mtlo";
2719 break;
6af0bf9c 2720 }
2abf314d 2721 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2722 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2723}
2724
b42ee5e1
LA
2725static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
2726{
2727 const char *opn = "r6 mul/div";
2728 TCGv t0, t1;
2729
2730 if (rd == 0) {
2731 /* Treat as NOP. */
2732 MIPS_DEBUG("NOP");
2733 return;
2734 }
2735
2736 t0 = tcg_temp_new();
2737 t1 = tcg_temp_new();
2738
2739 gen_load_gpr(t0, rs);
2740 gen_load_gpr(t1, rt);
2741
2742 switch (opc) {
2743 case R6_OPC_DIV:
2744 {
2745 TCGv t2 = tcg_temp_new();
2746 TCGv t3 = tcg_temp_new();
2747 tcg_gen_ext32s_tl(t0, t0);
2748 tcg_gen_ext32s_tl(t1, t1);
2749 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2750 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2751 tcg_gen_and_tl(t2, t2, t3);
2752 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2753 tcg_gen_or_tl(t2, t2, t3);
2754 tcg_gen_movi_tl(t3, 0);
2755 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2756 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2757 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2758 tcg_temp_free(t3);
2759 tcg_temp_free(t2);
2760 }
2761 opn = "div";
2762 break;
2763 case R6_OPC_MOD:
2764 {
2765 TCGv t2 = tcg_temp_new();
2766 TCGv t3 = tcg_temp_new();
2767 tcg_gen_ext32s_tl(t0, t0);
2768 tcg_gen_ext32s_tl(t1, t1);
2769 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2770 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2771 tcg_gen_and_tl(t2, t2, t3);
2772 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2773 tcg_gen_or_tl(t2, t2, t3);
2774 tcg_gen_movi_tl(t3, 0);
2775 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2776 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2777 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2778 tcg_temp_free(t3);
2779 tcg_temp_free(t2);
2780 }
2781 opn = "mod";
2782 break;
2783 case R6_OPC_DIVU:
2784 {
2785 TCGv t2 = tcg_const_tl(0);
2786 TCGv t3 = tcg_const_tl(1);
2787 tcg_gen_ext32u_tl(t0, t0);
2788 tcg_gen_ext32u_tl(t1, t1);
2789 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2790 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2791 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2792 tcg_temp_free(t3);
2793 tcg_temp_free(t2);
2794 }
2795 opn = "divu";
2796 break;
2797 case R6_OPC_MODU:
2798 {
2799 TCGv t2 = tcg_const_tl(0);
2800 TCGv t3 = tcg_const_tl(1);
2801 tcg_gen_ext32u_tl(t0, t0);
2802 tcg_gen_ext32u_tl(t1, t1);
2803 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2804 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2805 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2806 tcg_temp_free(t3);
2807 tcg_temp_free(t2);
2808 }
2809 opn = "modu";
2810 break;
2811 case R6_OPC_MUL:
2812 {
2813 TCGv_i32 t2 = tcg_temp_new_i32();
2814 TCGv_i32 t3 = tcg_temp_new_i32();
2815 tcg_gen_trunc_tl_i32(t2, t0);
2816 tcg_gen_trunc_tl_i32(t3, t1);
2817 tcg_gen_mul_i32(t2, t2, t3);
2818 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2819 tcg_temp_free_i32(t2);
2820 tcg_temp_free_i32(t3);
2821 }
2822 opn = "mul";
2823 break;
2824 case R6_OPC_MUH:
2825 {
2826 TCGv_i32 t2 = tcg_temp_new_i32();
2827 TCGv_i32 t3 = tcg_temp_new_i32();
2828 tcg_gen_trunc_tl_i32(t2, t0);
2829 tcg_gen_trunc_tl_i32(t3, t1);
2830 tcg_gen_muls2_i32(t2, t3, t2, t3);
2831 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
2832 tcg_temp_free_i32(t2);
2833 tcg_temp_free_i32(t3);
2834 }
2835 opn = "muh";
2836 break;
2837 case R6_OPC_MULU:
2838 {
2839 TCGv_i32 t2 = tcg_temp_new_i32();
2840 TCGv_i32 t3 = tcg_temp_new_i32();
2841 tcg_gen_trunc_tl_i32(t2, t0);
2842 tcg_gen_trunc_tl_i32(t3, t1);
2843 tcg_gen_mul_i32(t2, t2, t3);
2844 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2845 tcg_temp_free_i32(t2);
2846 tcg_temp_free_i32(t3);
2847 }
2848 opn = "mulu";
2849 break;
2850 case R6_OPC_MUHU:
2851 {
2852 TCGv_i32 t2 = tcg_temp_new_i32();
2853 TCGv_i32 t3 = tcg_temp_new_i32();
2854 tcg_gen_trunc_tl_i32(t2, t0);
2855 tcg_gen_trunc_tl_i32(t3, t1);
2856 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2857 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
2858 tcg_temp_free_i32(t2);
2859 tcg_temp_free_i32(t3);
2860 }
2861 opn = "muhu";
2862 break;
2863#if defined(TARGET_MIPS64)
2864 case R6_OPC_DDIV:
2865 {
2866 TCGv t2 = tcg_temp_new();
2867 TCGv t3 = tcg_temp_new();
2868 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2869 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2870 tcg_gen_and_tl(t2, t2, t3);
2871 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2872 tcg_gen_or_tl(t2, t2, t3);
2873 tcg_gen_movi_tl(t3, 0);
2874 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2875 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2876 tcg_temp_free(t3);
2877 tcg_temp_free(t2);
2878 }
2879 opn = "ddiv";
2880 break;
2881 case R6_OPC_DMOD:
2882 {
2883 TCGv t2 = tcg_temp_new();
2884 TCGv t3 = tcg_temp_new();
2885 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2886 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2887 tcg_gen_and_tl(t2, t2, t3);
2888 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2889 tcg_gen_or_tl(t2, t2, t3);
2890 tcg_gen_movi_tl(t3, 0);
2891 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2892 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2893 tcg_temp_free(t3);
2894 tcg_temp_free(t2);
2895 }
2896 opn = "dmod";
2897 break;
2898 case R6_OPC_DDIVU:
2899 {
2900 TCGv t2 = tcg_const_tl(0);
2901 TCGv t3 = tcg_const_tl(1);
2902 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2903 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
2904 tcg_temp_free(t3);
2905 tcg_temp_free(t2);
2906 }
2907 opn = "ddivu";
2908 break;
2909 case R6_OPC_DMODU:
2910 {
2911 TCGv t2 = tcg_const_tl(0);
2912 TCGv t3 = tcg_const_tl(1);
2913 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2914 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
2915 tcg_temp_free(t3);
2916 tcg_temp_free(t2);
2917 }
2918 opn = "dmodu";
2919 break;
2920 case R6_OPC_DMUL:
2921 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
2922 opn = "dmul";
2923 break;
2924 case R6_OPC_DMUH:
2925 {
2926 TCGv t2 = tcg_temp_new();
2927 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
2928 tcg_temp_free(t2);
2929 }
2930 opn = "dmuh";
2931 break;
2932 case R6_OPC_DMULU:
2933 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
2934 opn = "dmulu";
2935 break;
2936 case R6_OPC_DMUHU:
2937 {
2938 TCGv t2 = tcg_temp_new();
2939 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
2940 tcg_temp_free(t2);
2941 }
2942 opn = "dmuhu";
2943 break;
2944#endif
2945 default:
2946 MIPS_INVAL(opn);
2947 generate_exception(ctx, EXCP_RI);
2948 goto out;
2949 }
2950 (void)opn; /* avoid a compiler warning */
2951 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2952 out:
2953 tcg_temp_free(t0);
2954 tcg_temp_free(t1);
2955}
2956
26135ead
RS
2957static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2958 int acc, int rs, int rt)
6af0bf9c 2959{
923617a3 2960 const char *opn = "mul/div";
d45f89f4
AJ
2961 TCGv t0, t1;
2962
51127181
AJ
2963 t0 = tcg_temp_new();
2964 t1 = tcg_temp_new();
6af0bf9c 2965
78723684
TS
2966 gen_load_gpr(t0, rs);
2967 gen_load_gpr(t1, rt);
51127181 2968
26135ead
RS
2969 if (acc != 0) {
2970 check_dsp(ctx);
2971 }
2972
6af0bf9c
FB
2973 switch (opc) {
2974 case OPC_DIV:
48d38ca5 2975 {
51127181
AJ
2976 TCGv t2 = tcg_temp_new();
2977 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
2978 tcg_gen_ext32s_tl(t0, t0);
2979 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
2980 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2981 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2982 tcg_gen_and_tl(t2, t2, t3);
2983 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2984 tcg_gen_or_tl(t2, t2, t3);
2985 tcg_gen_movi_tl(t3, 0);
2986 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
2987 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2988 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2989 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2990 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
2991 tcg_temp_free(t3);
2992 tcg_temp_free(t2);
48d38ca5 2993 }
6af0bf9c
FB
2994 opn = "div";
2995 break;
2996 case OPC_DIVU:
48d38ca5 2997 {
51127181
AJ
2998 TCGv t2 = tcg_const_tl(0);
2999 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3000 tcg_gen_ext32u_tl(t0, t0);
3001 tcg_gen_ext32u_tl(t1, t1);
51127181 3002 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3003 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3004 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3005 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3006 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3007 tcg_temp_free(t3);
3008 tcg_temp_free(t2);
48d38ca5 3009 }
6af0bf9c
FB
3010 opn = "divu";
3011 break;
3012 case OPC_MULT:
214c465f 3013 {
ce1dd5d1
RH
3014 TCGv_i32 t2 = tcg_temp_new_i32();
3015 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3016 tcg_gen_trunc_tl_i32(t2, t0);
3017 tcg_gen_trunc_tl_i32(t3, t1);
3018 tcg_gen_muls2_i32(t2, t3, t2, t3);
3019 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3020 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3021 tcg_temp_free_i32(t2);
3022 tcg_temp_free_i32(t3);
214c465f 3023 }
6af0bf9c
FB
3024 opn = "mult";
3025 break;
3026 case OPC_MULTU:
214c465f 3027 {
ce1dd5d1
RH
3028 TCGv_i32 t2 = tcg_temp_new_i32();
3029 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3030 tcg_gen_trunc_tl_i32(t2, t0);
3031 tcg_gen_trunc_tl_i32(t3, t1);
3032 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3033 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3034 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3035 tcg_temp_free_i32(t2);
3036 tcg_temp_free_i32(t3);
214c465f 3037 }
6af0bf9c
FB
3038 opn = "multu";
3039 break;
d26bc211 3040#if defined(TARGET_MIPS64)
7a387fff 3041 case OPC_DDIV:
48d38ca5 3042 {
51127181
AJ
3043 TCGv t2 = tcg_temp_new();
3044 TCGv t3 = tcg_temp_new();
3045 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3046 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3047 tcg_gen_and_tl(t2, t2, t3);
3048 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3049 tcg_gen_or_tl(t2, t2, t3);
3050 tcg_gen_movi_tl(t3, 0);
3051 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3052 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3053 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3054 tcg_temp_free(t3);
3055 tcg_temp_free(t2);
48d38ca5 3056 }
7a387fff
TS
3057 opn = "ddiv";
3058 break;
3059 case OPC_DDIVU:
48d38ca5 3060 {
51127181
AJ
3061 TCGv t2 = tcg_const_tl(0);
3062 TCGv t3 = tcg_const_tl(1);
3063 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3064 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3065 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3066 tcg_temp_free(t3);
3067 tcg_temp_free(t2);
48d38ca5 3068 }
7a387fff
TS
3069 opn = "ddivu";
3070 break;
3071 case OPC_DMULT:
26135ead 3072 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3073 opn = "dmult";
3074 break;
3075 case OPC_DMULTU:
26135ead 3076 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3077 opn = "dmultu";
3078 break;
3079#endif
6af0bf9c 3080 case OPC_MADD:
214c465f 3081 {
d45f89f4
AJ
3082 TCGv_i64 t2 = tcg_temp_new_i64();
3083 TCGv_i64 t3 = tcg_temp_new_i64();
3084
3085 tcg_gen_ext_tl_i64(t2, t0);
3086 tcg_gen_ext_tl_i64(t3, t1);
3087 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3088 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3089 tcg_gen_add_i64(t2, t2, t3);
3090 tcg_temp_free_i64(t3);
3091 tcg_gen_trunc_i64_tl(t0, t2);
3092 tcg_gen_shri_i64(t2, t2, 32);
3093 tcg_gen_trunc_i64_tl(t1, t2);
3094 tcg_temp_free_i64(t2);
4133498f
JL
3095 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3096 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3097 }
6af0bf9c
FB
3098 opn = "madd";
3099 break;
3100 case OPC_MADDU:
4133498f 3101 {
d45f89f4
AJ
3102 TCGv_i64 t2 = tcg_temp_new_i64();
3103 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3104
78723684
TS
3105 tcg_gen_ext32u_tl(t0, t0);
3106 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3107 tcg_gen_extu_tl_i64(t2, t0);
3108 tcg_gen_extu_tl_i64(t3, t1);
3109 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3110 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3111 tcg_gen_add_i64(t2, t2, t3);
3112 tcg_temp_free_i64(t3);
3113 tcg_gen_trunc_i64_tl(t0, t2);
3114 tcg_gen_shri_i64(t2, t2, 32);
3115 tcg_gen_trunc_i64_tl(t1, t2);
3116 tcg_temp_free_i64(t2);
4133498f
JL
3117 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3118 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3119 }
6af0bf9c
FB
3120 opn = "maddu";
3121 break;
3122 case OPC_MSUB:
214c465f 3123 {
d45f89f4
AJ
3124 TCGv_i64 t2 = tcg_temp_new_i64();
3125 TCGv_i64 t3 = tcg_temp_new_i64();
3126
3127 tcg_gen_ext_tl_i64(t2, t0);
3128 tcg_gen_ext_tl_i64(t3, t1);
3129 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3130 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3131 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3132 tcg_temp_free_i64(t3);
3133 tcg_gen_trunc_i64_tl(t0, t2);
3134 tcg_gen_shri_i64(t2, t2, 32);
3135 tcg_gen_trunc_i64_tl(t1, t2);
3136 tcg_temp_free_i64(t2);
4133498f
JL
3137 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3138 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3139 }
6af0bf9c
FB
3140 opn = "msub";
3141 break;
3142 case OPC_MSUBU:
214c465f 3143 {
d45f89f4
AJ
3144 TCGv_i64 t2 = tcg_temp_new_i64();
3145 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3146
78723684
TS
3147 tcg_gen_ext32u_tl(t0, t0);
3148 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3149 tcg_gen_extu_tl_i64(t2, t0);
3150 tcg_gen_extu_tl_i64(t3, t1);
3151 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3152 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3153 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
3154 tcg_temp_free_i64(t3);
3155 tcg_gen_trunc_i64_tl(t0, t2);
3156 tcg_gen_shri_i64(t2, t2, 32);
3157 tcg_gen_trunc_i64_tl(t1, t2);
3158 tcg_temp_free_i64(t2);
4133498f
JL
3159 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3160 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 3161 }
6af0bf9c
FB
3162 opn = "msubu";
3163 break;
3164 default:
923617a3 3165 MIPS_INVAL(opn);
6af0bf9c 3166 generate_exception(ctx, EXCP_RI);
78723684 3167 goto out;
6af0bf9c 3168 }
2abf314d 3169 (void)opn; /* avoid a compiler warning */
6af0bf9c 3170 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
3171 out:
3172 tcg_temp_free(t0);
3173 tcg_temp_free(t1);
6af0bf9c
FB
3174}
3175
e9c71dd1
TS
3176static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3177 int rd, int rs, int rt)
3178{
3179 const char *opn = "mul vr54xx";
f157bfe1
AJ
3180 TCGv t0 = tcg_temp_new();
3181 TCGv t1 = tcg_temp_new();
e9c71dd1 3182
6c5c1e20
TS
3183 gen_load_gpr(t0, rs);
3184 gen_load_gpr(t1, rt);
e9c71dd1
TS
3185
3186 switch (opc) {
3187 case OPC_VR54XX_MULS:
895c2d04 3188 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 3189 opn = "muls";
6958549d 3190 break;
e9c71dd1 3191 case OPC_VR54XX_MULSU:
895c2d04 3192 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 3193 opn = "mulsu";
6958549d 3194 break;
e9c71dd1 3195 case OPC_VR54XX_MACC:
895c2d04 3196 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 3197 opn = "macc";
6958549d 3198 break;
e9c71dd1 3199 case OPC_VR54XX_MACCU:
895c2d04 3200 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 3201 opn = "maccu";
6958549d 3202 break;
e9c71dd1 3203 case OPC_VR54XX_MSAC:
895c2d04 3204 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 3205 opn = "msac";
6958549d 3206 break;
e9c71dd1 3207 case OPC_VR54XX_MSACU:
895c2d04 3208 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 3209 opn = "msacu";
6958549d 3210 break;
e9c71dd1 3211 case OPC_VR54XX_MULHI:
895c2d04 3212 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 3213 opn = "mulhi";
6958549d 3214 break;
e9c71dd1 3215 case OPC_VR54XX_MULHIU:
895c2d04 3216 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 3217 opn = "mulhiu";
6958549d 3218 break;
e9c71dd1 3219 case OPC_VR54XX_MULSHI:
895c2d04 3220 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 3221 opn = "mulshi";
6958549d 3222 break;
e9c71dd1 3223 case OPC_VR54XX_MULSHIU:
895c2d04 3224 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 3225 opn = "mulshiu";
6958549d 3226 break;
e9c71dd1 3227 case OPC_VR54XX_MACCHI:
895c2d04 3228 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 3229 opn = "macchi";
6958549d 3230 break;
e9c71dd1 3231 case OPC_VR54XX_MACCHIU:
895c2d04 3232 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 3233 opn = "macchiu";
6958549d 3234 break;
e9c71dd1 3235 case OPC_VR54XX_MSACHI:
895c2d04 3236 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 3237 opn = "msachi";
6958549d 3238 break;
e9c71dd1 3239 case OPC_VR54XX_MSACHIU:
895c2d04 3240 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 3241 opn = "msachiu";
6958549d 3242 break;
e9c71dd1
TS
3243 default:
3244 MIPS_INVAL("mul vr54xx");
3245 generate_exception(ctx, EXCP_RI);
6c5c1e20 3246 goto out;
e9c71dd1 3247 }
6c5c1e20 3248 gen_store_gpr(t0, rd);
2abf314d 3249 (void)opn; /* avoid a compiler warning */
e9c71dd1 3250 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
3251
3252 out:
3253 tcg_temp_free(t0);
3254 tcg_temp_free(t1);
e9c71dd1
TS
3255}
3256
7a387fff 3257static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3258 int rd, int rs)
3259{
923617a3 3260 const char *opn = "CLx";
20e1fb52 3261 TCGv t0;
6c5c1e20 3262
6af0bf9c 3263 if (rd == 0) {
ead9360e 3264 /* Treat as NOP. */
6af0bf9c 3265 MIPS_DEBUG("NOP");
20e1fb52 3266 return;
6af0bf9c 3267 }
20e1fb52 3268 t0 = tcg_temp_new();
6c5c1e20 3269 gen_load_gpr(t0, rs);
6af0bf9c
FB
3270 switch (opc) {
3271 case OPC_CLO:
4267d3e6 3272 case R6_OPC_CLO:
20e1fb52 3273 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
3274 opn = "clo";
3275 break;
3276 case OPC_CLZ:
4267d3e6 3277 case R6_OPC_CLZ:
20e1fb52 3278 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
3279 opn = "clz";
3280 break;
d26bc211 3281#if defined(TARGET_MIPS64)
7a387fff 3282 case OPC_DCLO:
4267d3e6 3283 case R6_OPC_DCLO:
20e1fb52 3284 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
3285 opn = "dclo";
3286 break;
3287 case OPC_DCLZ:
4267d3e6 3288 case R6_OPC_DCLZ:
20e1fb52 3289 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
3290 opn = "dclz";
3291 break;
3292#endif
6af0bf9c 3293 }
2abf314d 3294 (void)opn; /* avoid a compiler warning */
6af0bf9c 3295 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3296 tcg_temp_free(t0);
6af0bf9c
FB
3297}
3298
161f85e6 3299/* Godson integer instructions */
bd277fa1
RH
3300static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3301 int rd, int rs, int rt)
161f85e6
AJ
3302{
3303 const char *opn = "loongson";
3304 TCGv t0, t1;
3305
3306 if (rd == 0) {
3307 /* Treat as NOP. */
3308 MIPS_DEBUG("NOP");
3309 return;
3310 }
3311
3312 switch (opc) {
3313 case OPC_MULT_G_2E:
3314 case OPC_MULT_G_2F:
3315 case OPC_MULTU_G_2E:
3316 case OPC_MULTU_G_2F:
3317#if defined(TARGET_MIPS64)
3318 case OPC_DMULT_G_2E:
3319 case OPC_DMULT_G_2F:
3320 case OPC_DMULTU_G_2E:
3321 case OPC_DMULTU_G_2F:
3322#endif
3323 t0 = tcg_temp_new();
3324 t1 = tcg_temp_new();
3325 break;
3326 default:
3327 t0 = tcg_temp_local_new();
3328 t1 = tcg_temp_local_new();
3329 break;
3330 }
3331
3332 gen_load_gpr(t0, rs);
3333 gen_load_gpr(t1, rt);
3334
3335 switch (opc) {
3336 case OPC_MULT_G_2E:
3337 case OPC_MULT_G_2F:
3338 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3339 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3340 opn = "mult.g";
3341 break;
3342 case OPC_MULTU_G_2E:
3343 case OPC_MULTU_G_2F:
3344 tcg_gen_ext32u_tl(t0, t0);
3345 tcg_gen_ext32u_tl(t1, t1);
3346 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3347 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3348 opn = "multu.g";
3349 break;
3350 case OPC_DIV_G_2E:
3351 case OPC_DIV_G_2F:
3352 {
3353 int l1 = gen_new_label();
3354 int l2 = gen_new_label();
3355 int l3 = gen_new_label();
3356 tcg_gen_ext32s_tl(t0, t0);
3357 tcg_gen_ext32s_tl(t1, t1);
3358 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3359 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3360 tcg_gen_br(l3);
3361 gen_set_label(l1);
3362 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3363 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3364 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3365 tcg_gen_br(l3);
3366 gen_set_label(l2);
3367 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3368 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3369 gen_set_label(l3);
3370 }
3371 opn = "div.g";
3372 break;
3373 case OPC_DIVU_G_2E:
3374 case OPC_DIVU_G_2F:
3375 {
3376 int l1 = gen_new_label();
3377 int l2 = gen_new_label();
3378 tcg_gen_ext32u_tl(t0, t0);
3379 tcg_gen_ext32u_tl(t1, t1);
3380 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3381 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3382 tcg_gen_br(l2);
3383 gen_set_label(l1);
3384 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3385 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3386 gen_set_label(l2);
3387 }
3388 opn = "divu.g";
3389 break;
3390 case OPC_MOD_G_2E:
3391 case OPC_MOD_G_2F:
3392 {
3393 int l1 = gen_new_label();
3394 int l2 = gen_new_label();
3395 int l3 = gen_new_label();
3396 tcg_gen_ext32u_tl(t0, t0);
3397 tcg_gen_ext32u_tl(t1, t1);
3398 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3399 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3400 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3401 gen_set_label(l1);
3402 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3403 tcg_gen_br(l3);
3404 gen_set_label(l2);
3405 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3406 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3407 gen_set_label(l3);
3408 }
3409 opn = "mod.g";
3410 break;
3411 case OPC_MODU_G_2E:
3412 case OPC_MODU_G_2F:
3413 {
3414 int l1 = gen_new_label();
3415 int l2 = gen_new_label();
3416 tcg_gen_ext32u_tl(t0, t0);
3417 tcg_gen_ext32u_tl(t1, t1);
3418 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3419 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3420 tcg_gen_br(l2);
3421 gen_set_label(l1);
3422 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3423 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3424 gen_set_label(l2);
3425 }
3426 opn = "modu.g";
3427 break;
3428#if defined(TARGET_MIPS64)
3429 case OPC_DMULT_G_2E:
3430 case OPC_DMULT_G_2F:
3431 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3432 opn = "dmult.g";
3433 break;
3434 case OPC_DMULTU_G_2E:
3435 case OPC_DMULTU_G_2F:
3436 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3437 opn = "dmultu.g";
3438 break;
3439 case OPC_DDIV_G_2E:
3440 case OPC_DDIV_G_2F:
3441 {
3442 int l1 = gen_new_label();
3443 int l2 = gen_new_label();
3444 int l3 = gen_new_label();
3445 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3447 tcg_gen_br(l3);
3448 gen_set_label(l1);
3449 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3450 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3451 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3452 tcg_gen_br(l3);
3453 gen_set_label(l2);
3454 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3455 gen_set_label(l3);
3456 }
3457 opn = "ddiv.g";
3458 break;
3459 case OPC_DDIVU_G_2E:
3460 case OPC_DDIVU_G_2F:
3461 {
3462 int l1 = gen_new_label();
3463 int l2 = gen_new_label();
3464 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3465 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3466 tcg_gen_br(l2);
3467 gen_set_label(l1);
3468 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3469 gen_set_label(l2);
3470 }
3471 opn = "ddivu.g";
3472 break;
3473 case OPC_DMOD_G_2E:
3474 case OPC_DMOD_G_2F:
3475 {
3476 int l1 = gen_new_label();
3477 int l2 = gen_new_label();
3478 int l3 = gen_new_label();
3479 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3480 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3481 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3482 gen_set_label(l1);
3483 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3484 tcg_gen_br(l3);
3485 gen_set_label(l2);
3486 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3487 gen_set_label(l3);
3488 }
3489 opn = "dmod.g";
3490 break;
3491 case OPC_DMODU_G_2E:
3492 case OPC_DMODU_G_2F:
3493 {
3494 int l1 = gen_new_label();
3495 int l2 = gen_new_label();
3496 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3497 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3498 tcg_gen_br(l2);
3499 gen_set_label(l1);
3500 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3501 gen_set_label(l2);
3502 }
3503 opn = "dmodu.g";
3504 break;
3505#endif
3506 }
3507
2abf314d 3508 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3509 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3510 tcg_temp_free(t0);
3511 tcg_temp_free(t1);
3512}
3513
bd277fa1
RH
3514/* Loongson multimedia instructions */
3515static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3516{
3517 const char *opn = "loongson_cp2";
3518 uint32_t opc, shift_max;
3519 TCGv_i64 t0, t1;
3520
3521 opc = MASK_LMI(ctx->opcode);
3522 switch (opc) {
3523 case OPC_ADD_CP2:
3524 case OPC_SUB_CP2:
3525 case OPC_DADD_CP2:
3526 case OPC_DSUB_CP2:
3527 t0 = tcg_temp_local_new_i64();
3528 t1 = tcg_temp_local_new_i64();
3529 break;
3530 default:
3531 t0 = tcg_temp_new_i64();
3532 t1 = tcg_temp_new_i64();
3533 break;
3534 }
3535
3536 gen_load_fpr64(ctx, t0, rs);
3537 gen_load_fpr64(ctx, t1, rt);
3538
3539#define LMI_HELPER(UP, LO) \
3540 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3541#define LMI_HELPER_1(UP, LO) \
3542 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3543#define LMI_DIRECT(UP, LO, OP) \
3544 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3545
3546 switch (opc) {
3547 LMI_HELPER(PADDSH, paddsh);
3548 LMI_HELPER(PADDUSH, paddush);
3549 LMI_HELPER(PADDH, paddh);
3550 LMI_HELPER(PADDW, paddw);
3551 LMI_HELPER(PADDSB, paddsb);
3552 LMI_HELPER(PADDUSB, paddusb);
3553 LMI_HELPER(PADDB, paddb);
3554
3555 LMI_HELPER(PSUBSH, psubsh);
3556 LMI_HELPER(PSUBUSH, psubush);
3557 LMI_HELPER(PSUBH, psubh);
3558 LMI_HELPER(PSUBW, psubw);
3559 LMI_HELPER(PSUBSB, psubsb);
3560 LMI_HELPER(PSUBUSB, psubusb);
3561 LMI_HELPER(PSUBB, psubb);
3562
3563 LMI_HELPER(PSHUFH, pshufh);
3564 LMI_HELPER(PACKSSWH, packsswh);
3565 LMI_HELPER(PACKSSHB, packsshb);
3566 LMI_HELPER(PACKUSHB, packushb);
3567
3568 LMI_HELPER(PUNPCKLHW, punpcklhw);
3569 LMI_HELPER(PUNPCKHHW, punpckhhw);
3570 LMI_HELPER(PUNPCKLBH, punpcklbh);
3571 LMI_HELPER(PUNPCKHBH, punpckhbh);
3572 LMI_HELPER(PUNPCKLWD, punpcklwd);
3573 LMI_HELPER(PUNPCKHWD, punpckhwd);
3574
3575 LMI_HELPER(PAVGH, pavgh);
3576 LMI_HELPER(PAVGB, pavgb);
3577 LMI_HELPER(PMAXSH, pmaxsh);
3578 LMI_HELPER(PMINSH, pminsh);
3579 LMI_HELPER(PMAXUB, pmaxub);
3580 LMI_HELPER(PMINUB, pminub);
3581
3582 LMI_HELPER(PCMPEQW, pcmpeqw);
3583 LMI_HELPER(PCMPGTW, pcmpgtw);
3584 LMI_HELPER(PCMPEQH, pcmpeqh);
3585 LMI_HELPER(PCMPGTH, pcmpgth);
3586 LMI_HELPER(PCMPEQB, pcmpeqb);
3587 LMI_HELPER(PCMPGTB, pcmpgtb);
3588
3589 LMI_HELPER(PSLLW, psllw);
3590 LMI_HELPER(PSLLH, psllh);
3591 LMI_HELPER(PSRLW, psrlw);
3592 LMI_HELPER(PSRLH, psrlh);
3593 LMI_HELPER(PSRAW, psraw);
3594 LMI_HELPER(PSRAH, psrah);
3595
3596 LMI_HELPER(PMULLH, pmullh);
3597 LMI_HELPER(PMULHH, pmulhh);
3598 LMI_HELPER(PMULHUH, pmulhuh);
3599 LMI_HELPER(PMADDHW, pmaddhw);
3600
3601 LMI_HELPER(PASUBUB, pasubub);
3602 LMI_HELPER_1(BIADD, biadd);
3603 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3604
3605 LMI_DIRECT(PADDD, paddd, add);
3606 LMI_DIRECT(PSUBD, psubd, sub);
3607 LMI_DIRECT(XOR_CP2, xor, xor);
3608 LMI_DIRECT(NOR_CP2, nor, nor);
3609 LMI_DIRECT(AND_CP2, and, and);
3610 LMI_DIRECT(PANDN, pandn, andc);
3611 LMI_DIRECT(OR, or, or);
3612
3613 case OPC_PINSRH_0:
3614 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3615 opn = "pinsrh_0";
3616 break;
3617 case OPC_PINSRH_1:
3618 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3619 opn = "pinsrh_1";
3620 break;
3621 case OPC_PINSRH_2:
3622 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3623 opn = "pinsrh_2";
3624 break;
3625 case OPC_PINSRH_3:
3626 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3627 opn = "pinsrh_3";
3628 break;
3629
3630 case OPC_PEXTRH:
3631 tcg_gen_andi_i64(t1, t1, 3);
3632 tcg_gen_shli_i64(t1, t1, 4);
3633 tcg_gen_shr_i64(t0, t0, t1);
3634 tcg_gen_ext16u_i64(t0, t0);
3635 opn = "pextrh";
3636 break;
3637
3638 case OPC_ADDU_CP2:
3639 tcg_gen_add_i64(t0, t0, t1);
3640 tcg_gen_ext32s_i64(t0, t0);
3641 opn = "addu";
3642 break;
3643 case OPC_SUBU_CP2:
3644 tcg_gen_sub_i64(t0, t0, t1);
3645 tcg_gen_ext32s_i64(t0, t0);
3646 opn = "addu";
3647 break;
3648
3649 case OPC_SLL_CP2:
3650 opn = "sll";
3651 shift_max = 32;
3652 goto do_shift;
3653 case OPC_SRL_CP2:
3654 opn = "srl";
3655 shift_max = 32;
3656 goto do_shift;
3657 case OPC_SRA_CP2:
3658 opn = "sra";
3659 shift_max = 32;
3660 goto do_shift;
3661 case OPC_DSLL_CP2:
3662 opn = "dsll";
3663 shift_max = 64;
3664 goto do_shift;
3665 case OPC_DSRL_CP2:
3666 opn = "dsrl";
3667 shift_max = 64;
3668 goto do_shift;
3669 case OPC_DSRA_CP2:
3670 opn = "dsra";
3671 shift_max = 64;
3672 goto do_shift;
3673 do_shift:
3674 /* Make sure shift count isn't TCG undefined behaviour. */
3675 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3676
3677 switch (opc) {
3678 case OPC_SLL_CP2:
3679 case OPC_DSLL_CP2:
3680 tcg_gen_shl_i64(t0, t0, t1);
3681 break;
3682 case OPC_SRA_CP2:
3683 case OPC_DSRA_CP2:
3684 /* Since SRA is UndefinedResult without sign-extended inputs,
3685 we can treat SRA and DSRA the same. */
3686 tcg_gen_sar_i64(t0, t0, t1);
3687 break;
3688 case OPC_SRL_CP2:
3689 /* We want to shift in zeros for SRL; zero-extend first. */
3690 tcg_gen_ext32u_i64(t0, t0);
3691 /* FALLTHRU */
3692 case OPC_DSRL_CP2:
3693 tcg_gen_shr_i64(t0, t0, t1);
3694 break;
3695 }
3696
3697 if (shift_max == 32) {
3698 tcg_gen_ext32s_i64(t0, t0);
3699 }
3700
3701 /* Shifts larger than MAX produce zero. */
3702 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3703 tcg_gen_neg_i64(t1, t1);
3704 tcg_gen_and_i64(t0, t0, t1);
3705 break;
3706
3707 case OPC_ADD_CP2:
3708 case OPC_DADD_CP2:
3709 {
3710 TCGv_i64 t2 = tcg_temp_new_i64();
3711 int lab = gen_new_label();
3712
3713 tcg_gen_mov_i64(t2, t0);
3714 tcg_gen_add_i64(t0, t1, t2);
3715 if (opc == OPC_ADD_CP2) {
3716 tcg_gen_ext32s_i64(t0, t0);
3717 }
3718 tcg_gen_xor_i64(t1, t1, t2);
3719 tcg_gen_xor_i64(t2, t2, t0);
3720 tcg_gen_andc_i64(t1, t2, t1);
3721 tcg_temp_free_i64(t2);
3722 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3723 generate_exception(ctx, EXCP_OVERFLOW);
3724 gen_set_label(lab);
3725
3726 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3727 break;
3728 }
3729
3730 case OPC_SUB_CP2:
3731 case OPC_DSUB_CP2:
3732 {
3733 TCGv_i64 t2 = tcg_temp_new_i64();
3734 int lab = gen_new_label();
3735
3736 tcg_gen_mov_i64(t2, t0);
3737 tcg_gen_sub_i64(t0, t1, t2);
3738 if (opc == OPC_SUB_CP2) {
3739 tcg_gen_ext32s_i64(t0, t0);
3740 }
3741 tcg_gen_xor_i64(t1, t1, t2);
3742 tcg_gen_xor_i64(t2, t2, t0);
3743 tcg_gen_and_i64(t1, t1, t2);
3744 tcg_temp_free_i64(t2);
3745 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3746 generate_exception(ctx, EXCP_OVERFLOW);
3747 gen_set_label(lab);
3748
3749 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3750 break;
3751 }
3752
3753 case OPC_PMULUW:
3754 tcg_gen_ext32u_i64(t0, t0);
3755 tcg_gen_ext32u_i64(t1, t1);
3756 tcg_gen_mul_i64(t0, t0, t1);
3757 opn = "pmuluw";
3758 break;
3759
3760 case OPC_SEQU_CP2:
3761 case OPC_SEQ_CP2:
3762 case OPC_SLTU_CP2:
3763 case OPC_SLT_CP2:
3764 case OPC_SLEU_CP2:
3765 case OPC_SLE_CP2:
3766 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3767 FD field is the CC field? */
3768 default:
3769 MIPS_INVAL(opn);
3770 generate_exception(ctx, EXCP_RI);
3771 return;
3772 }
3773
3774#undef LMI_HELPER
3775#undef LMI_DIRECT
3776
3777 gen_store_fpr64(ctx, t0, rd);
3778
3779 (void)opn; /* avoid a compiler warning */
3780 MIPS_DEBUG("%s %s, %s, %s", opn,
3781 fregnames[rd], fregnames[rs], fregnames[rt]);
3782 tcg_temp_free_i64(t0);
3783 tcg_temp_free_i64(t1);
3784}
3785
6af0bf9c 3786/* Traps */
7a387fff 3787static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3788 int rs, int rt, int16_t imm)
3789{
3790 int cond;
cdc0faa6 3791 TCGv t0 = tcg_temp_new();
1ba74fb8 3792 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3793
3794 cond = 0;
3795 /* Load needed operands */
3796 switch (opc) {
3797 case OPC_TEQ:
3798 case OPC_TGE:
3799 case OPC_TGEU:
3800 case OPC_TLT:
3801 case OPC_TLTU:
3802 case OPC_TNE:
3803 /* Compare two registers */
3804 if (rs != rt) {
be24bb4f
TS
3805 gen_load_gpr(t0, rs);
3806 gen_load_gpr(t1, rt);
6af0bf9c
FB
3807 cond = 1;
3808 }
179e32bb 3809 break;
6af0bf9c
FB
3810 case OPC_TEQI:
3811 case OPC_TGEI:
3812 case OPC_TGEIU:
3813 case OPC_TLTI:
3814 case OPC_TLTIU:
3815 case OPC_TNEI:
3816 /* Compare register to immediate */
3817 if (rs != 0 || imm != 0) {
be24bb4f
TS
3818 gen_load_gpr(t0, rs);
3819 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3820 cond = 1;
3821 }
3822 break;
3823 }
3824 if (cond == 0) {
3825 switch (opc) {
3826 case OPC_TEQ: /* rs == rs */
3827 case OPC_TEQI: /* r0 == 0 */
3828 case OPC_TGE: /* rs >= rs */
3829 case OPC_TGEI: /* r0 >= 0 */
3830 case OPC_TGEU: /* rs >= rs unsigned */
3831 case OPC_TGEIU: /* r0 >= 0 unsigned */
3832 /* Always trap */
cdc0faa6 3833 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3834 break;
3835 case OPC_TLT: /* rs < rs */
3836 case OPC_TLTI: /* r0 < 0 */
3837 case OPC_TLTU: /* rs < rs unsigned */
3838 case OPC_TLTIU: /* r0 < 0 unsigned */
3839 case OPC_TNE: /* rs != rs */
3840 case OPC_TNEI: /* r0 != 0 */
ead9360e 3841 /* Never trap: treat as NOP. */
cdc0faa6 3842 break;
6af0bf9c
FB
3843 }
3844 } else {
cdc0faa6
AJ
3845 int l1 = gen_new_label();
3846
6af0bf9c
FB
3847 switch (opc) {
3848 case OPC_TEQ:
3849 case OPC_TEQI:
cdc0faa6 3850 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3851 break;
3852 case OPC_TGE:
3853 case OPC_TGEI:
cdc0faa6 3854 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3855 break;
3856 case OPC_TGEU:
3857 case OPC_TGEIU:
cdc0faa6 3858 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3859 break;
3860 case OPC_TLT:
3861 case OPC_TLTI:
cdc0faa6 3862 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3863 break;
3864 case OPC_TLTU:
3865 case OPC_TLTIU:
cdc0faa6 3866 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3867 break;
3868 case OPC_TNE:
3869 case OPC_TNEI:
cdc0faa6 3870 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3871 break;
6af0bf9c 3872 }
cdc0faa6 3873 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3874 gen_set_label(l1);
3875 }
be24bb4f
TS
3876 tcg_temp_free(t0);
3877 tcg_temp_free(t1);
6af0bf9c
FB
3878}
3879
356265ae 3880static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3881{
6e256c93
FB
3882 TranslationBlock *tb;
3883 tb = ctx->tb;
7b270ef2
NF
3884 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3885 likely(!ctx->singlestep_enabled)) {
57fec1fe 3886 tcg_gen_goto_tb(n);
9b9e4393 3887 gen_save_pc(dest);
8cfd0495 3888 tcg_gen_exit_tb((uintptr_t)tb + n);
6e256c93 3889 } else {
9b9e4393 3890 gen_save_pc(dest);
7b270ef2
NF
3891 if (ctx->singlestep_enabled) {
3892 save_cpu_state(ctx, 0);
895c2d04 3893 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3894 }
57fec1fe 3895 tcg_gen_exit_tb(0);
6e256c93 3896 }
c53be334
FB
3897}
3898
6af0bf9c 3899/* Branches (before delay slot) */
7a387fff 3900static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3901 int insn_bytes,
6af0bf9c
FB
3902 int rs, int rt, int32_t offset)
3903{
d077b6f7 3904 target_ulong btgt = -1;
3ad4bb2d 3905 int blink = 0;
2fdbad25 3906 int bcond_compute = 0;
1ba74fb8
AJ
3907 TCGv t0 = tcg_temp_new();
3908 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3909
3910 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3911#ifdef MIPS_DEBUG_DISAS
d12d51d5 3912 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3913#endif
3ad4bb2d 3914 generate_exception(ctx, EXCP_RI);
6c5c1e20 3915 goto out;
3ad4bb2d 3916 }
6af0bf9c 3917
6af0bf9c
FB
3918 /* Load needed operands */
3919 switch (opc) {
3920 case OPC_BEQ:
3921 case OPC_BEQL:
3922 case OPC_BNE:
3923 case OPC_BNEL:
3924 /* Compare two registers */
3925 if (rs != rt) {
6c5c1e20
TS
3926 gen_load_gpr(t0, rs);
3927 gen_load_gpr(t1, rt);
2fdbad25 3928 bcond_compute = 1;
6af0bf9c 3929 }
7dca4ad0 3930 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3931 break;
3932 case OPC_BGEZ:
3933 case OPC_BGEZAL:
3c824109 3934 case OPC_BGEZALS:
6af0bf9c
FB
3935 case OPC_BGEZALL:
3936 case OPC_BGEZL:
3937 case OPC_BGTZ:
3938 case OPC_BGTZL:
3939 case OPC_BLEZ:
3940 case OPC_BLEZL:
3941 case OPC_BLTZ:
3942 case OPC_BLTZAL:
3c824109 3943 case OPC_BLTZALS:
6af0bf9c
FB
3944 case OPC_BLTZALL:
3945 case OPC_BLTZL:
3946 /* Compare to zero */
3947 if (rs != 0) {
6c5c1e20 3948 gen_load_gpr(t0, rs);
2fdbad25 3949 bcond_compute = 1;
6af0bf9c 3950 }
7dca4ad0 3951 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3952 break;
e45a93e2
JL
3953 case OPC_BPOSGE32:
3954#if defined(TARGET_MIPS64)
3955 case OPC_BPOSGE64:
3956 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3957#else
3958 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3959#endif
3960 bcond_compute = 1;
3961 btgt = ctx->pc + insn_bytes + offset;
3962 break;
6af0bf9c
FB
3963 case OPC_J:
3964 case OPC_JAL:
364d4831 3965 case OPC_JALX:
620e48f6
NF
3966 case OPC_JALS:
3967 case OPC_JALXS:
6af0bf9c 3968 /* Jump to immediate */
7dca4ad0 3969 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3970 break;
3971 case OPC_JR:
3972 case OPC_JALR:
364d4831 3973 case OPC_JALRC:
620e48f6 3974 case OPC_JALRS:
6af0bf9c 3975 /* Jump to register */
7a387fff
TS
3976 if (offset != 0 && offset != 16) {
3977 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3978 others are reserved. */
923617a3 3979 MIPS_INVAL("jump hint");
6af0bf9c 3980 generate_exception(ctx, EXCP_RI);
6c5c1e20 3981 goto out;
6af0bf9c 3982 }
d077b6f7 3983 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3984 break;
3985 default:
3986 MIPS_INVAL("branch/jump");
3987 generate_exception(ctx, EXCP_RI);
6c5c1e20 3988 goto out;
6af0bf9c 3989 }
2fdbad25 3990 if (bcond_compute == 0) {
6af0bf9c
FB
3991 /* No condition to be computed */
3992 switch (opc) {
3993 case OPC_BEQ: /* rx == rx */
3994 case OPC_BEQL: /* rx == rx likely */
3995 case OPC_BGEZ: /* 0 >= 0 */
3996 case OPC_BGEZL: /* 0 >= 0 likely */
3997 case OPC_BLEZ: /* 0 <= 0 */
3998 case OPC_BLEZL: /* 0 <= 0 likely */
3999 /* Always take */
4ad40f36 4000 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4001 MIPS_DEBUG("balways");
4002 break;
3c824109 4003 case OPC_BGEZALS:
6af0bf9c
FB
4004 case OPC_BGEZAL: /* 0 >= 0 */
4005 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
4006 ctx->hflags |= (opc == OPC_BGEZALS
4007 ? MIPS_HFLAG_BDS16
4008 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
4009 /* Always take and link */
4010 blink = 31;
4ad40f36 4011 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4012 MIPS_DEBUG("balways and link");
4013 break;
4014 case OPC_BNE: /* rx != rx */
4015 case OPC_BGTZ: /* 0 > 0 */
4016 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4017 /* Treat as NOP. */
6af0bf9c 4018 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 4019 goto out;
3c824109 4020 case OPC_BLTZALS:
eeef26cd 4021 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4022 ctx->hflags |= (opc == OPC_BLTZALS
4023 ? MIPS_HFLAG_BDS16
4024 : MIPS_HFLAG_BDS32);
4025 /* Handle as an unconditional branch to get correct delay
4026 slot checking. */
4027 blink = 31;
4028 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
4029 ctx->hflags |= MIPS_HFLAG_B;
9898128f 4030 MIPS_DEBUG("bnever and link");
3c824109 4031 break;
eeef26cd 4032 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 4033 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
4034 /* Skip the instruction in the delay slot */
4035 MIPS_DEBUG("bnever, link and skip");
4036 ctx->pc += 4;
6c5c1e20 4037 goto out;
6af0bf9c
FB
4038 case OPC_BNEL: /* rx != rx likely */
4039 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4040 case OPC_BLTZL: /* 0 < 0 likely */
4041 /* Skip the instruction in the delay slot */
4042 MIPS_DEBUG("bnever and skip");
9898128f 4043 ctx->pc += 4;
6c5c1e20 4044 goto out;
6af0bf9c 4045 case OPC_J:
4ad40f36 4046 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 4047 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 4048 break;
620e48f6 4049 case OPC_JALXS:
364d4831
NF
4050 case OPC_JALX:
4051 ctx->hflags |= MIPS_HFLAG_BX;
4052 /* Fallthrough */
620e48f6 4053 case OPC_JALS:
6af0bf9c
FB
4054 case OPC_JAL:
4055 blink = 31;
4ad40f36 4056 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 4057 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
4058 ? MIPS_HFLAG_BDS16
4059 : MIPS_HFLAG_BDS32);
d077b6f7 4060 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
4061 break;
4062 case OPC_JR:
4ad40f36 4063 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
4064 if (insn_bytes == 4)
4065 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
4066 MIPS_DEBUG("jr %s", regnames[rs]);
4067 break;
620e48f6 4068 case OPC_JALRS:
6af0bf9c 4069 case OPC_JALR:
364d4831 4070 case OPC_JALRC:
6af0bf9c 4071 blink = rt;
4ad40f36 4072 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
4073 ctx->hflags |= (opc == OPC_JALRS
4074 ? MIPS_HFLAG_BDS16
4075 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
4076 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4077 break;
4078 default:
4079 MIPS_INVAL("branch/jump");
4080 generate_exception(ctx, EXCP_RI);
6c5c1e20 4081 goto out;
6af0bf9c
FB
4082 }
4083 } else {
4084 switch (opc) {
4085 case OPC_BEQ:
e68dd28f 4086 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4087 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 4088 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4089 goto not_likely;
4090 case OPC_BEQL:
e68dd28f 4091 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 4092 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 4093 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4094 goto likely;
4095 case OPC_BNE:
e68dd28f 4096 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4097 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 4098 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4099 goto not_likely;
4100 case OPC_BNEL:
e68dd28f 4101 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 4102 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 4103 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
4104 goto likely;
4105 case OPC_BGEZ:
e68dd28f 4106 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4107 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4108 goto not_likely;
4109 case OPC_BGEZL:
e68dd28f 4110 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4111 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4112 goto likely;
3c824109 4113 case OPC_BGEZALS:
6af0bf9c 4114 case OPC_BGEZAL:
3c824109
NF
4115 ctx->hflags |= (opc == OPC_BGEZALS
4116 ? MIPS_HFLAG_BDS16
4117 : MIPS_HFLAG_BDS32);
e68dd28f 4118 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 4119 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4120 blink = 31;
4121 goto not_likely;
4122 case OPC_BGEZALL:
e68dd28f 4123 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4124 blink = 31;
d077b6f7 4125 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4126 goto likely;
4127 case OPC_BGTZ:
e68dd28f 4128 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4129 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4130 goto not_likely;
4131 case OPC_BGTZL:
e68dd28f 4132 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 4133 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4134 goto likely;
4135 case OPC_BLEZ:
e68dd28f 4136 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4137 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4138 goto not_likely;
4139 case OPC_BLEZL:
e68dd28f 4140 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 4141 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4142 goto likely;
4143 case OPC_BLTZ:
e68dd28f 4144 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4145 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
4146 goto not_likely;
4147 case OPC_BLTZL:
e68dd28f 4148 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 4149 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4150 goto likely;
e45a93e2
JL
4151 case OPC_BPOSGE32:
4152 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4153 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4154 goto not_likely;
4155#if defined(TARGET_MIPS64)
4156 case OPC_BPOSGE64:
4157 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4158 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4159 goto not_likely;
4160#endif
3c824109 4161 case OPC_BLTZALS:
6af0bf9c 4162 case OPC_BLTZAL:
3c824109
NF
4163 ctx->hflags |= (opc == OPC_BLTZALS
4164 ? MIPS_HFLAG_BDS16
4165 : MIPS_HFLAG_BDS32);
e68dd28f 4166 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4167 blink = 31;
d077b6f7 4168 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4169 not_likely:
4ad40f36 4170 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4171 break;
4172 case OPC_BLTZALL:
e68dd28f 4173 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4174 blink = 31;
d077b6f7 4175 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 4176 likely:
4ad40f36 4177 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4178 break;
c53f4a62
TS
4179 default:
4180 MIPS_INVAL("conditional branch/jump");
4181 generate_exception(ctx, EXCP_RI);
6c5c1e20 4182 goto out;
6af0bf9c 4183 }
6af0bf9c 4184 }
923617a3 4185 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 4186 blink, ctx->hflags, btgt);
9b9e4393 4187
d077b6f7 4188 ctx->btarget = btgt;
6af0bf9c 4189 if (blink > 0) {
364d4831
NF
4190 int post_delay = insn_bytes;
4191 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4192
4193 if (opc != OPC_JALRC)
4194 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
4195
4196 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 4197 }
6c5c1e20
TS
4198
4199 out:
364d4831
NF
4200 if (insn_bytes == 2)
4201 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4202 tcg_temp_free(t0);
4203 tcg_temp_free(t1);
6af0bf9c
FB
4204}
4205
7a387fff
TS
4206/* special3 bitfield operations */
4207static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4208 int rs, int lsb, int msb)
7a387fff 4209{
a7812ae4
PB
4210 TCGv t0 = tcg_temp_new();
4211 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4212
4213 gen_load_gpr(t1, rs);
7a387fff
TS
4214 switch (opc) {
4215 case OPC_EXT:
4216 if (lsb + msb > 31)
4217 goto fail;
505ad7c2
AJ
4218 tcg_gen_shri_tl(t0, t1, lsb);
4219 if (msb != 31) {
4220 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4221 } else {
4222 tcg_gen_ext32s_tl(t0, t0);
4223 }
7a387fff 4224 break;
c6d6dd7c 4225#if defined(TARGET_MIPS64)
7a387fff 4226 case OPC_DEXTM:
505ad7c2
AJ
4227 tcg_gen_shri_tl(t0, t1, lsb);
4228 if (msb != 31) {
4229 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4230 }
7a387fff
TS
4231 break;
4232 case OPC_DEXTU:
505ad7c2
AJ
4233 tcg_gen_shri_tl(t0, t1, lsb + 32);
4234 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
4235 break;
4236 case OPC_DEXT:
505ad7c2
AJ
4237 tcg_gen_shri_tl(t0, t1, lsb);
4238 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 4239 break;
c6d6dd7c 4240#endif
7a387fff
TS
4241 case OPC_INS:
4242 if (lsb > msb)
4243 goto fail;
6c5c1e20 4244 gen_load_gpr(t0, rt);
e0d002f1 4245 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4246 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4247 break;
c6d6dd7c 4248#if defined(TARGET_MIPS64)
7a387fff 4249 case OPC_DINSM:
6c5c1e20 4250 gen_load_gpr(t0, rt);
e0d002f1 4251 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
7a387fff
TS
4252 break;
4253 case OPC_DINSU:
6c5c1e20 4254 gen_load_gpr(t0, rt);
e0d002f1 4255 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
7a387fff
TS
4256 break;
4257 case OPC_DINS:
6c5c1e20 4258 gen_load_gpr(t0, rt);
e0d002f1 4259 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4260 break;
c6d6dd7c 4261#endif
7a387fff
TS
4262 default:
4263fail:
4264 MIPS_INVAL("bitops");
4265 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
4266 tcg_temp_free(t0);
4267 tcg_temp_free(t1);
7a387fff
TS
4268 return;
4269 }
6c5c1e20
TS
4270 gen_store_gpr(t0, rt);
4271 tcg_temp_free(t0);
4272 tcg_temp_free(t1);
7a387fff
TS
4273}
4274
49bcf33c
AJ
4275static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4276{
3a55fa47 4277 TCGv t0;
49bcf33c 4278
3a55fa47
AJ
4279 if (rd == 0) {
4280 /* If no destination, treat it as a NOP. */
4281 MIPS_DEBUG("NOP");
4282 return;
4283 }
4284
4285 t0 = tcg_temp_new();
4286 gen_load_gpr(t0, rt);
49bcf33c
AJ
4287 switch (op2) {
4288 case OPC_WSBH:
3a55fa47
AJ
4289 {
4290 TCGv t1 = tcg_temp_new();
4291
4292 tcg_gen_shri_tl(t1, t0, 8);
4293 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4294 tcg_gen_shli_tl(t0, t0, 8);
4295 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4296 tcg_gen_or_tl(t0, t0, t1);
4297 tcg_temp_free(t1);
4298 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4299 }
49bcf33c
AJ
4300 break;
4301 case OPC_SEB:
3a55fa47 4302 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4303 break;
4304 case OPC_SEH:
3a55fa47 4305 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4306 break;
4307#if defined(TARGET_MIPS64)
4308 case OPC_DSBH:
3a55fa47
AJ
4309 {
4310 TCGv t1 = tcg_temp_new();
4311
4312 tcg_gen_shri_tl(t1, t0, 8);
4313 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4314 tcg_gen_shli_tl(t0, t0, 8);
4315 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4316 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4317 tcg_temp_free(t1);
4318 }
49bcf33c
AJ
4319 break;
4320 case OPC_DSHD:
3a55fa47
AJ
4321 {
4322 TCGv t1 = tcg_temp_new();
4323
4324 tcg_gen_shri_tl(t1, t0, 16);
4325 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4326 tcg_gen_shli_tl(t0, t0, 16);
4327 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4328 tcg_gen_or_tl(t0, t0, t1);
4329 tcg_gen_shri_tl(t1, t0, 32);
4330 tcg_gen_shli_tl(t0, t0, 32);
4331 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4332 tcg_temp_free(t1);
4333 }
49bcf33c
AJ
4334 break;
4335#endif
4336 default:
4337 MIPS_INVAL("bsfhl");
4338 generate_exception(ctx, EXCP_RI);
4339 tcg_temp_free(t0);
49bcf33c
AJ
4340 return;
4341 }
49bcf33c 4342 tcg_temp_free(t0);
49bcf33c
AJ
4343}
4344
f1aa6320 4345#ifndef CONFIG_USER_ONLY
0eaef5aa 4346/* CP0 (MMU and control) */
d9bea114 4347static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4348{
d9bea114 4349 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4350
d9bea114
AJ
4351 tcg_gen_ld_i32(t0, cpu_env, off);
4352 tcg_gen_ext_i32_tl(arg, t0);
4353 tcg_temp_free_i32(t0);
4f57689a
TS
4354}
4355
d9bea114 4356static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4357{
d9bea114
AJ
4358 tcg_gen_ld_tl(arg, cpu_env, off);
4359 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4360}
4361
d9bea114 4362static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4363{
d9bea114 4364 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4365
d9bea114
AJ
4366 tcg_gen_trunc_tl_i32(t0, arg);
4367 tcg_gen_st_i32(t0, cpu_env, off);
4368 tcg_temp_free_i32(t0);
f1aa6320
TS
4369}
4370
d9bea114 4371static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4372{
d9bea114
AJ
4373 tcg_gen_ext32s_tl(arg, arg);
4374 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4375}
4376
d75c135e 4377static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4378{
7a387fff 4379 const char *rn = "invalid";
873eb012 4380
e189e748 4381 if (sel != 0)
d75c135e 4382 check_insn(ctx, ISA_MIPS32);
e189e748 4383
873eb012
TS
4384 switch (reg) {
4385 case 0:
7a387fff
TS
4386 switch (sel) {
4387 case 0:
7db13fae 4388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4389 rn = "Index";
4390 break;
4391 case 1:
d75c135e 4392 check_insn(ctx, ASE_MT);
895c2d04 4393 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4394 rn = "MVPControl";
ead9360e 4395 break;
7a387fff 4396 case 2:
d75c135e 4397 check_insn(ctx, ASE_MT);
895c2d04 4398 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4399 rn = "MVPConf0";
ead9360e 4400 break;
7a387fff 4401 case 3:
d75c135e 4402 check_insn(ctx, ASE_MT);
895c2d04 4403 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4404 rn = "MVPConf1";
ead9360e 4405 break;
7a387fff
TS
4406 default:
4407 goto die;
4408 }
873eb012
TS
4409 break;
4410 case 1:
7a387fff
TS
4411 switch (sel) {
4412 case 0:
895c2d04 4413 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4414 rn = "Random";
2423f660 4415 break;
7a387fff 4416 case 1:
d75c135e 4417 check_insn(ctx, ASE_MT);
7db13fae 4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4419 rn = "VPEControl";
ead9360e 4420 break;
7a387fff 4421 case 2:
d75c135e 4422 check_insn(ctx, ASE_MT);
7db13fae 4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4424 rn = "VPEConf0";
ead9360e 4425 break;
7a387fff 4426 case 3:
d75c135e 4427 check_insn(ctx, ASE_MT);
7db13fae 4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4429 rn = "VPEConf1";
ead9360e 4430 break;
7a387fff 4431 case 4:
d75c135e 4432 check_insn(ctx, ASE_MT);
7db13fae 4433 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4434 rn = "YQMask";
ead9360e 4435 break;
7a387fff 4436 case 5:
d75c135e 4437 check_insn(ctx, ASE_MT);
7db13fae 4438 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4439 rn = "VPESchedule";
ead9360e 4440 break;
7a387fff 4441 case 6:
d75c135e 4442 check_insn(ctx, ASE_MT);
7db13fae 4443 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4444 rn = "VPEScheFBack";
ead9360e 4445 break;
7a387fff 4446 case 7:
d75c135e 4447 check_insn(ctx, ASE_MT);
7db13fae 4448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4449 rn = "VPEOpt";
ead9360e 4450 break;
7a387fff
TS
4451 default:
4452 goto die;
4453 }
873eb012
TS
4454 break;
4455 case 2:
7a387fff
TS
4456 switch (sel) {
4457 case 0:
7db13fae 4458 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4459 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4460 rn = "EntryLo0";
4461 break;
7a387fff 4462 case 1:
d75c135e 4463 check_insn(ctx, ASE_MT);
895c2d04 4464 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4465 rn = "TCStatus";
ead9360e 4466 break;
7a387fff 4467 case 2:
d75c135e 4468 check_insn(ctx, ASE_MT);
895c2d04 4469 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4470 rn = "TCBind";
ead9360e 4471 break;
7a387fff 4472 case 3:
d75c135e 4473 check_insn(ctx, ASE_MT);
895c2d04 4474 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4475 rn = "TCRestart";
ead9360e 4476 break;
7a387fff 4477 case 4:
d75c135e 4478 check_insn(ctx, ASE_MT);
895c2d04 4479 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4480 rn = "TCHalt";
ead9360e 4481 break;
7a387fff 4482 case 5:
d75c135e 4483 check_insn(ctx, ASE_MT);
895c2d04 4484 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4485 rn = "TCContext";
ead9360e 4486 break;
7a387fff 4487 case 6:
d75c135e 4488 check_insn(ctx, ASE_MT);
895c2d04 4489 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4490 rn = "TCSchedule";
ead9360e 4491 break;
7a387fff 4492 case 7:
d75c135e 4493 check_insn(ctx, ASE_MT);
895c2d04 4494 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4495 rn = "TCScheFBack";
ead9360e 4496 break;
7a387fff
TS
4497 default:
4498 goto die;
4499 }
873eb012
TS
4500 break;
4501 case 3:
7a387fff
TS
4502 switch (sel) {
4503 case 0:
7db13fae 4504 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4505 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4506 rn = "EntryLo1";
4507 break;
7a387fff
TS
4508 default:
4509 goto die;
1579a72e 4510 }
873eb012
TS
4511 break;
4512 case 4:
7a387fff
TS
4513 switch (sel) {
4514 case 0:
7db13fae 4515 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4516 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4517 rn = "Context";
4518 break;
7a387fff 4519 case 1:
d9bea114 4520// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 4521 rn = "ContextConfig";
d279279e 4522 goto die;
2423f660 4523// break;
d279279e
PJ
4524 case 2:
4525 if (ctx->ulri) {
4526 tcg_gen_ld32s_tl(arg, cpu_env,
4527 offsetof(CPUMIPSState,
4528 active_tc.CP0_UserLocal));
4529 rn = "UserLocal";
4530 } else {
4531 tcg_gen_movi_tl(arg, 0);
4532 }
4533 break;
7a387fff
TS
4534 default:
4535 goto die;
1579a72e 4536 }
873eb012
TS
4537 break;
4538 case 5:
7a387fff
TS
4539 switch (sel) {
4540 case 0:
7db13fae 4541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4542 rn = "PageMask";
4543 break;
7a387fff 4544 case 1:
d75c135e 4545 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4547 rn = "PageGrain";
4548 break;
7a387fff
TS
4549 default:
4550 goto die;
1579a72e 4551 }
873eb012
TS
4552 break;
4553 case 6:
7a387fff
TS
4554 switch (sel) {
4555 case 0:
7db13fae 4556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4557 rn = "Wired";
4558 break;
7a387fff 4559 case 1:
d75c135e 4560 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4562 rn = "SRSConf0";
ead9360e 4563 break;
7a387fff 4564 case 2:
d75c135e 4565 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4567 rn = "SRSConf1";
ead9360e 4568 break;
7a387fff 4569 case 3:
d75c135e 4570 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4572 rn = "SRSConf2";
ead9360e 4573 break;
7a387fff 4574 case 4:
d75c135e 4575 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4577 rn = "SRSConf3";
ead9360e 4578 break;
7a387fff 4579 case 5:
d75c135e 4580 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4582 rn = "SRSConf4";
ead9360e 4583 break;
7a387fff
TS
4584 default:
4585 goto die;
1579a72e 4586 }
873eb012 4587 break;
8c0fdd85 4588 case 7:
7a387fff
TS
4589 switch (sel) {
4590 case 0:
d75c135e 4591 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4593 rn = "HWREna";
4594 break;
7a387fff
TS
4595 default:
4596 goto die;
1579a72e 4597 }
8c0fdd85 4598 break;
873eb012 4599 case 8:
7a387fff
TS
4600 switch (sel) {
4601 case 0:
7db13fae 4602 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4603 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4604 rn = "BadVAddr";
2423f660 4605 break;
7a387fff
TS
4606 default:
4607 goto die;
4608 }
873eb012
TS
4609 break;
4610 case 9:
7a387fff
TS
4611 switch (sel) {
4612 case 0:
2e70f6ef
PB
4613 /* Mark as an IO operation because we read the time. */
4614 if (use_icount)
4615 gen_io_start();
895c2d04 4616 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4617 if (use_icount) {
4618 gen_io_end();
2e70f6ef 4619 }
55807224
EI
4620 /* Break the TB to be able to take timer interrupts immediately
4621 after reading count. */
4622 ctx->bstate = BS_STOP;
2423f660
TS
4623 rn = "Count";
4624 break;
4625 /* 6,7 are implementation dependent */
7a387fff
TS
4626 default:
4627 goto die;
2423f660 4628 }
873eb012
TS
4629 break;
4630 case 10:
7a387fff
TS
4631 switch (sel) {
4632 case 0:
7db13fae 4633 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4634 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4635 rn = "EntryHi";
4636 break;
7a387fff
TS
4637 default:
4638 goto die;
1579a72e 4639 }
873eb012
TS
4640 break;
4641 case 11:
7a387fff
TS
4642 switch (sel) {
4643 case 0:
7db13fae 4644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4645 rn = "Compare";
4646 break;
4647 /* 6,7 are implementation dependent */
7a387fff
TS
4648 default:
4649 goto die;
2423f660 4650 }
873eb012
TS
4651 break;
4652 case 12:
7a387fff
TS
4653 switch (sel) {
4654 case 0:
7db13fae 4655 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4656 rn = "Status";
4657 break;
7a387fff 4658 case 1:
d75c135e 4659 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4661 rn = "IntCtl";
4662 break;
7a387fff 4663 case 2:
d75c135e 4664 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4666 rn = "SRSCtl";
4667 break;
7a387fff 4668 case 3:
d75c135e 4669 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4671 rn = "SRSMap";
fd88b6ab 4672 break;
7a387fff
TS
4673 default:
4674 goto die;
4675 }
873eb012
TS
4676 break;
4677 case 13:
7a387fff
TS
4678 switch (sel) {
4679 case 0:
7db13fae 4680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4681 rn = "Cause";
4682 break;
7a387fff
TS
4683 default:
4684 goto die;
4685 }
873eb012
TS
4686 break;
4687 case 14:
7a387fff
TS
4688 switch (sel) {
4689 case 0:
7db13fae 4690 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4691 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4692 rn = "EPC";
4693 break;
7a387fff
TS
4694 default:
4695 goto die;
1579a72e 4696 }
873eb012
TS
4697 break;
4698 case 15:
7a387fff
TS
4699 switch (sel) {
4700 case 0:
7db13fae 4701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4702 rn = "PRid";
4703 break;
7a387fff 4704 case 1:
d75c135e 4705 check_insn(ctx, ISA_MIPS32R2);
7db13fae 4706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4707 rn = "EBase";
4708 break;
7a387fff
TS
4709 default:
4710 goto die;
4711 }
873eb012
TS
4712 break;
4713 case 16:
4714 switch (sel) {
4715 case 0:
7db13fae 4716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4717 rn = "Config";
4718 break;
4719 case 1:
7db13fae 4720 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4721 rn = "Config1";
4722 break;
7a387fff 4723 case 2:
7db13fae 4724 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4725 rn = "Config2";
4726 break;
4727 case 3:
7db13fae 4728 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4729 rn = "Config3";
4730 break;
b4160af1
PJ
4731 case 4:
4732 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4733 rn = "Config4";
4734 break;
b4dd99a3
PJ
4735 case 5:
4736 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4737 rn = "Config5";
4738 break;
e397ee33
TS
4739 /* 6,7 are implementation dependent */
4740 case 6:
7db13fae 4741 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4742 rn = "Config6";
4743 break;
4744 case 7:
7db13fae 4745 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4746 rn = "Config7";
4747 break;
873eb012 4748 default:
873eb012
TS
4749 goto die;
4750 }
4751 break;
4752 case 17:
7a387fff
TS
4753 switch (sel) {
4754 case 0:
895c2d04 4755 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4756 rn = "LLAddr";
4757 break;
7a387fff
TS
4758 default:
4759 goto die;
4760 }
873eb012
TS
4761 break;
4762 case 18:
7a387fff 4763 switch (sel) {
fd88b6ab 4764 case 0 ... 7:
895c2d04 4765 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4766 rn = "WatchLo";
4767 break;
7a387fff
TS
4768 default:
4769 goto die;
4770 }
873eb012
TS
4771 break;
4772 case 19:
7a387fff 4773 switch (sel) {
fd88b6ab 4774 case 0 ...7:
895c2d04 4775 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4776 rn = "WatchHi";
4777 break;
7a387fff
TS
4778 default:
4779 goto die;
4780 }
873eb012 4781 break;
8c0fdd85 4782 case 20:
7a387fff
TS
4783 switch (sel) {
4784 case 0:
d26bc211 4785#if defined(TARGET_MIPS64)
d75c135e 4786 check_insn(ctx, ISA_MIPS3);
7db13fae 4787 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4788 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4789 rn = "XContext";
4790 break;
703eaf37 4791#endif
7a387fff
TS
4792 default:
4793 goto die;
4794 }
8c0fdd85
TS
4795 break;
4796 case 21:
7a387fff
TS
4797 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4798 switch (sel) {
4799 case 0:
7db13fae 4800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4801 rn = "Framemask";
4802 break;
7a387fff
TS
4803 default:
4804 goto die;
4805 }
8c0fdd85
TS
4806 break;
4807 case 22:
d9bea114 4808 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4809 rn = "'Diagnostic"; /* implementation dependent */
4810 break;
873eb012 4811 case 23:
7a387fff
TS
4812 switch (sel) {
4813 case 0:
895c2d04 4814 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4815 rn = "Debug";
4816 break;
7a387fff 4817 case 1:
d9bea114 4818// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4819 rn = "TraceControl";
4820// break;
7a387fff 4821 case 2:
d9bea114 4822// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4823 rn = "TraceControl2";
4824// break;
7a387fff 4825 case 3:
d9bea114 4826// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4827 rn = "UserTraceData";
4828// break;
7a387fff 4829 case 4:
d9bea114 4830// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4831 rn = "TraceBPC";
4832// break;
7a387fff
TS
4833 default:
4834 goto die;
4835 }
873eb012
TS
4836 break;
4837 case 24:
7a387fff
TS
4838 switch (sel) {
4839 case 0:
f0b3f3ae 4840 /* EJTAG support */
7db13fae 4841 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4842 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4843 rn = "DEPC";
4844 break;
7a387fff
TS
4845 default:
4846 goto die;
4847 }
873eb012 4848 break;
8c0fdd85 4849 case 25:
7a387fff
TS
4850 switch (sel) {
4851 case 0:
7db13fae 4852 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4853 rn = "Performance0";
7a387fff
TS
4854 break;
4855 case 1:
d9bea114 4856// gen_helper_mfc0_performance1(arg);
2423f660
TS
4857 rn = "Performance1";
4858// break;
7a387fff 4859 case 2:
d9bea114 4860// gen_helper_mfc0_performance2(arg);
2423f660
TS
4861 rn = "Performance2";
4862// break;
7a387fff 4863 case 3:
d9bea114 4864// gen_helper_mfc0_performance3(arg);
2423f660
TS
4865 rn = "Performance3";
4866// break;
7a387fff 4867 case 4:
d9bea114 4868// gen_helper_mfc0_performance4(arg);
2423f660
TS
4869 rn = "Performance4";
4870// break;
7a387fff 4871 case 5:
d9bea114 4872// gen_helper_mfc0_performance5(arg);
2423f660
TS
4873 rn = "Performance5";
4874// break;
7a387fff 4875 case 6:
d9bea114 4876// gen_helper_mfc0_performance6(arg);
2423f660
TS
4877 rn = "Performance6";
4878// break;
7a387fff 4879 case 7:
d9bea114 4880// gen_helper_mfc0_performance7(arg);
2423f660
TS
4881 rn = "Performance7";
4882// break;
7a387fff
TS
4883 default:
4884 goto die;
4885 }
8c0fdd85
TS
4886 break;
4887 case 26:
d9bea114 4888 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4889 rn = "ECC";
4890 break;
8c0fdd85 4891 case 27:
7a387fff 4892 switch (sel) {
7a387fff 4893 case 0 ... 3:
d9bea114 4894 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4895 rn = "CacheErr";
4896 break;
7a387fff
TS
4897 default:
4898 goto die;
4899 }
8c0fdd85 4900 break;
873eb012
TS
4901 case 28:
4902 switch (sel) {
4903 case 0:
7a387fff
TS
4904 case 2:
4905 case 4:
4906 case 6:
7db13fae 4907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4908 rn = "TagLo";
4909 break;
4910 case 1:
7a387fff
TS
4911 case 3:
4912 case 5:
4913 case 7:
7db13fae 4914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4915 rn = "DataLo";
4916 break;
4917 default:
873eb012
TS
4918 goto die;
4919 }
4920 break;
8c0fdd85 4921 case 29:
7a387fff
TS
4922 switch (sel) {
4923 case 0:
4924 case 2:
4925 case 4:
4926 case 6:
7db13fae 4927 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4928 rn = "TagHi";
4929 break;
4930 case 1:
4931 case 3:
4932 case 5:
4933 case 7:
7db13fae 4934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4935 rn = "DataHi";
4936 break;
4937 default:
4938 goto die;
4939 }
8c0fdd85 4940 break;
873eb012 4941 case 30:
7a387fff
TS
4942 switch (sel) {
4943 case 0:
7db13fae 4944 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4945 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4946 rn = "ErrorEPC";
4947 break;
7a387fff
TS
4948 default:
4949 goto die;
4950 }
873eb012
TS
4951 break;
4952 case 31:
7a387fff
TS
4953 switch (sel) {
4954 case 0:
f0b3f3ae 4955 /* EJTAG support */
7db13fae 4956 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4957 rn = "DESAVE";
4958 break;
7a387fff
TS
4959 default:
4960 goto die;
4961 }
873eb012
TS
4962 break;
4963 default:
873eb012
TS
4964 goto die;
4965 }
2abf314d 4966 (void)rn; /* avoid a compiler warning */
d12d51d5 4967 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4968 return;
4969
4970die:
d12d51d5 4971 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4972 generate_exception(ctx, EXCP_RI);
4973}
4974
d75c135e 4975static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4976{
7a387fff
TS
4977 const char *rn = "invalid";
4978
e189e748 4979 if (sel != 0)
d75c135e 4980 check_insn(ctx, ISA_MIPS32);
e189e748 4981
2e70f6ef
PB
4982 if (use_icount)
4983 gen_io_start();
4984
8c0fdd85
TS
4985 switch (reg) {
4986 case 0:
7a387fff
TS
4987 switch (sel) {
4988 case 0:
895c2d04 4989 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4990 rn = "Index";
4991 break;
4992 case 1:
d75c135e 4993 check_insn(ctx, ASE_MT);
895c2d04 4994 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4995 rn = "MVPControl";
ead9360e 4996 break;
7a387fff 4997 case 2:
d75c135e 4998 check_insn(ctx, ASE_MT);
ead9360e 4999 /* ignored */
7a387fff 5000 rn = "MVPConf0";
ead9360e 5001 break;
7a387fff 5002 case 3:
d75c135e 5003 check_insn(ctx, ASE_MT);
ead9360e 5004 /* ignored */
7a387fff 5005 rn = "MVPConf1";
ead9360e 5006 break;
7a387fff
TS
5007 default:
5008 goto die;
5009 }
8c0fdd85
TS
5010 break;
5011 case 1:
7a387fff
TS
5012 switch (sel) {
5013 case 0:
2423f660 5014 /* ignored */
7a387fff 5015 rn = "Random";
2423f660 5016 break;
7a387fff 5017 case 1:
d75c135e 5018 check_insn(ctx, ASE_MT);
895c2d04 5019 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5020 rn = "VPEControl";
ead9360e 5021 break;
7a387fff 5022 case 2:
d75c135e 5023 check_insn(ctx, ASE_MT);
895c2d04 5024 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5025 rn = "VPEConf0";
ead9360e 5026 break;
7a387fff 5027 case 3:
d75c135e 5028 check_insn(ctx, ASE_MT);
895c2d04 5029 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5030 rn = "VPEConf1";
ead9360e 5031 break;
7a387fff 5032 case 4:
d75c135e 5033 check_insn(ctx, ASE_MT);
895c2d04 5034 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5035 rn = "YQMask";
ead9360e 5036 break;
7a387fff 5037 case 5:
d75c135e 5038 check_insn(ctx, ASE_MT);
7db13fae 5039 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5040 rn = "VPESchedule";
ead9360e 5041 break;
7a387fff 5042 case 6:
d75c135e 5043 check_insn(ctx, ASE_MT);
7db13fae 5044 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5045 rn = "VPEScheFBack";
ead9360e 5046 break;
7a387fff 5047 case 7:
d75c135e 5048 check_insn(ctx, ASE_MT);
895c2d04 5049 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5050 rn = "VPEOpt";
ead9360e 5051 break;
7a387fff
TS
5052 default:
5053 goto die;
5054 }
8c0fdd85
TS
5055 break;
5056 case 2:
7a387fff
TS
5057 switch (sel) {
5058 case 0:
895c2d04 5059 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5060 rn = "EntryLo0";
5061 break;
7a387fff 5062 case 1:
d75c135e 5063 check_insn(ctx, ASE_MT);
895c2d04 5064 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5065 rn = "TCStatus";
ead9360e 5066 break;
7a387fff 5067 case 2:
d75c135e 5068 check_insn(ctx, ASE_MT);
895c2d04 5069 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5070 rn = "TCBind";
ead9360e 5071 break;
7a387fff 5072 case 3:
d75c135e 5073 check_insn(ctx, ASE_MT);
895c2d04 5074 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5075 rn = "TCRestart";
ead9360e 5076 break;
7a387fff 5077 case 4:
d75c135e 5078 check_insn(ctx, ASE_MT);
895c2d04 5079 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5080 rn = "TCHalt";
ead9360e 5081 break;
7a387fff 5082 case 5:
d75c135e 5083 check_insn(ctx, ASE_MT);
895c2d04 5084 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5085 rn = "TCContext";
ead9360e 5086 break;
7a387fff 5087 case 6:
d75c135e 5088 check_insn(ctx, ASE_MT);
895c2d04 5089 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5090 rn = "TCSchedule";
ead9360e 5091 break;
7a387fff 5092 case 7:
d75c135e 5093 check_insn(ctx, ASE_MT);
895c2d04 5094 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5095 rn = "TCScheFBack";
ead9360e 5096 break;
7a387fff
TS
5097 default:
5098 goto die;
5099 }
8c0fdd85
TS
5100 break;
5101 case 3:
7a387fff
TS
5102 switch (sel) {
5103 case 0:
895c2d04 5104 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5105 rn = "EntryLo1";
5106 break;
7a387fff
TS
5107 default:
5108 goto die;
876d4b07 5109 }
8c0fdd85
TS
5110 break;
5111 case 4:
7a387fff
TS
5112 switch (sel) {
5113 case 0:
895c2d04 5114 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5115 rn = "Context";
5116 break;
7a387fff 5117 case 1:
895c2d04 5118// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5119 rn = "ContextConfig";
d279279e 5120 goto die;
2423f660 5121// break;
d279279e
PJ
5122 case 2:
5123 if (ctx->ulri) {
5124 tcg_gen_st_tl(arg, cpu_env,
5125 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5126 rn = "UserLocal";
5127 }
5128 break;
7a387fff
TS
5129 default:
5130 goto die;
876d4b07 5131 }
8c0fdd85
TS
5132 break;
5133 case 5:
7a387fff
TS
5134 switch (sel) {
5135 case 0:
895c2d04 5136 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5137 rn = "PageMask";
5138 break;
7a387fff 5139 case 1:
d75c135e 5140 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5141 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
5142 rn = "PageGrain";
5143 break;
7a387fff
TS
5144 default:
5145 goto die;
876d4b07 5146 }
8c0fdd85
TS
5147 break;
5148 case 6:
7a387fff
TS
5149 switch (sel) {
5150 case 0:
895c2d04 5151 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5152 rn = "Wired";
5153 break;
7a387fff 5154 case 1:
d75c135e 5155 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5156 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5157 rn = "SRSConf0";
ead9360e 5158 break;
7a387fff 5159 case 2:
d75c135e 5160 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5161 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5162 rn = "SRSConf1";
ead9360e 5163 break;
7a387fff 5164 case 3:
d75c135e 5165 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5166 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5167 rn = "SRSConf2";
ead9360e 5168 break;
7a387fff 5169 case 4:
d75c135e 5170 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5171 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5172 rn = "SRSConf3";
ead9360e 5173 break;
7a387fff 5174 case 5:
d75c135e 5175 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5176 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5177 rn = "SRSConf4";
ead9360e 5178 break;
7a387fff
TS
5179 default:
5180 goto die;
876d4b07 5181 }
8c0fdd85
TS
5182 break;
5183 case 7:
7a387fff
TS
5184 switch (sel) {
5185 case 0:
d75c135e 5186 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5187 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 5188 ctx->bstate = BS_STOP;
2423f660
TS
5189 rn = "HWREna";
5190 break;
7a387fff
TS
5191 default:
5192 goto die;
876d4b07 5193 }
8c0fdd85
TS
5194 break;
5195 case 8:
7a387fff 5196 /* ignored */
f0b3f3ae 5197 rn = "BadVAddr";
8c0fdd85
TS
5198 break;
5199 case 9:
7a387fff
TS
5200 switch (sel) {
5201 case 0:
895c2d04 5202 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5203 rn = "Count";
5204 break;
876d4b07 5205 /* 6,7 are implementation dependent */
7a387fff
TS
5206 default:
5207 goto die;
876d4b07 5208 }
8c0fdd85
TS
5209 break;
5210 case 10:
7a387fff
TS
5211 switch (sel) {
5212 case 0:
895c2d04 5213 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
5214 rn = "EntryHi";
5215 break;
7a387fff
TS
5216 default:
5217 goto die;
876d4b07 5218 }
8c0fdd85
TS
5219 break;
5220 case 11:
7a387fff
TS
5221 switch (sel) {
5222 case 0:
895c2d04 5223 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
5224 rn = "Compare";
5225 break;
5226 /* 6,7 are implementation dependent */
7a387fff
TS
5227 default:
5228 goto die;
876d4b07 5229 }
8c0fdd85
TS
5230 break;
5231 case 12:
7a387fff
TS
5232 switch (sel) {
5233 case 0:
867abc7e 5234 save_cpu_state(ctx, 1);
895c2d04 5235 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
5236 /* BS_STOP isn't good enough here, hflags may have changed. */
5237 gen_save_pc(ctx->pc + 4);
5238 ctx->bstate = BS_EXCP;
2423f660
TS
5239 rn = "Status";
5240 break;
7a387fff 5241 case 1:
d75c135e 5242 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5243 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
5244 /* Stop translation as we may have switched the execution mode */
5245 ctx->bstate = BS_STOP;
2423f660
TS
5246 rn = "IntCtl";
5247 break;
7a387fff 5248 case 2:
d75c135e 5249 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5250 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
5251 /* Stop translation as we may have switched the execution mode */
5252 ctx->bstate = BS_STOP;
2423f660
TS
5253 rn = "SRSCtl";
5254 break;
7a387fff 5255 case 3:
d75c135e 5256 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5257 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
5258 /* Stop translation as we may have switched the execution mode */
5259 ctx->bstate = BS_STOP;
2423f660 5260 rn = "SRSMap";
fd88b6ab 5261 break;
7a387fff
TS
5262 default:
5263 goto die;
876d4b07 5264 }
8c0fdd85
TS
5265 break;
5266 case 13:
7a387fff
TS
5267 switch (sel) {
5268 case 0:
867abc7e 5269 save_cpu_state(ctx, 1);
895c2d04 5270 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
5271 rn = "Cause";
5272 break;
7a387fff
TS
5273 default:
5274 goto die;
876d4b07 5275 }
8c0fdd85
TS
5276 break;
5277 case 14:
7a387fff
TS
5278 switch (sel) {
5279 case 0:
7db13fae 5280 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5281 rn = "EPC";
5282 break;
7a387fff
TS
5283 default:
5284 goto die;
876d4b07 5285 }
8c0fdd85
TS
5286 break;
5287 case 15:
7a387fff
TS
5288 switch (sel) {
5289 case 0:
2423f660
TS
5290 /* ignored */
5291 rn = "PRid";
5292 break;
7a387fff 5293 case 1:
d75c135e 5294 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5295 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
5296 rn = "EBase";
5297 break;
7a387fff
TS
5298 default:
5299 goto die;
1579a72e 5300 }
8c0fdd85
TS
5301 break;
5302 case 16:
5303 switch (sel) {
5304 case 0:
895c2d04 5305 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5306 rn = "Config";
2423f660
TS
5307 /* Stop translation as we may have switched the execution mode */
5308 ctx->bstate = BS_STOP;
7a387fff
TS
5309 break;
5310 case 1:
e397ee33 5311 /* ignored, read only */
7a387fff
TS
5312 rn = "Config1";
5313 break;
5314 case 2:
895c2d04 5315 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5316 rn = "Config2";
2423f660
TS
5317 /* Stop translation as we may have switched the execution mode */
5318 ctx->bstate = BS_STOP;
8c0fdd85 5319 break;
7a387fff 5320 case 3:
e397ee33 5321 /* ignored, read only */
7a387fff
TS
5322 rn = "Config3";
5323 break;
b4160af1
PJ
5324 case 4:
5325 gen_helper_mtc0_config4(cpu_env, arg);
5326 rn = "Config4";
5327 ctx->bstate = BS_STOP;
5328 break;
b4dd99a3
PJ
5329 case 5:
5330 gen_helper_mtc0_config5(cpu_env, arg);
5331 rn = "Config5";
5332 /* Stop translation as we may have switched the execution mode */
5333 ctx->bstate = BS_STOP;
5334 break;
e397ee33
TS
5335 /* 6,7 are implementation dependent */
5336 case 6:
5337 /* ignored */
5338 rn = "Config6";
5339 break;
5340 case 7:
5341 /* ignored */
5342 rn = "Config7";
5343 break;
8c0fdd85
TS
5344 default:
5345 rn = "Invalid config selector";
5346 goto die;
5347 }
5348 break;
5349 case 17:
7a387fff
TS
5350 switch (sel) {
5351 case 0:
895c2d04 5352 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5353 rn = "LLAddr";
5354 break;
7a387fff
TS
5355 default:
5356 goto die;
5357 }
8c0fdd85
TS
5358 break;
5359 case 18:
7a387fff 5360 switch (sel) {
fd88b6ab 5361 case 0 ... 7:
895c2d04 5362 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5363 rn = "WatchLo";
5364 break;
7a387fff
TS
5365 default:
5366 goto die;
5367 }
8c0fdd85
TS
5368 break;
5369 case 19:
7a387fff 5370 switch (sel) {
fd88b6ab 5371 case 0 ... 7:
895c2d04 5372 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5373 rn = "WatchHi";
5374 break;
7a387fff
TS
5375 default:
5376 goto die;
5377 }
8c0fdd85
TS
5378 break;
5379 case 20:
7a387fff
TS
5380 switch (sel) {
5381 case 0:
d26bc211 5382#if defined(TARGET_MIPS64)
d75c135e 5383 check_insn(ctx, ISA_MIPS3);
895c2d04 5384 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5385 rn = "XContext";
5386 break;
703eaf37 5387#endif
7a387fff
TS
5388 default:
5389 goto die;
5390 }
8c0fdd85
TS
5391 break;
5392 case 21:
7a387fff
TS
5393 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5394 switch (sel) {
5395 case 0:
895c2d04 5396 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5397 rn = "Framemask";
5398 break;
7a387fff
TS
5399 default:
5400 goto die;
5401 }
5402 break;
8c0fdd85 5403 case 22:
7a387fff
TS
5404 /* ignored */
5405 rn = "Diagnostic"; /* implementation dependent */
2423f660 5406 break;
8c0fdd85 5407 case 23:
7a387fff
TS
5408 switch (sel) {
5409 case 0:
895c2d04 5410 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5411 /* BS_STOP isn't good enough here, hflags may have changed. */
5412 gen_save_pc(ctx->pc + 4);
5413 ctx->bstate = BS_EXCP;
2423f660
TS
5414 rn = "Debug";
5415 break;
7a387fff 5416 case 1:
895c2d04 5417// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5418 rn = "TraceControl";
8487327a
TS
5419 /* Stop translation as we may have switched the execution mode */
5420 ctx->bstate = BS_STOP;
2423f660 5421// break;
7a387fff 5422 case 2:
895c2d04 5423// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5424 rn = "TraceControl2";
8487327a
TS
5425 /* Stop translation as we may have switched the execution mode */
5426 ctx->bstate = BS_STOP;
2423f660 5427// break;
7a387fff 5428 case 3:
8487327a
TS
5429 /* Stop translation as we may have switched the execution mode */
5430 ctx->bstate = BS_STOP;
895c2d04 5431// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5432 rn = "UserTraceData";
8487327a
TS
5433 /* Stop translation as we may have switched the execution mode */
5434 ctx->bstate = BS_STOP;
2423f660 5435// break;
7a387fff 5436 case 4:
895c2d04 5437// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5438 /* Stop translation as we may have switched the execution mode */
5439 ctx->bstate = BS_STOP;
2423f660
TS
5440 rn = "TraceBPC";
5441// break;
7a387fff
TS
5442 default:
5443 goto die;
5444 }
8c0fdd85
TS
5445 break;
5446 case 24:
7a387fff
TS
5447 switch (sel) {
5448 case 0:
f1aa6320 5449 /* EJTAG support */
7db13fae 5450 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5451 rn = "DEPC";
5452 break;
7a387fff
TS
5453 default:
5454 goto die;
5455 }
8c0fdd85
TS
5456 break;
5457 case 25:
7a387fff
TS
5458 switch (sel) {
5459 case 0:
895c2d04 5460 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5461 rn = "Performance0";
5462 break;
7a387fff 5463 case 1:
d9bea114 5464// gen_helper_mtc0_performance1(arg);
2423f660
TS
5465 rn = "Performance1";
5466// break;
7a387fff 5467 case 2:
d9bea114 5468// gen_helper_mtc0_performance2(arg);
2423f660
TS
5469 rn = "Performance2";
5470// break;
7a387fff 5471 case 3:
d9bea114 5472// gen_helper_mtc0_performance3(arg);
2423f660
TS
5473 rn = "Performance3";
5474// break;
7a387fff 5475 case 4:
d9bea114 5476// gen_helper_mtc0_performance4(arg);
2423f660
TS
5477 rn = "Performance4";
5478// break;
7a387fff 5479 case 5:
d9bea114 5480// gen_helper_mtc0_performance5(arg);
2423f660
TS
5481 rn = "Performance5";
5482// break;
7a387fff 5483 case 6:
d9bea114 5484// gen_helper_mtc0_performance6(arg);
2423f660
TS
5485 rn = "Performance6";
5486// break;
7a387fff 5487 case 7:
d9bea114 5488// gen_helper_mtc0_performance7(arg);
2423f660
TS
5489 rn = "Performance7";
5490// break;
7a387fff
TS
5491 default:
5492 goto die;
5493 }
8c0fdd85
TS
5494 break;
5495 case 26:
2423f660 5496 /* ignored */
8c0fdd85 5497 rn = "ECC";
2423f660 5498 break;
8c0fdd85 5499 case 27:
7a387fff
TS
5500 switch (sel) {
5501 case 0 ... 3:
2423f660
TS
5502 /* ignored */
5503 rn = "CacheErr";
5504 break;
7a387fff
TS
5505 default:
5506 goto die;
5507 }
8c0fdd85
TS
5508 break;
5509 case 28:
5510 switch (sel) {
5511 case 0:
7a387fff
TS
5512 case 2:
5513 case 4:
5514 case 6:
895c2d04 5515 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5516 rn = "TagLo";
5517 break;
7a387fff
TS
5518 case 1:
5519 case 3:
5520 case 5:
5521 case 7:
895c2d04 5522 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5523 rn = "DataLo";
5524 break;
8c0fdd85 5525 default:
8c0fdd85
TS
5526 goto die;
5527 }
5528 break;
5529 case 29:
7a387fff
TS
5530 switch (sel) {
5531 case 0:
5532 case 2:
5533 case 4:
5534 case 6:
895c2d04 5535 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5536 rn = "TagHi";
5537 break;
5538 case 1:
5539 case 3:
5540 case 5:
5541 case 7:
895c2d04 5542 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5543 rn = "DataHi";
5544 break;
5545 default:
5546 rn = "invalid sel";
5547 goto die;
5548 }
8c0fdd85
TS
5549 break;
5550 case 30:
7a387fff
TS
5551 switch (sel) {
5552 case 0:
7db13fae 5553 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5554 rn = "ErrorEPC";
5555 break;
7a387fff
TS
5556 default:
5557 goto die;
5558 }
8c0fdd85
TS
5559 break;
5560 case 31:
7a387fff
TS
5561 switch (sel) {
5562 case 0:
f1aa6320 5563 /* EJTAG support */
7db13fae 5564 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5565 rn = "DESAVE";
5566 break;
7a387fff
TS
5567 default:
5568 goto die;
5569 }
2423f660
TS
5570 /* Stop translation as we may have switched the execution mode */
5571 ctx->bstate = BS_STOP;
8c0fdd85
TS
5572 break;
5573 default:
8c0fdd85
TS
5574 goto die;
5575 }
2abf314d 5576 (void)rn; /* avoid a compiler warning */
d12d51d5 5577 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5578 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5579 if (use_icount) {
5580 gen_io_end();
5581 ctx->bstate = BS_STOP;
5582 }
8c0fdd85
TS
5583 return;
5584
5585die:
d12d51d5 5586 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5587 generate_exception(ctx, EXCP_RI);
5588}
5589
d26bc211 5590#if defined(TARGET_MIPS64)
d75c135e 5591static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5592{
5593 const char *rn = "invalid";
5594
e189e748 5595 if (sel != 0)
d75c135e 5596 check_insn(ctx, ISA_MIPS64);
e189e748 5597
9c2149c8
TS
5598 switch (reg) {
5599 case 0:
5600 switch (sel) {
5601 case 0:
7db13fae 5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5603 rn = "Index";
5604 break;
5605 case 1:
d75c135e 5606 check_insn(ctx, ASE_MT);
895c2d04 5607 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5608 rn = "MVPControl";
ead9360e 5609 break;
9c2149c8 5610 case 2:
d75c135e 5611 check_insn(ctx, ASE_MT);
895c2d04 5612 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5613 rn = "MVPConf0";
ead9360e 5614 break;
9c2149c8 5615 case 3:
d75c135e 5616 check_insn(ctx, ASE_MT);
895c2d04 5617 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5618 rn = "MVPConf1";
ead9360e 5619 break;
9c2149c8
TS
5620 default:
5621 goto die;
5622 }
5623 break;
5624 case 1:
5625 switch (sel) {
5626 case 0:
895c2d04 5627 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5628 rn = "Random";
2423f660 5629 break;
9c2149c8 5630 case 1:
d75c135e 5631 check_insn(ctx, ASE_MT);
7db13fae 5632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5633 rn = "VPEControl";
ead9360e 5634 break;
9c2149c8 5635 case 2:
d75c135e 5636 check_insn(ctx, ASE_MT);
7db13fae 5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5638 rn = "VPEConf0";
ead9360e 5639 break;
9c2149c8 5640 case 3:
d75c135e 5641 check_insn(ctx, ASE_MT);
7db13fae 5642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5643 rn = "VPEConf1";
ead9360e 5644 break;
9c2149c8 5645 case 4:
d75c135e 5646 check_insn(ctx, ASE_MT);
7db13fae 5647 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5648 rn = "YQMask";
ead9360e 5649 break;
9c2149c8 5650 case 5:
d75c135e 5651 check_insn(ctx, ASE_MT);
7db13fae 5652 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5653 rn = "VPESchedule";
ead9360e 5654 break;
9c2149c8 5655 case 6:
d75c135e 5656 check_insn(ctx, ASE_MT);
7db13fae 5657 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5658 rn = "VPEScheFBack";
ead9360e 5659 break;
9c2149c8 5660 case 7:
d75c135e 5661 check_insn(ctx, ASE_MT);
7db13fae 5662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5663 rn = "VPEOpt";
ead9360e 5664 break;
9c2149c8
TS
5665 default:
5666 goto die;
5667 }
5668 break;
5669 case 2:
5670 switch (sel) {
5671 case 0:
7db13fae 5672 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5673 rn = "EntryLo0";
5674 break;
9c2149c8 5675 case 1:
d75c135e 5676 check_insn(ctx, ASE_MT);
895c2d04 5677 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5678 rn = "TCStatus";
ead9360e 5679 break;
9c2149c8 5680 case 2:
d75c135e 5681 check_insn(ctx, ASE_MT);
895c2d04 5682 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5683 rn = "TCBind";
ead9360e 5684 break;
9c2149c8 5685 case 3:
d75c135e 5686 check_insn(ctx, ASE_MT);
895c2d04 5687 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5688 rn = "TCRestart";
ead9360e 5689 break;
9c2149c8 5690 case 4:
d75c135e 5691 check_insn(ctx, ASE_MT);
895c2d04 5692 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5693 rn = "TCHalt";
ead9360e 5694 break;
9c2149c8 5695 case 5:
d75c135e 5696 check_insn(ctx, ASE_MT);
895c2d04 5697 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5698 rn = "TCContext";
ead9360e 5699 break;
9c2149c8 5700 case 6:
d75c135e 5701 check_insn(ctx, ASE_MT);
895c2d04 5702 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5703 rn = "TCSchedule";
ead9360e 5704 break;
9c2149c8 5705 case 7:
d75c135e 5706 check_insn(ctx, ASE_MT);
895c2d04 5707 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5708 rn = "TCScheFBack";
ead9360e 5709 break;
9c2149c8
TS
5710 default:
5711 goto die;
5712 }
5713 break;
5714 case 3:
5715 switch (sel) {
5716 case 0:
7db13fae 5717 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5718 rn = "EntryLo1";
5719 break;
9c2149c8
TS
5720 default:
5721 goto die;
1579a72e 5722 }
9c2149c8
TS
5723 break;
5724 case 4:
5725 switch (sel) {
5726 case 0:
7db13fae 5727 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5728 rn = "Context";
5729 break;
9c2149c8 5730 case 1:
d9bea114 5731// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5732 rn = "ContextConfig";
d279279e 5733 goto die;
2423f660 5734// break;
d279279e
PJ
5735 case 2:
5736 if (ctx->ulri) {
5737 tcg_gen_ld_tl(arg, cpu_env,
5738 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5739 rn = "UserLocal";
5740 } else {
5741 tcg_gen_movi_tl(arg, 0);
5742 }
5743 break;
9c2149c8
TS
5744 default:
5745 goto die;
876d4b07 5746 }
9c2149c8
TS
5747 break;
5748 case 5:
5749 switch (sel) {
5750 case 0:
7db13fae 5751 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5752 rn = "PageMask";
5753 break;
9c2149c8 5754 case 1:
d75c135e 5755 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5757 rn = "PageGrain";
5758 break;
9c2149c8
TS
5759 default:
5760 goto die;
876d4b07 5761 }
9c2149c8
TS
5762 break;
5763 case 6:
5764 switch (sel) {
5765 case 0:
7db13fae 5766 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5767 rn = "Wired";
5768 break;
9c2149c8 5769 case 1:
d75c135e 5770 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5771 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5772 rn = "SRSConf0";
ead9360e 5773 break;
9c2149c8 5774 case 2:
d75c135e 5775 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5777 rn = "SRSConf1";
ead9360e 5778 break;
9c2149c8 5779 case 3:
d75c135e 5780 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5782 rn = "SRSConf2";
ead9360e 5783 break;
9c2149c8 5784 case 4:
d75c135e 5785 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5787 rn = "SRSConf3";
ead9360e 5788 break;
9c2149c8 5789 case 5:
d75c135e 5790 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5791 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5792 rn = "SRSConf4";
ead9360e 5793 break;
9c2149c8
TS
5794 default:
5795 goto die;
876d4b07 5796 }
9c2149c8
TS
5797 break;
5798 case 7:
5799 switch (sel) {
5800 case 0:
d75c135e 5801 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5803 rn = "HWREna";
5804 break;
9c2149c8
TS
5805 default:
5806 goto die;
876d4b07 5807 }
9c2149c8
TS
5808 break;
5809 case 8:
5810 switch (sel) {
5811 case 0:
7db13fae 5812 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5813 rn = "BadVAddr";
2423f660 5814 break;
9c2149c8
TS
5815 default:
5816 goto die;
876d4b07 5817 }
9c2149c8
TS
5818 break;
5819 case 9:
5820 switch (sel) {
5821 case 0:
2e70f6ef
PB
5822 /* Mark as an IO operation because we read the time. */
5823 if (use_icount)
5824 gen_io_start();
895c2d04 5825 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5826 if (use_icount) {
5827 gen_io_end();
2e70f6ef 5828 }
55807224
EI
5829 /* Break the TB to be able to take timer interrupts immediately
5830 after reading count. */
5831 ctx->bstate = BS_STOP;
2423f660
TS
5832 rn = "Count";
5833 break;
5834 /* 6,7 are implementation dependent */
9c2149c8
TS
5835 default:
5836 goto die;
876d4b07 5837 }
9c2149c8
TS
5838 break;
5839 case 10:
5840 switch (sel) {
5841 case 0:
7db13fae 5842 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5843 rn = "EntryHi";
5844 break;
9c2149c8
TS
5845 default:
5846 goto die;
876d4b07 5847 }
9c2149c8
TS
5848 break;
5849 case 11:
5850 switch (sel) {
5851 case 0:
7db13fae 5852 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5853 rn = "Compare";
5854 break;
876d4b07 5855 /* 6,7 are implementation dependent */
9c2149c8
TS
5856 default:
5857 goto die;
876d4b07 5858 }
9c2149c8
TS
5859 break;
5860 case 12:
5861 switch (sel) {
5862 case 0:
7db13fae 5863 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5864 rn = "Status";
5865 break;
9c2149c8 5866 case 1:
d75c135e 5867 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5869 rn = "IntCtl";
5870 break;
9c2149c8 5871 case 2:
d75c135e 5872 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5874 rn = "SRSCtl";
5875 break;
9c2149c8 5876 case 3:
d75c135e 5877 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5879 rn = "SRSMap";
5880 break;
9c2149c8
TS
5881 default:
5882 goto die;
876d4b07 5883 }
9c2149c8
TS
5884 break;
5885 case 13:
5886 switch (sel) {
5887 case 0:
7db13fae 5888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5889 rn = "Cause";
5890 break;
9c2149c8
TS
5891 default:
5892 goto die;
876d4b07 5893 }
9c2149c8
TS
5894 break;
5895 case 14:
5896 switch (sel) {
5897 case 0:
7db13fae 5898 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5899 rn = "EPC";
5900 break;
9c2149c8
TS
5901 default:
5902 goto die;
876d4b07 5903 }
9c2149c8
TS
5904 break;
5905 case 15:
5906 switch (sel) {
5907 case 0:
7db13fae 5908 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5909 rn = "PRid";
5910 break;
9c2149c8 5911 case 1:
d75c135e 5912 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5914 rn = "EBase";
5915 break;
9c2149c8
TS
5916 default:
5917 goto die;
876d4b07 5918 }
9c2149c8
TS
5919 break;
5920 case 16:
5921 switch (sel) {
5922 case 0:
7db13fae 5923 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5924 rn = "Config";
5925 break;
5926 case 1:
7db13fae 5927 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5928 rn = "Config1";
5929 break;
5930 case 2:
7db13fae 5931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5932 rn = "Config2";
5933 break;
5934 case 3:
7db13fae 5935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5936 rn = "Config3";
5937 break;
5938 /* 6,7 are implementation dependent */
f0b3f3ae 5939 case 6:
7db13fae 5940 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5941 rn = "Config6";
5942 break;
5943 case 7:
7db13fae 5944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5945 rn = "Config7";
5946 break;
9c2149c8
TS
5947 default:
5948 goto die;
5949 }
5950 break;
5951 case 17:
5952 switch (sel) {
5953 case 0:
895c2d04 5954 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5955 rn = "LLAddr";
5956 break;
9c2149c8
TS
5957 default:
5958 goto die;
5959 }
5960 break;
5961 case 18:
5962 switch (sel) {
fd88b6ab 5963 case 0 ... 7:
895c2d04 5964 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5965 rn = "WatchLo";
5966 break;
9c2149c8
TS
5967 default:
5968 goto die;
5969 }
5970 break;
5971 case 19:
5972 switch (sel) {
fd88b6ab 5973 case 0 ... 7:
895c2d04 5974 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5975 rn = "WatchHi";
5976 break;
9c2149c8
TS
5977 default:
5978 goto die;
5979 }
5980 break;
5981 case 20:
5982 switch (sel) {
5983 case 0:
d75c135e 5984 check_insn(ctx, ISA_MIPS3);
7db13fae 5985 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5986 rn = "XContext";
5987 break;
9c2149c8
TS
5988 default:
5989 goto die;
5990 }
5991 break;
5992 case 21:
5993 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5994 switch (sel) {
5995 case 0:
7db13fae 5996 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5997 rn = "Framemask";
5998 break;
9c2149c8
TS
5999 default:
6000 goto die;
6001 }
6002 break;
6003 case 22:
d9bea114 6004 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6005 rn = "'Diagnostic"; /* implementation dependent */
6006 break;
9c2149c8
TS
6007 case 23:
6008 switch (sel) {
6009 case 0:
895c2d04 6010 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6011 rn = "Debug";
6012 break;
9c2149c8 6013 case 1:
895c2d04 6014// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
6015 rn = "TraceControl";
6016// break;
9c2149c8 6017 case 2:
895c2d04 6018// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
6019 rn = "TraceControl2";
6020// break;
9c2149c8 6021 case 3:
895c2d04 6022// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
6023 rn = "UserTraceData";
6024// break;
9c2149c8 6025 case 4:
895c2d04 6026// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
6027 rn = "TraceBPC";
6028// break;
9c2149c8
TS
6029 default:
6030 goto die;
6031 }
6032 break;
6033 case 24:
6034 switch (sel) {
6035 case 0:
f0b3f3ae 6036 /* EJTAG support */
7db13fae 6037 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6038 rn = "DEPC";
6039 break;
9c2149c8
TS
6040 default:
6041 goto die;
6042 }
6043 break;
6044 case 25:
6045 switch (sel) {
6046 case 0:
7db13fae 6047 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6048 rn = "Performance0";
9c2149c8
TS
6049 break;
6050 case 1:
d9bea114 6051// gen_helper_dmfc0_performance1(arg);
2423f660
TS
6052 rn = "Performance1";
6053// break;
9c2149c8 6054 case 2:
d9bea114 6055// gen_helper_dmfc0_performance2(arg);
2423f660
TS
6056 rn = "Performance2";
6057// break;
9c2149c8 6058 case 3:
d9bea114 6059// gen_helper_dmfc0_performance3(arg);
2423f660
TS
6060 rn = "Performance3";
6061// break;
9c2149c8 6062 case 4:
d9bea114 6063// gen_helper_dmfc0_performance4(arg);
2423f660
TS
6064 rn = "Performance4";
6065// break;
9c2149c8 6066 case 5:
d9bea114 6067// gen_helper_dmfc0_performance5(arg);
2423f660
TS
6068 rn = "Performance5";
6069// break;
9c2149c8 6070 case 6:
d9bea114 6071// gen_helper_dmfc0_performance6(arg);
2423f660
TS
6072 rn = "Performance6";
6073// break;
9c2149c8 6074 case 7:
d9bea114 6075// gen_helper_dmfc0_performance7(arg);
2423f660
TS
6076 rn = "Performance7";
6077// break;
9c2149c8
TS
6078 default:
6079 goto die;
6080 }
6081 break;
6082 case 26:
d9bea114 6083 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
6084 rn = "ECC";
6085 break;
9c2149c8
TS
6086 case 27:
6087 switch (sel) {
6088 /* ignored */
6089 case 0 ... 3:
d9bea114 6090 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6091 rn = "CacheErr";
6092 break;
9c2149c8
TS
6093 default:
6094 goto die;
6095 }
6096 break;
6097 case 28:
6098 switch (sel) {
6099 case 0:
6100 case 2:
6101 case 4:
6102 case 6:
7db13fae 6103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6104 rn = "TagLo";
6105 break;
6106 case 1:
6107 case 3:
6108 case 5:
6109 case 7:
7db13fae 6110 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
6111 rn = "DataLo";
6112 break;
6113 default:
6114 goto die;
6115 }
6116 break;
6117 case 29:
6118 switch (sel) {
6119 case 0:
6120 case 2:
6121 case 4:
6122 case 6:
7db13fae 6123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
6124 rn = "TagHi";
6125 break;
6126 case 1:
6127 case 3:
6128 case 5:
6129 case 7:
7db13fae 6130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
6131 rn = "DataHi";
6132 break;
6133 default:
6134 goto die;
6135 }
6136 break;
6137 case 30:
6138 switch (sel) {
6139 case 0:
7db13fae 6140 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6141 rn = "ErrorEPC";
6142 break;
9c2149c8
TS
6143 default:
6144 goto die;
6145 }
6146 break;
6147 case 31:
6148 switch (sel) {
6149 case 0:
f0b3f3ae 6150 /* EJTAG support */
7db13fae 6151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6152 rn = "DESAVE";
6153 break;
9c2149c8
TS
6154 default:
6155 goto die;
6156 }
6157 break;
6158 default:
876d4b07 6159 goto die;
9c2149c8 6160 }
2abf314d 6161 (void)rn; /* avoid a compiler warning */
d12d51d5 6162 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6163 return;
6164
6165die:
d12d51d5 6166 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6167 generate_exception(ctx, EXCP_RI);
6168}
6169
d75c135e 6170static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6171{
6172 const char *rn = "invalid";
6173
e189e748 6174 if (sel != 0)
d75c135e 6175 check_insn(ctx, ISA_MIPS64);
e189e748 6176
2e70f6ef
PB
6177 if (use_icount)
6178 gen_io_start();
6179
9c2149c8
TS
6180 switch (reg) {
6181 case 0:
6182 switch (sel) {
6183 case 0:
895c2d04 6184 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
6185 rn = "Index";
6186 break;
6187 case 1:
d75c135e 6188 check_insn(ctx, ASE_MT);
895c2d04 6189 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 6190 rn = "MVPControl";
ead9360e 6191 break;
9c2149c8 6192 case 2:
d75c135e 6193 check_insn(ctx, ASE_MT);
ead9360e 6194 /* ignored */
9c2149c8 6195 rn = "MVPConf0";
ead9360e 6196 break;
9c2149c8 6197 case 3:
d75c135e 6198 check_insn(ctx, ASE_MT);
ead9360e 6199 /* ignored */
9c2149c8 6200 rn = "MVPConf1";
ead9360e 6201 break;
9c2149c8
TS
6202 default:
6203 goto die;
6204 }
6205 break;
6206 case 1:
6207 switch (sel) {
6208 case 0:
2423f660 6209 /* ignored */
9c2149c8 6210 rn = "Random";
2423f660 6211 break;
9c2149c8 6212 case 1:
d75c135e 6213 check_insn(ctx, ASE_MT);
895c2d04 6214 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 6215 rn = "VPEControl";
ead9360e 6216 break;
9c2149c8 6217 case 2:
d75c135e 6218 check_insn(ctx, ASE_MT);
895c2d04 6219 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 6220 rn = "VPEConf0";
ead9360e 6221 break;
9c2149c8 6222 case 3:
d75c135e 6223 check_insn(ctx, ASE_MT);
895c2d04 6224 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 6225 rn = "VPEConf1";
ead9360e 6226 break;
9c2149c8 6227 case 4:
d75c135e 6228 check_insn(ctx, ASE_MT);
895c2d04 6229 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 6230 rn = "YQMask";
ead9360e 6231 break;
9c2149c8 6232 case 5:
d75c135e 6233 check_insn(ctx, ASE_MT);
7db13fae 6234 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6235 rn = "VPESchedule";
ead9360e 6236 break;
9c2149c8 6237 case 6:
d75c135e 6238 check_insn(ctx, ASE_MT);
7db13fae 6239 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6240 rn = "VPEScheFBack";
ead9360e 6241 break;
9c2149c8 6242 case 7:
d75c135e 6243 check_insn(ctx, ASE_MT);
895c2d04 6244 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 6245 rn = "VPEOpt";
ead9360e 6246 break;
9c2149c8
TS
6247 default:
6248 goto die;
6249 }
6250 break;
6251 case 2:
6252 switch (sel) {
6253 case 0:
895c2d04 6254 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
6255 rn = "EntryLo0";
6256 break;
9c2149c8 6257 case 1:
d75c135e 6258 check_insn(ctx, ASE_MT);
895c2d04 6259 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 6260 rn = "TCStatus";
ead9360e 6261 break;
9c2149c8 6262 case 2:
d75c135e 6263 check_insn(ctx, ASE_MT);
895c2d04 6264 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 6265 rn = "TCBind";
ead9360e 6266 break;
9c2149c8 6267 case 3:
d75c135e 6268 check_insn(ctx, ASE_MT);
895c2d04 6269 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 6270 rn = "TCRestart";
ead9360e 6271 break;
9c2149c8 6272 case 4:
d75c135e 6273 check_insn(ctx, ASE_MT);
895c2d04 6274 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6275 rn = "TCHalt";
ead9360e 6276 break;
9c2149c8 6277 case 5:
d75c135e 6278 check_insn(ctx, ASE_MT);
895c2d04 6279 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6280 rn = "TCContext";
ead9360e 6281 break;
9c2149c8 6282 case 6:
d75c135e 6283 check_insn(ctx, ASE_MT);
895c2d04 6284 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6285 rn = "TCSchedule";
ead9360e 6286 break;
9c2149c8 6287 case 7:
d75c135e 6288 check_insn(ctx, ASE_MT);
895c2d04 6289 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6290 rn = "TCScheFBack";
ead9360e 6291 break;
9c2149c8
TS
6292 default:
6293 goto die;
6294 }
6295 break;
6296 case 3:
6297 switch (sel) {
6298 case 0:
895c2d04 6299 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6300 rn = "EntryLo1";
6301 break;
9c2149c8
TS
6302 default:
6303 goto die;
876d4b07 6304 }
9c2149c8
TS
6305 break;
6306 case 4:
6307 switch (sel) {
6308 case 0:
895c2d04 6309 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6310 rn = "Context";
6311 break;
9c2149c8 6312 case 1:
895c2d04 6313// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6314 rn = "ContextConfig";
d279279e 6315 goto die;
2423f660 6316// break;
d279279e
PJ
6317 case 2:
6318 if (ctx->ulri) {
6319 tcg_gen_st_tl(arg, cpu_env,
6320 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6321 rn = "UserLocal";
6322 }
6323 break;
9c2149c8
TS
6324 default:
6325 goto die;
876d4b07 6326 }
9c2149c8
TS
6327 break;
6328 case 5:
6329 switch (sel) {
6330 case 0:
895c2d04 6331 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6332 rn = "PageMask";
6333 break;
9c2149c8 6334 case 1:
d75c135e 6335 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6336 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6337 rn = "PageGrain";
6338 break;
9c2149c8
TS
6339 default:
6340 goto die;
876d4b07 6341 }
9c2149c8
TS
6342 break;
6343 case 6:
6344 switch (sel) {
6345 case 0:
895c2d04 6346 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6347 rn = "Wired";
6348 break;
9c2149c8 6349 case 1:
d75c135e 6350 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6351 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6352 rn = "SRSConf0";
ead9360e 6353 break;
9c2149c8 6354 case 2:
d75c135e 6355 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6356 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6357 rn = "SRSConf1";
ead9360e 6358 break;
9c2149c8 6359 case 3:
d75c135e 6360 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6361 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6362 rn = "SRSConf2";
ead9360e 6363 break;
9c2149c8 6364 case 4:
d75c135e 6365 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6366 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6367 rn = "SRSConf3";
ead9360e 6368 break;
9c2149c8 6369 case 5:
d75c135e 6370 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6371 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6372 rn = "SRSConf4";
ead9360e 6373 break;
9c2149c8
TS
6374 default:
6375 goto die;
876d4b07 6376 }
9c2149c8
TS
6377 break;
6378 case 7:
6379 switch (sel) {
6380 case 0:
d75c135e 6381 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6382 gen_helper_mtc0_hwrena(cpu_env, arg);
d279279e 6383 ctx->bstate = BS_STOP;
2423f660
TS
6384 rn = "HWREna";
6385 break;
9c2149c8
TS
6386 default:
6387 goto die;
876d4b07 6388 }
9c2149c8
TS
6389 break;
6390 case 8:
6391 /* ignored */
f0b3f3ae 6392 rn = "BadVAddr";
9c2149c8
TS
6393 break;
6394 case 9:
6395 switch (sel) {
6396 case 0:
895c2d04 6397 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6398 rn = "Count";
6399 break;
876d4b07 6400 /* 6,7 are implementation dependent */
9c2149c8
TS
6401 default:
6402 goto die;
876d4b07
TS
6403 }
6404 /* Stop translation as we may have switched the execution mode */
6405 ctx->bstate = BS_STOP;
9c2149c8
TS
6406 break;
6407 case 10:
6408 switch (sel) {
6409 case 0:
895c2d04 6410 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6411 rn = "EntryHi";
6412 break;
9c2149c8
TS
6413 default:
6414 goto die;
876d4b07 6415 }
9c2149c8
TS
6416 break;
6417 case 11:
6418 switch (sel) {
6419 case 0:
895c2d04 6420 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6421 rn = "Compare";
6422 break;
876d4b07 6423 /* 6,7 are implementation dependent */
9c2149c8
TS
6424 default:
6425 goto die;
876d4b07 6426 }
de9a95f0
AJ
6427 /* Stop translation as we may have switched the execution mode */
6428 ctx->bstate = BS_STOP;
9c2149c8
TS
6429 break;
6430 case 12:
6431 switch (sel) {
6432 case 0:
867abc7e 6433 save_cpu_state(ctx, 1);
895c2d04 6434 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6435 /* BS_STOP isn't good enough here, hflags may have changed. */
6436 gen_save_pc(ctx->pc + 4);
6437 ctx->bstate = BS_EXCP;
2423f660
TS
6438 rn = "Status";
6439 break;
9c2149c8 6440 case 1:
d75c135e 6441 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6442 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6443 /* Stop translation as we may have switched the execution mode */
6444 ctx->bstate = BS_STOP;
2423f660
TS
6445 rn = "IntCtl";
6446 break;
9c2149c8 6447 case 2:
d75c135e 6448 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6449 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6450 /* Stop translation as we may have switched the execution mode */
6451 ctx->bstate = BS_STOP;
2423f660
TS
6452 rn = "SRSCtl";
6453 break;
9c2149c8 6454 case 3:
d75c135e 6455 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6456 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6457 /* Stop translation as we may have switched the execution mode */
6458 ctx->bstate = BS_STOP;
2423f660
TS
6459 rn = "SRSMap";
6460 break;
6461 default:
9c2149c8 6462 goto die;
876d4b07 6463 }
9c2149c8
TS
6464 break;
6465 case 13:
6466 switch (sel) {
6467 case 0:
867abc7e 6468 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6469 /* Mark as an IO operation because we may trigger a software
6470 interrupt. */
6471 if (use_icount) {
6472 gen_io_start();
6473 }
895c2d04 6474 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6475 if (use_icount) {
6476 gen_io_end();
6477 }
6478 /* Stop translation as we may have triggered an intetrupt */
6479 ctx->bstate = BS_STOP;
2423f660
TS
6480 rn = "Cause";
6481 break;
9c2149c8
TS
6482 default:
6483 goto die;
876d4b07 6484 }
9c2149c8
TS
6485 break;
6486 case 14:
6487 switch (sel) {
6488 case 0:
7db13fae 6489 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6490 rn = "EPC";
6491 break;
9c2149c8
TS
6492 default:
6493 goto die;
876d4b07 6494 }
9c2149c8
TS
6495 break;
6496 case 15:
6497 switch (sel) {
6498 case 0:
2423f660
TS
6499 /* ignored */
6500 rn = "PRid";
6501 break;
9c2149c8 6502 case 1:
d75c135e 6503 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6504 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6505 rn = "EBase";
6506 break;
9c2149c8
TS
6507 default:
6508 goto die;
876d4b07 6509 }
9c2149c8
TS
6510 break;
6511 case 16:
6512 switch (sel) {
6513 case 0:
895c2d04 6514 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6515 rn = "Config";
2423f660
TS
6516 /* Stop translation as we may have switched the execution mode */
6517 ctx->bstate = BS_STOP;
9c2149c8
TS
6518 break;
6519 case 1:
1fc7bf6e 6520 /* ignored, read only */
9c2149c8
TS
6521 rn = "Config1";
6522 break;
6523 case 2:
895c2d04 6524 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6525 rn = "Config2";
2423f660
TS
6526 /* Stop translation as we may have switched the execution mode */
6527 ctx->bstate = BS_STOP;
9c2149c8
TS
6528 break;
6529 case 3:
2423f660 6530 /* ignored */
9c2149c8
TS
6531 rn = "Config3";
6532 break;
6533 /* 6,7 are implementation dependent */
6534 default:
6535 rn = "Invalid config selector";
6536 goto die;
6537 }
9c2149c8
TS
6538 break;
6539 case 17:
6540 switch (sel) {
6541 case 0:
895c2d04 6542 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6543 rn = "LLAddr";
6544 break;
9c2149c8
TS
6545 default:
6546 goto die;
6547 }
6548 break;
6549 case 18:
6550 switch (sel) {
fd88b6ab 6551 case 0 ... 7:
895c2d04 6552 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6553 rn = "WatchLo";
6554 break;
9c2149c8
TS
6555 default:
6556 goto die;
6557 }
6558 break;
6559 case 19:
6560 switch (sel) {
fd88b6ab 6561 case 0 ... 7:
895c2d04 6562 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6563 rn = "WatchHi";
6564 break;
9c2149c8
TS
6565 default:
6566 goto die;
6567 }
6568 break;
6569 case 20:
6570 switch (sel) {
6571 case 0:
d75c135e 6572 check_insn(ctx, ISA_MIPS3);
895c2d04 6573 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6574 rn = "XContext";
6575 break;
9c2149c8
TS
6576 default:
6577 goto die;
6578 }
6579 break;
6580 case 21:
6581 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6582 switch (sel) {
6583 case 0:
895c2d04 6584 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6585 rn = "Framemask";
6586 break;
9c2149c8
TS
6587 default:
6588 goto die;
6589 }
6590 break;
6591 case 22:
6592 /* ignored */
6593 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6594 break;
9c2149c8
TS
6595 case 23:
6596 switch (sel) {
6597 case 0:
895c2d04 6598 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6599 /* BS_STOP isn't good enough here, hflags may have changed. */
6600 gen_save_pc(ctx->pc + 4);
6601 ctx->bstate = BS_EXCP;
2423f660
TS
6602 rn = "Debug";
6603 break;
9c2149c8 6604 case 1:
895c2d04 6605// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6606 /* Stop translation as we may have switched the execution mode */
6607 ctx->bstate = BS_STOP;
2423f660
TS
6608 rn = "TraceControl";
6609// break;
9c2149c8 6610 case 2:
895c2d04 6611// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6612 /* Stop translation as we may have switched the execution mode */
6613 ctx->bstate = BS_STOP;
2423f660
TS
6614 rn = "TraceControl2";
6615// break;
9c2149c8 6616 case 3:
895c2d04 6617// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6618 /* Stop translation as we may have switched the execution mode */
6619 ctx->bstate = BS_STOP;
2423f660
TS
6620 rn = "UserTraceData";
6621// break;
9c2149c8 6622 case 4:
895c2d04 6623// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6624 /* Stop translation as we may have switched the execution mode */
6625 ctx->bstate = BS_STOP;
2423f660
TS
6626 rn = "TraceBPC";
6627// break;
9c2149c8
TS
6628 default:
6629 goto die;
6630 }
9c2149c8
TS
6631 break;
6632 case 24:
6633 switch (sel) {
6634 case 0:
f1aa6320 6635 /* EJTAG support */
7db13fae 6636 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6637 rn = "DEPC";
6638 break;
9c2149c8
TS
6639 default:
6640 goto die;
6641 }
6642 break;
6643 case 25:
6644 switch (sel) {
6645 case 0:
895c2d04 6646 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6647 rn = "Performance0";
6648 break;
9c2149c8 6649 case 1:
895c2d04 6650// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6651 rn = "Performance1";
6652// break;
9c2149c8 6653 case 2:
895c2d04 6654// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6655 rn = "Performance2";
6656// break;
9c2149c8 6657 case 3:
895c2d04 6658// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6659 rn = "Performance3";
6660// break;
9c2149c8 6661 case 4:
895c2d04 6662// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6663 rn = "Performance4";
6664// break;
9c2149c8 6665 case 5:
895c2d04 6666// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6667 rn = "Performance5";
6668// break;
9c2149c8 6669 case 6:
895c2d04 6670// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6671 rn = "Performance6";
6672// break;
9c2149c8 6673 case 7:
895c2d04 6674// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6675 rn = "Performance7";
6676// break;
9c2149c8
TS
6677 default:
6678 goto die;
6679 }
876d4b07 6680 break;
9c2149c8 6681 case 26:
876d4b07 6682 /* ignored */
9c2149c8 6683 rn = "ECC";
876d4b07 6684 break;
9c2149c8
TS
6685 case 27:
6686 switch (sel) {
6687 case 0 ... 3:
2423f660
TS
6688 /* ignored */
6689 rn = "CacheErr";
6690 break;
9c2149c8
TS
6691 default:
6692 goto die;
6693 }
876d4b07 6694 break;
9c2149c8
TS
6695 case 28:
6696 switch (sel) {
6697 case 0:
6698 case 2:
6699 case 4:
6700 case 6:
895c2d04 6701 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6702 rn = "TagLo";
6703 break;
6704 case 1:
6705 case 3:
6706 case 5:
6707 case 7:
895c2d04 6708 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6709 rn = "DataLo";
6710 break;
6711 default:
6712 goto die;
6713 }
6714 break;
6715 case 29:
6716 switch (sel) {
6717 case 0:
6718 case 2:
6719 case 4:
6720 case 6:
895c2d04 6721 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6722 rn = "TagHi";
6723 break;
6724 case 1:
6725 case 3:
6726 case 5:
6727 case 7:
895c2d04 6728 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6729 rn = "DataHi";
6730 break;
6731 default:
6732 rn = "invalid sel";
6733 goto die;
6734 }
876d4b07 6735 break;
9c2149c8
TS
6736 case 30:
6737 switch (sel) {
6738 case 0:
7db13fae 6739 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6740 rn = "ErrorEPC";
6741 break;
9c2149c8
TS
6742 default:
6743 goto die;
6744 }
6745 break;
6746 case 31:
6747 switch (sel) {
6748 case 0:
f1aa6320 6749 /* EJTAG support */
7db13fae 6750 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6751 rn = "DESAVE";
6752 break;
9c2149c8
TS
6753 default:
6754 goto die;
6755 }
876d4b07
TS
6756 /* Stop translation as we may have switched the execution mode */
6757 ctx->bstate = BS_STOP;
9c2149c8
TS
6758 break;
6759 default:
876d4b07 6760 goto die;
9c2149c8 6761 }
2abf314d 6762 (void)rn; /* avoid a compiler warning */
d12d51d5 6763 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6764 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6765 if (use_icount) {
6766 gen_io_end();
6767 ctx->bstate = BS_STOP;
6768 }
9c2149c8
TS
6769 return;
6770
6771die:
d12d51d5 6772 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6773 generate_exception(ctx, EXCP_RI);
6774}
d26bc211 6775#endif /* TARGET_MIPS64 */
9c2149c8 6776
7db13fae 6777static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6778 int u, int sel, int h)
6779{
6780 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6781 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6782
6783 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6784 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6785 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6786 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6787 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6788 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6789 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6790 else if (u == 0) {
6791 switch (rt) {
5a25ce94
EI
6792 case 1:
6793 switch (sel) {
6794 case 1:
895c2d04 6795 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6796 break;
6797 case 2:
895c2d04 6798 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6799 break;
6800 default:
6801 goto die;
6802 break;
6803 }
6804 break;
ead9360e
TS
6805 case 2:
6806 switch (sel) {
6807 case 1:
895c2d04 6808 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6809 break;
6810 case 2:
895c2d04 6811 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6812 break;
6813 case 3:
895c2d04 6814 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6815 break;
6816 case 4:
895c2d04 6817 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6818 break;
6819 case 5:
895c2d04 6820 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6821 break;
6822 case 6:
895c2d04 6823 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6824 break;
6825 case 7:
895c2d04 6826 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6827 break;
6828 default:
d75c135e 6829 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6830 break;
6831 }
6832 break;
6833 case 10:
6834 switch (sel) {
6835 case 0:
895c2d04 6836 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6837 break;
6838 default:
d75c135e 6839 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6840 break;
6841 }
6842 case 12:
6843 switch (sel) {
6844 case 0:
895c2d04 6845 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6846 break;
6847 default:
d75c135e 6848 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6849 break;
6850 }
5a25ce94
EI
6851 case 13:
6852 switch (sel) {
6853 case 0:
895c2d04 6854 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6855 break;
6856 default:
6857 goto die;
6858 break;
6859 }
6860 break;
6861 case 14:
6862 switch (sel) {
6863 case 0:
895c2d04 6864 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6865 break;
6866 default:
6867 goto die;
6868 break;
6869 }
6870 break;
6871 case 15:
6872 switch (sel) {
6873 case 1:
895c2d04 6874 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6875 break;
6876 default:
6877 goto die;
6878 break;
6879 }
6880 break;
6881 case 16:
6882 switch (sel) {
6883 case 0 ... 7:
895c2d04 6884 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6885 break;
6886 default:
6887 goto die;
6888 break;
6889 }
6890 break;
ead9360e
TS
6891 case 23:
6892 switch (sel) {
6893 case 0:
895c2d04 6894 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6895 break;
6896 default:
d75c135e 6897 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6898 break;
6899 }
6900 break;
6901 default:
d75c135e 6902 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
6903 }
6904 } else switch (sel) {
6905 /* GPR registers. */
6906 case 0:
895c2d04 6907 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6908 break;
6909 /* Auxiliary CPU registers */
6910 case 1:
6911 switch (rt) {
6912 case 0:
895c2d04 6913 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6914 break;
6915 case 1:
895c2d04 6916 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6917 break;
6918 case 2:
895c2d04 6919 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6920 break;
6921 case 4:
895c2d04 6922 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6923 break;
6924 case 5:
895c2d04 6925 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6926 break;
6927 case 6:
895c2d04 6928 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6929 break;
6930 case 8:
895c2d04 6931 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6932 break;
6933 case 9:
895c2d04 6934 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6935 break;
6936 case 10:
895c2d04 6937 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6938 break;
6939 case 12:
895c2d04 6940 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6941 break;
6942 case 13:
895c2d04 6943 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6944 break;
6945 case 14:
895c2d04 6946 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6947 break;
6948 case 16:
895c2d04 6949 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6950 break;
6951 default:
6952 goto die;
6953 }
6954 break;
6955 /* Floating point (COP1). */
6956 case 2:
6957 /* XXX: For now we support only a single FPU context. */
6958 if (h == 0) {
a7812ae4 6959 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6960
6961 gen_load_fpr32(fp0, rt);
6962 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6963 tcg_temp_free_i32(fp0);
ead9360e 6964 } else {
a7812ae4 6965 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 6966
7f6613ce 6967 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 6968 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6969 tcg_temp_free_i32(fp0);
ead9360e
TS
6970 }
6971 break;
6972 case 3:
6973 /* XXX: For now we support only a single FPU context. */
895c2d04 6974 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6975 break;
6976 /* COP2: Not implemented. */
6977 case 4:
6978 case 5:
6979 /* fall through */
6980 default:
6981 goto die;
6982 }
d12d51d5 6983 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6984 gen_store_gpr(t0, rd);
6985 tcg_temp_free(t0);
ead9360e
TS
6986 return;
6987
6988die:
1a3fd9c3 6989 tcg_temp_free(t0);
d12d51d5 6990 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6991 generate_exception(ctx, EXCP_RI);
6992}
6993
7db13fae 6994static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6995 int u, int sel, int h)
6996{
6997 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6998 TCGv t0 = tcg_temp_local_new();
ead9360e 6999
1a3fd9c3 7000 gen_load_gpr(t0, rt);
ead9360e 7001 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7002 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7003 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7004 /* NOP */ ;
7005 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7006 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7007 /* NOP */ ;
7008 else if (u == 0) {
7009 switch (rd) {
5a25ce94
EI
7010 case 1:
7011 switch (sel) {
7012 case 1:
895c2d04 7013 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7014 break;
7015 case 2:
895c2d04 7016 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7017 break;
7018 default:
7019 goto die;
7020 break;
7021 }
7022 break;
ead9360e
TS
7023 case 2:
7024 switch (sel) {
7025 case 1:
895c2d04 7026 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7027 break;
7028 case 2:
895c2d04 7029 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7030 break;
7031 case 3:
895c2d04 7032 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7033 break;
7034 case 4:
895c2d04 7035 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7036 break;
7037 case 5:
895c2d04 7038 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
7039 break;
7040 case 6:
895c2d04 7041 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
7042 break;
7043 case 7:
895c2d04 7044 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
7045 break;
7046 default:
d75c135e 7047 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7048 break;
7049 }
7050 break;
7051 case 10:
7052 switch (sel) {
7053 case 0:
895c2d04 7054 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
7055 break;
7056 default:
d75c135e 7057 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7058 break;
7059 }
7060 case 12:
7061 switch (sel) {
7062 case 0:
895c2d04 7063 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
7064 break;
7065 default:
d75c135e 7066 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7067 break;
7068 }
5a25ce94
EI
7069 case 13:
7070 switch (sel) {
7071 case 0:
895c2d04 7072 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
7073 break;
7074 default:
7075 goto die;
7076 break;
7077 }
7078 break;
7079 case 15:
7080 switch (sel) {
7081 case 1:
895c2d04 7082 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
7083 break;
7084 default:
7085 goto die;
7086 break;
7087 }
7088 break;
ead9360e
TS
7089 case 23:
7090 switch (sel) {
7091 case 0:
895c2d04 7092 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
7093 break;
7094 default:
d75c135e 7095 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7096 break;
7097 }
7098 break;
7099 default:
d75c135e 7100 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
7101 }
7102 } else switch (sel) {
7103 /* GPR registers. */
7104 case 0:
895c2d04 7105 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
7106 break;
7107 /* Auxiliary CPU registers */
7108 case 1:
7109 switch (rd) {
7110 case 0:
895c2d04 7111 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
7112 break;
7113 case 1:
895c2d04 7114 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
7115 break;
7116 case 2:
895c2d04 7117 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
7118 break;
7119 case 4:
895c2d04 7120 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
7121 break;
7122 case 5:
895c2d04 7123 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
7124 break;
7125 case 6:
895c2d04 7126 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
7127 break;
7128 case 8:
895c2d04 7129 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
7130 break;
7131 case 9:
895c2d04 7132 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
7133 break;
7134 case 10:
895c2d04 7135 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
7136 break;
7137 case 12:
895c2d04 7138 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
7139 break;
7140 case 13:
895c2d04 7141 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
7142 break;
7143 case 14:
895c2d04 7144 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
7145 break;
7146 case 16:
895c2d04 7147 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
7148 break;
7149 default:
7150 goto die;
7151 }
7152 break;
7153 /* Floating point (COP1). */
7154 case 2:
7155 /* XXX: For now we support only a single FPU context. */
7156 if (h == 0) {
a7812ae4 7157 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7158
7159 tcg_gen_trunc_tl_i32(fp0, t0);
7160 gen_store_fpr32(fp0, rd);
a7812ae4 7161 tcg_temp_free_i32(fp0);
ead9360e 7162 } else {
a7812ae4 7163 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7164
7165 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7166 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 7167 tcg_temp_free_i32(fp0);
ead9360e
TS
7168 }
7169 break;
7170 case 3:
7171 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
7172 {
7173 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7174
7175 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7176 tcg_temp_free_i32(fs_tmp);
7177 }
ead9360e
TS
7178 break;
7179 /* COP2: Not implemented. */
7180 case 4:
7181 case 5:
7182 /* fall through */
7183 default:
7184 goto die;
7185 }
d12d51d5 7186 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 7187 tcg_temp_free(t0);
ead9360e
TS
7188 return;
7189
7190die:
1a3fd9c3 7191 tcg_temp_free(t0);
d12d51d5 7192 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
7193 generate_exception(ctx, EXCP_RI);
7194}
7195
7db13fae 7196static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 7197{
287c4b84 7198 const char *opn = "ldst";
6af0bf9c 7199
2e15497c 7200 check_cp0_enabled(ctx);
6af0bf9c
FB
7201 switch (opc) {
7202 case OPC_MFC0:
7203 if (rt == 0) {
ead9360e 7204 /* Treat as NOP. */
6af0bf9c
FB
7205 return;
7206 }
d75c135e 7207 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
7208 opn = "mfc0";
7209 break;
7210 case OPC_MTC0:
1a3fd9c3 7211 {
1fc7bf6e 7212 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7213
7214 gen_load_gpr(t0, rt);
d75c135e 7215 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7216 tcg_temp_free(t0);
7217 }
6af0bf9c
FB
7218 opn = "mtc0";
7219 break;
d26bc211 7220#if defined(TARGET_MIPS64)
9c2149c8 7221 case OPC_DMFC0:
d75c135e 7222 check_insn(ctx, ISA_MIPS3);
9c2149c8 7223 if (rt == 0) {
ead9360e 7224 /* Treat as NOP. */
9c2149c8
TS
7225 return;
7226 }
d75c135e 7227 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
7228 opn = "dmfc0";
7229 break;
7230 case OPC_DMTC0:
d75c135e 7231 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 7232 {
1fc7bf6e 7233 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
7234
7235 gen_load_gpr(t0, rt);
d75c135e 7236 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
7237 tcg_temp_free(t0);
7238 }
9c2149c8
TS
7239 opn = "dmtc0";
7240 break;
534ce69f 7241#endif
ead9360e 7242 case OPC_MFTR:
d75c135e 7243 check_insn(ctx, ASE_MT);
ead9360e
TS
7244 if (rd == 0) {
7245 /* Treat as NOP. */
7246 return;
7247 }
6c5c1e20 7248 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 7249 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
7250 opn = "mftr";
7251 break;
7252 case OPC_MTTR:
d75c135e 7253 check_insn(ctx, ASE_MT);
6c5c1e20 7254 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
7255 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7256 opn = "mttr";
7257 break;
6af0bf9c 7258 case OPC_TLBWI:
6af0bf9c 7259 opn = "tlbwi";
c01fccd2 7260 if (!env->tlb->helper_tlbwi)
29929e34 7261 goto die;
895c2d04 7262 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
7263 break;
7264 case OPC_TLBWR:
6af0bf9c 7265 opn = "tlbwr";
c01fccd2 7266 if (!env->tlb->helper_tlbwr)
29929e34 7267 goto die;
895c2d04 7268 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
7269 break;
7270 case OPC_TLBP:
6af0bf9c 7271 opn = "tlbp";
c01fccd2 7272 if (!env->tlb->helper_tlbp)
29929e34 7273 goto die;
895c2d04 7274 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
7275 break;
7276 case OPC_TLBR:
6af0bf9c 7277 opn = "tlbr";
c01fccd2 7278 if (!env->tlb->helper_tlbr)
29929e34 7279 goto die;
895c2d04 7280 gen_helper_tlbr(cpu_env);
6af0bf9c 7281 break;
6af0bf9c
FB
7282 case OPC_ERET:
7283 opn = "eret";
d75c135e 7284 check_insn(ctx, ISA_MIPS2);
895c2d04 7285 gen_helper_eret(cpu_env);
6af0bf9c
FB
7286 ctx->bstate = BS_EXCP;
7287 break;
7288 case OPC_DERET:
7289 opn = "deret";
d75c135e 7290 check_insn(ctx, ISA_MIPS32);
6af0bf9c 7291 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 7292 MIPS_INVAL(opn);
6af0bf9c
FB
7293 generate_exception(ctx, EXCP_RI);
7294 } else {
895c2d04 7295 gen_helper_deret(cpu_env);
6af0bf9c
FB
7296 ctx->bstate = BS_EXCP;
7297 }
7298 break;
4ad40f36
FB
7299 case OPC_WAIT:
7300 opn = "wait";
d75c135e 7301 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
7302 /* If we get an exception, we want to restart at next instruction */
7303 ctx->pc += 4;
7304 save_cpu_state(ctx, 1);
7305 ctx->pc -= 4;
895c2d04 7306 gen_helper_wait(cpu_env);
4ad40f36
FB
7307 ctx->bstate = BS_EXCP;
7308 break;
6af0bf9c 7309 default:
29929e34 7310 die:
923617a3 7311 MIPS_INVAL(opn);
6af0bf9c
FB
7312 generate_exception(ctx, EXCP_RI);
7313 return;
7314 }
2abf314d 7315 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
7316 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7317}
f1aa6320 7318#endif /* !CONFIG_USER_ONLY */
6af0bf9c 7319
6ea83fed 7320/* CP1 Branches (before delay slot) */
d75c135e
AJ
7321static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7322 int32_t cc, int32_t offset)
6ea83fed
FB
7323{
7324 target_ulong btarget;
923617a3 7325 const char *opn = "cp1 cond branch";
a7812ae4 7326 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 7327
e189e748 7328 if (cc != 0)
d75c135e 7329 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 7330
6ea83fed
FB
7331 btarget = ctx->pc + 4 + offset;
7332
7a387fff
TS
7333 switch (op) {
7334 case OPC_BC1F:
d94536f4
AJ
7335 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7336 tcg_gen_not_i32(t0, t0);
7337 tcg_gen_andi_i32(t0, t0, 1);
7338 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7339 opn = "bc1f";
6ea83fed 7340 goto not_likely;
7a387fff 7341 case OPC_BC1FL:
d94536f4
AJ
7342 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7343 tcg_gen_not_i32(t0, t0);
7344 tcg_gen_andi_i32(t0, t0, 1);
7345 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7346 opn = "bc1fl";
6ea83fed 7347 goto likely;
7a387fff 7348 case OPC_BC1T:
d94536f4
AJ
7349 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7350 tcg_gen_andi_i32(t0, t0, 1);
7351 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7352 opn = "bc1t";
5a5012ec 7353 goto not_likely;
7a387fff 7354 case OPC_BC1TL:
d94536f4
AJ
7355 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7356 tcg_gen_andi_i32(t0, t0, 1);
7357 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7358 opn = "bc1tl";
6ea83fed
FB
7359 likely:
7360 ctx->hflags |= MIPS_HFLAG_BL;
7361 break;
5a5012ec 7362 case OPC_BC1FANY2:
a16336e4 7363 {
d94536f4
AJ
7364 TCGv_i32 t1 = tcg_temp_new_i32();
7365 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7366 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7367 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7368 tcg_temp_free_i32(t1);
d94536f4
AJ
7369 tcg_gen_andi_i32(t0, t0, 1);
7370 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7371 }
fd4a04eb 7372 opn = "bc1any2f";
5a5012ec
TS
7373 goto not_likely;
7374 case OPC_BC1TANY2:
a16336e4 7375 {
d94536f4
AJ
7376 TCGv_i32 t1 = tcg_temp_new_i32();
7377 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7378 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7379 tcg_gen_or_i32(t0, t0, t1);
7380 tcg_temp_free_i32(t1);
7381 tcg_gen_andi_i32(t0, t0, 1);
7382 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7383 }
fd4a04eb 7384 opn = "bc1any2t";
5a5012ec
TS
7385 goto not_likely;
7386 case OPC_BC1FANY4:
a16336e4 7387 {
d94536f4
AJ
7388 TCGv_i32 t1 = tcg_temp_new_i32();
7389 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7390 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7391 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7392 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7393 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7394 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7395 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7396 tcg_temp_free_i32(t1);
d94536f4
AJ
7397 tcg_gen_andi_i32(t0, t0, 1);
7398 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7399 }
fd4a04eb 7400 opn = "bc1any4f";
5a5012ec
TS
7401 goto not_likely;
7402 case OPC_BC1TANY4:
a16336e4 7403 {
d94536f4
AJ
7404 TCGv_i32 t1 = tcg_temp_new_i32();
7405 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7406 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7407 tcg_gen_or_i32(t0, t0, t1);
7408 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7409 tcg_gen_or_i32(t0, t0, t1);
7410 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7411 tcg_gen_or_i32(t0, t0, t1);
7412 tcg_temp_free_i32(t1);
7413 tcg_gen_andi_i32(t0, t0, 1);
7414 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7415 }
fd4a04eb 7416 opn = "bc1any4t";
5a5012ec
TS
7417 not_likely:
7418 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7419 break;
7420 default:
923617a3 7421 MIPS_INVAL(opn);
e397ee33 7422 generate_exception (ctx, EXCP_RI);
6c5c1e20 7423 goto out;
6ea83fed 7424 }
2abf314d 7425 (void)opn; /* avoid a compiler warning */
923617a3 7426 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7427 ctx->hflags, btarget);
7428 ctx->btarget = btarget;
6c5c1e20
TS
7429
7430 out:
a7812ae4 7431 tcg_temp_free_i32(t0);
6ea83fed
FB
7432}
7433
6af0bf9c 7434/* Coprocessor 1 (FPU) */
5a5012ec 7435
5a5012ec
TS
7436#define FOP(func, fmt) (((fmt) << 21) | (func))
7437
bf4120ad
NF
7438enum fopcode {
7439 OPC_ADD_S = FOP(0, FMT_S),
7440 OPC_SUB_S = FOP(1, FMT_S),
7441 OPC_MUL_S = FOP(2, FMT_S),
7442 OPC_DIV_S = FOP(3, FMT_S),
7443 OPC_SQRT_S = FOP(4, FMT_S),
7444 OPC_ABS_S = FOP(5, FMT_S),
7445 OPC_MOV_S = FOP(6, FMT_S),
7446 OPC_NEG_S = FOP(7, FMT_S),
7447 OPC_ROUND_L_S = FOP(8, FMT_S),
7448 OPC_TRUNC_L_S = FOP(9, FMT_S),
7449 OPC_CEIL_L_S = FOP(10, FMT_S),
7450 OPC_FLOOR_L_S = FOP(11, FMT_S),
7451 OPC_ROUND_W_S = FOP(12, FMT_S),
7452 OPC_TRUNC_W_S = FOP(13, FMT_S),
7453 OPC_CEIL_W_S = FOP(14, FMT_S),
7454 OPC_FLOOR_W_S = FOP(15, FMT_S),
7455 OPC_MOVCF_S = FOP(17, FMT_S),
7456 OPC_MOVZ_S = FOP(18, FMT_S),
7457 OPC_MOVN_S = FOP(19, FMT_S),
7458 OPC_RECIP_S = FOP(21, FMT_S),
7459 OPC_RSQRT_S = FOP(22, FMT_S),
7460 OPC_RECIP2_S = FOP(28, FMT_S),
7461 OPC_RECIP1_S = FOP(29, FMT_S),
7462 OPC_RSQRT1_S = FOP(30, FMT_S),
7463 OPC_RSQRT2_S = FOP(31, FMT_S),
7464 OPC_CVT_D_S = FOP(33, FMT_S),
7465 OPC_CVT_W_S = FOP(36, FMT_S),
7466 OPC_CVT_L_S = FOP(37, FMT_S),
7467 OPC_CVT_PS_S = FOP(38, FMT_S),
7468 OPC_CMP_F_S = FOP (48, FMT_S),
7469 OPC_CMP_UN_S = FOP (49, FMT_S),
7470 OPC_CMP_EQ_S = FOP (50, FMT_S),
7471 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7472 OPC_CMP_OLT_S = FOP (52, FMT_S),
7473 OPC_CMP_ULT_S = FOP (53, FMT_S),
7474 OPC_CMP_OLE_S = FOP (54, FMT_S),
7475 OPC_CMP_ULE_S = FOP (55, FMT_S),
7476 OPC_CMP_SF_S = FOP (56, FMT_S),
7477 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7478 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7479 OPC_CMP_NGL_S = FOP (59, FMT_S),
7480 OPC_CMP_LT_S = FOP (60, FMT_S),
7481 OPC_CMP_NGE_S = FOP (61, FMT_S),
7482 OPC_CMP_LE_S = FOP (62, FMT_S),
7483 OPC_CMP_NGT_S = FOP (63, FMT_S),
7484
7485 OPC_ADD_D = FOP(0, FMT_D),
7486 OPC_SUB_D = FOP(1, FMT_D),
7487 OPC_MUL_D = FOP(2, FMT_D),
7488 OPC_DIV_D = FOP(3, FMT_D),
7489 OPC_SQRT_D = FOP(4, FMT_D),
7490 OPC_ABS_D = FOP(5, FMT_D),
7491 OPC_MOV_D = FOP(6, FMT_D),
7492 OPC_NEG_D = FOP(7, FMT_D),
7493 OPC_ROUND_L_D = FOP(8, FMT_D),
7494 OPC_TRUNC_L_D = FOP(9, FMT_D),
7495 OPC_CEIL_L_D = FOP(10, FMT_D),
7496 OPC_FLOOR_L_D = FOP(11, FMT_D),
7497 OPC_ROUND_W_D = FOP(12, FMT_D),
7498 OPC_TRUNC_W_D = FOP(13, FMT_D),
7499 OPC_CEIL_W_D = FOP(14, FMT_D),
7500 OPC_FLOOR_W_D = FOP(15, FMT_D),
7501 OPC_MOVCF_D = FOP(17, FMT_D),
7502 OPC_MOVZ_D = FOP(18, FMT_D),
7503 OPC_MOVN_D = FOP(19, FMT_D),
7504 OPC_RECIP_D = FOP(21, FMT_D),
7505 OPC_RSQRT_D = FOP(22, FMT_D),
7506 OPC_RECIP2_D = FOP(28, FMT_D),
7507 OPC_RECIP1_D = FOP(29, FMT_D),
7508 OPC_RSQRT1_D = FOP(30, FMT_D),
7509 OPC_RSQRT2_D = FOP(31, FMT_D),
7510 OPC_CVT_S_D = FOP(32, FMT_D),
7511 OPC_CVT_W_D = FOP(36, FMT_D),
7512 OPC_CVT_L_D = FOP(37, FMT_D),
7513 OPC_CMP_F_D = FOP (48, FMT_D),
7514 OPC_CMP_UN_D = FOP (49, FMT_D),
7515 OPC_CMP_EQ_D = FOP (50, FMT_D),
7516 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7517 OPC_CMP_OLT_D = FOP (52, FMT_D),
7518 OPC_CMP_ULT_D = FOP (53, FMT_D),
7519 OPC_CMP_OLE_D = FOP (54, FMT_D),
7520 OPC_CMP_ULE_D = FOP (55, FMT_D),
7521 OPC_CMP_SF_D = FOP (56, FMT_D),
7522 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7523 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7524 OPC_CMP_NGL_D = FOP (59, FMT_D),
7525 OPC_CMP_LT_D = FOP (60, FMT_D),
7526 OPC_CMP_NGE_D = FOP (61, FMT_D),
7527 OPC_CMP_LE_D = FOP (62, FMT_D),
7528 OPC_CMP_NGT_D = FOP (63, FMT_D),
7529
7530 OPC_CVT_S_W = FOP(32, FMT_W),
7531 OPC_CVT_D_W = FOP(33, FMT_W),
7532 OPC_CVT_S_L = FOP(32, FMT_L),
7533 OPC_CVT_D_L = FOP(33, FMT_L),
7534 OPC_CVT_PS_PW = FOP(38, FMT_W),
7535
7536 OPC_ADD_PS = FOP(0, FMT_PS),
7537 OPC_SUB_PS = FOP(1, FMT_PS),
7538 OPC_MUL_PS = FOP(2, FMT_PS),
7539 OPC_DIV_PS = FOP(3, FMT_PS),
7540 OPC_ABS_PS = FOP(5, FMT_PS),
7541 OPC_MOV_PS = FOP(6, FMT_PS),
7542 OPC_NEG_PS = FOP(7, FMT_PS),
7543 OPC_MOVCF_PS = FOP(17, FMT_PS),
7544 OPC_MOVZ_PS = FOP(18, FMT_PS),
7545 OPC_MOVN_PS = FOP(19, FMT_PS),
7546 OPC_ADDR_PS = FOP(24, FMT_PS),
7547 OPC_MULR_PS = FOP(26, FMT_PS),
7548 OPC_RECIP2_PS = FOP(28, FMT_PS),
7549 OPC_RECIP1_PS = FOP(29, FMT_PS),
7550 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7551 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7552
7553 OPC_CVT_S_PU = FOP(32, FMT_PS),
7554 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7555 OPC_CVT_S_PL = FOP(40, FMT_PS),
7556 OPC_PLL_PS = FOP(44, FMT_PS),
7557 OPC_PLU_PS = FOP(45, FMT_PS),
7558 OPC_PUL_PS = FOP(46, FMT_PS),
7559 OPC_PUU_PS = FOP(47, FMT_PS),
7560 OPC_CMP_F_PS = FOP (48, FMT_PS),
7561 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7562 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7563 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7564 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7565 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7566 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7567 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7568 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7569 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7570 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7571 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7572 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7573 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7574 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7575 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7576};
7577
7a387fff 7578static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7579{
923617a3 7580 const char *opn = "cp1 move";
72c3a3ee 7581 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7582
7583 switch (opc) {
7584 case OPC_MFC1:
b6d96bed 7585 {
a7812ae4 7586 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7587
7588 gen_load_fpr32(fp0, fs);
7589 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7590 tcg_temp_free_i32(fp0);
6958549d 7591 }
6c5c1e20 7592 gen_store_gpr(t0, rt);
6ea83fed
FB
7593 opn = "mfc1";
7594 break;
7595 case OPC_MTC1:
6c5c1e20 7596 gen_load_gpr(t0, rt);
b6d96bed 7597 {
a7812ae4 7598 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7599
7600 tcg_gen_trunc_tl_i32(fp0, t0);
7601 gen_store_fpr32(fp0, fs);
a7812ae4 7602 tcg_temp_free_i32(fp0);
6958549d 7603 }
6ea83fed
FB
7604 opn = "mtc1";
7605 break;
7606 case OPC_CFC1:
895c2d04 7607 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7608 gen_store_gpr(t0, rt);
6ea83fed
FB
7609 opn = "cfc1";
7610 break;
7611 case OPC_CTC1:
6c5c1e20 7612 gen_load_gpr(t0, rt);
736d120a
PJ
7613 {
7614 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7615
7616 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7617 tcg_temp_free_i32(fs_tmp);
7618 }
6ea83fed
FB
7619 opn = "ctc1";
7620 break;
72c3a3ee 7621#if defined(TARGET_MIPS64)
9c2149c8 7622 case OPC_DMFC1:
72c3a3ee 7623 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7624 gen_store_gpr(t0, rt);
5a5012ec
TS
7625 opn = "dmfc1";
7626 break;
9c2149c8 7627 case OPC_DMTC1:
6c5c1e20 7628 gen_load_gpr(t0, rt);
72c3a3ee 7629 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7630 opn = "dmtc1";
7631 break;
72c3a3ee 7632#endif
5a5012ec 7633 case OPC_MFHC1:
b6d96bed 7634 {
a7812ae4 7635 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7636
7f6613ce 7637 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 7638 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7639 tcg_temp_free_i32(fp0);
6958549d 7640 }
6c5c1e20 7641 gen_store_gpr(t0, rt);
5a5012ec
TS
7642 opn = "mfhc1";
7643 break;
7644 case OPC_MTHC1:
6c5c1e20 7645 gen_load_gpr(t0, rt);
b6d96bed 7646 {
a7812ae4 7647 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7648
7649 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 7650 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 7651 tcg_temp_free_i32(fp0);
6958549d 7652 }
5a5012ec
TS
7653 opn = "mthc1";
7654 break;
6ea83fed 7655 default:
923617a3 7656 MIPS_INVAL(opn);
e397ee33 7657 generate_exception (ctx, EXCP_RI);
6c5c1e20 7658 goto out;
6ea83fed 7659 }
2abf314d 7660 (void)opn; /* avoid a compiler warning */
6ea83fed 7661 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7662
7663 out:
7664 tcg_temp_free(t0);
6ea83fed
FB
7665}
7666
5a5012ec
TS
7667static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7668{
af58f9ca 7669 int l1;
e214b9bb 7670 TCGCond cond;
af58f9ca
AJ
7671 TCGv_i32 t0;
7672
7673 if (rd == 0) {
7674 /* Treat as NOP. */
7675 return;
7676 }
6ea83fed 7677
e214b9bb 7678 if (tf)
e214b9bb 7679 cond = TCG_COND_EQ;
27848470
TS
7680 else
7681 cond = TCG_COND_NE;
7682
af58f9ca
AJ
7683 l1 = gen_new_label();
7684 t0 = tcg_temp_new_i32();
fa31af0e 7685 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7686 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7687 tcg_temp_free_i32(t0);
af58f9ca
AJ
7688 if (rs == 0) {
7689 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7690 } else {
7691 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7692 }
e214b9bb 7693 gen_set_label(l1);
5a5012ec
TS
7694}
7695
b6d96bed 7696static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7697{
a16336e4 7698 int cond;
cbc37b28 7699 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7700 int l1 = gen_new_label();
7701
a16336e4
TS
7702 if (tf)
7703 cond = TCG_COND_EQ;
7704 else
7705 cond = TCG_COND_NE;
7706
fa31af0e 7707 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7708 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7709 gen_load_fpr32(t0, fs);
7710 gen_store_fpr32(t0, fd);
a16336e4 7711 gen_set_label(l1);
cbc37b28 7712 tcg_temp_free_i32(t0);
5a5012ec 7713}
a16336e4 7714
b6d96bed 7715static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7716{
a16336e4 7717 int cond;
cbc37b28
AJ
7718 TCGv_i32 t0 = tcg_temp_new_i32();
7719 TCGv_i64 fp0;
a16336e4
TS
7720 int l1 = gen_new_label();
7721
a16336e4
TS
7722 if (tf)
7723 cond = TCG_COND_EQ;
7724 else
7725 cond = TCG_COND_NE;
7726
fa31af0e 7727 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7728 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7729 tcg_temp_free_i32(t0);
11f94258 7730 fp0 = tcg_temp_new_i64();
9bf3eb2c 7731 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7732 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7733 tcg_temp_free_i64(fp0);
cbc37b28 7734 gen_set_label(l1);
a16336e4
TS
7735}
7736
7f6613ce
PJ
7737static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7738 int cc, int tf)
a16336e4
TS
7739{
7740 int cond;
cbc37b28 7741 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7742 int l1 = gen_new_label();
7743 int l2 = gen_new_label();
7744
7745 if (tf)
7746 cond = TCG_COND_EQ;
7747 else
7748 cond = TCG_COND_NE;
7749
fa31af0e 7750 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7751 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7752 gen_load_fpr32(t0, fs);
7753 gen_store_fpr32(t0, fd);
a16336e4 7754 gen_set_label(l1);
9bf3eb2c 7755
fa31af0e 7756 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 7757 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
7758 gen_load_fpr32h(ctx, t0, fs);
7759 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 7760 tcg_temp_free_i32(t0);
a16336e4 7761 gen_set_label(l2);
a16336e4
TS
7762}
7763
6ea83fed 7764
bf4120ad 7765static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7766 int ft, int fs, int fd, int cc)
6ea83fed 7767{
923617a3 7768 const char *opn = "farith";
6ea83fed
FB
7769 const char *condnames[] = {
7770 "c.f",
7771 "c.un",
7772 "c.eq",
7773 "c.ueq",
7774 "c.olt",
7775 "c.ult",
7776 "c.ole",
7777 "c.ule",
7778 "c.sf",
7779 "c.ngle",
7780 "c.seq",
7781 "c.ngl",
7782 "c.lt",
7783 "c.nge",
7784 "c.le",
7785 "c.ngt",
7786 };
5a1e8ffb
TS
7787 const char *condnames_abs[] = {
7788 "cabs.f",
7789 "cabs.un",
7790 "cabs.eq",
7791 "cabs.ueq",
7792 "cabs.olt",
7793 "cabs.ult",
7794 "cabs.ole",
7795 "cabs.ule",
7796 "cabs.sf",
7797 "cabs.ngle",
7798 "cabs.seq",
7799 "cabs.ngl",
7800 "cabs.lt",
7801 "cabs.nge",
7802 "cabs.le",
7803 "cabs.ngt",
7804 };
7805 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7806 uint32_t func = ctx->opcode & 0x3f;
7807
bf4120ad
NF
7808 switch (op1) {
7809 case OPC_ADD_S:
b6d96bed 7810 {
a7812ae4
PB
7811 TCGv_i32 fp0 = tcg_temp_new_i32();
7812 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7813
7814 gen_load_fpr32(fp0, fs);
7815 gen_load_fpr32(fp1, ft);
895c2d04 7816 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7817 tcg_temp_free_i32(fp1);
b6d96bed 7818 gen_store_fpr32(fp0, fd);
a7812ae4 7819 tcg_temp_free_i32(fp0);
b6d96bed 7820 }
5a5012ec 7821 opn = "add.s";
5a1e8ffb 7822 optype = BINOP;
5a5012ec 7823 break;
bf4120ad 7824 case OPC_SUB_S:
b6d96bed 7825 {
a7812ae4
PB
7826 TCGv_i32 fp0 = tcg_temp_new_i32();
7827 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7828
7829 gen_load_fpr32(fp0, fs);
7830 gen_load_fpr32(fp1, ft);
895c2d04 7831 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7832 tcg_temp_free_i32(fp1);
b6d96bed 7833 gen_store_fpr32(fp0, fd);
a7812ae4 7834 tcg_temp_free_i32(fp0);
b6d96bed 7835 }
5a5012ec 7836 opn = "sub.s";
5a1e8ffb 7837 optype = BINOP;
5a5012ec 7838 break;
bf4120ad 7839 case OPC_MUL_S:
b6d96bed 7840 {
a7812ae4
PB
7841 TCGv_i32 fp0 = tcg_temp_new_i32();
7842 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7843
7844 gen_load_fpr32(fp0, fs);
7845 gen_load_fpr32(fp1, ft);
895c2d04 7846 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7847 tcg_temp_free_i32(fp1);
b6d96bed 7848 gen_store_fpr32(fp0, fd);
a7812ae4 7849 tcg_temp_free_i32(fp0);
b6d96bed 7850 }
5a5012ec 7851 opn = "mul.s";
5a1e8ffb 7852 optype = BINOP;
5a5012ec 7853 break;
bf4120ad 7854 case OPC_DIV_S:
b6d96bed 7855 {
a7812ae4
PB
7856 TCGv_i32 fp0 = tcg_temp_new_i32();
7857 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7858
7859 gen_load_fpr32(fp0, fs);
7860 gen_load_fpr32(fp1, ft);
895c2d04 7861 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7862 tcg_temp_free_i32(fp1);
b6d96bed 7863 gen_store_fpr32(fp0, fd);
a7812ae4 7864 tcg_temp_free_i32(fp0);
b6d96bed 7865 }
5a5012ec 7866 opn = "div.s";
5a1e8ffb 7867 optype = BINOP;
5a5012ec 7868 break;
bf4120ad 7869 case OPC_SQRT_S:
b6d96bed 7870 {
a7812ae4 7871 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7872
7873 gen_load_fpr32(fp0, fs);
895c2d04 7874 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7875 gen_store_fpr32(fp0, fd);
a7812ae4 7876 tcg_temp_free_i32(fp0);
b6d96bed 7877 }
5a5012ec
TS
7878 opn = "sqrt.s";
7879 break;
bf4120ad 7880 case OPC_ABS_S:
b6d96bed 7881 {
a7812ae4 7882 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7883
7884 gen_load_fpr32(fp0, fs);
a7812ae4 7885 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7886 gen_store_fpr32(fp0, fd);
a7812ae4 7887 tcg_temp_free_i32(fp0);
b6d96bed 7888 }
5a5012ec
TS
7889 opn = "abs.s";
7890 break;
bf4120ad 7891 case OPC_MOV_S:
b6d96bed 7892 {
a7812ae4 7893 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7894
7895 gen_load_fpr32(fp0, fs);
7896 gen_store_fpr32(fp0, fd);
a7812ae4 7897 tcg_temp_free_i32(fp0);
b6d96bed 7898 }
5a5012ec
TS
7899 opn = "mov.s";
7900 break;
bf4120ad 7901 case OPC_NEG_S:
b6d96bed 7902 {
a7812ae4 7903 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7904
7905 gen_load_fpr32(fp0, fs);
a7812ae4 7906 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7907 gen_store_fpr32(fp0, fd);
a7812ae4 7908 tcg_temp_free_i32(fp0);
b6d96bed 7909 }
5a5012ec
TS
7910 opn = "neg.s";
7911 break;
bf4120ad 7912 case OPC_ROUND_L_S:
5e755519 7913 check_cp1_64bitmode(ctx);
b6d96bed 7914 {
a7812ae4
PB
7915 TCGv_i32 fp32 = tcg_temp_new_i32();
7916 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7917
7918 gen_load_fpr32(fp32, fs);
895c2d04 7919 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7920 tcg_temp_free_i32(fp32);
b6d96bed 7921 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7922 tcg_temp_free_i64(fp64);
b6d96bed 7923 }
5a5012ec
TS
7924 opn = "round.l.s";
7925 break;
bf4120ad 7926 case OPC_TRUNC_L_S:
5e755519 7927 check_cp1_64bitmode(ctx);
b6d96bed 7928 {
a7812ae4
PB
7929 TCGv_i32 fp32 = tcg_temp_new_i32();
7930 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7931
7932 gen_load_fpr32(fp32, fs);
895c2d04 7933 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7934 tcg_temp_free_i32(fp32);
b6d96bed 7935 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7936 tcg_temp_free_i64(fp64);
b6d96bed 7937 }
5a5012ec
TS
7938 opn = "trunc.l.s";
7939 break;
bf4120ad 7940 case OPC_CEIL_L_S:
5e755519 7941 check_cp1_64bitmode(ctx);
b6d96bed 7942 {
a7812ae4
PB
7943 TCGv_i32 fp32 = tcg_temp_new_i32();
7944 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7945
7946 gen_load_fpr32(fp32, fs);
895c2d04 7947 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7948 tcg_temp_free_i32(fp32);
b6d96bed 7949 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7950 tcg_temp_free_i64(fp64);
b6d96bed 7951 }
5a5012ec
TS
7952 opn = "ceil.l.s";
7953 break;
bf4120ad 7954 case OPC_FLOOR_L_S:
5e755519 7955 check_cp1_64bitmode(ctx);
b6d96bed 7956 {
a7812ae4
PB
7957 TCGv_i32 fp32 = tcg_temp_new_i32();
7958 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7959
7960 gen_load_fpr32(fp32, fs);
895c2d04 7961 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7962 tcg_temp_free_i32(fp32);
b6d96bed 7963 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7964 tcg_temp_free_i64(fp64);
b6d96bed 7965 }
5a5012ec
TS
7966 opn = "floor.l.s";
7967 break;
bf4120ad 7968 case OPC_ROUND_W_S:
b6d96bed 7969 {
a7812ae4 7970 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7971
7972 gen_load_fpr32(fp0, fs);
895c2d04 7973 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7974 gen_store_fpr32(fp0, fd);
a7812ae4 7975 tcg_temp_free_i32(fp0);
b6d96bed 7976 }
5a5012ec
TS
7977 opn = "round.w.s";
7978 break;
bf4120ad 7979 case OPC_TRUNC_W_S:
b6d96bed 7980 {
a7812ae4 7981 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7982
7983 gen_load_fpr32(fp0, fs);
895c2d04 7984 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7985 gen_store_fpr32(fp0, fd);
a7812ae4 7986 tcg_temp_free_i32(fp0);
b6d96bed 7987 }
5a5012ec
TS
7988 opn = "trunc.w.s";
7989 break;
bf4120ad 7990 case OPC_CEIL_W_S:
b6d96bed 7991 {
a7812ae4 7992 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7993
7994 gen_load_fpr32(fp0, fs);
895c2d04 7995 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7996 gen_store_fpr32(fp0, fd);
a7812ae4 7997 tcg_temp_free_i32(fp0);
b6d96bed 7998 }
5a5012ec
TS
7999 opn = "ceil.w.s";
8000 break;
bf4120ad 8001 case OPC_FLOOR_W_S:
b6d96bed 8002 {
a7812ae4 8003 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8004
8005 gen_load_fpr32(fp0, fs);
895c2d04 8006 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 8007 gen_store_fpr32(fp0, fd);
a7812ae4 8008 tcg_temp_free_i32(fp0);
b6d96bed 8009 }
5a5012ec
TS
8010 opn = "floor.w.s";
8011 break;
bf4120ad 8012 case OPC_MOVCF_S:
fecd2646 8013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8014 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
8015 opn = "movcf.s";
8016 break;
bf4120ad 8017 case OPC_MOVZ_S:
fecd2646 8018 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8019 {
8020 int l1 = gen_new_label();
c9297f4d 8021 TCGv_i32 fp0;
a16336e4 8022
c9297f4d
AJ
8023 if (ft != 0) {
8024 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8025 }
8026 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8027 gen_load_fpr32(fp0, fs);
8028 gen_store_fpr32(fp0, fd);
a7812ae4 8029 tcg_temp_free_i32(fp0);
a16336e4
TS
8030 gen_set_label(l1);
8031 }
5a5012ec
TS
8032 opn = "movz.s";
8033 break;
bf4120ad 8034 case OPC_MOVN_S:
fecd2646 8035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8036 {
8037 int l1 = gen_new_label();
c9297f4d
AJ
8038 TCGv_i32 fp0;
8039
8040 if (ft != 0) {
8041 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8042 fp0 = tcg_temp_new_i32();
8043 gen_load_fpr32(fp0, fs);
8044 gen_store_fpr32(fp0, fd);
8045 tcg_temp_free_i32(fp0);
8046 gen_set_label(l1);
8047 }
a16336e4 8048 }
5a5012ec
TS
8049 opn = "movn.s";
8050 break;
bf4120ad 8051 case OPC_RECIP_S:
b8aa4598 8052 check_cop1x(ctx);
b6d96bed 8053 {
a7812ae4 8054 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8055
8056 gen_load_fpr32(fp0, fs);
895c2d04 8057 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 8058 gen_store_fpr32(fp0, fd);
a7812ae4 8059 tcg_temp_free_i32(fp0);
b6d96bed 8060 }
57fa1fb3
TS
8061 opn = "recip.s";
8062 break;
bf4120ad 8063 case OPC_RSQRT_S:
b8aa4598 8064 check_cop1x(ctx);
b6d96bed 8065 {
a7812ae4 8066 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8067
8068 gen_load_fpr32(fp0, fs);
895c2d04 8069 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 8070 gen_store_fpr32(fp0, fd);
a7812ae4 8071 tcg_temp_free_i32(fp0);
b6d96bed 8072 }
57fa1fb3
TS
8073 opn = "rsqrt.s";
8074 break;
bf4120ad 8075 case OPC_RECIP2_S:
5e755519 8076 check_cp1_64bitmode(ctx);
b6d96bed 8077 {
a7812ae4
PB
8078 TCGv_i32 fp0 = tcg_temp_new_i32();
8079 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8080
8081 gen_load_fpr32(fp0, fs);
d22d7289 8082 gen_load_fpr32(fp1, ft);
895c2d04 8083 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8084 tcg_temp_free_i32(fp1);
b6d96bed 8085 gen_store_fpr32(fp0, fd);
a7812ae4 8086 tcg_temp_free_i32(fp0);
b6d96bed 8087 }
57fa1fb3
TS
8088 opn = "recip2.s";
8089 break;
bf4120ad 8090 case OPC_RECIP1_S:
5e755519 8091 check_cp1_64bitmode(ctx);
b6d96bed 8092 {
a7812ae4 8093 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8094
8095 gen_load_fpr32(fp0, fs);
895c2d04 8096 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 8097 gen_store_fpr32(fp0, fd);
a7812ae4 8098 tcg_temp_free_i32(fp0);
b6d96bed 8099 }
57fa1fb3
TS
8100 opn = "recip1.s";
8101 break;
bf4120ad 8102 case OPC_RSQRT1_S:
5e755519 8103 check_cp1_64bitmode(ctx);
b6d96bed 8104 {
a7812ae4 8105 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8106
8107 gen_load_fpr32(fp0, fs);
895c2d04 8108 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 8109 gen_store_fpr32(fp0, fd);
a7812ae4 8110 tcg_temp_free_i32(fp0);
b6d96bed 8111 }
57fa1fb3
TS
8112 opn = "rsqrt1.s";
8113 break;
bf4120ad 8114 case OPC_RSQRT2_S:
5e755519 8115 check_cp1_64bitmode(ctx);
b6d96bed 8116 {
a7812ae4
PB
8117 TCGv_i32 fp0 = tcg_temp_new_i32();
8118 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8119
8120 gen_load_fpr32(fp0, fs);
8121 gen_load_fpr32(fp1, ft);
895c2d04 8122 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8123 tcg_temp_free_i32(fp1);
b6d96bed 8124 gen_store_fpr32(fp0, fd);
a7812ae4 8125 tcg_temp_free_i32(fp0);
b6d96bed 8126 }
57fa1fb3
TS
8127 opn = "rsqrt2.s";
8128 break;
bf4120ad 8129 case OPC_CVT_D_S:
5e755519 8130 check_cp1_registers(ctx, fd);
b6d96bed 8131 {
a7812ae4
PB
8132 TCGv_i32 fp32 = tcg_temp_new_i32();
8133 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8134
8135 gen_load_fpr32(fp32, fs);
895c2d04 8136 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 8137 tcg_temp_free_i32(fp32);
b6d96bed 8138 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8139 tcg_temp_free_i64(fp64);
b6d96bed 8140 }
5a5012ec
TS
8141 opn = "cvt.d.s";
8142 break;
bf4120ad 8143 case OPC_CVT_W_S:
b6d96bed 8144 {
a7812ae4 8145 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8146
8147 gen_load_fpr32(fp0, fs);
895c2d04 8148 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 8149 gen_store_fpr32(fp0, fd);
a7812ae4 8150 tcg_temp_free_i32(fp0);
b6d96bed 8151 }
5a5012ec
TS
8152 opn = "cvt.w.s";
8153 break;
bf4120ad 8154 case OPC_CVT_L_S:
5e755519 8155 check_cp1_64bitmode(ctx);
b6d96bed 8156 {
a7812ae4
PB
8157 TCGv_i32 fp32 = tcg_temp_new_i32();
8158 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8159
8160 gen_load_fpr32(fp32, fs);
895c2d04 8161 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 8162 tcg_temp_free_i32(fp32);
b6d96bed 8163 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8164 tcg_temp_free_i64(fp64);
b6d96bed 8165 }
5a5012ec
TS
8166 opn = "cvt.l.s";
8167 break;
bf4120ad 8168 case OPC_CVT_PS_S:
fecd2646 8169 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 8170 check_cp1_64bitmode(ctx);
b6d96bed 8171 {
a7812ae4
PB
8172 TCGv_i64 fp64 = tcg_temp_new_i64();
8173 TCGv_i32 fp32_0 = tcg_temp_new_i32();
8174 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
8175
8176 gen_load_fpr32(fp32_0, fs);
8177 gen_load_fpr32(fp32_1, ft);
13d24f49 8178 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
8179 tcg_temp_free_i32(fp32_1);
8180 tcg_temp_free_i32(fp32_0);
36aa55dc 8181 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8182 tcg_temp_free_i64(fp64);
b6d96bed 8183 }
5a5012ec
TS
8184 opn = "cvt.ps.s";
8185 break;
bf4120ad
NF
8186 case OPC_CMP_F_S:
8187 case OPC_CMP_UN_S:
8188 case OPC_CMP_EQ_S:
8189 case OPC_CMP_UEQ_S:
8190 case OPC_CMP_OLT_S:
8191 case OPC_CMP_ULT_S:
8192 case OPC_CMP_OLE_S:
8193 case OPC_CMP_ULE_S:
8194 case OPC_CMP_SF_S:
8195 case OPC_CMP_NGLE_S:
8196 case OPC_CMP_SEQ_S:
8197 case OPC_CMP_NGL_S:
8198 case OPC_CMP_LT_S:
8199 case OPC_CMP_NGE_S:
8200 case OPC_CMP_LE_S:
8201 case OPC_CMP_NGT_S:
fecd2646 8202 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
8203 if (ctx->opcode & (1 << 6)) {
8204 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8205 opn = condnames_abs[func-48];
8206 } else {
8207 gen_cmp_s(ctx, func-48, ft, fs, cc);
8208 opn = condnames[func-48];
5a1e8ffb 8209 }
5a5012ec 8210 break;
bf4120ad 8211 case OPC_ADD_D:
5e755519 8212 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8213 {
a7812ae4
PB
8214 TCGv_i64 fp0 = tcg_temp_new_i64();
8215 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8216
8217 gen_load_fpr64(ctx, fp0, fs);
8218 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8219 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8220 tcg_temp_free_i64(fp1);
b6d96bed 8221 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8222 tcg_temp_free_i64(fp0);
b6d96bed 8223 }
6ea83fed 8224 opn = "add.d";
5a1e8ffb 8225 optype = BINOP;
6ea83fed 8226 break;
bf4120ad 8227 case OPC_SUB_D:
5e755519 8228 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8229 {
a7812ae4
PB
8230 TCGv_i64 fp0 = tcg_temp_new_i64();
8231 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8232
8233 gen_load_fpr64(ctx, fp0, fs);
8234 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8235 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8236 tcg_temp_free_i64(fp1);
b6d96bed 8237 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8238 tcg_temp_free_i64(fp0);
b6d96bed 8239 }
6ea83fed 8240 opn = "sub.d";
5a1e8ffb 8241 optype = BINOP;
6ea83fed 8242 break;
bf4120ad 8243 case OPC_MUL_D:
5e755519 8244 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8245 {
a7812ae4
PB
8246 TCGv_i64 fp0 = tcg_temp_new_i64();
8247 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8248
8249 gen_load_fpr64(ctx, fp0, fs);
8250 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8251 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8252 tcg_temp_free_i64(fp1);
b6d96bed 8253 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8254 tcg_temp_free_i64(fp0);
b6d96bed 8255 }
6ea83fed 8256 opn = "mul.d";
5a1e8ffb 8257 optype = BINOP;
6ea83fed 8258 break;
bf4120ad 8259 case OPC_DIV_D:
5e755519 8260 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 8261 {
a7812ae4
PB
8262 TCGv_i64 fp0 = tcg_temp_new_i64();
8263 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8264
8265 gen_load_fpr64(ctx, fp0, fs);
8266 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8267 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8268 tcg_temp_free_i64(fp1);
b6d96bed 8269 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8270 tcg_temp_free_i64(fp0);
b6d96bed 8271 }
6ea83fed 8272 opn = "div.d";
5a1e8ffb 8273 optype = BINOP;
6ea83fed 8274 break;
bf4120ad 8275 case OPC_SQRT_D:
5e755519 8276 check_cp1_registers(ctx, fs | fd);
b6d96bed 8277 {
a7812ae4 8278 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8279
8280 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8281 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 8282 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8283 tcg_temp_free_i64(fp0);
b6d96bed 8284 }
6ea83fed
FB
8285 opn = "sqrt.d";
8286 break;
bf4120ad 8287 case OPC_ABS_D:
5e755519 8288 check_cp1_registers(ctx, fs | fd);
b6d96bed 8289 {
a7812ae4 8290 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8291
8292 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8293 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 8294 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8295 tcg_temp_free_i64(fp0);
b6d96bed 8296 }
6ea83fed
FB
8297 opn = "abs.d";
8298 break;
bf4120ad 8299 case OPC_MOV_D:
5e755519 8300 check_cp1_registers(ctx, fs | fd);
b6d96bed 8301 {
a7812ae4 8302 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8303
8304 gen_load_fpr64(ctx, fp0, fs);
8305 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8306 tcg_temp_free_i64(fp0);
b6d96bed 8307 }
6ea83fed
FB
8308 opn = "mov.d";
8309 break;
bf4120ad 8310 case OPC_NEG_D:
5e755519 8311 check_cp1_registers(ctx, fs | fd);
b6d96bed 8312 {
a7812ae4 8313 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8314
8315 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8316 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 8317 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8318 tcg_temp_free_i64(fp0);
b6d96bed 8319 }
6ea83fed
FB
8320 opn = "neg.d";
8321 break;
bf4120ad 8322 case OPC_ROUND_L_D:
5e755519 8323 check_cp1_64bitmode(ctx);
b6d96bed 8324 {
a7812ae4 8325 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8326
8327 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8328 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 8329 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8330 tcg_temp_free_i64(fp0);
b6d96bed 8331 }
5a5012ec
TS
8332 opn = "round.l.d";
8333 break;
bf4120ad 8334 case OPC_TRUNC_L_D:
5e755519 8335 check_cp1_64bitmode(ctx);
b6d96bed 8336 {
a7812ae4 8337 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8338
8339 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8340 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 8341 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8342 tcg_temp_free_i64(fp0);
b6d96bed 8343 }
5a5012ec
TS
8344 opn = "trunc.l.d";
8345 break;
bf4120ad 8346 case OPC_CEIL_L_D:
5e755519 8347 check_cp1_64bitmode(ctx);
b6d96bed 8348 {
a7812ae4 8349 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8350
8351 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8352 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8353 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8354 tcg_temp_free_i64(fp0);
b6d96bed 8355 }
5a5012ec
TS
8356 opn = "ceil.l.d";
8357 break;
bf4120ad 8358 case OPC_FLOOR_L_D:
5e755519 8359 check_cp1_64bitmode(ctx);
b6d96bed 8360 {
a7812ae4 8361 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8362
8363 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8364 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8365 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8366 tcg_temp_free_i64(fp0);
b6d96bed 8367 }
5a5012ec
TS
8368 opn = "floor.l.d";
8369 break;
bf4120ad 8370 case OPC_ROUND_W_D:
5e755519 8371 check_cp1_registers(ctx, fs);
b6d96bed 8372 {
a7812ae4
PB
8373 TCGv_i32 fp32 = tcg_temp_new_i32();
8374 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8375
8376 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8377 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8378 tcg_temp_free_i64(fp64);
b6d96bed 8379 gen_store_fpr32(fp32, fd);
a7812ae4 8380 tcg_temp_free_i32(fp32);
b6d96bed 8381 }
6ea83fed
FB
8382 opn = "round.w.d";
8383 break;
bf4120ad 8384 case OPC_TRUNC_W_D:
5e755519 8385 check_cp1_registers(ctx, fs);
b6d96bed 8386 {
a7812ae4
PB
8387 TCGv_i32 fp32 = tcg_temp_new_i32();
8388 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8389
8390 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8391 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8392 tcg_temp_free_i64(fp64);
b6d96bed 8393 gen_store_fpr32(fp32, fd);
a7812ae4 8394 tcg_temp_free_i32(fp32);
b6d96bed 8395 }
6ea83fed
FB
8396 opn = "trunc.w.d";
8397 break;
bf4120ad 8398 case OPC_CEIL_W_D:
5e755519 8399 check_cp1_registers(ctx, fs);
b6d96bed 8400 {
a7812ae4
PB
8401 TCGv_i32 fp32 = tcg_temp_new_i32();
8402 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8403
8404 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8405 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8406 tcg_temp_free_i64(fp64);
b6d96bed 8407 gen_store_fpr32(fp32, fd);
a7812ae4 8408 tcg_temp_free_i32(fp32);
b6d96bed 8409 }
6ea83fed
FB
8410 opn = "ceil.w.d";
8411 break;
bf4120ad 8412 case OPC_FLOOR_W_D:
5e755519 8413 check_cp1_registers(ctx, fs);
b6d96bed 8414 {
a7812ae4
PB
8415 TCGv_i32 fp32 = tcg_temp_new_i32();
8416 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8417
8418 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8419 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8420 tcg_temp_free_i64(fp64);
b6d96bed 8421 gen_store_fpr32(fp32, fd);
a7812ae4 8422 tcg_temp_free_i32(fp32);
b6d96bed 8423 }
7a387fff 8424 opn = "floor.w.d";
6ea83fed 8425 break;
bf4120ad 8426 case OPC_MOVCF_D:
fecd2646 8427 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 8428 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8429 opn = "movcf.d";
dd016883 8430 break;
bf4120ad 8431 case OPC_MOVZ_D:
fecd2646 8432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8433 {
8434 int l1 = gen_new_label();
c9297f4d 8435 TCGv_i64 fp0;
a16336e4 8436
c9297f4d
AJ
8437 if (ft != 0) {
8438 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8439 }
8440 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8441 gen_load_fpr64(ctx, fp0, fs);
8442 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8443 tcg_temp_free_i64(fp0);
a16336e4
TS
8444 gen_set_label(l1);
8445 }
5a5012ec
TS
8446 opn = "movz.d";
8447 break;
bf4120ad 8448 case OPC_MOVN_D:
fecd2646 8449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4
TS
8450 {
8451 int l1 = gen_new_label();
c9297f4d
AJ
8452 TCGv_i64 fp0;
8453
8454 if (ft != 0) {
8455 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8456 fp0 = tcg_temp_new_i64();
8457 gen_load_fpr64(ctx, fp0, fs);
8458 gen_store_fpr64(ctx, fp0, fd);
8459 tcg_temp_free_i64(fp0);
8460 gen_set_label(l1);
8461 }
a16336e4 8462 }
5a5012ec 8463 opn = "movn.d";
6ea83fed 8464 break;
bf4120ad 8465 case OPC_RECIP_D:
b8aa4598 8466 check_cp1_64bitmode(ctx);
b6d96bed 8467 {
a7812ae4 8468 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8469
8470 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8471 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8472 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8473 tcg_temp_free_i64(fp0);
b6d96bed 8474 }
57fa1fb3
TS
8475 opn = "recip.d";
8476 break;
bf4120ad 8477 case OPC_RSQRT_D:
b8aa4598 8478 check_cp1_64bitmode(ctx);
b6d96bed 8479 {
a7812ae4 8480 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8481
8482 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8483 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8484 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8485 tcg_temp_free_i64(fp0);
b6d96bed 8486 }
57fa1fb3
TS
8487 opn = "rsqrt.d";
8488 break;
bf4120ad 8489 case OPC_RECIP2_D:
5e755519 8490 check_cp1_64bitmode(ctx);
b6d96bed 8491 {
a7812ae4
PB
8492 TCGv_i64 fp0 = tcg_temp_new_i64();
8493 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8494
8495 gen_load_fpr64(ctx, fp0, fs);
8496 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8497 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8498 tcg_temp_free_i64(fp1);
b6d96bed 8499 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8500 tcg_temp_free_i64(fp0);
b6d96bed 8501 }
57fa1fb3
TS
8502 opn = "recip2.d";
8503 break;
bf4120ad 8504 case OPC_RECIP1_D:
5e755519 8505 check_cp1_64bitmode(ctx);
b6d96bed 8506 {
a7812ae4 8507 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8508
8509 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8510 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8511 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8512 tcg_temp_free_i64(fp0);
b6d96bed 8513 }
57fa1fb3
TS
8514 opn = "recip1.d";
8515 break;
bf4120ad 8516 case OPC_RSQRT1_D:
5e755519 8517 check_cp1_64bitmode(ctx);
b6d96bed 8518 {
a7812ae4 8519 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8520
8521 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8522 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8523 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8524 tcg_temp_free_i64(fp0);
b6d96bed 8525 }
57fa1fb3
TS
8526 opn = "rsqrt1.d";
8527 break;
bf4120ad 8528 case OPC_RSQRT2_D:
5e755519 8529 check_cp1_64bitmode(ctx);
b6d96bed 8530 {
a7812ae4
PB
8531 TCGv_i64 fp0 = tcg_temp_new_i64();
8532 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8533
8534 gen_load_fpr64(ctx, fp0, fs);
8535 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8536 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8537 tcg_temp_free_i64(fp1);
b6d96bed 8538 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8539 tcg_temp_free_i64(fp0);
b6d96bed 8540 }
57fa1fb3
TS
8541 opn = "rsqrt2.d";
8542 break;
bf4120ad
NF
8543 case OPC_CMP_F_D:
8544 case OPC_CMP_UN_D:
8545 case OPC_CMP_EQ_D:
8546 case OPC_CMP_UEQ_D:
8547 case OPC_CMP_OLT_D:
8548 case OPC_CMP_ULT_D:
8549 case OPC_CMP_OLE_D:
8550 case OPC_CMP_ULE_D:
8551 case OPC_CMP_SF_D:
8552 case OPC_CMP_NGLE_D:
8553 case OPC_CMP_SEQ_D:
8554 case OPC_CMP_NGL_D:
8555 case OPC_CMP_LT_D:
8556 case OPC_CMP_NGE_D:
8557 case OPC_CMP_LE_D:
8558 case OPC_CMP_NGT_D:
fecd2646 8559 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
8560 if (ctx->opcode & (1 << 6)) {
8561 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8562 opn = condnames_abs[func-48];
8563 } else {
8564 gen_cmp_d(ctx, func-48, ft, fs, cc);
8565 opn = condnames[func-48];
5a1e8ffb 8566 }
6ea83fed 8567 break;
bf4120ad 8568 case OPC_CVT_S_D:
5e755519 8569 check_cp1_registers(ctx, fs);
b6d96bed 8570 {
a7812ae4
PB
8571 TCGv_i32 fp32 = tcg_temp_new_i32();
8572 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8573
8574 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8575 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8576 tcg_temp_free_i64(fp64);
b6d96bed 8577 gen_store_fpr32(fp32, fd);
a7812ae4 8578 tcg_temp_free_i32(fp32);
b6d96bed 8579 }
5a5012ec
TS
8580 opn = "cvt.s.d";
8581 break;
bf4120ad 8582 case OPC_CVT_W_D:
5e755519 8583 check_cp1_registers(ctx, fs);
b6d96bed 8584 {
a7812ae4
PB
8585 TCGv_i32 fp32 = tcg_temp_new_i32();
8586 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8587
8588 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8589 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8590 tcg_temp_free_i64(fp64);
b6d96bed 8591 gen_store_fpr32(fp32, fd);
a7812ae4 8592 tcg_temp_free_i32(fp32);
b6d96bed 8593 }
5a5012ec
TS
8594 opn = "cvt.w.d";
8595 break;
bf4120ad 8596 case OPC_CVT_L_D:
5e755519 8597 check_cp1_64bitmode(ctx);
b6d96bed 8598 {
a7812ae4 8599 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8600
8601 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8602 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8603 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8604 tcg_temp_free_i64(fp0);
b6d96bed 8605 }
5a5012ec
TS
8606 opn = "cvt.l.d";
8607 break;
bf4120ad 8608 case OPC_CVT_S_W:
b6d96bed 8609 {
a7812ae4 8610 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8611
8612 gen_load_fpr32(fp0, fs);
895c2d04 8613 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8614 gen_store_fpr32(fp0, fd);
a7812ae4 8615 tcg_temp_free_i32(fp0);
b6d96bed 8616 }
5a5012ec 8617 opn = "cvt.s.w";
6ea83fed 8618 break;
bf4120ad 8619 case OPC_CVT_D_W:
5e755519 8620 check_cp1_registers(ctx, fd);
b6d96bed 8621 {
a7812ae4
PB
8622 TCGv_i32 fp32 = tcg_temp_new_i32();
8623 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8624
8625 gen_load_fpr32(fp32, fs);
895c2d04 8626 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8627 tcg_temp_free_i32(fp32);
b6d96bed 8628 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8629 tcg_temp_free_i64(fp64);
b6d96bed 8630 }
5a5012ec
TS
8631 opn = "cvt.d.w";
8632 break;
bf4120ad 8633 case OPC_CVT_S_L:
5e755519 8634 check_cp1_64bitmode(ctx);
b6d96bed 8635 {
a7812ae4
PB
8636 TCGv_i32 fp32 = tcg_temp_new_i32();
8637 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8638
8639 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8640 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8641 tcg_temp_free_i64(fp64);
b6d96bed 8642 gen_store_fpr32(fp32, fd);
a7812ae4 8643 tcg_temp_free_i32(fp32);
b6d96bed 8644 }
5a5012ec
TS
8645 opn = "cvt.s.l";
8646 break;
bf4120ad 8647 case OPC_CVT_D_L:
5e755519 8648 check_cp1_64bitmode(ctx);
b6d96bed 8649 {
a7812ae4 8650 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8651
8652 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8653 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8654 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8655 tcg_temp_free_i64(fp0);
b6d96bed 8656 }
5a5012ec
TS
8657 opn = "cvt.d.l";
8658 break;
bf4120ad 8659 case OPC_CVT_PS_PW:
fecd2646 8660 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e755519 8661 check_cp1_64bitmode(ctx);
b6d96bed 8662 {
a7812ae4 8663 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8664
8665 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8666 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8667 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8668 tcg_temp_free_i64(fp0);
b6d96bed 8669 }
5a5012ec
TS
8670 opn = "cvt.ps.pw";
8671 break;
bf4120ad 8672 case OPC_ADD_PS:
5e755519 8673 check_cp1_64bitmode(ctx);
b6d96bed 8674 {
a7812ae4
PB
8675 TCGv_i64 fp0 = tcg_temp_new_i64();
8676 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8677
8678 gen_load_fpr64(ctx, fp0, fs);
8679 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8680 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8681 tcg_temp_free_i64(fp1);
b6d96bed 8682 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8683 tcg_temp_free_i64(fp0);
b6d96bed 8684 }
5a5012ec 8685 opn = "add.ps";
6ea83fed 8686 break;
bf4120ad 8687 case OPC_SUB_PS:
5e755519 8688 check_cp1_64bitmode(ctx);
b6d96bed 8689 {
a7812ae4
PB
8690 TCGv_i64 fp0 = tcg_temp_new_i64();
8691 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8692
8693 gen_load_fpr64(ctx, fp0, fs);
8694 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8695 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8696 tcg_temp_free_i64(fp1);
b6d96bed 8697 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8698 tcg_temp_free_i64(fp0);
b6d96bed 8699 }
5a5012ec 8700 opn = "sub.ps";
6ea83fed 8701 break;
bf4120ad 8702 case OPC_MUL_PS:
5e755519 8703 check_cp1_64bitmode(ctx);
b6d96bed 8704 {
a7812ae4
PB
8705 TCGv_i64 fp0 = tcg_temp_new_i64();
8706 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8707
8708 gen_load_fpr64(ctx, fp0, fs);
8709 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8710 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8711 tcg_temp_free_i64(fp1);
b6d96bed 8712 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8713 tcg_temp_free_i64(fp0);
b6d96bed 8714 }
5a5012ec 8715 opn = "mul.ps";
6ea83fed 8716 break;
bf4120ad 8717 case OPC_ABS_PS:
5e755519 8718 check_cp1_64bitmode(ctx);
b6d96bed 8719 {
a7812ae4 8720 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8721
8722 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8723 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8724 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8725 tcg_temp_free_i64(fp0);
b6d96bed 8726 }
5a5012ec 8727 opn = "abs.ps";
6ea83fed 8728 break;
bf4120ad 8729 case OPC_MOV_PS:
5e755519 8730 check_cp1_64bitmode(ctx);
b6d96bed 8731 {
a7812ae4 8732 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8733
8734 gen_load_fpr64(ctx, fp0, fs);
8735 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8736 tcg_temp_free_i64(fp0);
b6d96bed 8737 }
5a5012ec 8738 opn = "mov.ps";
6ea83fed 8739 break;
bf4120ad 8740 case OPC_NEG_PS:
5e755519 8741 check_cp1_64bitmode(ctx);
b6d96bed 8742 {
a7812ae4 8743 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8744
8745 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8746 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8747 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8748 tcg_temp_free_i64(fp0);
b6d96bed 8749 }
5a5012ec 8750 opn = "neg.ps";
6ea83fed 8751 break;
bf4120ad 8752 case OPC_MOVCF_PS:
5e755519 8753 check_cp1_64bitmode(ctx);
7f6613ce 8754 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8755 opn = "movcf.ps";
6ea83fed 8756 break;
bf4120ad 8757 case OPC_MOVZ_PS:
5e755519 8758 check_cp1_64bitmode(ctx);
a16336e4
TS
8759 {
8760 int l1 = gen_new_label();
30a3848b 8761 TCGv_i64 fp0;
a16336e4 8762
c9297f4d
AJ
8763 if (ft != 0)
8764 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8765 fp0 = tcg_temp_new_i64();
8766 gen_load_fpr64(ctx, fp0, fs);
8767 gen_store_fpr64(ctx, fp0, fd);
8768 tcg_temp_free_i64(fp0);
a16336e4
TS
8769 gen_set_label(l1);
8770 }
5a5012ec 8771 opn = "movz.ps";
6ea83fed 8772 break;
bf4120ad 8773 case OPC_MOVN_PS:
5e755519 8774 check_cp1_64bitmode(ctx);
a16336e4
TS
8775 {
8776 int l1 = gen_new_label();
30a3848b 8777 TCGv_i64 fp0;
c9297f4d
AJ
8778
8779 if (ft != 0) {
8780 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8781 fp0 = tcg_temp_new_i64();
8782 gen_load_fpr64(ctx, fp0, fs);
8783 gen_store_fpr64(ctx, fp0, fd);
8784 tcg_temp_free_i64(fp0);
8785 gen_set_label(l1);
8786 }
a16336e4 8787 }
5a5012ec 8788 opn = "movn.ps";
6ea83fed 8789 break;
bf4120ad 8790 case OPC_ADDR_PS:
5e755519 8791 check_cp1_64bitmode(ctx);
b6d96bed 8792 {
a7812ae4
PB
8793 TCGv_i64 fp0 = tcg_temp_new_i64();
8794 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8795
8796 gen_load_fpr64(ctx, fp0, ft);
8797 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8798 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8799 tcg_temp_free_i64(fp1);
b6d96bed 8800 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8801 tcg_temp_free_i64(fp0);
b6d96bed 8802 }
fbcc6828
TS
8803 opn = "addr.ps";
8804 break;
bf4120ad 8805 case OPC_MULR_PS:
5e755519 8806 check_cp1_64bitmode(ctx);
b6d96bed 8807 {
a7812ae4
PB
8808 TCGv_i64 fp0 = tcg_temp_new_i64();
8809 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8810
8811 gen_load_fpr64(ctx, fp0, ft);
8812 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8813 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8814 tcg_temp_free_i64(fp1);
b6d96bed 8815 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8816 tcg_temp_free_i64(fp0);
b6d96bed 8817 }
57fa1fb3
TS
8818 opn = "mulr.ps";
8819 break;
bf4120ad 8820 case OPC_RECIP2_PS:
5e755519 8821 check_cp1_64bitmode(ctx);
b6d96bed 8822 {
a7812ae4
PB
8823 TCGv_i64 fp0 = tcg_temp_new_i64();
8824 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8825
8826 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8827 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8828 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8829 tcg_temp_free_i64(fp1);
b6d96bed 8830 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8831 tcg_temp_free_i64(fp0);
b6d96bed 8832 }
57fa1fb3
TS
8833 opn = "recip2.ps";
8834 break;
bf4120ad 8835 case OPC_RECIP1_PS:
5e755519 8836 check_cp1_64bitmode(ctx);
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_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8842 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8843 tcg_temp_free_i64(fp0);
b6d96bed 8844 }
57fa1fb3
TS
8845 opn = "recip1.ps";
8846 break;
bf4120ad 8847 case OPC_RSQRT1_PS:
5e755519 8848 check_cp1_64bitmode(ctx);
b6d96bed 8849 {
a7812ae4 8850 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8851
8852 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8853 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8854 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8855 tcg_temp_free_i64(fp0);
b6d96bed 8856 }
57fa1fb3
TS
8857 opn = "rsqrt1.ps";
8858 break;
bf4120ad 8859 case OPC_RSQRT2_PS:
5e755519 8860 check_cp1_64bitmode(ctx);
b6d96bed 8861 {
a7812ae4
PB
8862 TCGv_i64 fp0 = tcg_temp_new_i64();
8863 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8864
8865 gen_load_fpr64(ctx, fp0, fs);
8866 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8867 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8868 tcg_temp_free_i64(fp1);
b6d96bed 8869 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8870 tcg_temp_free_i64(fp0);
b6d96bed 8871 }
57fa1fb3
TS
8872 opn = "rsqrt2.ps";
8873 break;
bf4120ad 8874 case OPC_CVT_S_PU:
5e755519 8875 check_cp1_64bitmode(ctx);
b6d96bed 8876 {
a7812ae4 8877 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8878
7f6613ce 8879 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 8880 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8881 gen_store_fpr32(fp0, fd);
a7812ae4 8882 tcg_temp_free_i32(fp0);
b6d96bed 8883 }
5a5012ec 8884 opn = "cvt.s.pu";
dd016883 8885 break;
bf4120ad 8886 case OPC_CVT_PW_PS:
5e755519 8887 check_cp1_64bitmode(ctx);
b6d96bed 8888 {
a7812ae4 8889 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8890
8891 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8892 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8893 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8894 tcg_temp_free_i64(fp0);
b6d96bed 8895 }
5a5012ec 8896 opn = "cvt.pw.ps";
6ea83fed 8897 break;
bf4120ad 8898 case OPC_CVT_S_PL:
5e755519 8899 check_cp1_64bitmode(ctx);
b6d96bed 8900 {
a7812ae4 8901 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8902
8903 gen_load_fpr32(fp0, fs);
895c2d04 8904 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8905 gen_store_fpr32(fp0, fd);
a7812ae4 8906 tcg_temp_free_i32(fp0);
b6d96bed 8907 }
5a5012ec 8908 opn = "cvt.s.pl";
6ea83fed 8909 break;
bf4120ad 8910 case OPC_PLL_PS:
5e755519 8911 check_cp1_64bitmode(ctx);
b6d96bed 8912 {
a7812ae4
PB
8913 TCGv_i32 fp0 = tcg_temp_new_i32();
8914 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8915
8916 gen_load_fpr32(fp0, fs);
8917 gen_load_fpr32(fp1, ft);
7f6613ce 8918 gen_store_fpr32h(ctx, fp0, fd);
b6d96bed 8919 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8920 tcg_temp_free_i32(fp0);
8921 tcg_temp_free_i32(fp1);
b6d96bed 8922 }
5a5012ec 8923 opn = "pll.ps";
6ea83fed 8924 break;
bf4120ad 8925 case OPC_PLU_PS:
5e755519 8926 check_cp1_64bitmode(ctx);
b6d96bed 8927 {
a7812ae4
PB
8928 TCGv_i32 fp0 = tcg_temp_new_i32();
8929 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8930
8931 gen_load_fpr32(fp0, fs);
7f6613ce 8932 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8933 gen_store_fpr32(fp1, fd);
7f6613ce 8934 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8935 tcg_temp_free_i32(fp0);
8936 tcg_temp_free_i32(fp1);
b6d96bed 8937 }
5a5012ec
TS
8938 opn = "plu.ps";
8939 break;
bf4120ad 8940 case OPC_PUL_PS:
5e755519 8941 check_cp1_64bitmode(ctx);
b6d96bed 8942 {
a7812ae4
PB
8943 TCGv_i32 fp0 = tcg_temp_new_i32();
8944 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8945
7f6613ce 8946 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed
TS
8947 gen_load_fpr32(fp1, ft);
8948 gen_store_fpr32(fp1, fd);
7f6613ce 8949 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8950 tcg_temp_free_i32(fp0);
8951 tcg_temp_free_i32(fp1);
b6d96bed 8952 }
5a5012ec
TS
8953 opn = "pul.ps";
8954 break;
bf4120ad 8955 case OPC_PUU_PS:
5e755519 8956 check_cp1_64bitmode(ctx);
b6d96bed 8957 {
a7812ae4
PB
8958 TCGv_i32 fp0 = tcg_temp_new_i32();
8959 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8960
7f6613ce
PJ
8961 gen_load_fpr32h(ctx, fp0, fs);
8962 gen_load_fpr32h(ctx, fp1, ft);
b6d96bed 8963 gen_store_fpr32(fp1, fd);
7f6613ce 8964 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
8965 tcg_temp_free_i32(fp0);
8966 tcg_temp_free_i32(fp1);
b6d96bed 8967 }
5a5012ec
TS
8968 opn = "puu.ps";
8969 break;
bf4120ad
NF
8970 case OPC_CMP_F_PS:
8971 case OPC_CMP_UN_PS:
8972 case OPC_CMP_EQ_PS:
8973 case OPC_CMP_UEQ_PS:
8974 case OPC_CMP_OLT_PS:
8975 case OPC_CMP_ULT_PS:
8976 case OPC_CMP_OLE_PS:
8977 case OPC_CMP_ULE_PS:
8978 case OPC_CMP_SF_PS:
8979 case OPC_CMP_NGLE_PS:
8980 case OPC_CMP_SEQ_PS:
8981 case OPC_CMP_NGL_PS:
8982 case OPC_CMP_LT_PS:
8983 case OPC_CMP_NGE_PS:
8984 case OPC_CMP_LE_PS:
8985 case OPC_CMP_NGT_PS:
8153667c
NF
8986 if (ctx->opcode & (1 << 6)) {
8987 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8988 opn = condnames_abs[func-48];
8989 } else {
8990 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8991 opn = condnames[func-48];
5a1e8ffb 8992 }
6ea83fed 8993 break;
5a5012ec 8994 default:
923617a3 8995 MIPS_INVAL(opn);
e397ee33 8996 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8997 return;
8998 }
2abf314d 8999 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
9000 switch (optype) {
9001 case BINOP:
6ea83fed 9002 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
9003 break;
9004 case CMPOP:
9005 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
9006 break;
9007 default:
6ea83fed 9008 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
9009 break;
9010 }
6ea83fed 9011}
6af0bf9c 9012
5a5012ec 9013/* Coprocessor 3 (FPU) */
5e755519
TS
9014static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
9015 int fd, int fs, int base, int index)
7a387fff 9016{
923617a3 9017 const char *opn = "extended float load/store";
93b12ccc 9018 int store = 0;
4e2474d6 9019 TCGv t0 = tcg_temp_new();
7a387fff 9020
93b12ccc 9021 if (base == 0) {
6c5c1e20 9022 gen_load_gpr(t0, index);
93b12ccc 9023 } else if (index == 0) {
6c5c1e20 9024 gen_load_gpr(t0, base);
93b12ccc 9025 } else {
05168674 9026 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 9027 }
5a5012ec 9028 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 9029 memory access. */
5a5012ec
TS
9030 switch (opc) {
9031 case OPC_LWXC1:
8c0ab41f 9032 check_cop1x(ctx);
b6d96bed 9033 {
a7812ae4 9034 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9035
5f68f5ae 9036 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 9037 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 9038 gen_store_fpr32(fp0, fd);
a7812ae4 9039 tcg_temp_free_i32(fp0);
b6d96bed 9040 }
5a5012ec
TS
9041 opn = "lwxc1";
9042 break;
9043 case OPC_LDXC1:
8c0ab41f
AJ
9044 check_cop1x(ctx);
9045 check_cp1_registers(ctx, fd);
b6d96bed 9046 {
a7812ae4 9047 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 9048 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9049 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9050 tcg_temp_free_i64(fp0);
b6d96bed 9051 }
5a5012ec
TS
9052 opn = "ldxc1";
9053 break;
9054 case OPC_LUXC1:
8c0ab41f 9055 check_cp1_64bitmode(ctx);
6c5c1e20 9056 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9057 {
a7812ae4 9058 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9059
5f68f5ae 9060 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 9061 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9062 tcg_temp_free_i64(fp0);
b6d96bed 9063 }
5a5012ec
TS
9064 opn = "luxc1";
9065 break;
9066 case OPC_SWXC1:
8c0ab41f 9067 check_cop1x(ctx);
b6d96bed 9068 {
a7812ae4 9069 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9070 gen_load_fpr32(fp0, fs);
5f68f5ae 9071 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 9072 tcg_temp_free_i32(fp0);
b6d96bed 9073 }
5a5012ec 9074 opn = "swxc1";
93b12ccc 9075 store = 1;
5a5012ec
TS
9076 break;
9077 case OPC_SDXC1:
8c0ab41f
AJ
9078 check_cop1x(ctx);
9079 check_cp1_registers(ctx, fs);
b6d96bed 9080 {
a7812ae4 9081 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9082 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9083 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9084 tcg_temp_free_i64(fp0);
b6d96bed 9085 }
5a5012ec 9086 opn = "sdxc1";
93b12ccc 9087 store = 1;
5a5012ec
TS
9088 break;
9089 case OPC_SUXC1:
8c0ab41f 9090 check_cp1_64bitmode(ctx);
6c5c1e20 9091 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 9092 {
a7812ae4 9093 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9094 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 9095 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 9096 tcg_temp_free_i64(fp0);
b6d96bed 9097 }
5a5012ec 9098 opn = "suxc1";
93b12ccc 9099 store = 1;
5a5012ec 9100 break;
5a5012ec 9101 }
6c5c1e20 9102 tcg_temp_free(t0);
2abf314d 9103 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
9104 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
9105 regnames[index], regnames[base]);
5a5012ec
TS
9106}
9107
5e755519
TS
9108static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
9109 int fd, int fr, int fs, int ft)
5a5012ec 9110{
923617a3 9111 const char *opn = "flt3_arith";
5a5012ec 9112
5a5012ec
TS
9113 switch (opc) {
9114 case OPC_ALNV_PS:
b8aa4598 9115 check_cp1_64bitmode(ctx);
a16336e4 9116 {
a7812ae4 9117 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
9118 TCGv_i32 fp = tcg_temp_new_i32();
9119 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
9120 int l1 = gen_new_label();
9121 int l2 = gen_new_label();
9122
6c5c1e20
TS
9123 gen_load_gpr(t0, fr);
9124 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
9125
9126 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac 9127 gen_load_fpr32(fp, fs);
7f6613ce 9128 gen_load_fpr32h(ctx, fph, fs);
c905fdac 9129 gen_store_fpr32(fp, fd);
7f6613ce 9130 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
9131 tcg_gen_br(l2);
9132 gen_set_label(l1);
6c5c1e20
TS
9133 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
9134 tcg_temp_free(t0);
a16336e4 9135#ifdef TARGET_WORDS_BIGENDIAN
c905fdac 9136 gen_load_fpr32(fp, fs);
7f6613ce
PJ
9137 gen_load_fpr32h(ctx, fph, ft);
9138 gen_store_fpr32h(ctx, fp, fd);
c905fdac 9139 gen_store_fpr32(fph, fd);
a16336e4 9140#else
7f6613ce 9141 gen_load_fpr32h(ctx, fph, fs);
c905fdac
AJ
9142 gen_load_fpr32(fp, ft);
9143 gen_store_fpr32(fph, fd);
7f6613ce 9144 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
9145#endif
9146 gen_set_label(l2);
c905fdac
AJ
9147 tcg_temp_free_i32(fp);
9148 tcg_temp_free_i32(fph);
a16336e4 9149 }
5a5012ec
TS
9150 opn = "alnv.ps";
9151 break;
9152 case OPC_MADD_S:
b8aa4598 9153 check_cop1x(ctx);
b6d96bed 9154 {
a7812ae4
PB
9155 TCGv_i32 fp0 = tcg_temp_new_i32();
9156 TCGv_i32 fp1 = tcg_temp_new_i32();
9157 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9158
9159 gen_load_fpr32(fp0, fs);
9160 gen_load_fpr32(fp1, ft);
9161 gen_load_fpr32(fp2, fr);
b3d6cd44 9162 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9163 tcg_temp_free_i32(fp0);
9164 tcg_temp_free_i32(fp1);
b6d96bed 9165 gen_store_fpr32(fp2, fd);
a7812ae4 9166 tcg_temp_free_i32(fp2);
b6d96bed 9167 }
5a5012ec
TS
9168 opn = "madd.s";
9169 break;
9170 case OPC_MADD_D:
b8aa4598
TS
9171 check_cop1x(ctx);
9172 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9173 {
a7812ae4
PB
9174 TCGv_i64 fp0 = tcg_temp_new_i64();
9175 TCGv_i64 fp1 = tcg_temp_new_i64();
9176 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9177
9178 gen_load_fpr64(ctx, fp0, fs);
9179 gen_load_fpr64(ctx, fp1, ft);
9180 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9181 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9182 tcg_temp_free_i64(fp0);
9183 tcg_temp_free_i64(fp1);
b6d96bed 9184 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9185 tcg_temp_free_i64(fp2);
b6d96bed 9186 }
5a5012ec
TS
9187 opn = "madd.d";
9188 break;
9189 case OPC_MADD_PS:
b8aa4598 9190 check_cp1_64bitmode(ctx);
b6d96bed 9191 {
a7812ae4
PB
9192 TCGv_i64 fp0 = tcg_temp_new_i64();
9193 TCGv_i64 fp1 = tcg_temp_new_i64();
9194 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9195
9196 gen_load_fpr64(ctx, fp0, fs);
9197 gen_load_fpr64(ctx, fp1, ft);
9198 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9199 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9200 tcg_temp_free_i64(fp0);
9201 tcg_temp_free_i64(fp1);
b6d96bed 9202 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9203 tcg_temp_free_i64(fp2);
b6d96bed 9204 }
5a5012ec
TS
9205 opn = "madd.ps";
9206 break;
9207 case OPC_MSUB_S:
b8aa4598 9208 check_cop1x(ctx);
b6d96bed 9209 {
a7812ae4
PB
9210 TCGv_i32 fp0 = tcg_temp_new_i32();
9211 TCGv_i32 fp1 = tcg_temp_new_i32();
9212 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9213
9214 gen_load_fpr32(fp0, fs);
9215 gen_load_fpr32(fp1, ft);
9216 gen_load_fpr32(fp2, fr);
b3d6cd44 9217 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9218 tcg_temp_free_i32(fp0);
9219 tcg_temp_free_i32(fp1);
b6d96bed 9220 gen_store_fpr32(fp2, fd);
a7812ae4 9221 tcg_temp_free_i32(fp2);
b6d96bed 9222 }
5a5012ec
TS
9223 opn = "msub.s";
9224 break;
9225 case OPC_MSUB_D:
b8aa4598
TS
9226 check_cop1x(ctx);
9227 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9228 {
a7812ae4
PB
9229 TCGv_i64 fp0 = tcg_temp_new_i64();
9230 TCGv_i64 fp1 = tcg_temp_new_i64();
9231 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9232
9233 gen_load_fpr64(ctx, fp0, fs);
9234 gen_load_fpr64(ctx, fp1, ft);
9235 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9236 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9237 tcg_temp_free_i64(fp0);
9238 tcg_temp_free_i64(fp1);
b6d96bed 9239 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9240 tcg_temp_free_i64(fp2);
b6d96bed 9241 }
5a5012ec
TS
9242 opn = "msub.d";
9243 break;
9244 case OPC_MSUB_PS:
b8aa4598 9245 check_cp1_64bitmode(ctx);
b6d96bed 9246 {
a7812ae4
PB
9247 TCGv_i64 fp0 = tcg_temp_new_i64();
9248 TCGv_i64 fp1 = tcg_temp_new_i64();
9249 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9250
9251 gen_load_fpr64(ctx, fp0, fs);
9252 gen_load_fpr64(ctx, fp1, ft);
9253 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9254 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9255 tcg_temp_free_i64(fp0);
9256 tcg_temp_free_i64(fp1);
b6d96bed 9257 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9258 tcg_temp_free_i64(fp2);
b6d96bed 9259 }
5a5012ec
TS
9260 opn = "msub.ps";
9261 break;
9262 case OPC_NMADD_S:
b8aa4598 9263 check_cop1x(ctx);
b6d96bed 9264 {
a7812ae4
PB
9265 TCGv_i32 fp0 = tcg_temp_new_i32();
9266 TCGv_i32 fp1 = tcg_temp_new_i32();
9267 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9268
9269 gen_load_fpr32(fp0, fs);
9270 gen_load_fpr32(fp1, ft);
9271 gen_load_fpr32(fp2, fr);
b3d6cd44 9272 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9273 tcg_temp_free_i32(fp0);
9274 tcg_temp_free_i32(fp1);
b6d96bed 9275 gen_store_fpr32(fp2, fd);
a7812ae4 9276 tcg_temp_free_i32(fp2);
b6d96bed 9277 }
5a5012ec
TS
9278 opn = "nmadd.s";
9279 break;
9280 case OPC_NMADD_D:
b8aa4598
TS
9281 check_cop1x(ctx);
9282 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9283 {
a7812ae4
PB
9284 TCGv_i64 fp0 = tcg_temp_new_i64();
9285 TCGv_i64 fp1 = tcg_temp_new_i64();
9286 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9287
9288 gen_load_fpr64(ctx, fp0, fs);
9289 gen_load_fpr64(ctx, fp1, ft);
9290 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9291 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9292 tcg_temp_free_i64(fp0);
9293 tcg_temp_free_i64(fp1);
b6d96bed 9294 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9295 tcg_temp_free_i64(fp2);
b6d96bed 9296 }
5a5012ec
TS
9297 opn = "nmadd.d";
9298 break;
9299 case OPC_NMADD_PS:
b8aa4598 9300 check_cp1_64bitmode(ctx);
b6d96bed 9301 {
a7812ae4
PB
9302 TCGv_i64 fp0 = tcg_temp_new_i64();
9303 TCGv_i64 fp1 = tcg_temp_new_i64();
9304 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9305
9306 gen_load_fpr64(ctx, fp0, fs);
9307 gen_load_fpr64(ctx, fp1, ft);
9308 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9309 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9310 tcg_temp_free_i64(fp0);
9311 tcg_temp_free_i64(fp1);
b6d96bed 9312 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9313 tcg_temp_free_i64(fp2);
b6d96bed 9314 }
5a5012ec
TS
9315 opn = "nmadd.ps";
9316 break;
9317 case OPC_NMSUB_S:
b8aa4598 9318 check_cop1x(ctx);
b6d96bed 9319 {
a7812ae4
PB
9320 TCGv_i32 fp0 = tcg_temp_new_i32();
9321 TCGv_i32 fp1 = tcg_temp_new_i32();
9322 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
9323
9324 gen_load_fpr32(fp0, fs);
9325 gen_load_fpr32(fp1, ft);
9326 gen_load_fpr32(fp2, fr);
b3d6cd44 9327 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9328 tcg_temp_free_i32(fp0);
9329 tcg_temp_free_i32(fp1);
b6d96bed 9330 gen_store_fpr32(fp2, fd);
a7812ae4 9331 tcg_temp_free_i32(fp2);
b6d96bed 9332 }
5a5012ec
TS
9333 opn = "nmsub.s";
9334 break;
9335 case OPC_NMSUB_D:
b8aa4598
TS
9336 check_cop1x(ctx);
9337 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 9338 {
a7812ae4
PB
9339 TCGv_i64 fp0 = tcg_temp_new_i64();
9340 TCGv_i64 fp1 = tcg_temp_new_i64();
9341 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9342
9343 gen_load_fpr64(ctx, fp0, fs);
9344 gen_load_fpr64(ctx, fp1, ft);
9345 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9346 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9347 tcg_temp_free_i64(fp0);
9348 tcg_temp_free_i64(fp1);
b6d96bed 9349 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9350 tcg_temp_free_i64(fp2);
b6d96bed 9351 }
5a5012ec
TS
9352 opn = "nmsub.d";
9353 break;
9354 case OPC_NMSUB_PS:
b8aa4598 9355 check_cp1_64bitmode(ctx);
b6d96bed 9356 {
a7812ae4
PB
9357 TCGv_i64 fp0 = tcg_temp_new_i64();
9358 TCGv_i64 fp1 = tcg_temp_new_i64();
9359 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9360
9361 gen_load_fpr64(ctx, fp0, fs);
9362 gen_load_fpr64(ctx, fp1, ft);
9363 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9364 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9365 tcg_temp_free_i64(fp0);
9366 tcg_temp_free_i64(fp1);
b6d96bed 9367 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9368 tcg_temp_free_i64(fp2);
b6d96bed 9369 }
5a5012ec
TS
9370 opn = "nmsub.ps";
9371 break;
923617a3
TS
9372 default:
9373 MIPS_INVAL(opn);
5a5012ec
TS
9374 generate_exception (ctx, EXCP_RI);
9375 return;
9376 }
2abf314d 9377 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9378 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9379 fregnames[fs], fregnames[ft]);
7a387fff
TS
9380}
9381
d75c135e 9382static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
26ebe468
NF
9383{
9384 TCGv t0;
9385
b3167288
RH
9386#if !defined(CONFIG_USER_ONLY)
9387 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9388 Therefore only check the ISA in system mode. */
d75c135e 9389 check_insn(ctx, ISA_MIPS32R2);
b3167288 9390#endif
26ebe468
NF
9391 t0 = tcg_temp_new();
9392
9393 switch (rd) {
9394 case 0:
9395 save_cpu_state(ctx, 1);
895c2d04 9396 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9397 gen_store_gpr(t0, rt);
9398 break;
9399 case 1:
9400 save_cpu_state(ctx, 1);
895c2d04 9401 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9402 gen_store_gpr(t0, rt);
9403 break;
9404 case 2:
9405 save_cpu_state(ctx, 1);
895c2d04 9406 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9407 gen_store_gpr(t0, rt);
9408 break;
9409 case 3:
9410 save_cpu_state(ctx, 1);
895c2d04 9411 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9412 gen_store_gpr(t0, rt);
9413 break;
9414 case 29:
9415#if defined(CONFIG_USER_ONLY)
d279279e
PJ
9416 tcg_gen_ld_tl(t0, cpu_env,
9417 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
9418 gen_store_gpr(t0, rt);
9419 break;
9420#else
d279279e
PJ
9421 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
9422 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
9423 tcg_gen_ld_tl(t0, cpu_env,
9424 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9425 gen_store_gpr(t0, rt);
9426 } else {
9427 generate_exception(ctx, EXCP_RI);
9428 }
9429 break;
26ebe468
NF
9430#endif
9431 default: /* Invalid */
9432 MIPS_INVAL("rdhwr");
9433 generate_exception(ctx, EXCP_RI);
9434 break;
9435 }
9436 tcg_temp_free(t0);
9437}
9438
d75c135e 9439static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
c9602061
NF
9440{
9441 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9442 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9443 /* Branches completion */
9444 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9445 ctx->bstate = BS_BRANCH;
9446 save_cpu_state(ctx, 0);
9447 /* FIXME: Need to clear can_do_io. */
364d4831 9448 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9449 case MIPS_HFLAG_B:
9450 /* unconditional branch */
9451 MIPS_DEBUG("unconditional branch");
364d4831
NF
9452 if (proc_hflags & MIPS_HFLAG_BX) {
9453 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9454 }
c9602061
NF
9455 gen_goto_tb(ctx, 0, ctx->btarget);
9456 break;
9457 case MIPS_HFLAG_BL:
9458 /* blikely taken case */
9459 MIPS_DEBUG("blikely branch taken");
9460 gen_goto_tb(ctx, 0, ctx->btarget);
9461 break;
9462 case MIPS_HFLAG_BC:
9463 /* Conditional branch */
9464 MIPS_DEBUG("conditional branch");
9465 {
9466 int l1 = gen_new_label();
9467
9468 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9469 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9470 gen_set_label(l1);
9471 gen_goto_tb(ctx, 0, ctx->btarget);
9472 }
9473 break;
9474 case MIPS_HFLAG_BR:
9475 /* unconditional branch to register */
9476 MIPS_DEBUG("branch to register");
d75c135e 9477 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9478 TCGv t0 = tcg_temp_new();
9479 TCGv_i32 t1 = tcg_temp_new_i32();
9480
9481 tcg_gen_andi_tl(t0, btarget, 0x1);
9482 tcg_gen_trunc_tl_i32(t1, t0);
9483 tcg_temp_free(t0);
9484 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9485 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9486 tcg_gen_or_i32(hflags, hflags, t1);
9487 tcg_temp_free_i32(t1);
9488
9489 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9490 } else {
9491 tcg_gen_mov_tl(cpu_PC, btarget);
9492 }
c9602061
NF
9493 if (ctx->singlestep_enabled) {
9494 save_cpu_state(ctx, 0);
895c2d04 9495 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9496 }
9497 tcg_gen_exit_tb(0);
9498 break;
9499 default:
9500 MIPS_DEBUG("unknown branch");
9501 break;
9502 }
9503 }
9504}
9505
7a387fff 9506/* ISA extensions (ASEs) */
6af0bf9c 9507/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9508
9509/* MIPS16 major opcodes */
9510enum {
9511 M16_OPC_ADDIUSP = 0x00,
9512 M16_OPC_ADDIUPC = 0x01,
9513 M16_OPC_B = 0x02,
9514 M16_OPC_JAL = 0x03,
9515 M16_OPC_BEQZ = 0x04,
9516 M16_OPC_BNEQZ = 0x05,
9517 M16_OPC_SHIFT = 0x06,
9518 M16_OPC_LD = 0x07,
9519 M16_OPC_RRIA = 0x08,
9520 M16_OPC_ADDIU8 = 0x09,
9521 M16_OPC_SLTI = 0x0a,
9522 M16_OPC_SLTIU = 0x0b,
9523 M16_OPC_I8 = 0x0c,
9524 M16_OPC_LI = 0x0d,
9525 M16_OPC_CMPI = 0x0e,
9526 M16_OPC_SD = 0x0f,
9527 M16_OPC_LB = 0x10,
9528 M16_OPC_LH = 0x11,
9529 M16_OPC_LWSP = 0x12,
9530 M16_OPC_LW = 0x13,
9531 M16_OPC_LBU = 0x14,
9532 M16_OPC_LHU = 0x15,
9533 M16_OPC_LWPC = 0x16,
9534 M16_OPC_LWU = 0x17,
9535 M16_OPC_SB = 0x18,
9536 M16_OPC_SH = 0x19,
9537 M16_OPC_SWSP = 0x1a,
9538 M16_OPC_SW = 0x1b,
9539 M16_OPC_RRR = 0x1c,
9540 M16_OPC_RR = 0x1d,
9541 M16_OPC_EXTEND = 0x1e,
9542 M16_OPC_I64 = 0x1f
9543};
9544
9545/* I8 funct field */
9546enum {
9547 I8_BTEQZ = 0x0,
9548 I8_BTNEZ = 0x1,
9549 I8_SWRASP = 0x2,
9550 I8_ADJSP = 0x3,
9551 I8_SVRS = 0x4,
9552 I8_MOV32R = 0x5,
9553 I8_MOVR32 = 0x7
9554};
9555
9556/* RRR f field */
9557enum {
9558 RRR_DADDU = 0x0,
9559 RRR_ADDU = 0x1,
9560 RRR_DSUBU = 0x2,
9561 RRR_SUBU = 0x3
9562};
9563
9564/* RR funct field */
9565enum {
9566 RR_JR = 0x00,
9567 RR_SDBBP = 0x01,
9568 RR_SLT = 0x02,
9569 RR_SLTU = 0x03,
9570 RR_SLLV = 0x04,
9571 RR_BREAK = 0x05,
9572 RR_SRLV = 0x06,
9573 RR_SRAV = 0x07,
9574 RR_DSRL = 0x08,
9575 RR_CMP = 0x0a,
9576 RR_NEG = 0x0b,
9577 RR_AND = 0x0c,
9578 RR_OR = 0x0d,
9579 RR_XOR = 0x0e,
9580 RR_NOT = 0x0f,
9581 RR_MFHI = 0x10,
9582 RR_CNVT = 0x11,
9583 RR_MFLO = 0x12,
9584 RR_DSRA = 0x13,
9585 RR_DSLLV = 0x14,
9586 RR_DSRLV = 0x16,
9587 RR_DSRAV = 0x17,
9588 RR_MULT = 0x18,
9589 RR_MULTU = 0x19,
9590 RR_DIV = 0x1a,
9591 RR_DIVU = 0x1b,
9592 RR_DMULT = 0x1c,
9593 RR_DMULTU = 0x1d,
9594 RR_DDIV = 0x1e,
9595 RR_DDIVU = 0x1f
9596};
9597
9598/* I64 funct field */
9599enum {
9600 I64_LDSP = 0x0,
9601 I64_SDSP = 0x1,
9602 I64_SDRASP = 0x2,
9603 I64_DADJSP = 0x3,
9604 I64_LDPC = 0x4,
364d4831 9605 I64_DADDIU5 = 0x5,
6ea219d0
NF
9606 I64_DADDIUPC = 0x6,
9607 I64_DADDIUSP = 0x7
9608};
9609
9610/* RR ry field for CNVT */
9611enum {
9612 RR_RY_CNVT_ZEB = 0x0,
9613 RR_RY_CNVT_ZEH = 0x1,
9614 RR_RY_CNVT_ZEW = 0x2,
9615 RR_RY_CNVT_SEB = 0x4,
9616 RR_RY_CNVT_SEH = 0x5,
9617 RR_RY_CNVT_SEW = 0x6,
9618};
9619
364d4831
NF
9620static int xlat (int r)
9621{
9622 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9623
9624 return map[r];
9625}
9626
9627static void gen_mips16_save (DisasContext *ctx,
9628 int xsregs, int aregs,
9629 int do_ra, int do_s0, int do_s1,
9630 int framesize)
9631{
9632 TCGv t0 = tcg_temp_new();
9633 TCGv t1 = tcg_temp_new();
9634 int args, astatic;
9635
9636 switch (aregs) {
9637 case 0:
9638 case 1:
9639 case 2:
9640 case 3:
9641 case 11:
9642 args = 0;
9643 break;
9644 case 4:
9645 case 5:
9646 case 6:
9647 case 7:
9648 args = 1;
9649 break;
9650 case 8:
9651 case 9:
9652 case 10:
9653 args = 2;
9654 break;
9655 case 12:
9656 case 13:
9657 args = 3;
9658 break;
9659 case 14:
9660 args = 4;
9661 break;
9662 default:
9663 generate_exception(ctx, EXCP_RI);
9664 return;
9665 }
9666
9667 switch (args) {
9668 case 4:
9669 gen_base_offset_addr(ctx, t0, 29, 12);
9670 gen_load_gpr(t1, 7);
5f68f5ae 9671 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9672 /* Fall through */
9673 case 3:
9674 gen_base_offset_addr(ctx, t0, 29, 8);
9675 gen_load_gpr(t1, 6);
5f68f5ae 9676 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9677 /* Fall through */
9678 case 2:
9679 gen_base_offset_addr(ctx, t0, 29, 4);
9680 gen_load_gpr(t1, 5);
5f68f5ae 9681 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9682 /* Fall through */
9683 case 1:
9684 gen_base_offset_addr(ctx, t0, 29, 0);
9685 gen_load_gpr(t1, 4);
5f68f5ae 9686 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
9687 }
9688
9689 gen_load_gpr(t0, 29);
9690
5f68f5ae
AJ
9691#define DECR_AND_STORE(reg) do { \
9692 tcg_gen_subi_tl(t0, t0, 4); \
9693 gen_load_gpr(t1, reg); \
9694 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
9695 } while (0)
9696
9697 if (do_ra) {
9698 DECR_AND_STORE(31);
9699 }
9700
9701 switch (xsregs) {
9702 case 7:
9703 DECR_AND_STORE(30);
9704 /* Fall through */
9705 case 6:
9706 DECR_AND_STORE(23);
9707 /* Fall through */
9708 case 5:
9709 DECR_AND_STORE(22);
9710 /* Fall through */
9711 case 4:
9712 DECR_AND_STORE(21);
9713 /* Fall through */
9714 case 3:
9715 DECR_AND_STORE(20);
9716 /* Fall through */
9717 case 2:
9718 DECR_AND_STORE(19);
9719 /* Fall through */
9720 case 1:
9721 DECR_AND_STORE(18);
9722 }
9723
9724 if (do_s1) {
9725 DECR_AND_STORE(17);
9726 }
9727 if (do_s0) {
9728 DECR_AND_STORE(16);
9729 }
9730
9731 switch (aregs) {
9732 case 0:
9733 case 4:
9734 case 8:
9735 case 12:
9736 case 14:
9737 astatic = 0;
9738 break;
9739 case 1:
9740 case 5:
9741 case 9:
9742 case 13:
9743 astatic = 1;
9744 break;
9745 case 2:
9746 case 6:
9747 case 10:
9748 astatic = 2;
9749 break;
9750 case 3:
9751 case 7:
9752 astatic = 3;
9753 break;
9754 case 11:
9755 astatic = 4;
9756 break;
9757 default:
9758 generate_exception(ctx, EXCP_RI);
9759 return;
9760 }
9761
9762 if (astatic > 0) {
9763 DECR_AND_STORE(7);
9764 if (astatic > 1) {
9765 DECR_AND_STORE(6);
9766 if (astatic > 2) {
9767 DECR_AND_STORE(5);
9768 if (astatic > 3) {
9769 DECR_AND_STORE(4);
9770 }
9771 }
9772 }
9773 }
9774#undef DECR_AND_STORE
9775
9776 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9777 tcg_temp_free(t0);
9778 tcg_temp_free(t1);
9779}
9780
9781static void gen_mips16_restore (DisasContext *ctx,
9782 int xsregs, int aregs,
9783 int do_ra, int do_s0, int do_s1,
9784 int framesize)
9785{
9786 int astatic;
9787 TCGv t0 = tcg_temp_new();
9788 TCGv t1 = tcg_temp_new();
9789
9790 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9791
5f68f5ae
AJ
9792#define DECR_AND_LOAD(reg) do { \
9793 tcg_gen_subi_tl(t0, t0, 4); \
9794 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9795 gen_store_gpr(t1, reg); \
364d4831
NF
9796 } while (0)
9797
9798 if (do_ra) {
9799 DECR_AND_LOAD(31);
9800 }
9801
9802 switch (xsregs) {
9803 case 7:
9804 DECR_AND_LOAD(30);
9805 /* Fall through */
9806 case 6:
9807 DECR_AND_LOAD(23);
9808 /* Fall through */
9809 case 5:
9810 DECR_AND_LOAD(22);
9811 /* Fall through */
9812 case 4:
9813 DECR_AND_LOAD(21);
9814 /* Fall through */
9815 case 3:
9816 DECR_AND_LOAD(20);
9817 /* Fall through */
9818 case 2:
9819 DECR_AND_LOAD(19);
9820 /* Fall through */
9821 case 1:
9822 DECR_AND_LOAD(18);
9823 }
9824
9825 if (do_s1) {
9826 DECR_AND_LOAD(17);
9827 }
9828 if (do_s0) {
9829 DECR_AND_LOAD(16);
9830 }
9831
9832 switch (aregs) {
9833 case 0:
9834 case 4:
9835 case 8:
9836 case 12:
9837 case 14:
9838 astatic = 0;
9839 break;
9840 case 1:
9841 case 5:
9842 case 9:
9843 case 13:
9844 astatic = 1;
9845 break;
9846 case 2:
9847 case 6:
9848 case 10:
9849 astatic = 2;
9850 break;
9851 case 3:
9852 case 7:
9853 astatic = 3;
9854 break;
9855 case 11:
9856 astatic = 4;
9857 break;
9858 default:
9859 generate_exception(ctx, EXCP_RI);
9860 return;
9861 }
9862
9863 if (astatic > 0) {
9864 DECR_AND_LOAD(7);
9865 if (astatic > 1) {
9866 DECR_AND_LOAD(6);
9867 if (astatic > 2) {
9868 DECR_AND_LOAD(5);
9869 if (astatic > 3) {
9870 DECR_AND_LOAD(4);
9871 }
9872 }
9873 }
9874 }
9875#undef DECR_AND_LOAD
9876
9877 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9878 tcg_temp_free(t0);
9879 tcg_temp_free(t1);
9880}
9881
9882static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9883 int is_64_bit, int extended)
9884{
9885 TCGv t0;
9886
9887 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9888 generate_exception(ctx, EXCP_RI);
9889 return;
9890 }
9891
9892 t0 = tcg_temp_new();
9893
9894 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9895 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9896 if (!is_64_bit) {
9897 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9898 }
9899
9900 tcg_temp_free(t0);
9901}
9902
9903#if defined(TARGET_MIPS64)
d75c135e 9904static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
9905 int ry, int funct, int16_t offset,
9906 int extended)
9907{
9908 switch (funct) {
9909 case I64_LDSP:
9910 check_mips_64(ctx);
9911 offset = extended ? offset : offset << 3;
d75c135e 9912 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9913 break;
9914 case I64_SDSP:
9915 check_mips_64(ctx);
9916 offset = extended ? offset : offset << 3;
5c13fdfd 9917 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9918 break;
9919 case I64_SDRASP:
9920 check_mips_64(ctx);
9921 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9922 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9923 break;
9924 case I64_DADJSP:
9925 check_mips_64(ctx);
9926 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 9927 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
9928 break;
9929 case I64_LDPC:
9930 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9931 generate_exception(ctx, EXCP_RI);
9932 } else {
9933 offset = extended ? offset : offset << 3;
d75c135e 9934 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9935 }
9936 break;
9937 case I64_DADDIU5:
9938 check_mips_64(ctx);
9939 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 9940 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
9941 break;
9942 case I64_DADDIUPC:
9943 check_mips_64(ctx);
9944 offset = extended ? offset : offset << 2;
9945 gen_addiupc(ctx, ry, offset, 1, extended);
9946 break;
9947 case I64_DADDIUSP:
9948 check_mips_64(ctx);
9949 offset = extended ? offset : offset << 2;
d75c135e 9950 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
9951 break;
9952 }
9953}
9954#endif
9955
240ce26a 9956static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 9957{
895c2d04 9958 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9959 int op, rx, ry, funct, sa;
9960 int16_t imm, offset;
9961
9962 ctx->opcode = (ctx->opcode << 16) | extend;
9963 op = (ctx->opcode >> 11) & 0x1f;
9964 sa = (ctx->opcode >> 22) & 0x1f;
9965 funct = (ctx->opcode >> 8) & 0x7;
9966 rx = xlat((ctx->opcode >> 8) & 0x7);
9967 ry = xlat((ctx->opcode >> 5) & 0x7);
9968 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9969 | ((ctx->opcode >> 21) & 0x3f) << 5
9970 | (ctx->opcode & 0x1f));
9971
9972 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9973 counterparts. */
9974 switch (op) {
9975 case M16_OPC_ADDIUSP:
d75c135e 9976 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
9977 break;
9978 case M16_OPC_ADDIUPC:
9979 gen_addiupc(ctx, rx, imm, 0, 1);
9980 break;
9981 case M16_OPC_B:
9982 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9983 /* No delay slot, so just process as a normal instruction */
9984 break;
9985 case M16_OPC_BEQZ:
9986 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9987 /* No delay slot, so just process as a normal instruction */
9988 break;
9989 case M16_OPC_BNEQZ:
9990 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9991 /* No delay slot, so just process as a normal instruction */
9992 break;
9993 case M16_OPC_SHIFT:
9994 switch (ctx->opcode & 0x3) {
9995 case 0x0:
d75c135e 9996 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
9997 break;
9998 case 0x1:
9999#if defined(TARGET_MIPS64)
10000 check_mips_64(ctx);
d75c135e 10001 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10002#else
10003 generate_exception(ctx, EXCP_RI);
10004#endif
10005 break;
10006 case 0x2:
d75c135e 10007 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10008 break;
10009 case 0x3:
d75c135e 10010 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10011 break;
10012 }
10013 break;
10014#if defined(TARGET_MIPS64)
10015 case M16_OPC_LD:
10016 check_mips_64(ctx);
d75c135e 10017 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
10018 break;
10019#endif
10020 case M16_OPC_RRIA:
10021 imm = ctx->opcode & 0xf;
10022 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
10023 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
10024 imm = (int16_t) (imm << 1) >> 1;
10025 if ((ctx->opcode >> 4) & 0x1) {
10026#if defined(TARGET_MIPS64)
10027 check_mips_64(ctx);
d75c135e 10028 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10029#else
10030 generate_exception(ctx, EXCP_RI);
10031#endif
10032 } else {
d75c135e 10033 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10034 }
10035 break;
10036 case M16_OPC_ADDIU8:
d75c135e 10037 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10038 break;
10039 case M16_OPC_SLTI:
d75c135e 10040 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10041 break;
10042 case M16_OPC_SLTIU:
d75c135e 10043 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10044 break;
10045 case M16_OPC_I8:
10046 switch (funct) {
10047 case I8_BTEQZ:
10048 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
10049 break;
10050 case I8_BTNEZ:
10051 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
10052 break;
10053 case I8_SWRASP:
5c13fdfd 10054 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
10055 break;
10056 case I8_ADJSP:
d75c135e 10057 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
10058 break;
10059 case I8_SVRS:
10060 {
10061 int xsregs = (ctx->opcode >> 24) & 0x7;
10062 int aregs = (ctx->opcode >> 16) & 0xf;
10063 int do_ra = (ctx->opcode >> 6) & 0x1;
10064 int do_s0 = (ctx->opcode >> 5) & 0x1;
10065 int do_s1 = (ctx->opcode >> 4) & 0x1;
10066 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
10067 | (ctx->opcode & 0xf)) << 3;
10068
10069 if (ctx->opcode & (1 << 7)) {
10070 gen_mips16_save(ctx, xsregs, aregs,
10071 do_ra, do_s0, do_s1,
10072 framesize);
10073 } else {
10074 gen_mips16_restore(ctx, xsregs, aregs,
10075 do_ra, do_s0, do_s1,
10076 framesize);
10077 }
10078 }
10079 break;
10080 default:
10081 generate_exception(ctx, EXCP_RI);
10082 break;
10083 }
10084 break;
10085 case M16_OPC_LI:
10086 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
10087 break;
10088 case M16_OPC_CMPI:
10089 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
10090 break;
10091#if defined(TARGET_MIPS64)
10092 case M16_OPC_SD:
5c13fdfd 10093 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
10094 break;
10095#endif
10096 case M16_OPC_LB:
d75c135e 10097 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10098 break;
10099 case M16_OPC_LH:
d75c135e 10100 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
10101 break;
10102 case M16_OPC_LWSP:
d75c135e 10103 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
10104 break;
10105 case M16_OPC_LW:
d75c135e 10106 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
10107 break;
10108 case M16_OPC_LBU:
d75c135e 10109 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10110 break;
10111 case M16_OPC_LHU:
d75c135e 10112 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
10113 break;
10114 case M16_OPC_LWPC:
d75c135e 10115 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
10116 break;
10117#if defined(TARGET_MIPS64)
10118 case M16_OPC_LWU:
d75c135e 10119 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
10120 break;
10121#endif
10122 case M16_OPC_SB:
5c13fdfd 10123 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10124 break;
10125 case M16_OPC_SH:
5c13fdfd 10126 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
10127 break;
10128 case M16_OPC_SWSP:
5c13fdfd 10129 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
10130 break;
10131 case M16_OPC_SW:
5c13fdfd 10132 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
10133 break;
10134#if defined(TARGET_MIPS64)
10135 case M16_OPC_I64:
d75c135e 10136 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
10137 break;
10138#endif
10139 default:
10140 generate_exception(ctx, EXCP_RI);
10141 break;
10142 }
10143
10144 return 4;
10145}
10146
240ce26a 10147static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
10148{
10149 int rx, ry;
10150 int sa;
10151 int op, cnvt_op, op1, offset;
10152 int funct;
10153 int n_bytes;
10154
10155 op = (ctx->opcode >> 11) & 0x1f;
10156 sa = (ctx->opcode >> 2) & 0x7;
10157 sa = sa == 0 ? 8 : sa;
10158 rx = xlat((ctx->opcode >> 8) & 0x7);
10159 cnvt_op = (ctx->opcode >> 5) & 0x7;
10160 ry = xlat((ctx->opcode >> 5) & 0x7);
10161 op1 = offset = ctx->opcode & 0x1f;
10162
10163 n_bytes = 2;
10164
10165 switch (op) {
10166 case M16_OPC_ADDIUSP:
10167 {
10168 int16_t imm = ((uint8_t) ctx->opcode) << 2;
10169
d75c135e 10170 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
10171 }
10172 break;
10173 case M16_OPC_ADDIUPC:
10174 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
10175 break;
10176 case M16_OPC_B:
10177 offset = (ctx->opcode & 0x7ff) << 1;
10178 offset = (int16_t)(offset << 4) >> 4;
10179 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
10180 /* No delay slot, so just process as a normal instruction */
10181 break;
10182 case M16_OPC_JAL:
895c2d04 10183 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
10184 offset = (((ctx->opcode & 0x1f) << 21)
10185 | ((ctx->opcode >> 5) & 0x1f) << 16
10186 | offset) << 2;
620e48f6 10187 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
10188 gen_compute_branch(ctx, op, 4, rx, ry, offset);
10189 n_bytes = 4;
364d4831
NF
10190 break;
10191 case M16_OPC_BEQZ:
10192 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10193 /* No delay slot, so just process as a normal instruction */
10194 break;
10195 case M16_OPC_BNEQZ:
10196 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10197 /* No delay slot, so just process as a normal instruction */
10198 break;
10199 case M16_OPC_SHIFT:
10200 switch (ctx->opcode & 0x3) {
10201 case 0x0:
d75c135e 10202 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
10203 break;
10204 case 0x1:
10205#if defined(TARGET_MIPS64)
10206 check_mips_64(ctx);
d75c135e 10207 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831
NF
10208#else
10209 generate_exception(ctx, EXCP_RI);
10210#endif
10211 break;
10212 case 0x2:
d75c135e 10213 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
10214 break;
10215 case 0x3:
d75c135e 10216 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
10217 break;
10218 }
10219 break;
10220#if defined(TARGET_MIPS64)
10221 case M16_OPC_LD:
10222 check_mips_64(ctx);
d75c135e 10223 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
10224 break;
10225#endif
10226 case M16_OPC_RRIA:
10227 {
10228 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
10229
10230 if ((ctx->opcode >> 4) & 1) {
10231#if defined(TARGET_MIPS64)
10232 check_mips_64(ctx);
d75c135e 10233 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831
NF
10234#else
10235 generate_exception(ctx, EXCP_RI);
10236#endif
10237 } else {
d75c135e 10238 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
10239 }
10240 }
10241 break;
10242 case M16_OPC_ADDIU8:
10243 {
10244 int16_t imm = (int8_t) ctx->opcode;
10245
d75c135e 10246 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
10247 }
10248 break;
10249 case M16_OPC_SLTI:
10250 {
10251 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10252 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
10253 }
10254 break;
10255 case M16_OPC_SLTIU:
10256 {
10257 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10258 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
10259 }
10260 break;
10261 case M16_OPC_I8:
10262 {
10263 int reg32;
10264
10265 funct = (ctx->opcode >> 8) & 0x7;
10266 switch (funct) {
10267 case I8_BTEQZ:
10268 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
10269 ((int8_t)ctx->opcode) << 1);
10270 break;
10271 case I8_BTNEZ:
10272 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
10273 ((int8_t)ctx->opcode) << 1);
10274 break;
10275 case I8_SWRASP:
5c13fdfd 10276 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
10277 break;
10278 case I8_ADJSP:
d75c135e 10279 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
10280 ((int8_t)ctx->opcode) << 3);
10281 break;
10282 case I8_SVRS:
10283 {
10284 int do_ra = ctx->opcode & (1 << 6);
10285 int do_s0 = ctx->opcode & (1 << 5);
10286 int do_s1 = ctx->opcode & (1 << 4);
10287 int framesize = ctx->opcode & 0xf;
10288
10289 if (framesize == 0) {
10290 framesize = 128;
10291 } else {
10292 framesize = framesize << 3;
10293 }
10294
10295 if (ctx->opcode & (1 << 7)) {
10296 gen_mips16_save(ctx, 0, 0,
10297 do_ra, do_s0, do_s1, framesize);
10298 } else {
10299 gen_mips16_restore(ctx, 0, 0,
10300 do_ra, do_s0, do_s1, framesize);
10301 }
10302 }
10303 break;
10304 case I8_MOV32R:
10305 {
10306 int rz = xlat(ctx->opcode & 0x7);
10307
10308 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10309 ((ctx->opcode >> 5) & 0x7);
d75c135e 10310 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
10311 }
10312 break;
10313 case I8_MOVR32:
10314 reg32 = ctx->opcode & 0x1f;
d75c135e 10315 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
10316 break;
10317 default:
10318 generate_exception(ctx, EXCP_RI);
10319 break;
10320 }
10321 }
10322 break;
10323 case M16_OPC_LI:
10324 {
10325 int16_t imm = (uint8_t) ctx->opcode;
10326
d75c135e 10327 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
10328 }
10329 break;
10330 case M16_OPC_CMPI:
10331 {
10332 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 10333 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
10334 }
10335 break;
10336#if defined(TARGET_MIPS64)
10337 case M16_OPC_SD:
10338 check_mips_64(ctx);
5c13fdfd 10339 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
10340 break;
10341#endif
10342 case M16_OPC_LB:
d75c135e 10343 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
10344 break;
10345 case M16_OPC_LH:
d75c135e 10346 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10347 break;
10348 case M16_OPC_LWSP:
d75c135e 10349 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10350 break;
10351 case M16_OPC_LW:
d75c135e 10352 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10353 break;
10354 case M16_OPC_LBU:
d75c135e 10355 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10356 break;
10357 case M16_OPC_LHU:
d75c135e 10358 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10359 break;
10360 case M16_OPC_LWPC:
d75c135e 10361 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10362 break;
10363#if defined (TARGET_MIPS64)
10364 case M16_OPC_LWU:
10365 check_mips_64(ctx);
d75c135e 10366 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10367 break;
10368#endif
10369 case M16_OPC_SB:
5c13fdfd 10370 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10371 break;
10372 case M16_OPC_SH:
5c13fdfd 10373 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10374 break;
10375 case M16_OPC_SWSP:
5c13fdfd 10376 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10377 break;
10378 case M16_OPC_SW:
5c13fdfd 10379 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10380 break;
10381 case M16_OPC_RRR:
10382 {
10383 int rz = xlat((ctx->opcode >> 2) & 0x7);
10384 int mips32_op;
10385
10386 switch (ctx->opcode & 0x3) {
10387 case RRR_ADDU:
10388 mips32_op = OPC_ADDU;
10389 break;
10390 case RRR_SUBU:
10391 mips32_op = OPC_SUBU;
10392 break;
10393#if defined(TARGET_MIPS64)
10394 case RRR_DADDU:
10395 mips32_op = OPC_DADDU;
10396 check_mips_64(ctx);
10397 break;
10398 case RRR_DSUBU:
10399 mips32_op = OPC_DSUBU;
10400 check_mips_64(ctx);
10401 break;
10402#endif
10403 default:
10404 generate_exception(ctx, EXCP_RI);
10405 goto done;
10406 }
10407
d75c135e 10408 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
10409 done:
10410 ;
10411 }
10412 break;
10413 case M16_OPC_RR:
10414 switch (op1) {
10415 case RR_JR:
10416 {
10417 int nd = (ctx->opcode >> 7) & 0x1;
10418 int link = (ctx->opcode >> 6) & 0x1;
10419 int ra = (ctx->opcode >> 5) & 0x1;
10420
10421 if (link) {
620e48f6 10422 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10423 } else {
10424 op = OPC_JR;
10425 }
10426
10427 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
364d4831
NF
10428 }
10429 break;
10430 case RR_SDBBP:
10431 /* XXX: not clear which exception should be raised
10432 * when in debug mode...
10433 */
d75c135e 10434 check_insn(ctx, ISA_MIPS32);
364d4831
NF
10435 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10436 generate_exception(ctx, EXCP_DBp);
10437 } else {
10438 generate_exception(ctx, EXCP_DBp);
10439 }
10440 break;
10441 case RR_SLT:
d75c135e 10442 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10443 break;
10444 case RR_SLTU:
d75c135e 10445 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10446 break;
10447 case RR_BREAK:
10448 generate_exception(ctx, EXCP_BREAK);
10449 break;
10450 case RR_SLLV:
d75c135e 10451 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
10452 break;
10453 case RR_SRLV:
d75c135e 10454 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
10455 break;
10456 case RR_SRAV:
d75c135e 10457 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
10458 break;
10459#if defined (TARGET_MIPS64)
10460 case RR_DSRL:
10461 check_mips_64(ctx);
d75c135e 10462 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
10463 break;
10464#endif
10465 case RR_CMP:
d75c135e 10466 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10467 break;
10468 case RR_NEG:
d75c135e 10469 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
10470 break;
10471 case RR_AND:
d75c135e 10472 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10473 break;
10474 case RR_OR:
d75c135e 10475 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10476 break;
10477 case RR_XOR:
d75c135e 10478 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10479 break;
10480 case RR_NOT:
d75c135e 10481 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10482 break;
10483 case RR_MFHI:
26135ead 10484 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
10485 break;
10486 case RR_CNVT:
10487 switch (cnvt_op) {
10488 case RR_RY_CNVT_ZEB:
10489 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10490 break;
10491 case RR_RY_CNVT_ZEH:
10492 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10493 break;
10494 case RR_RY_CNVT_SEB:
10495 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10496 break;
10497 case RR_RY_CNVT_SEH:
10498 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10499 break;
10500#if defined (TARGET_MIPS64)
10501 case RR_RY_CNVT_ZEW:
10502 check_mips_64(ctx);
10503 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10504 break;
10505 case RR_RY_CNVT_SEW:
10506 check_mips_64(ctx);
10507 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10508 break;
10509#endif
10510 default:
10511 generate_exception(ctx, EXCP_RI);
10512 break;
10513 }
10514 break;
10515 case RR_MFLO:
26135ead 10516 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
10517 break;
10518#if defined (TARGET_MIPS64)
10519 case RR_DSRA:
10520 check_mips_64(ctx);
d75c135e 10521 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
10522 break;
10523 case RR_DSLLV:
10524 check_mips_64(ctx);
d75c135e 10525 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
10526 break;
10527 case RR_DSRLV:
10528 check_mips_64(ctx);
d75c135e 10529 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
10530 break;
10531 case RR_DSRAV:
10532 check_mips_64(ctx);
d75c135e 10533 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
10534 break;
10535#endif
10536 case RR_MULT:
26135ead 10537 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
10538 break;
10539 case RR_MULTU:
26135ead 10540 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
10541 break;
10542 case RR_DIV:
26135ead 10543 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
10544 break;
10545 case RR_DIVU:
26135ead 10546 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
10547 break;
10548#if defined (TARGET_MIPS64)
10549 case RR_DMULT:
10550 check_mips_64(ctx);
26135ead 10551 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
10552 break;
10553 case RR_DMULTU:
10554 check_mips_64(ctx);
26135ead 10555 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
10556 break;
10557 case RR_DDIV:
10558 check_mips_64(ctx);
26135ead 10559 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
10560 break;
10561 case RR_DDIVU:
10562 check_mips_64(ctx);
26135ead 10563 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
10564 break;
10565#endif
10566 default:
10567 generate_exception(ctx, EXCP_RI);
10568 break;
10569 }
10570 break;
10571 case M16_OPC_EXTEND:
240ce26a 10572 decode_extended_mips16_opc(env, ctx);
364d4831
NF
10573 n_bytes = 4;
10574 break;
10575#if defined(TARGET_MIPS64)
10576 case M16_OPC_I64:
10577 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 10578 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
10579 break;
10580#endif
10581 default:
10582 generate_exception(ctx, EXCP_RI);
10583 break;
10584 }
10585
10586 return n_bytes;
10587}
10588
211da992 10589/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 10590
211da992
CWR
10591/*
10592 * microMIPS32/microMIPS64 major opcodes
10593 *
10594 * 1. MIPS Architecture for Programmers Volume II-B:
10595 * The microMIPS32 Instruction Set (Revision 3.05)
10596 *
10597 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10598 *
10599 * 2. MIPS Architecture For Programmers Volume II-A:
10600 * The MIPS64 Instruction Set (Revision 3.51)
10601 */
6af0bf9c 10602
3c824109
NF
10603enum {
10604 POOL32A = 0x00,
10605 POOL16A = 0x01,
10606 LBU16 = 0x02,
10607 MOVE16 = 0x03,
10608 ADDI32 = 0x04,
10609 LBU32 = 0x05,
10610 SB32 = 0x06,
10611 LB32 = 0x07,
10612
10613 POOL32B = 0x08,
10614 POOL16B = 0x09,
10615 LHU16 = 0x0a,
10616 ANDI16 = 0x0b,
10617 ADDIU32 = 0x0c,
10618 LHU32 = 0x0d,
10619 SH32 = 0x0e,
10620 LH32 = 0x0f,
10621
10622 POOL32I = 0x10,
10623 POOL16C = 0x11,
10624 LWSP16 = 0x12,
10625 POOL16D = 0x13,
10626 ORI32 = 0x14,
10627 POOL32F = 0x15,
211da992
CWR
10628 POOL32S = 0x16, /* MIPS64 */
10629 DADDIU32 = 0x17, /* MIPS64 */
3c824109 10630
211da992 10631 /* 0x1f is reserved */
3c824109
NF
10632 POOL32C = 0x18,
10633 LWGP16 = 0x19,
10634 LW16 = 0x1a,
10635 POOL16E = 0x1b,
10636 XORI32 = 0x1c,
10637 JALS32 = 0x1d,
10638 ADDIUPC = 0x1e,
3c824109
NF
10639
10640 /* 0x20 is reserved */
10641 RES_20 = 0x20,
10642 POOL16F = 0x21,
10643 SB16 = 0x22,
10644 BEQZ16 = 0x23,
10645 SLTI32 = 0x24,
10646 BEQ32 = 0x25,
10647 SWC132 = 0x26,
10648 LWC132 = 0x27,
10649
10650 /* 0x28 and 0x29 are reserved */
10651 RES_28 = 0x28,
10652 RES_29 = 0x29,
10653 SH16 = 0x2a,
10654 BNEZ16 = 0x2b,
10655 SLTIU32 = 0x2c,
10656 BNE32 = 0x2d,
10657 SDC132 = 0x2e,
10658 LDC132 = 0x2f,
10659
10660 /* 0x30 and 0x31 are reserved */
10661 RES_30 = 0x30,
10662 RES_31 = 0x31,
10663 SWSP16 = 0x32,
10664 B16 = 0x33,
10665 ANDI32 = 0x34,
10666 J32 = 0x35,
211da992
CWR
10667 SD32 = 0x36, /* MIPS64 */
10668 LD32 = 0x37, /* MIPS64 */
3c824109
NF
10669
10670 /* 0x38 and 0x39 are reserved */
10671 RES_38 = 0x38,
10672 RES_39 = 0x39,
10673 SW16 = 0x3a,
10674 LI16 = 0x3b,
10675 JALX32 = 0x3c,
10676 JAL32 = 0x3d,
10677 SW32 = 0x3e,
10678 LW32 = 0x3f
10679};
10680
10681/* POOL32A encoding of minor opcode field */
10682
10683enum {
10684 /* These opcodes are distinguished only by bits 9..6; those bits are
10685 * what are recorded below. */
10686 SLL32 = 0x0,
10687 SRL32 = 0x1,
10688 SRA = 0x2,
10689 ROTR = 0x3,
10690
10691 SLLV = 0x0,
10692 SRLV = 0x1,
10693 SRAV = 0x2,
10694 ROTRV = 0x3,
10695 ADD = 0x4,
10696 ADDU32 = 0x5,
10697 SUB = 0x6,
10698 SUBU32 = 0x7,
10699 MUL = 0x8,
10700 AND = 0x9,
10701 OR32 = 0xa,
10702 NOR = 0xb,
10703 XOR32 = 0xc,
10704 SLT = 0xd,
10705 SLTU = 0xe,
10706
10707 MOVN = 0x0,
10708 MOVZ = 0x1,
10709 LWXS = 0x4,
10710
10711 /* The following can be distinguished by their lower 6 bits. */
10712 INS = 0x0c,
10713 EXT = 0x2c,
10714 POOL32AXF = 0x3c
10715};
10716
10717/* POOL32AXF encoding of minor opcode field extension */
10718
d132c79f
CWR
10719/*
10720 * 1. MIPS Architecture for Programmers Volume II-B:
10721 * The microMIPS32 Instruction Set (Revision 3.05)
10722 *
10723 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10724 *
10725 * 2. MIPS Architecture for Programmers VolumeIV-e:
10726 * The MIPS DSP Application-Specific Extension
10727 * to the microMIPS32 Architecture (Revision 2.34)
10728 *
10729 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10730 */
10731
3c824109
NF
10732enum {
10733 /* bits 11..6 */
10734 TEQ = 0x00,
10735 TGE = 0x08,
10736 TGEU = 0x10,
10737 TLT = 0x20,
10738 TLTU = 0x28,
10739 TNE = 0x30,
10740
10741 MFC0 = 0x03,
10742 MTC0 = 0x0b,
10743
d132c79f
CWR
10744 /* begin of microMIPS32 DSP */
10745
3c824109
NF
10746 /* bits 13..12 for 0x01 */
10747 MFHI_ACC = 0x0,
10748 MFLO_ACC = 0x1,
10749 MTHI_ACC = 0x2,
10750 MTLO_ACC = 0x3,
10751
10752 /* bits 13..12 for 0x2a */
10753 MADD_ACC = 0x0,
10754 MADDU_ACC = 0x1,
10755 MSUB_ACC = 0x2,
10756 MSUBU_ACC = 0x3,
10757
10758 /* bits 13..12 for 0x32 */
10759 MULT_ACC = 0x0,
6801038b 10760 MULTU_ACC = 0x1,
3c824109 10761
d132c79f
CWR
10762 /* end of microMIPS32 DSP */
10763
3c824109
NF
10764 /* bits 15..12 for 0x2c */
10765 SEB = 0x2,
10766 SEH = 0x3,
10767 CLO = 0x4,
10768 CLZ = 0x5,
10769 RDHWR = 0x6,
10770 WSBH = 0x7,
10771 MULT = 0x8,
10772 MULTU = 0x9,
10773 DIV = 0xa,
10774 DIVU = 0xb,
10775 MADD = 0xc,
10776 MADDU = 0xd,
10777 MSUB = 0xe,
10778 MSUBU = 0xf,
10779
10780 /* bits 15..12 for 0x34 */
10781 MFC2 = 0x4,
10782 MTC2 = 0x5,
10783 MFHC2 = 0x8,
10784 MTHC2 = 0x9,
10785 CFC2 = 0xc,
10786 CTC2 = 0xd,
10787
10788 /* bits 15..12 for 0x3c */
10789 JALR = 0x0,
10790 JR = 0x0, /* alias */
10791 JALR_HB = 0x1,
10792 JALRS = 0x4,
10793 JALRS_HB = 0x5,
10794
10795 /* bits 15..12 for 0x05 */
10796 RDPGPR = 0xe,
10797 WRPGPR = 0xf,
10798
10799 /* bits 15..12 for 0x0d */
10800 TLBP = 0x0,
10801 TLBR = 0x1,
10802 TLBWI = 0x2,
10803 TLBWR = 0x3,
10804 WAIT = 0x9,
10805 IRET = 0xd,
10806 DERET = 0xe,
10807 ERET = 0xf,
10808
10809 /* bits 15..12 for 0x15 */
10810 DMT = 0x0,
10811 DVPE = 0x1,
10812 EMT = 0x2,
10813 EVPE = 0x3,
10814
10815 /* bits 15..12 for 0x1d */
10816 DI = 0x4,
10817 EI = 0x5,
10818
10819 /* bits 15..12 for 0x2d */
10820 SYNC = 0x6,
10821 SYSCALL = 0x8,
10822 SDBBP = 0xd,
10823
10824 /* bits 15..12 for 0x35 */
10825 MFHI32 = 0x0,
10826 MFLO32 = 0x1,
10827 MTHI32 = 0x2,
10828 MTLO32 = 0x3,
10829};
10830
10831/* POOL32B encoding of minor opcode field (bits 15..12) */
10832
10833enum {
10834 LWC2 = 0x0,
10835 LWP = 0x1,
10836 LDP = 0x4,
10837 LWM32 = 0x5,
10838 CACHE = 0x6,
10839 LDM = 0x7,
10840 SWC2 = 0x8,
10841 SWP = 0x9,
10842 SDP = 0xc,
10843 SWM32 = 0xd,
10844 SDM = 0xf
10845};
10846
10847/* POOL32C encoding of minor opcode field (bits 15..12) */
10848
10849enum {
10850 LWL = 0x0,
10851 SWL = 0x8,
10852 LWR = 0x1,
10853 SWR = 0x9,
10854 PREF = 0x2,
10855 /* 0xa is reserved */
10856 LL = 0x3,
10857 SC = 0xb,
10858 LDL = 0x4,
10859 SDL = 0xc,
10860 LDR = 0x5,
10861 SDR = 0xd,
10862 /* 0x6 is reserved */
10863 LWU = 0xe,
10864 LLD = 0x7,
10865 SCD = 0xf
10866};
10867
10868/* POOL32F encoding of minor opcode field (bits 5..0) */
10869
10870enum {
10871 /* These are the bit 7..6 values */
10872 ADD_FMT = 0x0,
10873 MOVN_FMT = 0x0,
10874
10875 SUB_FMT = 0x1,
10876 MOVZ_FMT = 0x1,
10877
10878 MUL_FMT = 0x2,
10879
10880 DIV_FMT = 0x3,
10881
10882 /* These are the bit 8..6 values */
10883 RSQRT2_FMT = 0x0,
10884 MOVF_FMT = 0x0,
10885
10886 LWXC1 = 0x1,
10887 MOVT_FMT = 0x1,
10888
10889 PLL_PS = 0x2,
10890 SWXC1 = 0x2,
10891
10892 PLU_PS = 0x3,
10893 LDXC1 = 0x3,
10894
10895 PUL_PS = 0x4,
10896 SDXC1 = 0x4,
10897 RECIP2_FMT = 0x4,
10898
10899 PUU_PS = 0x5,
10900 LUXC1 = 0x5,
10901
10902 CVT_PS_S = 0x6,
10903 SUXC1 = 0x6,
10904 ADDR_PS = 0x6,
10905 PREFX = 0x6,
10906
10907 MULR_PS = 0x7,
10908
10909 MADD_S = 0x01,
10910 MADD_D = 0x09,
10911 MADD_PS = 0x11,
10912 ALNV_PS = 0x19,
10913 MSUB_S = 0x21,
10914 MSUB_D = 0x29,
10915 MSUB_PS = 0x31,
10916
10917 NMADD_S = 0x02,
10918 NMADD_D = 0x0a,
10919 NMADD_PS = 0x12,
10920 NMSUB_S = 0x22,
10921 NMSUB_D = 0x2a,
10922 NMSUB_PS = 0x32,
10923
10924 POOL32FXF = 0x3b,
10925
10926 CABS_COND_FMT = 0x1c, /* MIPS3D */
10927 C_COND_FMT = 0x3c
10928};
10929
10930/* POOL32Fxf encoding of minor opcode extension field */
10931
10932enum {
10933 CVT_L = 0x04,
10934 RSQRT_FMT = 0x08,
10935 FLOOR_L = 0x0c,
10936 CVT_PW_PS = 0x1c,
10937 CVT_W = 0x24,
10938 SQRT_FMT = 0x28,
10939 FLOOR_W = 0x2c,
10940 CVT_PS_PW = 0x3c,
10941 CFC1 = 0x40,
10942 RECIP_FMT = 0x48,
10943 CEIL_L = 0x4c,
10944 CTC1 = 0x60,
10945 CEIL_W = 0x6c,
10946 MFC1 = 0x80,
10947 CVT_S_PL = 0x84,
10948 TRUNC_L = 0x8c,
10949 MTC1 = 0xa0,
10950 CVT_S_PU = 0xa4,
10951 TRUNC_W = 0xac,
10952 MFHC1 = 0xc0,
10953 ROUND_L = 0xcc,
10954 MTHC1 = 0xe0,
10955 ROUND_W = 0xec,
10956
10957 MOV_FMT = 0x01,
10958 MOVF = 0x05,
10959 ABS_FMT = 0x0d,
10960 RSQRT1_FMT = 0x1d,
10961 MOVT = 0x25,
10962 NEG_FMT = 0x2d,
10963 CVT_D = 0x4d,
10964 RECIP1_FMT = 0x5d,
10965 CVT_S = 0x6d
10966};
10967
10968/* POOL32I encoding of minor opcode field (bits 25..21) */
10969
10970enum {
10971 BLTZ = 0x00,
10972 BLTZAL = 0x01,
10973 BGEZ = 0x02,
10974 BGEZAL = 0x03,
10975 BLEZ = 0x04,
10976 BNEZC = 0x05,
10977 BGTZ = 0x06,
10978 BEQZC = 0x07,
10979 TLTI = 0x08,
10980 TGEI = 0x09,
10981 TLTIU = 0x0a,
10982 TGEIU = 0x0b,
10983 TNEI = 0x0c,
10984 LUI = 0x0d,
10985 TEQI = 0x0e,
10986 SYNCI = 0x10,
10987 BLTZALS = 0x11,
10988 BGEZALS = 0x13,
10989 BC2F = 0x14,
10990 BC2T = 0x15,
10991 BPOSGE64 = 0x1a,
10992 BPOSGE32 = 0x1b,
10993 /* These overlap and are distinguished by bit16 of the instruction */
10994 BC1F = 0x1c,
10995 BC1T = 0x1d,
10996 BC1ANY2F = 0x1c,
10997 BC1ANY2T = 0x1d,
10998 BC1ANY4F = 0x1e,
10999 BC1ANY4T = 0x1f
11000};
11001
11002/* POOL16A encoding of minor opcode field */
11003
11004enum {
11005 ADDU16 = 0x0,
11006 SUBU16 = 0x1
11007};
11008
11009/* POOL16B encoding of minor opcode field */
11010
11011enum {
11012 SLL16 = 0x0,
11013 SRL16 = 0x1
11014};
11015
11016/* POOL16C encoding of minor opcode field */
11017
11018enum {
11019 NOT16 = 0x00,
11020 XOR16 = 0x04,
11021 AND16 = 0x08,
11022 OR16 = 0x0c,
11023 LWM16 = 0x10,
11024 SWM16 = 0x14,
11025 JR16 = 0x18,
11026 JRC16 = 0x1a,
11027 JALR16 = 0x1c,
11028 JALR16S = 0x1e,
11029 MFHI16 = 0x20,
11030 MFLO16 = 0x24,
11031 BREAK16 = 0x28,
11032 SDBBP16 = 0x2c,
11033 JRADDIUSP = 0x30
11034};
11035
11036/* POOL16D encoding of minor opcode field */
11037
11038enum {
11039 ADDIUS5 = 0x0,
11040 ADDIUSP = 0x1
11041};
11042
11043/* POOL16E encoding of minor opcode field */
11044
11045enum {
11046 ADDIUR2 = 0x0,
11047 ADDIUR1SP = 0x1
11048};
11049
11050static int mmreg (int r)
11051{
11052 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11053
11054 return map[r];
11055}
11056
11057/* Used for 16-bit store instructions. */
11058static int mmreg2 (int r)
11059{
11060 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11061
11062 return map[r];
11063}
11064
11065#define uMIPS_RD(op) ((op >> 7) & 0x7)
11066#define uMIPS_RS(op) ((op >> 4) & 0x7)
11067#define uMIPS_RS2(op) uMIPS_RS(op)
11068#define uMIPS_RS1(op) ((op >> 1) & 0x7)
11069#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11070#define uMIPS_RS5(op) (op & 0x1f)
11071
11072/* Signed immediate */
11073#define SIMM(op, start, width) \
11074 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11075 << (32-width)) \
11076 >> (32-width))
11077/* Zero-extended immediate */
11078#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11079
d75c135e 11080static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
11081{
11082 int rd = mmreg(uMIPS_RD(ctx->opcode));
11083
d75c135e 11084 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
11085}
11086
d75c135e 11087static void gen_addiur2(DisasContext *ctx)
3c824109
NF
11088{
11089 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11090 int rd = mmreg(uMIPS_RD(ctx->opcode));
11091 int rs = mmreg(uMIPS_RS(ctx->opcode));
11092
d75c135e 11093 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
11094}
11095
d75c135e 11096static void gen_addiusp(DisasContext *ctx)
3c824109
NF
11097{
11098 int encoded = ZIMM(ctx->opcode, 1, 9);
11099 int decoded;
11100
11101 if (encoded <= 1) {
11102 decoded = 256 + encoded;
11103 } else if (encoded <= 255) {
11104 decoded = encoded;
11105 } else if (encoded <= 509) {
11106 decoded = encoded - 512;
11107 } else {
11108 decoded = encoded - 768;
11109 }
11110
d75c135e 11111 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
11112}
11113
d75c135e 11114static void gen_addius5(DisasContext *ctx)
3c824109
NF
11115{
11116 int imm = SIMM(ctx->opcode, 1, 4);
11117 int rd = (ctx->opcode >> 5) & 0x1f;
11118
d75c135e 11119 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
11120}
11121
d75c135e 11122static void gen_andi16(DisasContext *ctx)
3c824109
NF
11123{
11124 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11125 31, 32, 63, 64, 255, 32768, 65535 };
11126 int rd = mmreg(uMIPS_RD(ctx->opcode));
11127 int rs = mmreg(uMIPS_RS(ctx->opcode));
11128 int encoded = ZIMM(ctx->opcode, 0, 4);
11129
d75c135e 11130 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
11131}
11132
11133static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
11134 int base, int16_t offset)
11135{
e1050a76 11136 const char *opn = "ldst_multiple";
3c824109
NF
11137 TCGv t0, t1;
11138 TCGv_i32 t2;
11139
11140 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11141 generate_exception(ctx, EXCP_RI);
11142 return;
11143 }
11144
11145 t0 = tcg_temp_new();
11146
11147 gen_base_offset_addr(ctx, t0, base, offset);
11148
11149 t1 = tcg_const_tl(reglist);
11150 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 11151
3c824109
NF
11152 save_cpu_state(ctx, 1);
11153 switch (opc) {
11154 case LWM32:
895c2d04 11155 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 11156 opn = "lwm";
3c824109
NF
11157 break;
11158 case SWM32:
895c2d04 11159 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 11160 opn = "swm";
3c824109
NF
11161 break;
11162#ifdef TARGET_MIPS64
11163 case LDM:
895c2d04 11164 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 11165 opn = "ldm";
3c824109
NF
11166 break;
11167 case SDM:
895c2d04 11168 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 11169 opn = "sdm";
3c824109 11170 break;
6af0bf9c 11171#endif
3c824109 11172 }
e1050a76 11173 (void)opn;
3c824109
NF
11174 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
11175 tcg_temp_free(t0);
33087598 11176 tcg_temp_free(t1);
3c824109
NF
11177 tcg_temp_free_i32(t2);
11178}
6af0bf9c 11179
3c824109 11180
240ce26a 11181static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 11182{
3c824109
NF
11183 int rd = mmreg((ctx->opcode >> 3) & 0x7);
11184 int rs = mmreg(ctx->opcode & 0x7);
11185 int opc;
6af0bf9c 11186
3c824109
NF
11187 switch (((ctx->opcode) >> 4) & 0x3f) {
11188 case NOT16 + 0:
11189 case NOT16 + 1:
11190 case NOT16 + 2:
11191 case NOT16 + 3:
d75c135e 11192 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
11193 break;
11194 case XOR16 + 0:
11195 case XOR16 + 1:
11196 case XOR16 + 2:
11197 case XOR16 + 3:
d75c135e 11198 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
11199 break;
11200 case AND16 + 0:
11201 case AND16 + 1:
11202 case AND16 + 2:
11203 case AND16 + 3:
d75c135e 11204 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
11205 break;
11206 case OR16 + 0:
11207 case OR16 + 1:
11208 case OR16 + 2:
11209 case OR16 + 3:
d75c135e 11210 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
11211 break;
11212 case LWM16 + 0:
11213 case LWM16 + 1:
11214 case LWM16 + 2:
11215 case LWM16 + 3:
11216 {
11217 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11218 int offset = ZIMM(ctx->opcode, 0, 4);
11219
11220 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
11221 29, offset << 2);
11222 }
11223 break;
11224 case SWM16 + 0:
11225 case SWM16 + 1:
11226 case SWM16 + 2:
11227 case SWM16 + 3:
11228 {
11229 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11230 int offset = ZIMM(ctx->opcode, 0, 4);
11231
11232 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
11233 29, offset << 2);
11234 }
11235 break;
11236 case JR16 + 0:
11237 case JR16 + 1:
11238 {
11239 int reg = ctx->opcode & 0x1f;
11240
11241 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11242 }
3c824109
NF
11243 break;
11244 case JRC16 + 0:
11245 case JRC16 + 1:
11246 {
11247 int reg = ctx->opcode & 0x1f;
11248
11249 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11250 /* Let normal delay slot handling in our caller take us
11251 to the branch target. */
11252 }
11253 break;
11254 case JALR16 + 0:
11255 case JALR16 + 1:
11256 opc = OPC_JALR;
11257 goto do_jalr;
11258 case JALR16S + 0:
11259 case JALR16S + 1:
11260 opc = OPC_JALRS;
11261 do_jalr:
11262 {
11263 int reg = ctx->opcode & 0x1f;
11264
11265 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
11266 }
3c824109
NF
11267 break;
11268 case MFHI16 + 0:
11269 case MFHI16 + 1:
26135ead 11270 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11271 break;
11272 case MFLO16 + 0:
11273 case MFLO16 + 1:
26135ead 11274 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
11275 break;
11276 case BREAK16:
11277 generate_exception(ctx, EXCP_BREAK);
11278 break;
11279 case SDBBP16:
11280 /* XXX: not clear which exception should be raised
11281 * when in debug mode...
11282 */
d75c135e 11283 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11284 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11285 generate_exception(ctx, EXCP_DBp);
11286 } else {
11287 generate_exception(ctx, EXCP_DBp);
11288 }
11289 break;
11290 case JRADDIUSP + 0:
11291 case JRADDIUSP + 1:
11292 {
11293 int imm = ZIMM(ctx->opcode, 0, 5);
11294
11295 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
d75c135e 11296 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
11297 /* Let normal delay slot handling in our caller take us
11298 to the branch target. */
11299 }
11300 break;
11301 default:
11302 generate_exception(ctx, EXCP_RI);
11303 break;
11304 }
11305}
11306
11307static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
11308{
11309 TCGv t0 = tcg_temp_new();
11310 TCGv t1 = tcg_temp_new();
11311
11312 gen_load_gpr(t0, base);
11313
11314 if (index != 0) {
11315 gen_load_gpr(t1, index);
11316 tcg_gen_shli_tl(t1, t1, 2);
11317 gen_op_addr_add(ctx, t0, t1, t0);
11318 }
11319
5f68f5ae 11320 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11321 gen_store_gpr(t1, rd);
11322
11323 tcg_temp_free(t0);
11324 tcg_temp_free(t1);
11325}
11326
11327static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
11328 int base, int16_t offset)
11329{
11330 const char *opn = "ldst_pair";
11331 TCGv t0, t1;
11332
36c6711b 11333 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 11334 generate_exception(ctx, EXCP_RI);
d796321b
FB
11335 return;
11336 }
11337
3c824109
NF
11338 t0 = tcg_temp_new();
11339 t1 = tcg_temp_new();
8e9ade68 11340
3c824109
NF
11341 gen_base_offset_addr(ctx, t0, base, offset);
11342
11343 switch (opc) {
11344 case LWP:
36c6711b
EJ
11345 if (rd == base) {
11346 generate_exception(ctx, EXCP_RI);
11347 return;
11348 }
5f68f5ae 11349 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11350 gen_store_gpr(t1, rd);
11351 tcg_gen_movi_tl(t1, 4);
11352 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11353 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
11354 gen_store_gpr(t1, rd+1);
11355 opn = "lwp";
11356 break;
11357 case SWP:
3c824109 11358 gen_load_gpr(t1, rd);
5f68f5ae 11359 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11360 tcg_gen_movi_tl(t1, 4);
11361 gen_op_addr_add(ctx, t0, t0, t1);
11362 gen_load_gpr(t1, rd+1);
5f68f5ae 11363 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
11364 opn = "swp";
11365 break;
11366#ifdef TARGET_MIPS64
11367 case LDP:
36c6711b
EJ
11368 if (rd == base) {
11369 generate_exception(ctx, EXCP_RI);
11370 return;
11371 }
5f68f5ae 11372 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11373 gen_store_gpr(t1, rd);
11374 tcg_gen_movi_tl(t1, 8);
11375 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 11376 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11377 gen_store_gpr(t1, rd+1);
11378 opn = "ldp";
11379 break;
11380 case SDP:
3c824109 11381 gen_load_gpr(t1, rd);
5f68f5ae 11382 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11383 tcg_gen_movi_tl(t1, 8);
11384 gen_op_addr_add(ctx, t0, t0, t1);
11385 gen_load_gpr(t1, rd+1);
5f68f5ae 11386 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
11387 opn = "sdp";
11388 break;
11389#endif
6af0bf9c 11390 }
2abf314d 11391 (void)opn; /* avoid a compiler warning */
3c824109
NF
11392 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11393 tcg_temp_free(t0);
11394 tcg_temp_free(t1);
11395}
618b0fe9 11396
240ce26a 11397static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11398{
11399 int extension = (ctx->opcode >> 6) & 0x3f;
11400 int minor = (ctx->opcode >> 12) & 0xf;
11401 uint32_t mips32_op;
11402
11403 switch (extension) {
11404 case TEQ:
11405 mips32_op = OPC_TEQ;
11406 goto do_trap;
11407 case TGE:
11408 mips32_op = OPC_TGE;
11409 goto do_trap;
11410 case TGEU:
11411 mips32_op = OPC_TGEU;
11412 goto do_trap;
11413 case TLT:
11414 mips32_op = OPC_TLT;
11415 goto do_trap;
11416 case TLTU:
11417 mips32_op = OPC_TLTU;
11418 goto do_trap;
11419 case TNE:
11420 mips32_op = OPC_TNE;
11421 do_trap:
11422 gen_trap(ctx, mips32_op, rs, rt, -1);
11423 break;
11424#ifndef CONFIG_USER_ONLY
11425 case MFC0:
11426 case MFC0 + 32:
2e15497c 11427 check_cp0_enabled(ctx);
3c824109
NF
11428 if (rt == 0) {
11429 /* Treat as NOP. */
11430 break;
11431 }
d75c135e 11432 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11433 break;
11434 case MTC0:
11435 case MTC0 + 32:
2e15497c 11436 check_cp0_enabled(ctx);
3c824109
NF
11437 {
11438 TCGv t0 = tcg_temp_new();
618b0fe9 11439
3c824109 11440 gen_load_gpr(t0, rt);
d75c135e 11441 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
11442 tcg_temp_free(t0);
11443 }
11444 break;
11445#endif
a1fc6246
LA
11446 case 0x2a:
11447 switch (minor & 3) {
11448 case MADD_ACC:
11449 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11450 break;
11451 case MADDU_ACC:
11452 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11453 break;
11454 case MSUB_ACC:
11455 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11456 break;
11457 case MSUBU_ACC:
11458 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11459 break;
11460 default:
11461 goto pool32axf_invalid;
11462 }
11463 break;
11464 case 0x32:
11465 switch (minor & 3) {
11466 case MULT_ACC:
11467 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11468 break;
11469 case MULTU_ACC:
11470 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11471 break;
11472 default:
11473 goto pool32axf_invalid;
11474 }
11475 break;
3c824109
NF
11476 case 0x2c:
11477 switch (minor) {
11478 case SEB:
11479 gen_bshfl(ctx, OPC_SEB, rs, rt);
11480 break;
11481 case SEH:
11482 gen_bshfl(ctx, OPC_SEH, rs, rt);
11483 break;
11484 case CLO:
11485 mips32_op = OPC_CLO;
11486 goto do_cl;
11487 case CLZ:
11488 mips32_op = OPC_CLZ;
11489 do_cl:
d75c135e 11490 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11491 gen_cl(ctx, mips32_op, rt, rs);
11492 break;
11493 case RDHWR:
d75c135e 11494 gen_rdhwr(ctx, rt, rs);
3c824109
NF
11495 break;
11496 case WSBH:
11497 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11498 break;
11499 case MULT:
11500 mips32_op = OPC_MULT;
26135ead 11501 goto do_mul;
3c824109
NF
11502 case MULTU:
11503 mips32_op = OPC_MULTU;
26135ead 11504 goto do_mul;
3c824109
NF
11505 case DIV:
11506 mips32_op = OPC_DIV;
26135ead 11507 goto do_div;
3c824109
NF
11508 case DIVU:
11509 mips32_op = OPC_DIVU;
26135ead
RS
11510 goto do_div;
11511 do_div:
11512 check_insn(ctx, ISA_MIPS32);
11513 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11514 break;
3c824109
NF
11515 case MADD:
11516 mips32_op = OPC_MADD;
26135ead 11517 goto do_mul;
3c824109
NF
11518 case MADDU:
11519 mips32_op = OPC_MADDU;
26135ead 11520 goto do_mul;
3c824109
NF
11521 case MSUB:
11522 mips32_op = OPC_MSUB;
26135ead 11523 goto do_mul;
3c824109
NF
11524 case MSUBU:
11525 mips32_op = OPC_MSUBU;
26135ead 11526 do_mul:
d75c135e 11527 check_insn(ctx, ISA_MIPS32);
a1fc6246 11528 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
11529 break;
11530 default:
11531 goto pool32axf_invalid;
11532 }
11533 break;
11534 case 0x34:
11535 switch (minor) {
11536 case MFC2:
11537 case MTC2:
11538 case MFHC2:
11539 case MTHC2:
11540 case CFC2:
11541 case CTC2:
11542 generate_exception_err(ctx, EXCP_CpU, 2);
11543 break;
11544 default:
11545 goto pool32axf_invalid;
11546 }
11547 break;
11548 case 0x3c:
11549 switch (minor) {
11550 case JALR:
11551 case JALR_HB:
11552 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
3c824109
NF
11553 break;
11554 case JALRS:
11555 case JALRS_HB:
11556 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
3c824109
NF
11557 break;
11558 default:
11559 goto pool32axf_invalid;
11560 }
11561 break;
11562 case 0x05:
11563 switch (minor) {
11564 case RDPGPR:
2e15497c 11565 check_cp0_enabled(ctx);
d75c135e 11566 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11567 gen_load_srsgpr(rt, rs);
11568 break;
11569 case WRPGPR:
2e15497c 11570 check_cp0_enabled(ctx);
d75c135e 11571 check_insn(ctx, ISA_MIPS32R2);
3c824109
NF
11572 gen_store_srsgpr(rt, rs);
11573 break;
11574 default:
11575 goto pool32axf_invalid;
11576 }
11577 break;
11578#ifndef CONFIG_USER_ONLY
11579 case 0x0d:
11580 switch (minor) {
11581 case TLBP:
11582 mips32_op = OPC_TLBP;
11583 goto do_cp0;
11584 case TLBR:
11585 mips32_op = OPC_TLBR;
11586 goto do_cp0;
11587 case TLBWI:
11588 mips32_op = OPC_TLBWI;
11589 goto do_cp0;
11590 case TLBWR:
11591 mips32_op = OPC_TLBWR;
11592 goto do_cp0;
11593 case WAIT:
11594 mips32_op = OPC_WAIT;
11595 goto do_cp0;
11596 case DERET:
11597 mips32_op = OPC_DERET;
11598 goto do_cp0;
11599 case ERET:
11600 mips32_op = OPC_ERET;
11601 do_cp0:
11602 gen_cp0(env, ctx, mips32_op, rt, rs);
11603 break;
11604 default:
11605 goto pool32axf_invalid;
11606 }
11607 break;
11608 case 0x1d:
11609 switch (minor) {
11610 case DI:
2e15497c 11611 check_cp0_enabled(ctx);
3c824109
NF
11612 {
11613 TCGv t0 = tcg_temp_new();
11614
11615 save_cpu_state(ctx, 1);
895c2d04 11616 gen_helper_di(t0, cpu_env);
3c824109
NF
11617 gen_store_gpr(t0, rs);
11618 /* Stop translation as we may have switched the execution mode */
11619 ctx->bstate = BS_STOP;
11620 tcg_temp_free(t0);
11621 }
11622 break;
11623 case EI:
2e15497c 11624 check_cp0_enabled(ctx);
3c824109
NF
11625 {
11626 TCGv t0 = tcg_temp_new();
11627
11628 save_cpu_state(ctx, 1);
895c2d04 11629 gen_helper_ei(t0, cpu_env);
3c824109
NF
11630 gen_store_gpr(t0, rs);
11631 /* Stop translation as we may have switched the execution mode */
11632 ctx->bstate = BS_STOP;
11633 tcg_temp_free(t0);
11634 }
11635 break;
11636 default:
11637 goto pool32axf_invalid;
11638 }
11639 break;
11640#endif
11641 case 0x2d:
11642 switch (minor) {
11643 case SYNC:
11644 /* NOP */
11645 break;
11646 case SYSCALL:
11647 generate_exception(ctx, EXCP_SYSCALL);
11648 ctx->bstate = BS_STOP;
11649 break;
11650 case SDBBP:
d75c135e 11651 check_insn(ctx, ISA_MIPS32);
3c824109
NF
11652 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11653 generate_exception(ctx, EXCP_DBp);
11654 } else {
11655 generate_exception(ctx, EXCP_DBp);
11656 }
11657 break;
11658 default:
11659 goto pool32axf_invalid;
11660 }
11661 break;
a1fc6246 11662 case 0x01:
26135ead 11663 switch (minor & 3) {
a1fc6246 11664 case MFHI_ACC:
26135ead 11665 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 11666 break;
a1fc6246 11667 case MFLO_ACC:
26135ead 11668 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 11669 break;
a1fc6246 11670 case MTHI_ACC:
26135ead 11671 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 11672 break;
a1fc6246 11673 case MTLO_ACC:
26135ead 11674 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
11675 break;
11676 default:
11677 goto pool32axf_invalid;
11678 }
11679 break;
a1fc6246
LA
11680 case 0x35:
11681 switch (minor) {
11682 case MFHI32:
11683 gen_HILO(ctx, OPC_MFHI, 0, rs);
11684 break;
11685 case MFLO32:
11686 gen_HILO(ctx, OPC_MFLO, 0, rs);
11687 break;
11688 case MTHI32:
11689 gen_HILO(ctx, OPC_MTHI, 0, rs);
11690 break;
11691 case MTLO32:
11692 gen_HILO(ctx, OPC_MTLO, 0, rs);
11693 break;
11694 default:
11695 goto pool32axf_invalid;
11696 }
11697 break;
3c824109
NF
11698 default:
11699 pool32axf_invalid:
11700 MIPS_INVAL("pool32axf");
11701 generate_exception(ctx, EXCP_RI);
11702 break;
11703 }
11704}
11705
11706/* Values for microMIPS fmt field. Variable-width, depending on which
11707 formats the instruction supports. */
11708
11709enum {
11710 FMT_SD_S = 0,
11711 FMT_SD_D = 1,
11712
11713 FMT_SDPS_S = 0,
11714 FMT_SDPS_D = 1,
11715 FMT_SDPS_PS = 2,
11716
11717 FMT_SWL_S = 0,
11718 FMT_SWL_W = 1,
11719 FMT_SWL_L = 2,
11720
11721 FMT_DWL_D = 0,
11722 FMT_DWL_W = 1,
11723 FMT_DWL_L = 2
11724};
11725
d75c135e 11726static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
11727{
11728 int extension = (ctx->opcode >> 6) & 0x3ff;
11729 uint32_t mips32_op;
11730
11731#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11732#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11733#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11734
11735 switch (extension) {
11736 case FLOAT_1BIT_FMT(CFC1, 0):
11737 mips32_op = OPC_CFC1;
11738 goto do_cp1;
11739 case FLOAT_1BIT_FMT(CTC1, 0):
11740 mips32_op = OPC_CTC1;
11741 goto do_cp1;
11742 case FLOAT_1BIT_FMT(MFC1, 0):
11743 mips32_op = OPC_MFC1;
11744 goto do_cp1;
11745 case FLOAT_1BIT_FMT(MTC1, 0):
11746 mips32_op = OPC_MTC1;
11747 goto do_cp1;
11748 case FLOAT_1BIT_FMT(MFHC1, 0):
11749 mips32_op = OPC_MFHC1;
11750 goto do_cp1;
11751 case FLOAT_1BIT_FMT(MTHC1, 0):
11752 mips32_op = OPC_MTHC1;
11753 do_cp1:
11754 gen_cp1(ctx, mips32_op, rt, rs);
11755 break;
11756
11757 /* Reciprocal square root */
11758 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11759 mips32_op = OPC_RSQRT_S;
11760 goto do_unaryfp;
11761 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11762 mips32_op = OPC_RSQRT_D;
11763 goto do_unaryfp;
11764
11765 /* Square root */
11766 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11767 mips32_op = OPC_SQRT_S;
11768 goto do_unaryfp;
11769 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11770 mips32_op = OPC_SQRT_D;
11771 goto do_unaryfp;
11772
11773 /* Reciprocal */
11774 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11775 mips32_op = OPC_RECIP_S;
11776 goto do_unaryfp;
11777 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11778 mips32_op = OPC_RECIP_D;
11779 goto do_unaryfp;
11780
11781 /* Floor */
11782 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11783 mips32_op = OPC_FLOOR_L_S;
11784 goto do_unaryfp;
11785 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11786 mips32_op = OPC_FLOOR_L_D;
11787 goto do_unaryfp;
11788 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11789 mips32_op = OPC_FLOOR_W_S;
11790 goto do_unaryfp;
11791 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11792 mips32_op = OPC_FLOOR_W_D;
11793 goto do_unaryfp;
11794
11795 /* Ceiling */
11796 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11797 mips32_op = OPC_CEIL_L_S;
11798 goto do_unaryfp;
11799 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11800 mips32_op = OPC_CEIL_L_D;
11801 goto do_unaryfp;
11802 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11803 mips32_op = OPC_CEIL_W_S;
11804 goto do_unaryfp;
11805 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11806 mips32_op = OPC_CEIL_W_D;
11807 goto do_unaryfp;
11808
11809 /* Truncation */
11810 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11811 mips32_op = OPC_TRUNC_L_S;
11812 goto do_unaryfp;
11813 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11814 mips32_op = OPC_TRUNC_L_D;
11815 goto do_unaryfp;
11816 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11817 mips32_op = OPC_TRUNC_W_S;
11818 goto do_unaryfp;
11819 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11820 mips32_op = OPC_TRUNC_W_D;
11821 goto do_unaryfp;
11822
11823 /* Round */
11824 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11825 mips32_op = OPC_ROUND_L_S;
11826 goto do_unaryfp;
11827 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11828 mips32_op = OPC_ROUND_L_D;
11829 goto do_unaryfp;
11830 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11831 mips32_op = OPC_ROUND_W_S;
11832 goto do_unaryfp;
11833 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11834 mips32_op = OPC_ROUND_W_D;
11835 goto do_unaryfp;
11836
11837 /* Integer to floating-point conversion */
11838 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11839 mips32_op = OPC_CVT_L_S;
11840 goto do_unaryfp;
11841 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11842 mips32_op = OPC_CVT_L_D;
11843 goto do_unaryfp;
11844 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11845 mips32_op = OPC_CVT_W_S;
11846 goto do_unaryfp;
11847 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11848 mips32_op = OPC_CVT_W_D;
11849 goto do_unaryfp;
11850
11851 /* Paired-foo conversions */
11852 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11853 mips32_op = OPC_CVT_S_PL;
11854 goto do_unaryfp;
11855 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11856 mips32_op = OPC_CVT_S_PU;
11857 goto do_unaryfp;
11858 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11859 mips32_op = OPC_CVT_PW_PS;
11860 goto do_unaryfp;
11861 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11862 mips32_op = OPC_CVT_PS_PW;
11863 goto do_unaryfp;
11864
11865 /* Floating-point moves */
11866 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11867 mips32_op = OPC_MOV_S;
11868 goto do_unaryfp;
11869 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11870 mips32_op = OPC_MOV_D;
11871 goto do_unaryfp;
11872 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11873 mips32_op = OPC_MOV_PS;
11874 goto do_unaryfp;
11875
11876 /* Absolute value */
11877 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11878 mips32_op = OPC_ABS_S;
11879 goto do_unaryfp;
11880 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11881 mips32_op = OPC_ABS_D;
11882 goto do_unaryfp;
11883 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11884 mips32_op = OPC_ABS_PS;
11885 goto do_unaryfp;
11886
11887 /* Negation */
11888 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11889 mips32_op = OPC_NEG_S;
11890 goto do_unaryfp;
11891 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11892 mips32_op = OPC_NEG_D;
11893 goto do_unaryfp;
11894 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11895 mips32_op = OPC_NEG_PS;
11896 goto do_unaryfp;
11897
11898 /* Reciprocal square root step */
11899 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11900 mips32_op = OPC_RSQRT1_S;
11901 goto do_unaryfp;
11902 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11903 mips32_op = OPC_RSQRT1_D;
11904 goto do_unaryfp;
11905 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11906 mips32_op = OPC_RSQRT1_PS;
11907 goto do_unaryfp;
11908
11909 /* Reciprocal step */
11910 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11911 mips32_op = OPC_RECIP1_S;
11912 goto do_unaryfp;
11913 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11914 mips32_op = OPC_RECIP1_S;
11915 goto do_unaryfp;
11916 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11917 mips32_op = OPC_RECIP1_PS;
11918 goto do_unaryfp;
11919
11920 /* Conversions from double */
11921 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11922 mips32_op = OPC_CVT_D_S;
11923 goto do_unaryfp;
11924 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11925 mips32_op = OPC_CVT_D_W;
11926 goto do_unaryfp;
11927 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11928 mips32_op = OPC_CVT_D_L;
11929 goto do_unaryfp;
11930
11931 /* Conversions from single */
11932 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11933 mips32_op = OPC_CVT_S_D;
11934 goto do_unaryfp;
11935 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11936 mips32_op = OPC_CVT_S_W;
11937 goto do_unaryfp;
11938 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11939 mips32_op = OPC_CVT_S_L;
11940 do_unaryfp:
11941 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11942 break;
11943
11944 /* Conditional moves on floating-point codes */
11945 case COND_FLOAT_MOV(MOVT, 0):
11946 case COND_FLOAT_MOV(MOVT, 1):
11947 case COND_FLOAT_MOV(MOVT, 2):
11948 case COND_FLOAT_MOV(MOVT, 3):
11949 case COND_FLOAT_MOV(MOVT, 4):
11950 case COND_FLOAT_MOV(MOVT, 5):
11951 case COND_FLOAT_MOV(MOVT, 6):
11952 case COND_FLOAT_MOV(MOVT, 7):
11953 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11954 break;
11955 case COND_FLOAT_MOV(MOVF, 0):
11956 case COND_FLOAT_MOV(MOVF, 1):
11957 case COND_FLOAT_MOV(MOVF, 2):
11958 case COND_FLOAT_MOV(MOVF, 3):
11959 case COND_FLOAT_MOV(MOVF, 4):
11960 case COND_FLOAT_MOV(MOVF, 5):
11961 case COND_FLOAT_MOV(MOVF, 6):
11962 case COND_FLOAT_MOV(MOVF, 7):
11963 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11964 break;
11965 default:
11966 MIPS_INVAL("pool32fxf");
11967 generate_exception(ctx, EXCP_RI);
11968 break;
11969 }
11970}
11971
7db13fae 11972static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
240ce26a 11973 uint16_t insn_hw1)
3c824109
NF
11974{
11975 int32_t offset;
11976 uint16_t insn;
11977 int rt, rs, rd, rr;
11978 int16_t imm;
11979 uint32_t op, minor, mips32_op;
11980 uint32_t cond, fmt, cc;
11981
895c2d04 11982 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11983 ctx->opcode = (ctx->opcode << 16) | insn;
11984
11985 rt = (ctx->opcode >> 21) & 0x1f;
11986 rs = (ctx->opcode >> 16) & 0x1f;
11987 rd = (ctx->opcode >> 11) & 0x1f;
11988 rr = (ctx->opcode >> 6) & 0x1f;
11989 imm = (int16_t) ctx->opcode;
11990
11991 op = (ctx->opcode >> 26) & 0x3f;
11992 switch (op) {
11993 case POOL32A:
11994 minor = ctx->opcode & 0x3f;
11995 switch (minor) {
11996 case 0x00:
11997 minor = (ctx->opcode >> 6) & 0xf;
11998 switch (minor) {
11999 case SLL32:
12000 mips32_op = OPC_SLL;
12001 goto do_shifti;
12002 case SRA:
12003 mips32_op = OPC_SRA;
12004 goto do_shifti;
12005 case SRL32:
12006 mips32_op = OPC_SRL;
12007 goto do_shifti;
12008 case ROTR:
12009 mips32_op = OPC_ROTR;
12010 do_shifti:
d75c135e 12011 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109
NF
12012 break;
12013 default:
12014 goto pool32a_invalid;
12015 }
12016 break;
12017 case 0x10:
12018 minor = (ctx->opcode >> 6) & 0xf;
12019 switch (minor) {
12020 /* Arithmetic */
12021 case ADD:
12022 mips32_op = OPC_ADD;
12023 goto do_arith;
12024 case ADDU32:
12025 mips32_op = OPC_ADDU;
12026 goto do_arith;
12027 case SUB:
12028 mips32_op = OPC_SUB;
12029 goto do_arith;
12030 case SUBU32:
12031 mips32_op = OPC_SUBU;
12032 goto do_arith;
12033 case MUL:
12034 mips32_op = OPC_MUL;
12035 do_arith:
d75c135e 12036 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12037 break;
12038 /* Shifts */
12039 case SLLV:
12040 mips32_op = OPC_SLLV;
12041 goto do_shift;
12042 case SRLV:
12043 mips32_op = OPC_SRLV;
12044 goto do_shift;
12045 case SRAV:
12046 mips32_op = OPC_SRAV;
12047 goto do_shift;
12048 case ROTRV:
12049 mips32_op = OPC_ROTRV;
12050 do_shift:
d75c135e 12051 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12052 break;
12053 /* Logical operations */
12054 case AND:
12055 mips32_op = OPC_AND;
12056 goto do_logic;
12057 case OR32:
12058 mips32_op = OPC_OR;
12059 goto do_logic;
12060 case NOR:
12061 mips32_op = OPC_NOR;
12062 goto do_logic;
12063 case XOR32:
12064 mips32_op = OPC_XOR;
12065 do_logic:
d75c135e 12066 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12067 break;
12068 /* Set less than */
12069 case SLT:
12070 mips32_op = OPC_SLT;
12071 goto do_slt;
12072 case SLTU:
12073 mips32_op = OPC_SLTU;
12074 do_slt:
d75c135e 12075 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12076 break;
12077 default:
12078 goto pool32a_invalid;
12079 }
12080 break;
12081 case 0x18:
12082 minor = (ctx->opcode >> 6) & 0xf;
12083 switch (minor) {
12084 /* Conditional moves */
12085 case MOVN:
12086 mips32_op = OPC_MOVN;
12087 goto do_cmov;
12088 case MOVZ:
12089 mips32_op = OPC_MOVZ;
12090 do_cmov:
d75c135e 12091 gen_cond_move(ctx, mips32_op, rd, rs, rt);
3c824109
NF
12092 break;
12093 case LWXS:
12094 gen_ldxs(ctx, rs, rt, rd);
12095 break;
12096 default:
12097 goto pool32a_invalid;
12098 }
12099 break;
12100 case INS:
12101 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
12102 return;
12103 case EXT:
12104 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
12105 return;
12106 case POOL32AXF:
240ce26a 12107 gen_pool32axf(env, ctx, rt, rs);
3c824109
NF
12108 break;
12109 case 0x07:
12110 generate_exception(ctx, EXCP_BREAK);
12111 break;
12112 default:
12113 pool32a_invalid:
12114 MIPS_INVAL("pool32a");
12115 generate_exception(ctx, EXCP_RI);
12116 break;
12117 }
12118 break;
12119 case POOL32B:
12120 minor = (ctx->opcode >> 12) & 0xf;
12121 switch (minor) {
12122 case CACHE:
2e15497c 12123 check_cp0_enabled(ctx);
3c824109
NF
12124 /* Treat as no-op. */
12125 break;
12126 case LWC2:
12127 case SWC2:
12128 /* COP2: Not implemented. */
12129 generate_exception_err(ctx, EXCP_CpU, 2);
12130 break;
12131 case LWP:
12132 case SWP:
12133#ifdef TARGET_MIPS64
12134 case LDP:
12135 case SDP:
12136#endif
12137 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12138 break;
12139 case LWM32:
12140 case SWM32:
12141#ifdef TARGET_MIPS64
12142 case LDM:
12143 case SDM:
12144#endif
12145 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12146 break;
12147 default:
12148 MIPS_INVAL("pool32b");
12149 generate_exception(ctx, EXCP_RI);
12150 break;
12151 }
12152 break;
12153 case POOL32F:
5ab5c041 12154 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
12155 minor = ctx->opcode & 0x3f;
12156 check_cp1_enabled(ctx);
12157 switch (minor) {
12158 case ALNV_PS:
12159 mips32_op = OPC_ALNV_PS;
12160 goto do_madd;
12161 case MADD_S:
12162 mips32_op = OPC_MADD_S;
12163 goto do_madd;
12164 case MADD_D:
12165 mips32_op = OPC_MADD_D;
12166 goto do_madd;
12167 case MADD_PS:
12168 mips32_op = OPC_MADD_PS;
12169 goto do_madd;
12170 case MSUB_S:
12171 mips32_op = OPC_MSUB_S;
12172 goto do_madd;
12173 case MSUB_D:
12174 mips32_op = OPC_MSUB_D;
12175 goto do_madd;
12176 case MSUB_PS:
12177 mips32_op = OPC_MSUB_PS;
12178 goto do_madd;
12179 case NMADD_S:
12180 mips32_op = OPC_NMADD_S;
12181 goto do_madd;
12182 case NMADD_D:
12183 mips32_op = OPC_NMADD_D;
12184 goto do_madd;
12185 case NMADD_PS:
12186 mips32_op = OPC_NMADD_PS;
12187 goto do_madd;
12188 case NMSUB_S:
12189 mips32_op = OPC_NMSUB_S;
12190 goto do_madd;
12191 case NMSUB_D:
12192 mips32_op = OPC_NMSUB_D;
12193 goto do_madd;
12194 case NMSUB_PS:
12195 mips32_op = OPC_NMSUB_PS;
12196 do_madd:
12197 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
12198 break;
12199 case CABS_COND_FMT:
12200 cond = (ctx->opcode >> 6) & 0xf;
12201 cc = (ctx->opcode >> 13) & 0x7;
12202 fmt = (ctx->opcode >> 10) & 0x3;
12203 switch (fmt) {
12204 case 0x0:
12205 gen_cmpabs_s(ctx, cond, rt, rs, cc);
12206 break;
12207 case 0x1:
12208 gen_cmpabs_d(ctx, cond, rt, rs, cc);
12209 break;
12210 case 0x2:
12211 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
12212 break;
12213 default:
12214 goto pool32f_invalid;
12215 }
12216 break;
12217 case C_COND_FMT:
12218 cond = (ctx->opcode >> 6) & 0xf;
12219 cc = (ctx->opcode >> 13) & 0x7;
12220 fmt = (ctx->opcode >> 10) & 0x3;
12221 switch (fmt) {
12222 case 0x0:
12223 gen_cmp_s(ctx, cond, rt, rs, cc);
12224 break;
12225 case 0x1:
12226 gen_cmp_d(ctx, cond, rt, rs, cc);
12227 break;
12228 case 0x2:
12229 gen_cmp_ps(ctx, cond, rt, rs, cc);
12230 break;
12231 default:
12232 goto pool32f_invalid;
12233 }
12234 break;
12235 case POOL32FXF:
d75c135e 12236 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
12237 break;
12238 case 0x00:
12239 /* PLL foo */
12240 switch ((ctx->opcode >> 6) & 0x7) {
12241 case PLL_PS:
12242 mips32_op = OPC_PLL_PS;
12243 goto do_ps;
12244 case PLU_PS:
12245 mips32_op = OPC_PLU_PS;
12246 goto do_ps;
12247 case PUL_PS:
12248 mips32_op = OPC_PUL_PS;
12249 goto do_ps;
12250 case PUU_PS:
12251 mips32_op = OPC_PUU_PS;
12252 goto do_ps;
12253 case CVT_PS_S:
12254 mips32_op = OPC_CVT_PS_S;
12255 do_ps:
12256 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12257 break;
12258 default:
12259 goto pool32f_invalid;
12260 }
12261 break;
12262 case 0x08:
12263 /* [LS][WDU]XC1 */
12264 switch ((ctx->opcode >> 6) & 0x7) {
12265 case LWXC1:
12266 mips32_op = OPC_LWXC1;
12267 goto do_ldst_cp1;
12268 case SWXC1:
12269 mips32_op = OPC_SWXC1;
12270 goto do_ldst_cp1;
12271 case LDXC1:
12272 mips32_op = OPC_LDXC1;
12273 goto do_ldst_cp1;
12274 case SDXC1:
12275 mips32_op = OPC_SDXC1;
12276 goto do_ldst_cp1;
12277 case LUXC1:
12278 mips32_op = OPC_LUXC1;
12279 goto do_ldst_cp1;
12280 case SUXC1:
12281 mips32_op = OPC_SUXC1;
12282 do_ldst_cp1:
12283 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
12284 break;
12285 default:
12286 goto pool32f_invalid;
12287 }
12288 break;
12289 case 0x18:
12290 /* 3D insns */
12291 fmt = (ctx->opcode >> 9) & 0x3;
12292 switch ((ctx->opcode >> 6) & 0x7) {
12293 case RSQRT2_FMT:
12294 switch (fmt) {
12295 case FMT_SDPS_S:
12296 mips32_op = OPC_RSQRT2_S;
12297 goto do_3d;
12298 case FMT_SDPS_D:
12299 mips32_op = OPC_RSQRT2_D;
12300 goto do_3d;
12301 case FMT_SDPS_PS:
12302 mips32_op = OPC_RSQRT2_PS;
12303 goto do_3d;
12304 default:
12305 goto pool32f_invalid;
12306 }
12307 break;
12308 case RECIP2_FMT:
12309 switch (fmt) {
12310 case FMT_SDPS_S:
12311 mips32_op = OPC_RECIP2_S;
12312 goto do_3d;
12313 case FMT_SDPS_D:
12314 mips32_op = OPC_RECIP2_D;
12315 goto do_3d;
12316 case FMT_SDPS_PS:
12317 mips32_op = OPC_RECIP2_PS;
12318 goto do_3d;
12319 default:
12320 goto pool32f_invalid;
12321 }
12322 break;
12323 case ADDR_PS:
12324 mips32_op = OPC_ADDR_PS;
12325 goto do_3d;
12326 case MULR_PS:
12327 mips32_op = OPC_MULR_PS;
12328 do_3d:
12329 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12330 break;
12331 default:
12332 goto pool32f_invalid;
12333 }
12334 break;
12335 case 0x20:
12336 /* MOV[FT].fmt and PREFX */
12337 cc = (ctx->opcode >> 13) & 0x7;
12338 fmt = (ctx->opcode >> 9) & 0x3;
12339 switch ((ctx->opcode >> 6) & 0x7) {
12340 case MOVF_FMT:
12341 switch (fmt) {
12342 case FMT_SDPS_S:
12343 gen_movcf_s(rs, rt, cc, 0);
12344 break;
12345 case FMT_SDPS_D:
12346 gen_movcf_d(ctx, rs, rt, cc, 0);
12347 break;
12348 case FMT_SDPS_PS:
7f6613ce 12349 gen_movcf_ps(ctx, rs, rt, cc, 0);
3c824109
NF
12350 break;
12351 default:
12352 goto pool32f_invalid;
12353 }
12354 break;
12355 case MOVT_FMT:
12356 switch (fmt) {
12357 case FMT_SDPS_S:
12358 gen_movcf_s(rs, rt, cc, 1);
12359 break;
12360 case FMT_SDPS_D:
12361 gen_movcf_d(ctx, rs, rt, cc, 1);
12362 break;
12363 case FMT_SDPS_PS:
7f6613ce 12364 gen_movcf_ps(ctx, rs, rt, cc, 1);
3c824109
NF
12365 break;
12366 default:
12367 goto pool32f_invalid;
12368 }
12369 break;
12370 case PREFX:
12371 break;
12372 default:
12373 goto pool32f_invalid;
12374 }
12375 break;
12376#define FINSN_3ARG_SDPS(prfx) \
12377 switch ((ctx->opcode >> 8) & 0x3) { \
12378 case FMT_SDPS_S: \
12379 mips32_op = OPC_##prfx##_S; \
12380 goto do_fpop; \
12381 case FMT_SDPS_D: \
12382 mips32_op = OPC_##prfx##_D; \
12383 goto do_fpop; \
12384 case FMT_SDPS_PS: \
12385 mips32_op = OPC_##prfx##_PS; \
12386 goto do_fpop; \
12387 default: \
12388 goto pool32f_invalid; \
12389 }
12390 case 0x30:
12391 /* regular FP ops */
12392 switch ((ctx->opcode >> 6) & 0x3) {
12393 case ADD_FMT:
12394 FINSN_3ARG_SDPS(ADD);
12395 break;
12396 case SUB_FMT:
12397 FINSN_3ARG_SDPS(SUB);
12398 break;
12399 case MUL_FMT:
12400 FINSN_3ARG_SDPS(MUL);
12401 break;
12402 case DIV_FMT:
12403 fmt = (ctx->opcode >> 8) & 0x3;
12404 if (fmt == 1) {
12405 mips32_op = OPC_DIV_D;
12406 } else if (fmt == 0) {
12407 mips32_op = OPC_DIV_S;
12408 } else {
12409 goto pool32f_invalid;
12410 }
12411 goto do_fpop;
12412 default:
12413 goto pool32f_invalid;
12414 }
12415 break;
12416 case 0x38:
12417 /* cmovs */
12418 switch ((ctx->opcode >> 6) & 0x3) {
12419 case MOVN_FMT:
12420 FINSN_3ARG_SDPS(MOVN);
12421 break;
12422 case MOVZ_FMT:
12423 FINSN_3ARG_SDPS(MOVZ);
12424 break;
12425 default:
12426 goto pool32f_invalid;
12427 }
12428 break;
12429 do_fpop:
12430 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12431 break;
12432 default:
12433 pool32f_invalid:
12434 MIPS_INVAL("pool32f");
12435 generate_exception(ctx, EXCP_RI);
12436 break;
12437 }
12438 } else {
12439 generate_exception_err(ctx, EXCP_CpU, 1);
12440 }
12441 break;
12442 case POOL32I:
12443 minor = (ctx->opcode >> 21) & 0x1f;
12444 switch (minor) {
12445 case BLTZ:
12446 mips32_op = OPC_BLTZ;
12447 goto do_branch;
12448 case BLTZAL:
12449 mips32_op = OPC_BLTZAL;
12450 goto do_branch;
12451 case BLTZALS:
12452 mips32_op = OPC_BLTZALS;
12453 goto do_branch;
12454 case BGEZ:
12455 mips32_op = OPC_BGEZ;
12456 goto do_branch;
12457 case BGEZAL:
12458 mips32_op = OPC_BGEZAL;
12459 goto do_branch;
12460 case BGEZALS:
12461 mips32_op = OPC_BGEZALS;
12462 goto do_branch;
12463 case BLEZ:
12464 mips32_op = OPC_BLEZ;
12465 goto do_branch;
12466 case BGTZ:
12467 mips32_op = OPC_BGTZ;
12468 do_branch:
12469 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
3c824109
NF
12470 break;
12471
12472 /* Traps */
12473 case TLTI:
12474 mips32_op = OPC_TLTI;
12475 goto do_trapi;
12476 case TGEI:
12477 mips32_op = OPC_TGEI;
12478 goto do_trapi;
12479 case TLTIU:
12480 mips32_op = OPC_TLTIU;
12481 goto do_trapi;
12482 case TGEIU:
12483 mips32_op = OPC_TGEIU;
12484 goto do_trapi;
12485 case TNEI:
12486 mips32_op = OPC_TNEI;
12487 goto do_trapi;
12488 case TEQI:
12489 mips32_op = OPC_TEQI;
12490 do_trapi:
12491 gen_trap(ctx, mips32_op, rs, -1, imm);
12492 break;
12493
12494 case BNEZC:
12495 case BEQZC:
12496 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12497 4, rs, 0, imm << 1);
12498 /* Compact branches don't have a delay slot, so just let
12499 the normal delay slot handling take us to the branch
12500 target. */
12501 break;
12502 case LUI:
d75c135e 12503 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12504 break;
12505 case SYNCI:
12506 break;
12507 case BC2F:
12508 case BC2T:
12509 /* COP2: Not implemented. */
12510 generate_exception_err(ctx, EXCP_CpU, 2);
12511 break;
12512 case BC1F:
12513 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12514 goto do_cp1branch;
12515 case BC1T:
12516 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12517 goto do_cp1branch;
12518 case BC1ANY4F:
12519 mips32_op = OPC_BC1FANY4;
12520 goto do_cp1mips3d;
12521 case BC1ANY4T:
12522 mips32_op = OPC_BC1TANY4;
12523 do_cp1mips3d:
12524 check_cop1x(ctx);
d75c135e 12525 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
12526 /* Fall through */
12527 do_cp1branch:
d75c135e 12528 gen_compute_branch1(ctx, mips32_op,
3c824109 12529 (ctx->opcode >> 18) & 0x7, imm << 1);
3c824109
NF
12530 break;
12531 case BPOSGE64:
12532 case BPOSGE32:
12533 /* MIPS DSP: not implemented */
12534 /* Fall through */
12535 default:
12536 MIPS_INVAL("pool32i");
12537 generate_exception(ctx, EXCP_RI);
12538 break;
12539 }
12540 break;
12541 case POOL32C:
12542 minor = (ctx->opcode >> 12) & 0xf;
12543 switch (minor) {
12544 case LWL:
12545 mips32_op = OPC_LWL;
5c13fdfd 12546 goto do_ld_lr;
3c824109
NF
12547 case SWL:
12548 mips32_op = OPC_SWL;
5c13fdfd 12549 goto do_st_lr;
3c824109
NF
12550 case LWR:
12551 mips32_op = OPC_LWR;
5c13fdfd 12552 goto do_ld_lr;
3c824109
NF
12553 case SWR:
12554 mips32_op = OPC_SWR;
5c13fdfd 12555 goto do_st_lr;
3c824109
NF
12556#if defined(TARGET_MIPS64)
12557 case LDL:
12558 mips32_op = OPC_LDL;
5c13fdfd 12559 goto do_ld_lr;
3c824109
NF
12560 case SDL:
12561 mips32_op = OPC_SDL;
5c13fdfd 12562 goto do_st_lr;
3c824109
NF
12563 case LDR:
12564 mips32_op = OPC_LDR;
5c13fdfd 12565 goto do_ld_lr;
3c824109
NF
12566 case SDR:
12567 mips32_op = OPC_SDR;
5c13fdfd 12568 goto do_st_lr;
3c824109
NF
12569 case LWU:
12570 mips32_op = OPC_LWU;
5c13fdfd 12571 goto do_ld_lr;
3c824109
NF
12572 case LLD:
12573 mips32_op = OPC_LLD;
5c13fdfd 12574 goto do_ld_lr;
3c824109
NF
12575#endif
12576 case LL:
12577 mips32_op = OPC_LL;
5c13fdfd
AJ
12578 goto do_ld_lr;
12579 do_ld_lr:
d75c135e 12580 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12581 break;
12582 do_st_lr:
12583 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12584 break;
12585 case SC:
12586 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12587 break;
12588#if defined(TARGET_MIPS64)
12589 case SCD:
12590 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12591 break;
12592#endif
12593 case PREF:
12594 /* Treat as no-op */
12595 break;
12596 default:
12597 MIPS_INVAL("pool32c");
12598 generate_exception(ctx, EXCP_RI);
12599 break;
12600 }
12601 break;
12602 case ADDI32:
12603 mips32_op = OPC_ADDI;
12604 goto do_addi;
12605 case ADDIU32:
12606 mips32_op = OPC_ADDIU;
12607 do_addi:
d75c135e 12608 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12609 break;
12610
12611 /* Logical operations */
12612 case ORI32:
12613 mips32_op = OPC_ORI;
12614 goto do_logici;
12615 case XORI32:
12616 mips32_op = OPC_XORI;
12617 goto do_logici;
12618 case ANDI32:
12619 mips32_op = OPC_ANDI;
12620 do_logici:
d75c135e 12621 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12622 break;
12623
12624 /* Set less than immediate */
12625 case SLTI32:
12626 mips32_op = OPC_SLTI;
12627 goto do_slti;
12628 case SLTIU32:
12629 mips32_op = OPC_SLTIU;
12630 do_slti:
d75c135e 12631 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12632 break;
12633 case JALX32:
12634 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12635 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
3c824109
NF
12636 break;
12637 case JALS32:
12638 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12639 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
3c824109
NF
12640 break;
12641 case BEQ32:
12642 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
3c824109
NF
12643 break;
12644 case BNE32:
12645 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
3c824109
NF
12646 break;
12647 case J32:
12648 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12649 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12650 break;
12651 case JAL32:
12652 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12653 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
3c824109
NF
12654 break;
12655 /* Floating point (COP1) */
12656 case LWC132:
12657 mips32_op = OPC_LWC1;
12658 goto do_cop1;
12659 case LDC132:
12660 mips32_op = OPC_LDC1;
12661 goto do_cop1;
12662 case SWC132:
12663 mips32_op = OPC_SWC1;
12664 goto do_cop1;
12665 case SDC132:
12666 mips32_op = OPC_SDC1;
12667 do_cop1:
5ab5c041 12668 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12669 break;
12670 case ADDIUPC:
12671 {
12672 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12673 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12674
12675 gen_addiupc(ctx, reg, offset, 0, 0);
12676 }
12677 break;
12678 /* Loads and stores */
12679 case LB32:
12680 mips32_op = OPC_LB;
5c13fdfd 12681 goto do_ld;
3c824109
NF
12682 case LBU32:
12683 mips32_op = OPC_LBU;
5c13fdfd 12684 goto do_ld;
3c824109
NF
12685 case LH32:
12686 mips32_op = OPC_LH;
5c13fdfd 12687 goto do_ld;
3c824109
NF
12688 case LHU32:
12689 mips32_op = OPC_LHU;
5c13fdfd 12690 goto do_ld;
3c824109
NF
12691 case LW32:
12692 mips32_op = OPC_LW;
5c13fdfd 12693 goto do_ld;
3c824109
NF
12694#ifdef TARGET_MIPS64
12695 case LD32:
12696 mips32_op = OPC_LD;
5c13fdfd 12697 goto do_ld;
3c824109
NF
12698 case SD32:
12699 mips32_op = OPC_SD;
5c13fdfd 12700 goto do_st;
3c824109
NF
12701#endif
12702 case SB32:
12703 mips32_op = OPC_SB;
5c13fdfd 12704 goto do_st;
3c824109
NF
12705 case SH32:
12706 mips32_op = OPC_SH;
5c13fdfd 12707 goto do_st;
3c824109
NF
12708 case SW32:
12709 mips32_op = OPC_SW;
5c13fdfd
AJ
12710 goto do_st;
12711 do_ld:
d75c135e 12712 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12713 break;
12714 do_st:
12715 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12716 break;
12717 default:
12718 generate_exception(ctx, EXCP_RI);
12719 break;
12720 }
12721}
12722
240ce26a 12723static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
12724{
12725 uint32_t op;
12726
12727 /* make sure instructions are on a halfword boundary */
12728 if (ctx->pc & 0x1) {
12729 env->CP0_BadVAddr = ctx->pc;
12730 generate_exception(ctx, EXCP_AdEL);
12731 ctx->bstate = BS_STOP;
12732 return 2;
12733 }
12734
12735 op = (ctx->opcode >> 10) & 0x3f;
12736 /* Enforce properly-sized instructions in a delay slot */
12737 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12738 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12739
12740 switch (op) {
12741 case POOL32A:
12742 case POOL32B:
12743 case POOL32I:
12744 case POOL32C:
12745 case ADDI32:
12746 case ADDIU32:
12747 case ORI32:
12748 case XORI32:
12749 case SLTI32:
12750 case SLTIU32:
12751 case ANDI32:
12752 case JALX32:
12753 case LBU32:
12754 case LHU32:
12755 case POOL32F:
12756 case JALS32:
12757 case BEQ32:
12758 case BNE32:
12759 case J32:
12760 case JAL32:
12761 case SB32:
12762 case SH32:
12763 case POOL32S:
12764 case ADDIUPC:
12765 case SWC132:
12766 case SDC132:
12767 case SD32:
12768 case SW32:
12769 case LB32:
12770 case LH32:
12771 case DADDIU32:
3c824109
NF
12772 case LWC132:
12773 case LDC132:
12774 case LD32:
12775 case LW32:
12776 if (bits & MIPS_HFLAG_BDS16) {
12777 generate_exception(ctx, EXCP_RI);
12778 /* Just stop translation; the user is confused. */
12779 ctx->bstate = BS_STOP;
12780 return 2;
12781 }
12782 break;
12783 case POOL16A:
12784 case POOL16B:
12785 case POOL16C:
12786 case LWGP16:
12787 case POOL16F:
12788 case LBU16:
12789 case LHU16:
12790 case LWSP16:
12791 case LW16:
12792 case SB16:
12793 case SH16:
12794 case SWSP16:
12795 case SW16:
12796 case MOVE16:
12797 case ANDI16:
12798 case POOL16D:
12799 case POOL16E:
12800 case BEQZ16:
12801 case BNEZ16:
12802 case B16:
12803 case LI16:
12804 if (bits & MIPS_HFLAG_BDS32) {
12805 generate_exception(ctx, EXCP_RI);
12806 /* Just stop translation; the user is confused. */
12807 ctx->bstate = BS_STOP;
12808 return 2;
12809 }
12810 break;
12811 default:
12812 break;
12813 }
12814 }
12815 switch (op) {
12816 case POOL16A:
12817 {
12818 int rd = mmreg(uMIPS_RD(ctx->opcode));
12819 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12820 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12821 uint32_t opc = 0;
12822
12823 switch (ctx->opcode & 0x1) {
12824 case ADDU16:
12825 opc = OPC_ADDU;
12826 break;
12827 case SUBU16:
12828 opc = OPC_SUBU;
12829 break;
12830 }
12831
d75c135e 12832 gen_arith(ctx, opc, rd, rs1, rs2);
3c824109
NF
12833 }
12834 break;
12835 case POOL16B:
12836 {
12837 int rd = mmreg(uMIPS_RD(ctx->opcode));
12838 int rs = mmreg(uMIPS_RS(ctx->opcode));
12839 int amount = (ctx->opcode >> 1) & 0x7;
12840 uint32_t opc = 0;
12841 amount = amount == 0 ? 8 : amount;
12842
12843 switch (ctx->opcode & 0x1) {
12844 case SLL16:
12845 opc = OPC_SLL;
12846 break;
12847 case SRL16:
12848 opc = OPC_SRL;
12849 break;
12850 }
12851
d75c135e 12852 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
12853 }
12854 break;
12855 case POOL16C:
240ce26a 12856 gen_pool16c_insn(ctx);
3c824109
NF
12857 break;
12858 case LWGP16:
12859 {
12860 int rd = mmreg(uMIPS_RD(ctx->opcode));
12861 int rb = 28; /* GP */
12862 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12863
d75c135e 12864 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12865 }
12866 break;
12867 case POOL16F:
12868 if (ctx->opcode & 1) {
12869 generate_exception(ctx, EXCP_RI);
12870 } else {
12871 /* MOVEP */
12872 int enc_dest = uMIPS_RD(ctx->opcode);
12873 int enc_rt = uMIPS_RS2(ctx->opcode);
12874 int enc_rs = uMIPS_RS1(ctx->opcode);
12875 int rd, rs, re, rt;
12876 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12877 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12878 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12879
12880 rd = rd_enc[enc_dest];
12881 re = re_enc[enc_dest];
12882 rs = rs_rt_enc[enc_rs];
12883 rt = rs_rt_enc[enc_rt];
12884
d75c135e
AJ
12885 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12886 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
3c824109
NF
12887 }
12888 break;
12889 case LBU16:
12890 {
12891 int rd = mmreg(uMIPS_RD(ctx->opcode));
12892 int rb = mmreg(uMIPS_RS(ctx->opcode));
12893 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12894 offset = (offset == 0xf ? -1 : offset);
12895
d75c135e 12896 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12897 }
12898 break;
12899 case LHU16:
12900 {
12901 int rd = mmreg(uMIPS_RD(ctx->opcode));
12902 int rb = mmreg(uMIPS_RS(ctx->opcode));
12903 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12904
d75c135e 12905 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12906 }
12907 break;
12908 case LWSP16:
12909 {
12910 int rd = (ctx->opcode >> 5) & 0x1f;
12911 int rb = 29; /* SP */
12912 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12913
d75c135e 12914 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12915 }
12916 break;
12917 case LW16:
12918 {
12919 int rd = mmreg(uMIPS_RD(ctx->opcode));
12920 int rb = mmreg(uMIPS_RS(ctx->opcode));
12921 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12922
d75c135e 12923 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12924 }
12925 break;
12926 case SB16:
12927 {
12928 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12929 int rb = mmreg(uMIPS_RS(ctx->opcode));
12930 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12931
5c13fdfd 12932 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12933 }
12934 break;
12935 case SH16:
12936 {
12937 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12938 int rb = mmreg(uMIPS_RS(ctx->opcode));
12939 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12940
5c13fdfd 12941 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12942 }
12943 break;
12944 case SWSP16:
12945 {
12946 int rd = (ctx->opcode >> 5) & 0x1f;
12947 int rb = 29; /* SP */
12948 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12949
5c13fdfd 12950 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12951 }
12952 break;
12953 case SW16:
12954 {
12955 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12956 int rb = mmreg(uMIPS_RS(ctx->opcode));
12957 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12958
5c13fdfd 12959 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12960 }
12961 break;
12962 case MOVE16:
12963 {
12964 int rd = uMIPS_RD5(ctx->opcode);
12965 int rs = uMIPS_RS5(ctx->opcode);
12966
d75c135e 12967 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
3c824109
NF
12968 }
12969 break;
12970 case ANDI16:
d75c135e 12971 gen_andi16(ctx);
3c824109
NF
12972 break;
12973 case POOL16D:
12974 switch (ctx->opcode & 0x1) {
12975 case ADDIUS5:
d75c135e 12976 gen_addius5(ctx);
3c824109
NF
12977 break;
12978 case ADDIUSP:
d75c135e 12979 gen_addiusp(ctx);
3c824109
NF
12980 break;
12981 }
12982 break;
12983 case POOL16E:
12984 switch (ctx->opcode & 0x1) {
12985 case ADDIUR2:
d75c135e 12986 gen_addiur2(ctx);
3c824109
NF
12987 break;
12988 case ADDIUR1SP:
d75c135e 12989 gen_addiur1sp(ctx);
3c824109
NF
12990 break;
12991 }
12992 break;
12993 case B16:
12994 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12995 SIMM(ctx->opcode, 0, 10) << 1);
3c824109
NF
12996 break;
12997 case BNEZ16:
12998 case BEQZ16:
12999 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
13000 mmreg(uMIPS_RD(ctx->opcode)),
13001 0, SIMM(ctx->opcode, 0, 7) << 1);
3c824109
NF
13002 break;
13003 case LI16:
13004 {
13005 int reg = mmreg(uMIPS_RD(ctx->opcode));
13006 int imm = ZIMM(ctx->opcode, 0, 7);
13007
13008 imm = (imm == 0x7f ? -1 : imm);
13009 tcg_gen_movi_tl(cpu_gpr[reg], imm);
13010 }
13011 break;
13012 case RES_20:
13013 case RES_28:
13014 case RES_29:
13015 case RES_30:
13016 case RES_31:
13017 case RES_38:
13018 case RES_39:
13019 generate_exception(ctx, EXCP_RI);
13020 break;
13021 default:
240ce26a 13022 decode_micromips32_opc (env, ctx, op);
3c824109
NF
13023 return 4;
13024 }
13025
13026 return 2;
13027}
13028
13029/* SmartMIPS extension to MIPS32 */
13030
13031#if defined(TARGET_MIPS64)
13032
13033/* MDMX extension to MIPS64 */
13034
13035#endif
13036
9b1a1d68 13037/* MIPSDSP functions. */
d75c135e 13038static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
13039 int rd, int base, int offset)
13040{
13041 const char *opn = "ldx";
13042 TCGv t0;
13043
9b1a1d68
JL
13044 check_dsp(ctx);
13045 t0 = tcg_temp_new();
13046
13047 if (base == 0) {
13048 gen_load_gpr(t0, offset);
13049 } else if (offset == 0) {
13050 gen_load_gpr(t0, base);
13051 } else {
13052 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
13053 }
13054
9b1a1d68
JL
13055 switch (opc) {
13056 case OPC_LBUX:
5f68f5ae 13057 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68
JL
13058 gen_store_gpr(t0, rd);
13059 opn = "lbux";
13060 break;
13061 case OPC_LHX:
5f68f5ae 13062 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68
JL
13063 gen_store_gpr(t0, rd);
13064 opn = "lhx";
13065 break;
13066 case OPC_LWX:
5f68f5ae 13067 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68
JL
13068 gen_store_gpr(t0, rd);
13069 opn = "lwx";
13070 break;
13071#if defined(TARGET_MIPS64)
13072 case OPC_LDX:
5f68f5ae 13073 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68
JL
13074 gen_store_gpr(t0, rd);
13075 opn = "ldx";
13076 break;
13077#endif
13078 }
13079 (void)opn; /* avoid a compiler warning */
13080 MIPS_DEBUG("%s %s, %s(%s)", opn,
13081 regnames[rd], regnames[offset], regnames[base]);
13082 tcg_temp_free(t0);
13083}
13084
461c08df
JL
13085static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
13086 int ret, int v1, int v2)
13087{
13088 const char *opn = "mipsdsp arith";
13089 TCGv v1_t;
13090 TCGv v2_t;
13091
13092 if (ret == 0) {
13093 /* Treat as NOP. */
13094 MIPS_DEBUG("NOP");
13095 return;
13096 }
13097
13098 v1_t = tcg_temp_new();
13099 v2_t = tcg_temp_new();
13100
13101 gen_load_gpr(v1_t, v1);
13102 gen_load_gpr(v2_t, v2);
13103
13104 switch (op1) {
13105 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13106 case OPC_MULT_G_2E:
13107 check_dspr2(ctx);
13108 switch (op2) {
13109 case OPC_ADDUH_QB:
13110 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
13111 break;
13112 case OPC_ADDUH_R_QB:
13113 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13114 break;
13115 case OPC_ADDQH_PH:
13116 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
13117 break;
13118 case OPC_ADDQH_R_PH:
13119 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13120 break;
13121 case OPC_ADDQH_W:
13122 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
13123 break;
13124 case OPC_ADDQH_R_W:
13125 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13126 break;
13127 case OPC_SUBUH_QB:
13128 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
13129 break;
13130 case OPC_SUBUH_R_QB:
13131 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13132 break;
13133 case OPC_SUBQH_PH:
13134 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
13135 break;
13136 case OPC_SUBQH_R_PH:
13137 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13138 break;
13139 case OPC_SUBQH_W:
13140 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
13141 break;
13142 case OPC_SUBQH_R_W:
13143 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13144 break;
13145 }
13146 break;
13147 case OPC_ABSQ_S_PH_DSP:
13148 switch (op2) {
13149 case OPC_ABSQ_S_QB:
13150 check_dspr2(ctx);
13151 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
13152 break;
13153 case OPC_ABSQ_S_PH:
13154 check_dsp(ctx);
13155 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
13156 break;
13157 case OPC_ABSQ_S_W:
13158 check_dsp(ctx);
13159 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
13160 break;
13161 case OPC_PRECEQ_W_PHL:
13162 check_dsp(ctx);
13163 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
13164 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13165 break;
13166 case OPC_PRECEQ_W_PHR:
13167 check_dsp(ctx);
13168 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
13169 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
13170 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13171 break;
13172 case OPC_PRECEQU_PH_QBL:
13173 check_dsp(ctx);
13174 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
13175 break;
13176 case OPC_PRECEQU_PH_QBR:
13177 check_dsp(ctx);
13178 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
13179 break;
13180 case OPC_PRECEQU_PH_QBLA:
13181 check_dsp(ctx);
13182 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
13183 break;
13184 case OPC_PRECEQU_PH_QBRA:
13185 check_dsp(ctx);
13186 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
13187 break;
13188 case OPC_PRECEU_PH_QBL:
13189 check_dsp(ctx);
13190 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
13191 break;
13192 case OPC_PRECEU_PH_QBR:
13193 check_dsp(ctx);
13194 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
13195 break;
13196 case OPC_PRECEU_PH_QBLA:
13197 check_dsp(ctx);
13198 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
13199 break;
13200 case OPC_PRECEU_PH_QBRA:
13201 check_dsp(ctx);
13202 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
13203 break;
13204 }
13205 break;
13206 case OPC_ADDU_QB_DSP:
13207 switch (op2) {
13208 case OPC_ADDQ_PH:
13209 check_dsp(ctx);
13210 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13211 break;
13212 case OPC_ADDQ_S_PH:
13213 check_dsp(ctx);
13214 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13215 break;
13216 case OPC_ADDQ_S_W:
13217 check_dsp(ctx);
13218 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13219 break;
13220 case OPC_ADDU_QB:
13221 check_dsp(ctx);
13222 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13223 break;
13224 case OPC_ADDU_S_QB:
13225 check_dsp(ctx);
13226 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13227 break;
13228 case OPC_ADDU_PH:
13229 check_dspr2(ctx);
13230 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13231 break;
13232 case OPC_ADDU_S_PH:
13233 check_dspr2(ctx);
13234 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13235 break;
13236 case OPC_SUBQ_PH:
13237 check_dsp(ctx);
13238 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13239 break;
13240 case OPC_SUBQ_S_PH:
13241 check_dsp(ctx);
13242 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13243 break;
13244 case OPC_SUBQ_S_W:
13245 check_dsp(ctx);
13246 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13247 break;
13248 case OPC_SUBU_QB:
13249 check_dsp(ctx);
13250 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13251 break;
13252 case OPC_SUBU_S_QB:
13253 check_dsp(ctx);
13254 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13255 break;
13256 case OPC_SUBU_PH:
13257 check_dspr2(ctx);
13258 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13259 break;
13260 case OPC_SUBU_S_PH:
13261 check_dspr2(ctx);
13262 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13263 break;
13264 case OPC_ADDSC:
13265 check_dsp(ctx);
13266 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13267 break;
13268 case OPC_ADDWC:
13269 check_dsp(ctx);
13270 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13271 break;
13272 case OPC_MODSUB:
13273 check_dsp(ctx);
13274 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
13275 break;
13276 case OPC_RADDU_W_QB:
13277 check_dsp(ctx);
13278 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
13279 break;
13280 }
13281 break;
13282 case OPC_CMPU_EQ_QB_DSP:
13283 switch (op2) {
13284 case OPC_PRECR_QB_PH:
13285 check_dspr2(ctx);
13286 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13287 break;
13288 case OPC_PRECRQ_QB_PH:
13289 check_dsp(ctx);
13290 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13291 break;
13292 case OPC_PRECR_SRA_PH_W:
13293 check_dspr2(ctx);
13294 {
13295 TCGv_i32 sa_t = tcg_const_i32(v2);
13296 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
13297 cpu_gpr[ret]);
13298 tcg_temp_free_i32(sa_t);
13299 break;
13300 }
13301 case OPC_PRECR_SRA_R_PH_W:
13302 check_dspr2(ctx);
13303 {
13304 TCGv_i32 sa_t = tcg_const_i32(v2);
13305 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
13306 cpu_gpr[ret]);
13307 tcg_temp_free_i32(sa_t);
13308 break;
13309 }
13310 case OPC_PRECRQ_PH_W:
13311 check_dsp(ctx);
13312 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
13313 break;
13314 case OPC_PRECRQ_RS_PH_W:
13315 check_dsp(ctx);
13316 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13317 break;
13318 case OPC_PRECRQU_S_QB_PH:
13319 check_dsp(ctx);
13320 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13321 break;
13322 }
13323 break;
13324#ifdef TARGET_MIPS64
13325 case OPC_ABSQ_S_QH_DSP:
13326 switch (op2) {
13327 case OPC_PRECEQ_L_PWL:
13328 check_dsp(ctx);
13329 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
13330 break;
13331 case OPC_PRECEQ_L_PWR:
13332 check_dsp(ctx);
13333 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
13334 break;
13335 case OPC_PRECEQ_PW_QHL:
13336 check_dsp(ctx);
13337 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
13338 break;
13339 case OPC_PRECEQ_PW_QHR:
13340 check_dsp(ctx);
13341 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
13342 break;
13343 case OPC_PRECEQ_PW_QHLA:
13344 check_dsp(ctx);
13345 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
13346 break;
13347 case OPC_PRECEQ_PW_QHRA:
13348 check_dsp(ctx);
13349 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
13350 break;
13351 case OPC_PRECEQU_QH_OBL:
13352 check_dsp(ctx);
13353 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
13354 break;
13355 case OPC_PRECEQU_QH_OBR:
13356 check_dsp(ctx);
13357 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
13358 break;
13359 case OPC_PRECEQU_QH_OBLA:
13360 check_dsp(ctx);
13361 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13362 break;
13363 case OPC_PRECEQU_QH_OBRA:
13364 check_dsp(ctx);
13365 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13366 break;
13367 case OPC_PRECEU_QH_OBL:
13368 check_dsp(ctx);
13369 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13370 break;
13371 case OPC_PRECEU_QH_OBR:
13372 check_dsp(ctx);
13373 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13374 break;
13375 case OPC_PRECEU_QH_OBLA:
13376 check_dsp(ctx);
13377 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13378 break;
13379 case OPC_PRECEU_QH_OBRA:
13380 check_dsp(ctx);
13381 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13382 break;
13383 case OPC_ABSQ_S_OB:
13384 check_dspr2(ctx);
13385 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13386 break;
13387 case OPC_ABSQ_S_PW:
13388 check_dsp(ctx);
13389 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13390 break;
13391 case OPC_ABSQ_S_QH:
13392 check_dsp(ctx);
13393 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13394 break;
13395 }
13396 break;
13397 case OPC_ADDU_OB_DSP:
13398 switch (op2) {
13399 case OPC_RADDU_L_OB:
13400 check_dsp(ctx);
13401 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13402 break;
13403 case OPC_SUBQ_PW:
13404 check_dsp(ctx);
13405 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13406 break;
13407 case OPC_SUBQ_S_PW:
13408 check_dsp(ctx);
13409 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13410 break;
13411 case OPC_SUBQ_QH:
13412 check_dsp(ctx);
13413 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13414 break;
13415 case OPC_SUBQ_S_QH:
13416 check_dsp(ctx);
13417 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13418 break;
13419 case OPC_SUBU_OB:
13420 check_dsp(ctx);
13421 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13422 break;
13423 case OPC_SUBU_S_OB:
13424 check_dsp(ctx);
13425 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13426 break;
13427 case OPC_SUBU_QH:
13428 check_dspr2(ctx);
13429 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13430 break;
13431 case OPC_SUBU_S_QH:
13432 check_dspr2(ctx);
13433 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13434 break;
13435 case OPC_SUBUH_OB:
13436 check_dspr2(ctx);
13437 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13438 break;
13439 case OPC_SUBUH_R_OB:
13440 check_dspr2(ctx);
13441 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13442 break;
13443 case OPC_ADDQ_PW:
13444 check_dsp(ctx);
13445 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 break;
13447 case OPC_ADDQ_S_PW:
13448 check_dsp(ctx);
13449 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13450 break;
13451 case OPC_ADDQ_QH:
13452 check_dsp(ctx);
13453 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13454 break;
13455 case OPC_ADDQ_S_QH:
13456 check_dsp(ctx);
13457 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13458 break;
13459 case OPC_ADDU_OB:
13460 check_dsp(ctx);
13461 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13462 break;
13463 case OPC_ADDU_S_OB:
13464 check_dsp(ctx);
13465 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13466 break;
13467 case OPC_ADDU_QH:
13468 check_dspr2(ctx);
13469 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13470 break;
13471 case OPC_ADDU_S_QH:
13472 check_dspr2(ctx);
13473 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13474 break;
13475 case OPC_ADDUH_OB:
13476 check_dspr2(ctx);
13477 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13478 break;
13479 case OPC_ADDUH_R_OB:
13480 check_dspr2(ctx);
13481 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13482 break;
13483 }
13484 break;
13485 case OPC_CMPU_EQ_OB_DSP:
13486 switch (op2) {
13487 case OPC_PRECR_OB_QH:
13488 check_dspr2(ctx);
13489 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13490 break;
13491 case OPC_PRECR_SRA_QH_PW:
13492 check_dspr2(ctx);
13493 {
13494 TCGv_i32 ret_t = tcg_const_i32(ret);
13495 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13496 tcg_temp_free_i32(ret_t);
13497 break;
13498 }
13499 case OPC_PRECR_SRA_R_QH_PW:
13500 check_dspr2(ctx);
13501 {
13502 TCGv_i32 sa_v = tcg_const_i32(ret);
13503 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13504 tcg_temp_free_i32(sa_v);
13505 break;
13506 }
13507 case OPC_PRECRQ_OB_QH:
13508 check_dsp(ctx);
13509 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13510 break;
13511 case OPC_PRECRQ_PW_L:
13512 check_dsp(ctx);
13513 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13514 break;
13515 case OPC_PRECRQ_QH_PW:
13516 check_dsp(ctx);
13517 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13518 break;
13519 case OPC_PRECRQ_RS_QH_PW:
13520 check_dsp(ctx);
13521 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13522 break;
13523 case OPC_PRECRQU_S_OB_QH:
13524 check_dsp(ctx);
13525 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13526 break;
13527 }
13528 break;
13529#endif
13530 }
13531
13532 tcg_temp_free(v1_t);
13533 tcg_temp_free(v2_t);
13534
13535 (void)opn; /* avoid a compiler warning */
13536 MIPS_DEBUG("%s", opn);
13537}
9b1a1d68 13538
77c5fa8b
JL
13539static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13540 int ret, int v1, int v2)
13541{
13542 uint32_t op2;
13543 const char *opn = "mipsdsp shift";
13544 TCGv t0;
13545 TCGv v1_t;
13546 TCGv v2_t;
13547
13548 if (ret == 0) {
13549 /* Treat as NOP. */
13550 MIPS_DEBUG("NOP");
13551 return;
13552 }
13553
13554 t0 = tcg_temp_new();
13555 v1_t = tcg_temp_new();
13556 v2_t = tcg_temp_new();
13557
13558 tcg_gen_movi_tl(t0, v1);
13559 gen_load_gpr(v1_t, v1);
13560 gen_load_gpr(v2_t, v2);
13561
13562 switch (opc) {
13563 case OPC_SHLL_QB_DSP:
13564 {
13565 op2 = MASK_SHLL_QB(ctx->opcode);
13566 switch (op2) {
13567 case OPC_SHLL_QB:
13568 check_dsp(ctx);
13569 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13570 break;
13571 case OPC_SHLLV_QB:
13572 check_dsp(ctx);
13573 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13574 break;
13575 case OPC_SHLL_PH:
13576 check_dsp(ctx);
13577 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13578 break;
13579 case OPC_SHLLV_PH:
13580 check_dsp(ctx);
13581 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13582 break;
13583 case OPC_SHLL_S_PH:
13584 check_dsp(ctx);
13585 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13586 break;
13587 case OPC_SHLLV_S_PH:
13588 check_dsp(ctx);
13589 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13590 break;
13591 case OPC_SHLL_S_W:
13592 check_dsp(ctx);
13593 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13594 break;
13595 case OPC_SHLLV_S_W:
13596 check_dsp(ctx);
13597 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13598 break;
13599 case OPC_SHRL_QB:
13600 check_dsp(ctx);
13601 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13602 break;
13603 case OPC_SHRLV_QB:
13604 check_dsp(ctx);
13605 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13606 break;
13607 case OPC_SHRL_PH:
13608 check_dspr2(ctx);
13609 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13610 break;
13611 case OPC_SHRLV_PH:
13612 check_dspr2(ctx);
13613 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13614 break;
13615 case OPC_SHRA_QB:
13616 check_dspr2(ctx);
13617 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13618 break;
13619 case OPC_SHRA_R_QB:
13620 check_dspr2(ctx);
13621 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13622 break;
13623 case OPC_SHRAV_QB:
13624 check_dspr2(ctx);
13625 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13626 break;
13627 case OPC_SHRAV_R_QB:
13628 check_dspr2(ctx);
13629 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13630 break;
13631 case OPC_SHRA_PH:
13632 check_dsp(ctx);
13633 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13634 break;
13635 case OPC_SHRA_R_PH:
13636 check_dsp(ctx);
13637 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13638 break;
13639 case OPC_SHRAV_PH:
13640 check_dsp(ctx);
13641 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13642 break;
13643 case OPC_SHRAV_R_PH:
13644 check_dsp(ctx);
13645 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13646 break;
13647 case OPC_SHRA_R_W:
13648 check_dsp(ctx);
13649 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13650 break;
13651 case OPC_SHRAV_R_W:
13652 check_dsp(ctx);
13653 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13654 break;
13655 default: /* Invalid */
13656 MIPS_INVAL("MASK SHLL.QB");
13657 generate_exception(ctx, EXCP_RI);
13658 break;
13659 }
13660 break;
13661 }
13662#ifdef TARGET_MIPS64
13663 case OPC_SHLL_OB_DSP:
13664 op2 = MASK_SHLL_OB(ctx->opcode);
13665 switch (op2) {
13666 case OPC_SHLL_PW:
13667 check_dsp(ctx);
13668 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13669 break;
13670 case OPC_SHLLV_PW:
13671 check_dsp(ctx);
13672 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13673 break;
13674 case OPC_SHLL_S_PW:
13675 check_dsp(ctx);
13676 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13677 break;
13678 case OPC_SHLLV_S_PW:
13679 check_dsp(ctx);
13680 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13681 break;
13682 case OPC_SHLL_OB:
13683 check_dsp(ctx);
13684 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13685 break;
13686 case OPC_SHLLV_OB:
13687 check_dsp(ctx);
13688 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13689 break;
13690 case OPC_SHLL_QH:
13691 check_dsp(ctx);
13692 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13693 break;
13694 case OPC_SHLLV_QH:
13695 check_dsp(ctx);
13696 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13697 break;
13698 case OPC_SHLL_S_QH:
13699 check_dsp(ctx);
13700 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13701 break;
13702 case OPC_SHLLV_S_QH:
13703 check_dsp(ctx);
13704 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13705 break;
13706 case OPC_SHRA_OB:
13707 check_dspr2(ctx);
13708 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13709 break;
13710 case OPC_SHRAV_OB:
13711 check_dspr2(ctx);
13712 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13713 break;
13714 case OPC_SHRA_R_OB:
13715 check_dspr2(ctx);
13716 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13717 break;
13718 case OPC_SHRAV_R_OB:
13719 check_dspr2(ctx);
13720 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13721 break;
13722 case OPC_SHRA_PW:
13723 check_dsp(ctx);
13724 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13725 break;
13726 case OPC_SHRAV_PW:
13727 check_dsp(ctx);
13728 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13729 break;
13730 case OPC_SHRA_R_PW:
13731 check_dsp(ctx);
13732 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13733 break;
13734 case OPC_SHRAV_R_PW:
13735 check_dsp(ctx);
13736 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13737 break;
13738 case OPC_SHRA_QH:
13739 check_dsp(ctx);
13740 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13741 break;
13742 case OPC_SHRAV_QH:
13743 check_dsp(ctx);
13744 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13745 break;
13746 case OPC_SHRA_R_QH:
13747 check_dsp(ctx);
13748 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13749 break;
13750 case OPC_SHRAV_R_QH:
13751 check_dsp(ctx);
13752 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13753 break;
13754 case OPC_SHRL_OB:
13755 check_dsp(ctx);
13756 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13757 break;
13758 case OPC_SHRLV_OB:
13759 check_dsp(ctx);
13760 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13761 break;
13762 case OPC_SHRL_QH:
13763 check_dspr2(ctx);
13764 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13765 break;
13766 case OPC_SHRLV_QH:
13767 check_dspr2(ctx);
13768 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13769 break;
13770 default: /* Invalid */
13771 MIPS_INVAL("MASK SHLL.OB");
13772 generate_exception(ctx, EXCP_RI);
13773 break;
13774 }
13775 break;
13776#endif
13777 }
13778
13779 tcg_temp_free(t0);
13780 tcg_temp_free(v1_t);
13781 tcg_temp_free(v2_t);
13782 (void)opn; /* avoid a compiler warning */
13783 MIPS_DEBUG("%s", opn);
13784}
13785
a22260ae
JL
13786static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13787 int ret, int v1, int v2, int check_ret)
13788{
13789 const char *opn = "mipsdsp multiply";
13790 TCGv_i32 t0;
13791 TCGv v1_t;
13792 TCGv v2_t;
13793
13794 if ((ret == 0) && (check_ret == 1)) {
13795 /* Treat as NOP. */
13796 MIPS_DEBUG("NOP");
13797 return;
13798 }
13799
13800 t0 = tcg_temp_new_i32();
13801 v1_t = tcg_temp_new();
13802 v2_t = tcg_temp_new();
13803
13804 tcg_gen_movi_i32(t0, ret);
13805 gen_load_gpr(v1_t, v1);
13806 gen_load_gpr(v2_t, v2);
13807
13808 switch (op1) {
13809 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13810 * the same mask and op1. */
13811 case OPC_MULT_G_2E:
639eadb9 13812 check_dspr2(ctx);
a22260ae
JL
13813 switch (op2) {
13814 case OPC_MUL_PH:
13815 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13816 break;
13817 case OPC_MUL_S_PH:
13818 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13819 break;
13820 case OPC_MULQ_S_W:
13821 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13822 break;
13823 case OPC_MULQ_RS_W:
13824 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13825 break;
13826 }
13827 break;
13828 case OPC_DPA_W_PH_DSP:
13829 switch (op2) {
13830 case OPC_DPAU_H_QBL:
13831 check_dsp(ctx);
13832 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13833 break;
13834 case OPC_DPAU_H_QBR:
13835 check_dsp(ctx);
13836 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13837 break;
13838 case OPC_DPSU_H_QBL:
13839 check_dsp(ctx);
13840 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13841 break;
13842 case OPC_DPSU_H_QBR:
13843 check_dsp(ctx);
13844 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13845 break;
13846 case OPC_DPA_W_PH:
13847 check_dspr2(ctx);
13848 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13849 break;
13850 case OPC_DPAX_W_PH:
13851 check_dspr2(ctx);
13852 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13853 break;
13854 case OPC_DPAQ_S_W_PH:
13855 check_dsp(ctx);
13856 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13857 break;
13858 case OPC_DPAQX_S_W_PH:
13859 check_dspr2(ctx);
13860 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13861 break;
13862 case OPC_DPAQX_SA_W_PH:
13863 check_dspr2(ctx);
13864 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13865 break;
13866 case OPC_DPS_W_PH:
13867 check_dspr2(ctx);
13868 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13869 break;
13870 case OPC_DPSX_W_PH:
13871 check_dspr2(ctx);
13872 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13873 break;
13874 case OPC_DPSQ_S_W_PH:
13875 check_dsp(ctx);
13876 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13877 break;
13878 case OPC_DPSQX_S_W_PH:
13879 check_dspr2(ctx);
13880 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13881 break;
13882 case OPC_DPSQX_SA_W_PH:
13883 check_dspr2(ctx);
13884 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13885 break;
13886 case OPC_MULSAQ_S_W_PH:
13887 check_dsp(ctx);
13888 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13889 break;
13890 case OPC_DPAQ_SA_L_W:
13891 check_dsp(ctx);
13892 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13893 break;
13894 case OPC_DPSQ_SA_L_W:
13895 check_dsp(ctx);
13896 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13897 break;
13898 case OPC_MAQ_S_W_PHL:
13899 check_dsp(ctx);
13900 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13901 break;
13902 case OPC_MAQ_S_W_PHR:
13903 check_dsp(ctx);
13904 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13905 break;
13906 case OPC_MAQ_SA_W_PHL:
13907 check_dsp(ctx);
13908 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13909 break;
13910 case OPC_MAQ_SA_W_PHR:
13911 check_dsp(ctx);
13912 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13913 break;
13914 case OPC_MULSA_W_PH:
13915 check_dspr2(ctx);
13916 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13917 break;
13918 }
13919 break;
13920#ifdef TARGET_MIPS64
13921 case OPC_DPAQ_W_QH_DSP:
13922 {
13923 int ac = ret & 0x03;
13924 tcg_gen_movi_i32(t0, ac);
13925
13926 switch (op2) {
13927 case OPC_DMADD:
13928 check_dsp(ctx);
13929 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13930 break;
13931 case OPC_DMADDU:
13932 check_dsp(ctx);
13933 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13934 break;
13935 case OPC_DMSUB:
13936 check_dsp(ctx);
13937 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13938 break;
13939 case OPC_DMSUBU:
13940 check_dsp(ctx);
13941 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13942 break;
13943 case OPC_DPA_W_QH:
13944 check_dspr2(ctx);
13945 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13946 break;
13947 case OPC_DPAQ_S_W_QH:
13948 check_dsp(ctx);
13949 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13950 break;
13951 case OPC_DPAQ_SA_L_PW:
13952 check_dsp(ctx);
13953 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13954 break;
13955 case OPC_DPAU_H_OBL:
13956 check_dsp(ctx);
13957 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13958 break;
13959 case OPC_DPAU_H_OBR:
13960 check_dsp(ctx);
13961 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13962 break;
13963 case OPC_DPS_W_QH:
13964 check_dspr2(ctx);
13965 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13966 break;
13967 case OPC_DPSQ_S_W_QH:
13968 check_dsp(ctx);
13969 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13970 break;
13971 case OPC_DPSQ_SA_L_PW:
13972 check_dsp(ctx);
13973 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13974 break;
13975 case OPC_DPSU_H_OBL:
13976 check_dsp(ctx);
13977 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13978 break;
13979 case OPC_DPSU_H_OBR:
13980 check_dsp(ctx);
13981 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13982 break;
13983 case OPC_MAQ_S_L_PWL:
13984 check_dsp(ctx);
13985 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13986 break;
13987 case OPC_MAQ_S_L_PWR:
13988 check_dsp(ctx);
13989 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13990 break;
13991 case OPC_MAQ_S_W_QHLL:
13992 check_dsp(ctx);
13993 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13994 break;
13995 case OPC_MAQ_SA_W_QHLL:
13996 check_dsp(ctx);
13997 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13998 break;
13999 case OPC_MAQ_S_W_QHLR:
14000 check_dsp(ctx);
14001 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
14002 break;
14003 case OPC_MAQ_SA_W_QHLR:
14004 check_dsp(ctx);
14005 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
14006 break;
14007 case OPC_MAQ_S_W_QHRL:
14008 check_dsp(ctx);
14009 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
14010 break;
14011 case OPC_MAQ_SA_W_QHRL:
14012 check_dsp(ctx);
14013 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
14014 break;
14015 case OPC_MAQ_S_W_QHRR:
14016 check_dsp(ctx);
14017 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
14018 break;
14019 case OPC_MAQ_SA_W_QHRR:
14020 check_dsp(ctx);
14021 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
14022 break;
14023 case OPC_MULSAQ_S_L_PW:
14024 check_dsp(ctx);
14025 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
14026 break;
14027 case OPC_MULSAQ_S_W_QH:
14028 check_dsp(ctx);
14029 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14030 break;
14031 }
14032 }
14033 break;
14034#endif
14035 case OPC_ADDU_QB_DSP:
14036 switch (op2) {
14037 case OPC_MULEU_S_PH_QBL:
14038 check_dsp(ctx);
14039 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14040 break;
14041 case OPC_MULEU_S_PH_QBR:
14042 check_dsp(ctx);
14043 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14044 break;
14045 case OPC_MULQ_RS_PH:
14046 check_dsp(ctx);
14047 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14048 break;
14049 case OPC_MULEQ_S_W_PHL:
14050 check_dsp(ctx);
14051 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14052 break;
14053 case OPC_MULEQ_S_W_PHR:
14054 check_dsp(ctx);
14055 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14056 break;
14057 case OPC_MULQ_S_PH:
14058 check_dspr2(ctx);
14059 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14060 break;
14061 }
14062 break;
14063#ifdef TARGET_MIPS64
14064 case OPC_ADDU_OB_DSP:
14065 switch (op2) {
14066 case OPC_MULEQ_S_PW_QHL:
14067 check_dsp(ctx);
14068 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14069 break;
14070 case OPC_MULEQ_S_PW_QHR:
14071 check_dsp(ctx);
14072 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14073 break;
14074 case OPC_MULEU_S_QH_OBL:
14075 check_dsp(ctx);
14076 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14077 break;
14078 case OPC_MULEU_S_QH_OBR:
14079 check_dsp(ctx);
14080 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14081 break;
14082 case OPC_MULQ_RS_QH:
14083 check_dsp(ctx);
14084 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14085 break;
14086 }
14087 break;
14088#endif
14089 }
14090
14091 tcg_temp_free_i32(t0);
14092 tcg_temp_free(v1_t);
14093 tcg_temp_free(v2_t);
14094
14095 (void)opn; /* avoid a compiler warning */
14096 MIPS_DEBUG("%s", opn);
14097
14098}
14099
d75c135e 14100static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
14101 int ret, int val)
14102{
14103 const char *opn = "mipsdsp Bit/ Manipulation";
14104 int16_t imm;
14105 TCGv t0;
14106 TCGv val_t;
14107
14108 if (ret == 0) {
14109 /* Treat as NOP. */
14110 MIPS_DEBUG("NOP");
14111 return;
14112 }
14113
14114 t0 = tcg_temp_new();
14115 val_t = tcg_temp_new();
14116 gen_load_gpr(val_t, val);
14117
14118 switch (op1) {
14119 case OPC_ABSQ_S_PH_DSP:
14120 switch (op2) {
14121 case OPC_BITREV:
14122 check_dsp(ctx);
14123 gen_helper_bitrev(cpu_gpr[ret], val_t);
14124 break;
14125 case OPC_REPL_QB:
14126 check_dsp(ctx);
14127 {
14128 target_long result;
14129 imm = (ctx->opcode >> 16) & 0xFF;
14130 result = (uint32_t)imm << 24 |
14131 (uint32_t)imm << 16 |
14132 (uint32_t)imm << 8 |
14133 (uint32_t)imm;
14134 result = (int32_t)result;
14135 tcg_gen_movi_tl(cpu_gpr[ret], result);
14136 }
14137 break;
14138 case OPC_REPLV_QB:
14139 check_dsp(ctx);
14140 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14141 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14142 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14143 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14144 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14145 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14146 break;
14147 case OPC_REPL_PH:
14148 check_dsp(ctx);
14149 {
14150 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 14151 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
14152 tcg_gen_movi_tl(cpu_gpr[ret], \
14153 (target_long)((int32_t)imm << 16 | \
c4aaba92 14154 (uint16_t)imm));
1cb6686c
JL
14155 }
14156 break;
14157 case OPC_REPLV_PH:
14158 check_dsp(ctx);
14159 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14160 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14161 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14162 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14163 break;
14164 }
14165 break;
14166#ifdef TARGET_MIPS64
14167 case OPC_ABSQ_S_QH_DSP:
14168 switch (op2) {
14169 case OPC_REPL_OB:
14170 check_dsp(ctx);
14171 {
14172 target_long temp;
14173
14174 imm = (ctx->opcode >> 16) & 0xFF;
14175 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
14176 temp = (temp << 16) | temp;
14177 temp = (temp << 32) | temp;
14178 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14179 break;
14180 }
14181 case OPC_REPL_PW:
14182 check_dsp(ctx);
14183 {
14184 target_long temp;
14185
14186 imm = (ctx->opcode >> 16) & 0x03FF;
14187 imm = (int16_t)(imm << 6) >> 6;
14188 temp = ((target_long)imm << 32) \
14189 | ((target_long)imm & 0xFFFFFFFF);
14190 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14191 break;
14192 }
14193 case OPC_REPL_QH:
14194 check_dsp(ctx);
14195 {
14196 target_long temp;
14197
14198 imm = (ctx->opcode >> 16) & 0x03FF;
14199 imm = (int16_t)(imm << 6) >> 6;
14200
14201 temp = ((uint64_t)(uint16_t)imm << 48) |
14202 ((uint64_t)(uint16_t)imm << 32) |
14203 ((uint64_t)(uint16_t)imm << 16) |
14204 (uint64_t)(uint16_t)imm;
14205 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14206 break;
14207 }
14208 case OPC_REPLV_OB:
14209 check_dsp(ctx);
14210 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14211 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14212 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14213 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14214 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14215 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14216 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14217 break;
14218 case OPC_REPLV_PW:
14219 check_dsp(ctx);
14220 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
14221 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14222 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14223 break;
14224 case OPC_REPLV_QH:
14225 check_dsp(ctx);
14226 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14227 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14228 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14229 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14230 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14231 break;
14232 }
14233 break;
14234#endif
14235 }
14236 tcg_temp_free(t0);
14237 tcg_temp_free(val_t);
14238
14239 (void)opn; /* avoid a compiler warning */
14240 MIPS_DEBUG("%s", opn);
14241}
14242
26690560
JL
14243static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
14244 uint32_t op1, uint32_t op2,
14245 int ret, int v1, int v2, int check_ret)
14246{
14247 const char *opn = "mipsdsp add compare pick";
26690560
JL
14248 TCGv t1;
14249 TCGv v1_t;
14250 TCGv v2_t;
14251
14252 if ((ret == 0) && (check_ret == 1)) {
14253 /* Treat as NOP. */
14254 MIPS_DEBUG("NOP");
14255 return;
14256 }
14257
26690560
JL
14258 t1 = tcg_temp_new();
14259 v1_t = tcg_temp_new();
14260 v2_t = tcg_temp_new();
14261
14262 gen_load_gpr(v1_t, v1);
14263 gen_load_gpr(v2_t, v2);
14264
14265 switch (op1) {
26690560
JL
14266 case OPC_CMPU_EQ_QB_DSP:
14267 switch (op2) {
14268 case OPC_CMPU_EQ_QB:
14269 check_dsp(ctx);
14270 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
14271 break;
14272 case OPC_CMPU_LT_QB:
14273 check_dsp(ctx);
14274 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
14275 break;
14276 case OPC_CMPU_LE_QB:
14277 check_dsp(ctx);
14278 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
14279 break;
14280 case OPC_CMPGU_EQ_QB:
14281 check_dsp(ctx);
14282 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
14283 break;
14284 case OPC_CMPGU_LT_QB:
14285 check_dsp(ctx);
14286 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
14287 break;
14288 case OPC_CMPGU_LE_QB:
14289 check_dsp(ctx);
14290 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
14291 break;
14292 case OPC_CMPGDU_EQ_QB:
14293 check_dspr2(ctx);
14294 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
14295 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14296 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14297 tcg_gen_shli_tl(t1, t1, 24);
14298 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14299 break;
14300 case OPC_CMPGDU_LT_QB:
14301 check_dspr2(ctx);
14302 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
14303 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14304 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14305 tcg_gen_shli_tl(t1, t1, 24);
14306 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14307 break;
14308 case OPC_CMPGDU_LE_QB:
14309 check_dspr2(ctx);
14310 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14311 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14312 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14313 tcg_gen_shli_tl(t1, t1, 24);
14314 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14315 break;
14316 case OPC_CMP_EQ_PH:
14317 check_dsp(ctx);
14318 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
14319 break;
14320 case OPC_CMP_LT_PH:
14321 check_dsp(ctx);
14322 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
14323 break;
14324 case OPC_CMP_LE_PH:
14325 check_dsp(ctx);
14326 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
14327 break;
14328 case OPC_PICK_QB:
14329 check_dsp(ctx);
14330 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14331 break;
14332 case OPC_PICK_PH:
14333 check_dsp(ctx);
14334 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14335 break;
14336 case OPC_PACKRL_PH:
14337 check_dsp(ctx);
14338 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
14339 break;
14340 }
14341 break;
14342#ifdef TARGET_MIPS64
14343 case OPC_CMPU_EQ_OB_DSP:
14344 switch (op2) {
14345 case OPC_CMP_EQ_PW:
14346 check_dsp(ctx);
14347 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
14348 break;
14349 case OPC_CMP_LT_PW:
14350 check_dsp(ctx);
14351 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14352 break;
14353 case OPC_CMP_LE_PW:
14354 check_dsp(ctx);
14355 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14356 break;
14357 case OPC_CMP_EQ_QH:
14358 check_dsp(ctx);
14359 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14360 break;
14361 case OPC_CMP_LT_QH:
14362 check_dsp(ctx);
14363 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14364 break;
14365 case OPC_CMP_LE_QH:
14366 check_dsp(ctx);
14367 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14368 break;
14369 case OPC_CMPGDU_EQ_OB:
14370 check_dspr2(ctx);
14371 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14372 break;
14373 case OPC_CMPGDU_LT_OB:
14374 check_dspr2(ctx);
14375 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14376 break;
14377 case OPC_CMPGDU_LE_OB:
14378 check_dspr2(ctx);
14379 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14380 break;
14381 case OPC_CMPGU_EQ_OB:
14382 check_dsp(ctx);
14383 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14384 break;
14385 case OPC_CMPGU_LT_OB:
14386 check_dsp(ctx);
14387 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14388 break;
14389 case OPC_CMPGU_LE_OB:
14390 check_dsp(ctx);
14391 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14392 break;
14393 case OPC_CMPU_EQ_OB:
14394 check_dsp(ctx);
14395 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14396 break;
14397 case OPC_CMPU_LT_OB:
14398 check_dsp(ctx);
14399 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14400 break;
14401 case OPC_CMPU_LE_OB:
14402 check_dsp(ctx);
14403 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14404 break;
14405 case OPC_PACKRL_PW:
14406 check_dsp(ctx);
14407 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14408 break;
14409 case OPC_PICK_OB:
14410 check_dsp(ctx);
14411 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14412 break;
14413 case OPC_PICK_PW:
14414 check_dsp(ctx);
14415 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14416 break;
14417 case OPC_PICK_QH:
14418 check_dsp(ctx);
14419 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14420 break;
14421 }
14422 break;
df6126a7
AJ
14423#endif
14424 }
14425
14426 tcg_temp_free(t1);
14427 tcg_temp_free(v1_t);
14428 tcg_temp_free(v2_t);
14429
14430 (void)opn; /* avoid a compiler warning */
14431 MIPS_DEBUG("%s", opn);
14432}
14433
14434static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14435 uint32_t op1, int rt, int rs, int sa)
14436{
14437 const char *opn = "mipsdsp append/dappend";
14438 TCGv t0;
14439
14440 check_dspr2(ctx);
14441
14442 if (rt == 0) {
14443 /* Treat as NOP. */
14444 MIPS_DEBUG("NOP");
14445 return;
14446 }
14447
14448 t0 = tcg_temp_new();
14449 gen_load_gpr(t0, rs);
14450
14451 switch (op1) {
14452 case OPC_APPEND_DSP:
14453 switch (MASK_APPEND(ctx->opcode)) {
14454 case OPC_APPEND:
14455 if (sa != 0) {
14456 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14457 }
14458 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14459 break;
14460 case OPC_PREPEND:
14461 if (sa != 0) {
14462 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14463 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14464 tcg_gen_shli_tl(t0, t0, 32 - sa);
14465 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14466 }
14467 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14468 break;
14469 case OPC_BALIGN:
14470 sa &= 3;
14471 if (sa != 0 && sa != 2) {
14472 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14473 tcg_gen_ext32u_tl(t0, t0);
14474 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14475 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14476 }
14477 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14478 break;
14479 default: /* Invalid */
14480 MIPS_INVAL("MASK APPEND");
14481 generate_exception(ctx, EXCP_RI);
14482 break;
14483 }
14484 break;
14485#ifdef TARGET_MIPS64
26690560 14486 case OPC_DAPPEND_DSP:
df6126a7 14487 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 14488 case OPC_DAPPEND:
df6126a7
AJ
14489 if (sa != 0) {
14490 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14491 }
26690560
JL
14492 break;
14493 case OPC_PREPENDD:
df6126a7
AJ
14494 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14495 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14496 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
14497 break;
14498 case OPC_PREPENDW:
df6126a7
AJ
14499 if (sa != 0) {
14500 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14501 tcg_gen_shli_tl(t0, t0, 64 - sa);
14502 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14503 }
26690560
JL
14504 break;
14505 case OPC_DBALIGN:
df6126a7
AJ
14506 sa &= 7;
14507 if (sa != 0 && sa != 2 && sa != 4) {
14508 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14509 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14510 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14511 }
26690560
JL
14512 break;
14513 default: /* Invalid */
14514 MIPS_INVAL("MASK DAPPEND");
14515 generate_exception(ctx, EXCP_RI);
14516 break;
14517 }
14518 break;
14519#endif
14520 }
df6126a7 14521 tcg_temp_free(t0);
26690560
JL
14522 (void)opn; /* avoid a compiler warning */
14523 MIPS_DEBUG("%s", opn);
14524}
14525
b53371ed
JL
14526static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14527 int ret, int v1, int v2, int check_ret)
14528
14529{
14530 const char *opn = "mipsdsp accumulator";
14531 TCGv t0;
14532 TCGv t1;
14533 TCGv v1_t;
14534 TCGv v2_t;
14535 int16_t imm;
14536
14537 if ((ret == 0) && (check_ret == 1)) {
14538 /* Treat as NOP. */
14539 MIPS_DEBUG("NOP");
14540 return;
14541 }
14542
14543 t0 = tcg_temp_new();
14544 t1 = tcg_temp_new();
14545 v1_t = tcg_temp_new();
14546 v2_t = tcg_temp_new();
14547
14548 gen_load_gpr(v1_t, v1);
14549 gen_load_gpr(v2_t, v2);
14550
14551 switch (op1) {
14552 case OPC_EXTR_W_DSP:
14553 check_dsp(ctx);
14554 switch (op2) {
14555 case OPC_EXTR_W:
14556 tcg_gen_movi_tl(t0, v2);
14557 tcg_gen_movi_tl(t1, v1);
14558 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14559 break;
14560 case OPC_EXTR_R_W:
14561 tcg_gen_movi_tl(t0, v2);
14562 tcg_gen_movi_tl(t1, v1);
14563 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14564 break;
14565 case OPC_EXTR_RS_W:
14566 tcg_gen_movi_tl(t0, v2);
14567 tcg_gen_movi_tl(t1, v1);
14568 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14569 break;
14570 case OPC_EXTR_S_H:
14571 tcg_gen_movi_tl(t0, v2);
14572 tcg_gen_movi_tl(t1, v1);
14573 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14574 break;
14575 case OPC_EXTRV_S_H:
14576 tcg_gen_movi_tl(t0, v2);
14577 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14578 break;
14579 case OPC_EXTRV_W:
14580 tcg_gen_movi_tl(t0, v2);
14581 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14582 break;
14583 case OPC_EXTRV_R_W:
14584 tcg_gen_movi_tl(t0, v2);
14585 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14586 break;
14587 case OPC_EXTRV_RS_W:
14588 tcg_gen_movi_tl(t0, v2);
14589 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14590 break;
14591 case OPC_EXTP:
14592 tcg_gen_movi_tl(t0, v2);
14593 tcg_gen_movi_tl(t1, v1);
14594 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14595 break;
14596 case OPC_EXTPV:
14597 tcg_gen_movi_tl(t0, v2);
14598 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14599 break;
14600 case OPC_EXTPDP:
14601 tcg_gen_movi_tl(t0, v2);
14602 tcg_gen_movi_tl(t1, v1);
14603 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14604 break;
14605 case OPC_EXTPDPV:
14606 tcg_gen_movi_tl(t0, v2);
14607 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14608 break;
14609 case OPC_SHILO:
14610 imm = (ctx->opcode >> 20) & 0x3F;
14611 tcg_gen_movi_tl(t0, ret);
14612 tcg_gen_movi_tl(t1, imm);
14613 gen_helper_shilo(t0, t1, cpu_env);
14614 break;
14615 case OPC_SHILOV:
14616 tcg_gen_movi_tl(t0, ret);
14617 gen_helper_shilo(t0, v1_t, cpu_env);
14618 break;
14619 case OPC_MTHLIP:
14620 tcg_gen_movi_tl(t0, ret);
14621 gen_helper_mthlip(t0, v1_t, cpu_env);
14622 break;
14623 case OPC_WRDSP:
14624 imm = (ctx->opcode >> 11) & 0x3FF;
14625 tcg_gen_movi_tl(t0, imm);
14626 gen_helper_wrdsp(v1_t, t0, cpu_env);
14627 break;
14628 case OPC_RDDSP:
14629 imm = (ctx->opcode >> 16) & 0x03FF;
14630 tcg_gen_movi_tl(t0, imm);
14631 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14632 break;
14633 }
14634 break;
14635#ifdef TARGET_MIPS64
14636 case OPC_DEXTR_W_DSP:
14637 check_dsp(ctx);
14638 switch (op2) {
14639 case OPC_DMTHLIP:
14640 tcg_gen_movi_tl(t0, ret);
14641 gen_helper_dmthlip(v1_t, t0, cpu_env);
14642 break;
14643 case OPC_DSHILO:
14644 {
14645 int shift = (ctx->opcode >> 19) & 0x7F;
14646 int ac = (ctx->opcode >> 11) & 0x03;
14647 tcg_gen_movi_tl(t0, shift);
14648 tcg_gen_movi_tl(t1, ac);
14649 gen_helper_dshilo(t0, t1, cpu_env);
14650 break;
14651 }
14652 case OPC_DSHILOV:
14653 {
14654 int ac = (ctx->opcode >> 11) & 0x03;
14655 tcg_gen_movi_tl(t0, ac);
14656 gen_helper_dshilo(v1_t, t0, cpu_env);
14657 break;
14658 }
14659 case OPC_DEXTP:
14660 tcg_gen_movi_tl(t0, v2);
14661 tcg_gen_movi_tl(t1, v1);
14662
14663 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14664 break;
14665 case OPC_DEXTPV:
14666 tcg_gen_movi_tl(t0, v2);
14667 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14668 break;
14669 case OPC_DEXTPDP:
14670 tcg_gen_movi_tl(t0, v2);
14671 tcg_gen_movi_tl(t1, v1);
14672 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14673 break;
14674 case OPC_DEXTPDPV:
14675 tcg_gen_movi_tl(t0, v2);
14676 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14677 break;
14678 case OPC_DEXTR_L:
14679 tcg_gen_movi_tl(t0, v2);
14680 tcg_gen_movi_tl(t1, v1);
14681 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14682 break;
14683 case OPC_DEXTR_R_L:
14684 tcg_gen_movi_tl(t0, v2);
14685 tcg_gen_movi_tl(t1, v1);
14686 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14687 break;
14688 case OPC_DEXTR_RS_L:
14689 tcg_gen_movi_tl(t0, v2);
14690 tcg_gen_movi_tl(t1, v1);
14691 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14692 break;
14693 case OPC_DEXTR_W:
14694 tcg_gen_movi_tl(t0, v2);
14695 tcg_gen_movi_tl(t1, v1);
14696 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14697 break;
14698 case OPC_DEXTR_R_W:
14699 tcg_gen_movi_tl(t0, v2);
14700 tcg_gen_movi_tl(t1, v1);
14701 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14702 break;
14703 case OPC_DEXTR_RS_W:
14704 tcg_gen_movi_tl(t0, v2);
14705 tcg_gen_movi_tl(t1, v1);
14706 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14707 break;
14708 case OPC_DEXTR_S_H:
14709 tcg_gen_movi_tl(t0, v2);
14710 tcg_gen_movi_tl(t1, v1);
14711 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14712 break;
14713 case OPC_DEXTRV_S_H:
14714 tcg_gen_movi_tl(t0, v2);
14715 tcg_gen_movi_tl(t1, v1);
14716 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14717 break;
14718 case OPC_DEXTRV_L:
14719 tcg_gen_movi_tl(t0, v2);
14720 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14721 break;
14722 case OPC_DEXTRV_R_L:
14723 tcg_gen_movi_tl(t0, v2);
14724 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14725 break;
14726 case OPC_DEXTRV_RS_L:
14727 tcg_gen_movi_tl(t0, v2);
14728 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14729 break;
14730 case OPC_DEXTRV_W:
14731 tcg_gen_movi_tl(t0, v2);
14732 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14733 break;
14734 case OPC_DEXTRV_R_W:
14735 tcg_gen_movi_tl(t0, v2);
14736 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14737 break;
14738 case OPC_DEXTRV_RS_W:
14739 tcg_gen_movi_tl(t0, v2);
14740 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14741 break;
14742 }
14743 break;
14744#endif
14745 }
14746
14747 tcg_temp_free(t0);
14748 tcg_temp_free(t1);
14749 tcg_temp_free(v1_t);
14750 tcg_temp_free(v2_t);
14751
14752 (void)opn; /* avoid a compiler warning */
14753 MIPS_DEBUG("%s", opn);
14754}
14755
9b1a1d68
JL
14756/* End MIPSDSP functions. */
14757
10dc65db
LA
14758static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
14759{
4267d3e6 14760 int rs, rt, rd, sa;
b42ee5e1 14761 uint32_t op1, op2;
10dc65db
LA
14762
14763 rs = (ctx->opcode >> 21) & 0x1f;
14764 rt = (ctx->opcode >> 16) & 0x1f;
14765 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 14766 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
14767
14768 op1 = MASK_SPECIAL(ctx->opcode);
14769 switch (op1) {
b42ee5e1
LA
14770 case OPC_MULT ... OPC_DIVU:
14771 op2 = MASK_R6_MULDIV(ctx->opcode);
14772 switch (op2) {
14773 case R6_OPC_MUL:
14774 case R6_OPC_MUH:
14775 case R6_OPC_MULU:
14776 case R6_OPC_MUHU:
14777 case R6_OPC_DIV:
14778 case R6_OPC_MOD:
14779 case R6_OPC_DIVU:
14780 case R6_OPC_MODU:
14781 gen_r6_muldiv(ctx, op2, rd, rs, rt);
14782 break;
14783 default:
14784 MIPS_INVAL("special_r6 muldiv");
14785 generate_exception(ctx, EXCP_RI);
14786 break;
14787 }
14788 break;
10dc65db
LA
14789 case OPC_SELEQZ:
14790 case OPC_SELNEZ:
14791 gen_cond_move(ctx, op1, rd, rs, rt);
14792 break;
4267d3e6
LA
14793 case R6_OPC_CLO:
14794 case R6_OPC_CLZ:
14795 if (rt == 0 && sa == 1) {
14796 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
14797 We need additionally to check other fields */
14798 gen_cl(ctx, op1, rd, rs);
14799 } else {
14800 generate_exception(ctx, EXCP_RI);
14801 }
14802 break;
14803 case R6_OPC_SDBBP:
14804 generate_exception(ctx, EXCP_DBp);
14805 break;
b42ee5e1 14806#if defined(TARGET_MIPS64)
4267d3e6
LA
14807 case R6_OPC_DCLO:
14808 case R6_OPC_DCLZ:
14809 if (rt == 0 && sa == 1) {
14810 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
14811 We need additionally to check other fields */
14812 check_mips_64(ctx);
14813 gen_cl(ctx, op1, rd, rs);
14814 } else {
14815 generate_exception(ctx, EXCP_RI);
14816 }
14817 break;
b42ee5e1
LA
14818 case OPC_DMULT ... OPC_DDIVU:
14819 op2 = MASK_R6_MULDIV(ctx->opcode);
14820 switch (op2) {
14821 case R6_OPC_DMUL:
14822 case R6_OPC_DMUH:
14823 case R6_OPC_DMULU:
14824 case R6_OPC_DMUHU:
14825 case R6_OPC_DDIV:
14826 case R6_OPC_DMOD:
14827 case R6_OPC_DDIVU:
14828 case R6_OPC_DMODU:
14829 check_mips_64(ctx);
14830 gen_r6_muldiv(ctx, op2, rd, rs, rt);
14831 break;
14832 default:
14833 MIPS_INVAL("special_r6 muldiv");
14834 generate_exception(ctx, EXCP_RI);
14835 break;
14836 }
14837 break;
14838#endif
10dc65db
LA
14839 default: /* Invalid */
14840 MIPS_INVAL("special_r6");
14841 generate_exception(ctx, EXCP_RI);
14842 break;
14843 }
14844}
14845
14846static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14847{
b42ee5e1 14848 int rs, rt, rd, sa;
10dc65db
LA
14849 uint32_t op1;
14850
14851 rs = (ctx->opcode >> 21) & 0x1f;
14852 rt = (ctx->opcode >> 16) & 0x1f;
14853 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 14854 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
14855
14856 op1 = MASK_SPECIAL(ctx->opcode);
14857 switch (op1) {
14858 case OPC_MOVN: /* Conditional move */
14859 case OPC_MOVZ:
14860 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14861 INSN_LOONGSON2E | INSN_LOONGSON2F);
14862 gen_cond_move(ctx, op1, rd, rs, rt);
14863 break;
14864 case OPC_MFHI: /* Move from HI/LO */
14865 case OPC_MFLO:
14866 gen_HILO(ctx, op1, rs & 3, rd);
14867 break;
14868 case OPC_MTHI:
14869 case OPC_MTLO: /* Move to HI/LO */
14870 gen_HILO(ctx, op1, rd & 3, rs);
14871 break;
14872 case OPC_MOVCI:
14873 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14874 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14875 check_cp1_enabled(ctx);
14876 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14877 (ctx->opcode >> 16) & 1);
14878 } else {
14879 generate_exception_err(ctx, EXCP_CpU, 1);
14880 }
14881 break;
b42ee5e1
LA
14882 case OPC_MULT:
14883 case OPC_MULTU:
14884 if (sa) {
14885 check_insn(ctx, INSN_VR54XX);
14886 op1 = MASK_MUL_VR54XX(ctx->opcode);
14887 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14888 } else {
14889 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14890 }
14891 break;
14892 case OPC_DIV:
14893 case OPC_DIVU:
14894 gen_muldiv(ctx, op1, 0, rs, rt);
14895 break;
14896#if defined(TARGET_MIPS64)
14897 case OPC_DMULT ... OPC_DDIVU:
14898 check_insn(ctx, ISA_MIPS3);
14899 check_mips_64(ctx);
14900 gen_muldiv(ctx, op1, 0, rs, rt);
14901 break;
14902#endif
4267d3e6
LA
14903 case OPC_SPIM:
14904#ifdef MIPS_STRICT_STANDARD
14905 MIPS_INVAL("SPIM");
14906 generate_exception(ctx, EXCP_RI);
14907#else
14908 /* Implemented as RI exception for now. */
14909 MIPS_INVAL("spim (unofficial)");
14910 generate_exception(ctx, EXCP_RI);
14911#endif
14912 break;
10dc65db
LA
14913 default: /* Invalid */
14914 MIPS_INVAL("special_legacy");
14915 generate_exception(ctx, EXCP_RI);
14916 break;
14917 }
14918}
14919
099e5b4d 14920static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 14921{
3c824109 14922 int rs, rt, rd, sa;
099e5b4d 14923 uint32_t op1;
3c824109 14924
3c824109
NF
14925 rs = (ctx->opcode >> 21) & 0x1f;
14926 rt = (ctx->opcode >> 16) & 0x1f;
14927 rd = (ctx->opcode >> 11) & 0x1f;
14928 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
14929
14930 op1 = MASK_SPECIAL(ctx->opcode);
14931 switch (op1) {
14932 case OPC_SLL: /* Shift with immediate */
14933 case OPC_SRA:
14934 gen_shift_imm(ctx, op1, rd, rt, sa);
14935 break;
14936 case OPC_SRL:
14937 switch ((ctx->opcode >> 21) & 0x1f) {
14938 case 1:
14939 /* rotr is decoded as srl on non-R2 CPUs */
14940 if (ctx->insn_flags & ISA_MIPS32R2) {
14941 op1 = OPC_ROTR;
ea63e2c3 14942 }
099e5b4d
LA
14943 /* Fallthrough */
14944 case 0:
14945 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 14946 break;
099e5b4d
LA
14947 default:
14948 generate_exception(ctx, EXCP_RI);
ea63e2c3 14949 break;
099e5b4d
LA
14950 }
14951 break;
099e5b4d
LA
14952 case OPC_ADD ... OPC_SUBU:
14953 gen_arith(ctx, op1, rd, rs, rt);
14954 break;
14955 case OPC_SLLV: /* Shifts */
14956 case OPC_SRAV:
14957 gen_shift(ctx, op1, rd, rs, rt);
14958 break;
14959 case OPC_SRLV:
14960 switch ((ctx->opcode >> 6) & 0x1f) {
14961 case 1:
14962 /* rotrv is decoded as srlv on non-R2 CPUs */
14963 if (ctx->insn_flags & ISA_MIPS32R2) {
14964 op1 = OPC_ROTRV;
26135ead 14965 }
099e5b4d
LA
14966 /* Fallthrough */
14967 case 0:
14968 gen_shift(ctx, op1, rd, rs, rt);
26135ead 14969 break;
099e5b4d
LA
14970 default:
14971 generate_exception(ctx, EXCP_RI);
6af0bf9c 14972 break;
099e5b4d
LA
14973 }
14974 break;
14975 case OPC_SLT: /* Set on less than */
14976 case OPC_SLTU:
14977 gen_slt(ctx, op1, rd, rs, rt);
14978 break;
14979 case OPC_AND: /* Logic*/
14980 case OPC_OR:
14981 case OPC_NOR:
14982 case OPC_XOR:
14983 gen_logic(ctx, op1, rd, rs, rt);
14984 break;
099e5b4d
LA
14985 case OPC_JR ... OPC_JALR:
14986 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14987 break;
14988 case OPC_TGE ... OPC_TEQ: /* Traps */
14989 case OPC_TNE:
14990 gen_trap(ctx, op1, rs, rt, -1);
14991 break;
099e5b4d 14992 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
b48cfdff 14993#ifdef MIPS_STRICT_STANDARD
099e5b4d
LA
14994 MIPS_INVAL("PMON / selsl");
14995 generate_exception(ctx, EXCP_RI);
b48cfdff 14996#else
099e5b4d 14997 gen_helper_0e0i(pmon, sa);
b48cfdff 14998#endif
099e5b4d
LA
14999 break;
15000 case OPC_SYSCALL:
15001 generate_exception(ctx, EXCP_SYSCALL);
15002 ctx->bstate = BS_STOP;
15003 break;
15004 case OPC_BREAK:
15005 generate_exception(ctx, EXCP_BREAK);
15006 break;
099e5b4d
LA
15007 case OPC_SYNC:
15008 /* Treat as NOP. */
15009 break;
4ad40f36 15010
d26bc211 15011#if defined(TARGET_MIPS64)
099e5b4d
LA
15012 /* MIPS64 specific opcodes */
15013 case OPC_DSLL:
15014 case OPC_DSRA:
15015 case OPC_DSLL32:
15016 case OPC_DSRA32:
15017 check_insn(ctx, ISA_MIPS3);
15018 check_mips_64(ctx);
15019 gen_shift_imm(ctx, op1, rd, rt, sa);
15020 break;
15021 case OPC_DSRL:
15022 switch ((ctx->opcode >> 21) & 0x1f) {
15023 case 1:
15024 /* drotr is decoded as dsrl on non-R2 CPUs */
15025 if (ctx->insn_flags & ISA_MIPS32R2) {
15026 op1 = OPC_DROTR;
ea63e2c3 15027 }
099e5b4d
LA
15028 /* Fallthrough */
15029 case 0:
d75c135e 15030 check_insn(ctx, ISA_MIPS3);
e189e748 15031 check_mips_64(ctx);
099e5b4d 15032 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 15033 break;
099e5b4d
LA
15034 default:
15035 generate_exception(ctx, EXCP_RI);
460f00c4 15036 break;
099e5b4d
LA
15037 }
15038 break;
15039 case OPC_DSRL32:
15040 switch ((ctx->opcode >> 21) & 0x1f) {
15041 case 1:
15042 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
15043 if (ctx->insn_flags & ISA_MIPS32R2) {
15044 op1 = OPC_DROTR32;
ea63e2c3 15045 }
099e5b4d
LA
15046 /* Fallthrough */
15047 case 0:
d75c135e 15048 check_insn(ctx, ISA_MIPS3);
e189e748 15049 check_mips_64(ctx);
099e5b4d 15050 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 15051 break;
099e5b4d 15052 default:
6af0bf9c
FB
15053 generate_exception(ctx, EXCP_RI);
15054 break;
15055 }
15056 break;
099e5b4d
LA
15057 case OPC_DADD ... OPC_DSUBU:
15058 check_insn(ctx, ISA_MIPS3);
15059 check_mips_64(ctx);
15060 gen_arith(ctx, op1, rd, rs, rt);
15061 break;
15062 case OPC_DSLLV:
15063 case OPC_DSRAV:
15064 check_insn(ctx, ISA_MIPS3);
15065 check_mips_64(ctx);
15066 gen_shift(ctx, op1, rd, rs, rt);
15067 break;
15068 case OPC_DSRLV:
15069 switch ((ctx->opcode >> 6) & 0x1f) {
15070 case 1:
15071 /* drotrv is decoded as dsrlv on non-R2 CPUs */
15072 if (ctx->insn_flags & ISA_MIPS32R2) {
15073 op1 = OPC_DROTRV;
6af0bf9c 15074 }
099e5b4d
LA
15075 /* Fallthrough */
15076 case 0:
15077 check_insn(ctx, ISA_MIPS3);
e189e748 15078 check_mips_64(ctx);
099e5b4d 15079 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 15080 break;
099e5b4d 15081 default:
6af0bf9c
FB
15082 generate_exception(ctx, EXCP_RI);
15083 break;
15084 }
15085 break;
099e5b4d 15086#endif
10dc65db
LA
15087 default:
15088 if (ctx->insn_flags & ISA_MIPS32R6) {
15089 decode_opc_special_r6(env, ctx);
15090 } else {
15091 decode_opc_special_legacy(env, ctx);
15092 }
15093 }
15094}
15095
10dc65db 15096static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
15097{
15098 int rs, rt, rd;
15099 uint32_t op1;
6c5c1e20 15100
4267d3e6
LA
15101 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15102
099e5b4d
LA
15103 rs = (ctx->opcode >> 21) & 0x1f;
15104 rt = (ctx->opcode >> 16) & 0x1f;
15105 rd = (ctx->opcode >> 11) & 0x1f;
15106
15107 op1 = MASK_SPECIAL2(ctx->opcode);
15108 switch (op1) {
15109 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
15110 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
15111 check_insn(ctx, ISA_MIPS32);
15112 gen_muldiv(ctx, op1, rd & 3, rs, rt);
15113 break;
15114 case OPC_MUL:
099e5b4d
LA
15115 gen_arith(ctx, op1, rd, rs, rt);
15116 break;
fac5a073
LA
15117 case OPC_DIV_G_2F:
15118 case OPC_DIVU_G_2F:
15119 case OPC_MULT_G_2F:
15120 case OPC_MULTU_G_2F:
15121 case OPC_MOD_G_2F:
15122 case OPC_MODU_G_2F:
15123 check_insn(ctx, INSN_LOONGSON2F);
15124 gen_loongson_integer(ctx, op1, rd, rs, rt);
15125 break;
099e5b4d
LA
15126 case OPC_CLO:
15127 case OPC_CLZ:
15128 check_insn(ctx, ISA_MIPS32);
15129 gen_cl(ctx, op1, rd, rs);
15130 break;
15131 case OPC_SDBBP:
15132 /* XXX: not clear which exception should be raised
15133 * when in debug mode...
15134 */
15135 check_insn(ctx, ISA_MIPS32);
15136 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
15137 generate_exception(ctx, EXCP_DBp);
15138 } else {
15139 generate_exception(ctx, EXCP_DBp);
15140 }
15141 /* Treat as NOP. */
15142 break;
9b1a1d68 15143#if defined(TARGET_MIPS64)
099e5b4d
LA
15144 case OPC_DCLO:
15145 case OPC_DCLZ:
15146 check_insn(ctx, ISA_MIPS64);
15147 check_mips_64(ctx);
15148 gen_cl(ctx, op1, rd, rs);
15149 break;
4267d3e6
LA
15150 case OPC_DMULT_G_2F:
15151 case OPC_DMULTU_G_2F:
15152 case OPC_DDIV_G_2F:
15153 case OPC_DDIVU_G_2F:
15154 case OPC_DMOD_G_2F:
15155 case OPC_DMODU_G_2F:
15156 check_insn(ctx, INSN_LOONGSON2F);
15157 gen_loongson_integer(ctx, op1, rd, rs, rt);
15158 break;
10dc65db 15159#endif
4267d3e6
LA
15160 default: /* Invalid */
15161 MIPS_INVAL("special2_legacy");
15162 generate_exception(ctx, EXCP_RI);
15163 break;
10dc65db
LA
15164 }
15165}
15166
15167static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
15168{
15169 int rs, rt;
15170 uint32_t op1;
15171 int16_t imm;
15172
15173 rs = (ctx->opcode >> 21) & 0x1f;
15174 rt = (ctx->opcode >> 16) & 0x1f;
15175 imm = (int16_t)ctx->opcode >> 7;
15176
15177 op1 = MASK_SPECIAL3(ctx->opcode);
15178 switch (op1) {
bf7910c6
LA
15179 case R6_OPC_PREF:
15180 if (rt >= 24) {
15181 /* hint codes 24-31 are reserved and signal RI */
15182 generate_exception(ctx, EXCP_RI);
15183 }
15184 /* Treat as NOP. */
15185 break;
15186 case R6_OPC_CACHE:
15187 /* Treat as NOP. */
15188 break;
10dc65db
LA
15189 case R6_OPC_SC:
15190 gen_st_cond(ctx, op1, rt, rs, imm);
15191 break;
15192 case R6_OPC_LL:
15193 gen_ld(ctx, op1, rt, rs, imm);
15194 break;
bf7910c6
LA
15195#if defined(TARGET_MIPS64)
15196 case R6_OPC_SCD:
15197 gen_st_cond(ctx, op1, rt, rs, imm);
15198 break;
15199 case R6_OPC_LLD:
15200 gen_ld(ctx, op1, rt, rs, imm);
15201 break;
15202#endif
10dc65db
LA
15203 default: /* Invalid */
15204 MIPS_INVAL("special3_r6");
15205 generate_exception(ctx, EXCP_RI);
15206 break;
15207 }
15208}
15209
15210static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
15211{
fac5a073 15212 int rs, rt, rd;
099e5b4d 15213 uint32_t op1, op2;
099e5b4d
LA
15214
15215 rs = (ctx->opcode >> 21) & 0x1f;
15216 rt = (ctx->opcode >> 16) & 0x1f;
15217 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
15218
15219 op1 = MASK_SPECIAL3(ctx->opcode);
15220 switch (op1) {
099e5b4d
LA
15221 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
15222 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
15223 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
15224 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15225 * the same mask and op1. */
15226 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
15227 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 15228 switch (op2) {
099e5b4d
LA
15229 case OPC_ADDUH_QB:
15230 case OPC_ADDUH_R_QB:
15231 case OPC_ADDQH_PH:
15232 case OPC_ADDQH_R_PH:
15233 case OPC_ADDQH_W:
15234 case OPC_ADDQH_R_W:
15235 case OPC_SUBUH_QB:
15236 case OPC_SUBUH_R_QB:
15237 case OPC_SUBQH_PH:
15238 case OPC_SUBQH_R_PH:
15239 case OPC_SUBQH_W:
15240 case OPC_SUBQH_R_W:
461c08df
JL
15241 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15242 break;
099e5b4d
LA
15243 case OPC_MUL_PH:
15244 case OPC_MUL_S_PH:
15245 case OPC_MULQ_S_W:
15246 case OPC_MULQ_RS_W:
15247 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 15248 break;
461c08df 15249 default:
099e5b4d 15250 MIPS_INVAL("MASK ADDUH.QB");
461c08df
JL
15251 generate_exception(ctx, EXCP_RI);
15252 break;
15253 }
099e5b4d
LA
15254 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
15255 gen_loongson_integer(ctx, op1, rd, rs, rt);
15256 } else {
15257 generate_exception(ctx, EXCP_RI);
15258 }
15259 break;
15260 case OPC_LX_DSP:
15261 op2 = MASK_LX(ctx->opcode);
15262 switch (op2) {
15263#if defined(TARGET_MIPS64)
15264 case OPC_LDX:
15265#endif
15266 case OPC_LBUX:
15267 case OPC_LHX:
15268 case OPC_LWX:
15269 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
15270 break;
15271 default: /* Invalid */
15272 MIPS_INVAL("MASK LX");
15273 generate_exception(ctx, EXCP_RI);
15274 break;
15275 }
15276 break;
15277 case OPC_ABSQ_S_PH_DSP:
15278 op2 = MASK_ABSQ_S_PH(ctx->opcode);
15279 switch (op2) {
15280 case OPC_ABSQ_S_QB:
15281 case OPC_ABSQ_S_PH:
15282 case OPC_ABSQ_S_W:
15283 case OPC_PRECEQ_W_PHL:
15284 case OPC_PRECEQ_W_PHR:
15285 case OPC_PRECEQU_PH_QBL:
15286 case OPC_PRECEQU_PH_QBR:
15287 case OPC_PRECEQU_PH_QBLA:
15288 case OPC_PRECEQU_PH_QBRA:
15289 case OPC_PRECEU_PH_QBL:
15290 case OPC_PRECEU_PH_QBR:
15291 case OPC_PRECEU_PH_QBLA:
15292 case OPC_PRECEU_PH_QBRA:
15293 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15294 break;
15295 case OPC_BITREV:
15296 case OPC_REPL_QB:
15297 case OPC_REPLV_QB:
15298 case OPC_REPL_PH:
15299 case OPC_REPLV_PH:
15300 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15301 break;
15302 default:
15303 MIPS_INVAL("MASK ABSQ_S.PH");
15304 generate_exception(ctx, EXCP_RI);
15305 break;
15306 }
15307 break;
15308 case OPC_ADDU_QB_DSP:
15309 op2 = MASK_ADDU_QB(ctx->opcode);
15310 switch (op2) {
15311 case OPC_ADDQ_PH:
15312 case OPC_ADDQ_S_PH:
15313 case OPC_ADDQ_S_W:
15314 case OPC_ADDU_QB:
15315 case OPC_ADDU_S_QB:
15316 case OPC_ADDU_PH:
15317 case OPC_ADDU_S_PH:
15318 case OPC_SUBQ_PH:
15319 case OPC_SUBQ_S_PH:
15320 case OPC_SUBQ_S_W:
15321 case OPC_SUBU_QB:
15322 case OPC_SUBU_S_QB:
15323 case OPC_SUBU_PH:
15324 case OPC_SUBU_S_PH:
15325 case OPC_ADDSC:
15326 case OPC_ADDWC:
15327 case OPC_MODSUB:
15328 case OPC_RADDU_W_QB:
15329 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15330 break;
15331 case OPC_MULEU_S_PH_QBL:
15332 case OPC_MULEU_S_PH_QBR:
15333 case OPC_MULQ_RS_PH:
15334 case OPC_MULEQ_S_W_PHL:
15335 case OPC_MULEQ_S_W_PHR:
15336 case OPC_MULQ_S_PH:
15337 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15338 break;
15339 default: /* Invalid */
15340 MIPS_INVAL("MASK ADDU.QB");
15341 generate_exception(ctx, EXCP_RI);
461c08df 15342 break;
461c08df 15343
099e5b4d
LA
15344 }
15345 break;
15346 case OPC_CMPU_EQ_QB_DSP:
15347 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
15348 switch (op2) {
15349 case OPC_PRECR_SRA_PH_W:
15350 case OPC_PRECR_SRA_R_PH_W:
15351 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 15352 break;
099e5b4d
LA
15353 case OPC_PRECR_QB_PH:
15354 case OPC_PRECRQ_QB_PH:
15355 case OPC_PRECRQ_PH_W:
15356 case OPC_PRECRQ_RS_PH_W:
15357 case OPC_PRECRQU_S_QB_PH:
15358 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 15359 break;
099e5b4d
LA
15360 case OPC_CMPU_EQ_QB:
15361 case OPC_CMPU_LT_QB:
15362 case OPC_CMPU_LE_QB:
15363 case OPC_CMP_EQ_PH:
15364 case OPC_CMP_LT_PH:
15365 case OPC_CMP_LE_PH:
15366 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 15367 break;
099e5b4d
LA
15368 case OPC_CMPGU_EQ_QB:
15369 case OPC_CMPGU_LT_QB:
15370 case OPC_CMPGU_LE_QB:
15371 case OPC_CMPGDU_EQ_QB:
15372 case OPC_CMPGDU_LT_QB:
15373 case OPC_CMPGDU_LE_QB:
15374 case OPC_PICK_QB:
15375 case OPC_PICK_PH:
15376 case OPC_PACKRL_PH:
15377 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15378 break;
15379 default: /* Invalid */
15380 MIPS_INVAL("MASK CMPU.EQ.QB");
15381 generate_exception(ctx, EXCP_RI);
15382 break;
15383 }
15384 break;
15385 case OPC_SHLL_QB_DSP:
15386 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15387 break;
15388 case OPC_DPA_W_PH_DSP:
15389 op2 = MASK_DPA_W_PH(ctx->opcode);
15390 switch (op2) {
15391 case OPC_DPAU_H_QBL:
15392 case OPC_DPAU_H_QBR:
15393 case OPC_DPSU_H_QBL:
15394 case OPC_DPSU_H_QBR:
15395 case OPC_DPA_W_PH:
15396 case OPC_DPAX_W_PH:
15397 case OPC_DPAQ_S_W_PH:
15398 case OPC_DPAQX_S_W_PH:
15399 case OPC_DPAQX_SA_W_PH:
15400 case OPC_DPS_W_PH:
15401 case OPC_DPSX_W_PH:
15402 case OPC_DPSQ_S_W_PH:
15403 case OPC_DPSQX_S_W_PH:
15404 case OPC_DPSQX_SA_W_PH:
15405 case OPC_MULSAQ_S_W_PH:
15406 case OPC_DPAQ_SA_L_W:
15407 case OPC_DPSQ_SA_L_W:
15408 case OPC_MAQ_S_W_PHL:
15409 case OPC_MAQ_S_W_PHR:
15410 case OPC_MAQ_SA_W_PHL:
15411 case OPC_MAQ_SA_W_PHR:
15412 case OPC_MULSA_W_PH:
15413 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15414 break;
15415 default: /* Invalid */
15416 MIPS_INVAL("MASK DPAW.PH");
15417 generate_exception(ctx, EXCP_RI);
15418 break;
15419 }
15420 break;
15421 case OPC_INSV_DSP:
15422 op2 = MASK_INSV(ctx->opcode);
15423 switch (op2) {
15424 case OPC_INSV:
15425 check_dsp(ctx);
15426 {
15427 TCGv t0, t1;
15428
15429 if (rt == 0) {
15430 MIPS_DEBUG("NOP");
15431 break;
15432 }
15433
15434 t0 = tcg_temp_new();
15435 t1 = tcg_temp_new();
15436
15437 gen_load_gpr(t0, rt);
15438 gen_load_gpr(t1, rs);
15439
15440 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
15441
15442 tcg_temp_free(t0);
15443 tcg_temp_free(t1);
a22260ae
JL
15444 break;
15445 }
099e5b4d
LA
15446 default: /* Invalid */
15447 MIPS_INVAL("MASK INSV");
15448 generate_exception(ctx, EXCP_RI);
15449 break;
15450 }
15451 break;
15452 case OPC_APPEND_DSP:
15453 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15454 break;
15455 case OPC_EXTR_W_DSP:
15456 op2 = MASK_EXTR_W(ctx->opcode);
15457 switch (op2) {
15458 case OPC_EXTR_W:
15459 case OPC_EXTR_R_W:
15460 case OPC_EXTR_RS_W:
15461 case OPC_EXTR_S_H:
15462 case OPC_EXTRV_S_H:
15463 case OPC_EXTRV_W:
15464 case OPC_EXTRV_R_W:
15465 case OPC_EXTRV_RS_W:
15466 case OPC_EXTP:
15467 case OPC_EXTPV:
15468 case OPC_EXTPDP:
15469 case OPC_EXTPDPV:
15470 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15471 break;
15472 case OPC_RDDSP:
15473 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15474 break;
15475 case OPC_SHILO:
15476 case OPC_SHILOV:
15477 case OPC_MTHLIP:
15478 case OPC_WRDSP:
15479 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15480 break;
15481 default: /* Invalid */
15482 MIPS_INVAL("MASK EXTR.W");
15483 generate_exception(ctx, EXCP_RI);
15484 break;
15485 }
15486 break;
099e5b4d 15487#if defined(TARGET_MIPS64)
fac5a073
LA
15488 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15489 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15490 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15491 check_insn(ctx, INSN_LOONGSON2E);
15492 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 15493 break;
099e5b4d
LA
15494 case OPC_ABSQ_S_QH_DSP:
15495 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15496 switch (op2) {
15497 case OPC_PRECEQ_L_PWL:
15498 case OPC_PRECEQ_L_PWR:
15499 case OPC_PRECEQ_PW_QHL:
15500 case OPC_PRECEQ_PW_QHR:
15501 case OPC_PRECEQ_PW_QHLA:
15502 case OPC_PRECEQ_PW_QHRA:
15503 case OPC_PRECEQU_QH_OBL:
15504 case OPC_PRECEQU_QH_OBR:
15505 case OPC_PRECEQU_QH_OBLA:
15506 case OPC_PRECEQU_QH_OBRA:
15507 case OPC_PRECEU_QH_OBL:
15508 case OPC_PRECEU_QH_OBR:
15509 case OPC_PRECEU_QH_OBLA:
15510 case OPC_PRECEU_QH_OBRA:
15511 case OPC_ABSQ_S_OB:
15512 case OPC_ABSQ_S_PW:
15513 case OPC_ABSQ_S_QH:
15514 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15515 break;
15516 case OPC_REPL_OB:
15517 case OPC_REPL_PW:
15518 case OPC_REPL_QH:
15519 case OPC_REPLV_OB:
15520 case OPC_REPLV_PW:
15521 case OPC_REPLV_QH:
15522 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15523 break;
15524 default: /* Invalid */
15525 MIPS_INVAL("MASK ABSQ_S.QH");
15526 generate_exception(ctx, EXCP_RI);
15527 break;
15528 }
15529 break;
15530 case OPC_ADDU_OB_DSP:
15531 op2 = MASK_ADDU_OB(ctx->opcode);
15532 switch (op2) {
15533 case OPC_RADDU_L_OB:
15534 case OPC_SUBQ_PW:
15535 case OPC_SUBQ_S_PW:
15536 case OPC_SUBQ_QH:
15537 case OPC_SUBQ_S_QH:
15538 case OPC_SUBU_OB:
15539 case OPC_SUBU_S_OB:
15540 case OPC_SUBU_QH:
15541 case OPC_SUBU_S_QH:
15542 case OPC_SUBUH_OB:
15543 case OPC_SUBUH_R_OB:
15544 case OPC_ADDQ_PW:
15545 case OPC_ADDQ_S_PW:
15546 case OPC_ADDQ_QH:
15547 case OPC_ADDQ_S_QH:
15548 case OPC_ADDU_OB:
15549 case OPC_ADDU_S_OB:
15550 case OPC_ADDU_QH:
15551 case OPC_ADDU_S_QH:
15552 case OPC_ADDUH_OB:
15553 case OPC_ADDUH_R_OB:
15554 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 15555 break;
099e5b4d
LA
15556 case OPC_MULEQ_S_PW_QHL:
15557 case OPC_MULEQ_S_PW_QHR:
15558 case OPC_MULEU_S_QH_OBL:
15559 case OPC_MULEU_S_QH_OBR:
15560 case OPC_MULQ_RS_QH:
15561 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 15562 break;
099e5b4d
LA
15563 default: /* Invalid */
15564 MIPS_INVAL("MASK ADDU.OB");
15565 generate_exception(ctx, EXCP_RI);
26690560 15566 break;
099e5b4d
LA
15567 }
15568 break;
15569 case OPC_CMPU_EQ_OB_DSP:
15570 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15571 switch (op2) {
15572 case OPC_PRECR_SRA_QH_PW:
15573 case OPC_PRECR_SRA_R_QH_PW:
15574 /* Return value is rt. */
15575 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 15576 break;
099e5b4d
LA
15577 case OPC_PRECR_OB_QH:
15578 case OPC_PRECRQ_OB_QH:
15579 case OPC_PRECRQ_PW_L:
15580 case OPC_PRECRQ_QH_PW:
15581 case OPC_PRECRQ_RS_QH_PW:
15582 case OPC_PRECRQU_S_OB_QH:
15583 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 15584 break;
099e5b4d
LA
15585 case OPC_CMPU_EQ_OB:
15586 case OPC_CMPU_LT_OB:
15587 case OPC_CMPU_LE_OB:
15588 case OPC_CMP_EQ_QH:
15589 case OPC_CMP_LT_QH:
15590 case OPC_CMP_LE_QH:
15591 case OPC_CMP_EQ_PW:
15592 case OPC_CMP_LT_PW:
15593 case OPC_CMP_LE_PW:
15594 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 15595 break;
099e5b4d
LA
15596 case OPC_CMPGDU_EQ_OB:
15597 case OPC_CMPGDU_LT_OB:
15598 case OPC_CMPGDU_LE_OB:
15599 case OPC_CMPGU_EQ_OB:
15600 case OPC_CMPGU_LT_OB:
15601 case OPC_CMPGU_LE_OB:
15602 case OPC_PACKRL_PW:
15603 case OPC_PICK_OB:
15604 case OPC_PICK_PW:
15605 case OPC_PICK_QH:
15606 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 15607 break;
099e5b4d
LA
15608 default: /* Invalid */
15609 MIPS_INVAL("MASK CMPU_EQ.OB");
15610 generate_exception(ctx, EXCP_RI);
161f85e6 15611 break;
099e5b4d
LA
15612 }
15613 break;
15614 case OPC_DAPPEND_DSP:
15615 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15616 break;
15617 case OPC_DEXTR_W_DSP:
15618 op2 = MASK_DEXTR_W(ctx->opcode);
15619 switch (op2) {
15620 case OPC_DEXTP:
15621 case OPC_DEXTPDP:
15622 case OPC_DEXTPDPV:
15623 case OPC_DEXTPV:
15624 case OPC_DEXTR_L:
15625 case OPC_DEXTR_R_L:
15626 case OPC_DEXTR_RS_L:
15627 case OPC_DEXTR_W:
15628 case OPC_DEXTR_R_W:
15629 case OPC_DEXTR_RS_W:
15630 case OPC_DEXTR_S_H:
15631 case OPC_DEXTRV_L:
15632 case OPC_DEXTRV_R_L:
15633 case OPC_DEXTRV_RS_L:
15634 case OPC_DEXTRV_S_H:
15635 case OPC_DEXTRV_W:
15636 case OPC_DEXTRV_R_W:
15637 case OPC_DEXTRV_RS_W:
15638 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 15639 break;
099e5b4d
LA
15640 case OPC_DMTHLIP:
15641 case OPC_DSHILO:
15642 case OPC_DSHILOV:
15643 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 15644 break;
099e5b4d
LA
15645 default: /* Invalid */
15646 MIPS_INVAL("MASK EXTR.W");
15647 generate_exception(ctx, EXCP_RI);
461c08df 15648 break;
099e5b4d
LA
15649 }
15650 break;
15651 case OPC_DPAQ_W_QH_DSP:
15652 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15653 switch (op2) {
15654 case OPC_DPAU_H_OBL:
15655 case OPC_DPAU_H_OBR:
15656 case OPC_DPSU_H_OBL:
15657 case OPC_DPSU_H_OBR:
15658 case OPC_DPA_W_QH:
15659 case OPC_DPAQ_S_W_QH:
15660 case OPC_DPS_W_QH:
15661 case OPC_DPSQ_S_W_QH:
15662 case OPC_MULSAQ_S_W_QH:
15663 case OPC_DPAQ_SA_L_PW:
15664 case OPC_DPSQ_SA_L_PW:
15665 case OPC_MULSAQ_S_L_PW:
15666 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15667 break;
15668 case OPC_MAQ_S_W_QHLL:
15669 case OPC_MAQ_S_W_QHLR:
15670 case OPC_MAQ_S_W_QHRL:
15671 case OPC_MAQ_S_W_QHRR:
15672 case OPC_MAQ_SA_W_QHLL:
15673 case OPC_MAQ_SA_W_QHLR:
15674 case OPC_MAQ_SA_W_QHRL:
15675 case OPC_MAQ_SA_W_QHRR:
15676 case OPC_MAQ_S_L_PWL:
15677 case OPC_MAQ_S_L_PWR:
15678 case OPC_DMADD:
15679 case OPC_DMADDU:
15680 case OPC_DMSUB:
15681 case OPC_DMSUBU:
15682 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 15683 break;
099e5b4d
LA
15684 default: /* Invalid */
15685 MIPS_INVAL("MASK DPAQ.W.QH");
15686 generate_exception(ctx, EXCP_RI);
b53371ed 15687 break;
099e5b4d
LA
15688 }
15689 break;
15690 case OPC_DINSV_DSP:
15691 op2 = MASK_INSV(ctx->opcode);
15692 switch (op2) {
15693 case OPC_DINSV:
15694 {
15695 TCGv t0, t1;
15696
15697 if (rt == 0) {
15698 MIPS_DEBUG("NOP");
a22260ae
JL
15699 break;
15700 }
099e5b4d 15701 check_dsp(ctx);
1cb6686c 15702
099e5b4d
LA
15703 t0 = tcg_temp_new();
15704 t1 = tcg_temp_new();
1cb6686c 15705
099e5b4d
LA
15706 gen_load_gpr(t0, rt);
15707 gen_load_gpr(t1, rs);
1cb6686c 15708
099e5b4d 15709 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 15710
099e5b4d
LA
15711 tcg_temp_free(t0);
15712 tcg_temp_free(t1);
77c5fa8b 15713 break;
099e5b4d 15714 }
7a387fff 15715 default: /* Invalid */
099e5b4d 15716 MIPS_INVAL("MASK DINSV");
7a387fff
TS
15717 generate_exception(ctx, EXCP_RI);
15718 break;
15719 }
15720 break;
099e5b4d
LA
15721 case OPC_SHLL_OB_DSP:
15722 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15723 break;
15724#endif
fac5a073
LA
15725 default: /* Invalid */
15726 MIPS_INVAL("special3_legacy");
15727 generate_exception(ctx, EXCP_RI);
15728 break;
15729 }
15730}
15731
15732static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15733{
15734 int rs, rt, rd, sa;
15735 uint32_t op1, op2;
15736
15737 rs = (ctx->opcode >> 21) & 0x1f;
15738 rt = (ctx->opcode >> 16) & 0x1f;
15739 rd = (ctx->opcode >> 11) & 0x1f;
15740 sa = (ctx->opcode >> 6) & 0x1f;
15741
15742 op1 = MASK_SPECIAL3(ctx->opcode);
15743 switch (op1) {
15744 case OPC_EXT:
15745 case OPC_INS:
15746 check_insn(ctx, ISA_MIPS32R2);
15747 gen_bitops(ctx, op1, rt, rs, sa, rd);
15748 break;
15749 case OPC_BSHFL:
15750 check_insn(ctx, ISA_MIPS32R2);
15751 op2 = MASK_BSHFL(ctx->opcode);
15752 gen_bshfl(ctx, op2, rt, rd);
15753 break;
15754#if defined(TARGET_MIPS64)
15755 case OPC_DEXTM ... OPC_DEXT:
15756 case OPC_DINSM ... OPC_DINS:
15757 check_insn(ctx, ISA_MIPS64R2);
15758 check_mips_64(ctx);
15759 gen_bitops(ctx, op1, rt, rs, sa, rd);
15760 break;
15761 case OPC_DBSHFL:
15762 check_insn(ctx, ISA_MIPS64R2);
15763 check_mips_64(ctx);
15764 op2 = MASK_DBSHFL(ctx->opcode);
15765 gen_bshfl(ctx, op2, rt, rd);
15766 break;
15767#endif
15768 case OPC_RDHWR:
15769 gen_rdhwr(ctx, rt, rd);
15770 break;
15771 case OPC_FORK:
15772 check_insn(ctx, ASE_MT);
15773 {
15774 TCGv t0 = tcg_temp_new();
15775 TCGv t1 = tcg_temp_new();
15776
15777 gen_load_gpr(t0, rt);
15778 gen_load_gpr(t1, rs);
15779 gen_helper_fork(t0, t1);
15780 tcg_temp_free(t0);
15781 tcg_temp_free(t1);
15782 }
15783 break;
15784 case OPC_YIELD:
15785 check_insn(ctx, ASE_MT);
15786 {
15787 TCGv t0 = tcg_temp_new();
15788
15789 save_cpu_state(ctx, 1);
15790 gen_load_gpr(t0, rs);
15791 gen_helper_yield(t0, cpu_env, t0);
15792 gen_store_gpr(t0, rd);
15793 tcg_temp_free(t0);
15794 }
15795 break;
10dc65db
LA
15796 default:
15797 if (ctx->insn_flags & ISA_MIPS32R6) {
15798 decode_opc_special3_r6(env, ctx);
15799 } else {
15800 decode_opc_special3_legacy(env, ctx);
15801 }
099e5b4d
LA
15802 }
15803}
15804
15805static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
15806{
15807 int32_t offset;
15808 int rs, rt, rd, sa;
15809 uint32_t op, op1;
15810 int16_t imm;
15811
15812 /* make sure instructions are on a word boundary */
15813 if (ctx->pc & 0x3) {
15814 env->CP0_BadVAddr = ctx->pc;
15815 generate_exception(ctx, EXCP_AdEL);
15816 return;
15817 }
15818
15819 /* Handle blikely not taken case */
15820 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15821 int l1 = gen_new_label();
15822
15823 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
15824 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15825 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15826 gen_goto_tb(ctx, 1, ctx->pc + 4);
15827 gen_set_label(l1);
15828 }
15829
15830 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
15831 tcg_gen_debug_insn_start(ctx->pc);
15832 }
15833
15834 op = MASK_OP_MAJOR(ctx->opcode);
15835 rs = (ctx->opcode >> 21) & 0x1f;
15836 rt = (ctx->opcode >> 16) & 0x1f;
15837 rd = (ctx->opcode >> 11) & 0x1f;
15838 sa = (ctx->opcode >> 6) & 0x1f;
15839 imm = (int16_t)ctx->opcode;
15840 switch (op) {
15841 case OPC_SPECIAL:
15842 decode_opc_special(env, ctx);
15843 break;
15844 case OPC_SPECIAL2:
4267d3e6 15845 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
15846 break;
15847 case OPC_SPECIAL3:
15848 decode_opc_special3(env, ctx);
15849 break;
7a387fff
TS
15850 case OPC_REGIMM:
15851 op1 = MASK_REGIMM(ctx->opcode);
15852 switch (op1) {
fecd2646
LA
15853 case OPC_BLTZL: /* REGIMM branches */
15854 case OPC_BGEZL:
15855 case OPC_BLTZALL:
15856 case OPC_BGEZALL:
15857 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15858 case OPC_BLTZ:
15859 case OPC_BGEZ:
15860 case OPC_BLTZAL:
15861 case OPC_BGEZAL:
7dca4ad0 15862 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061 15863 break;
7a387fff
TS
15864 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15865 case OPC_TNEI:
fecd2646 15866 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
15867 gen_trap(ctx, op1, rs, -1, imm);
15868 break;
15869 case OPC_SYNCI:
d75c135e 15870 check_insn(ctx, ISA_MIPS32R2);
ead9360e 15871 /* Treat as NOP. */
6af0bf9c 15872 break;
e45a93e2
JL
15873 case OPC_BPOSGE32: /* MIPS DSP branch */
15874#if defined(TARGET_MIPS64)
15875 case OPC_BPOSGE64:
15876#endif
15877 check_dsp(ctx);
15878 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
e45a93e2 15879 break;
6af0bf9c 15880 default: /* Invalid */
923617a3 15881 MIPS_INVAL("regimm");
6af0bf9c
FB
15882 generate_exception(ctx, EXCP_RI);
15883 break;
15884 }
15885 break;
7a387fff 15886 case OPC_CP0:
387a8fe5 15887 check_cp0_enabled(ctx);
7a387fff 15888 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15889 switch (op1) {
7a387fff
TS
15890 case OPC_MFC0:
15891 case OPC_MTC0:
ead9360e
TS
15892 case OPC_MFTR:
15893 case OPC_MTTR:
d26bc211 15894#if defined(TARGET_MIPS64)
7a387fff
TS
15895 case OPC_DMFC0:
15896 case OPC_DMTC0:
15897#endif
f1aa6320 15898#ifndef CONFIG_USER_ONLY
932e71cd 15899 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15900#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15901 break;
15902 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15903#ifndef CONFIG_USER_ONLY
932e71cd 15904 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15905#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15906 break;
15907 case OPC_MFMC0:
8706c382 15908#ifndef CONFIG_USER_ONLY
932e71cd 15909 {
099e5b4d 15910 uint32_t op2;
35fbce2c 15911 TCGv t0 = tcg_temp_new();
6c5c1e20 15912
0eaef5aa 15913 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15914 switch (op2) {
15915 case OPC_DMT:
d75c135e 15916 check_insn(ctx, ASE_MT);
9ed5726c 15917 gen_helper_dmt(t0);
35fbce2c 15918 gen_store_gpr(t0, rt);
6c5c1e20
TS
15919 break;
15920 case OPC_EMT:
d75c135e 15921 check_insn(ctx, ASE_MT);
9ed5726c 15922 gen_helper_emt(t0);
35fbce2c 15923 gen_store_gpr(t0, rt);
da80682b 15924 break;
6c5c1e20 15925 case OPC_DVPE:
d75c135e 15926 check_insn(ctx, ASE_MT);
895c2d04 15927 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15928 gen_store_gpr(t0, rt);
6c5c1e20
TS
15929 break;
15930 case OPC_EVPE:
d75c135e 15931 check_insn(ctx, ASE_MT);
895c2d04 15932 gen_helper_evpe(t0, cpu_env);
35fbce2c 15933 gen_store_gpr(t0, rt);
6c5c1e20
TS
15934 break;
15935 case OPC_DI:
d75c135e 15936 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15937 save_cpu_state(ctx, 1);
895c2d04 15938 gen_helper_di(t0, cpu_env);
35fbce2c 15939 gen_store_gpr(t0, rt);
6c5c1e20
TS
15940 /* Stop translation as we may have switched the execution mode */
15941 ctx->bstate = BS_STOP;
15942 break;
15943 case OPC_EI:
d75c135e 15944 check_insn(ctx, ISA_MIPS32R2);
867abc7e 15945 save_cpu_state(ctx, 1);
895c2d04 15946 gen_helper_ei(t0, cpu_env);
35fbce2c 15947 gen_store_gpr(t0, rt);
6c5c1e20
TS
15948 /* Stop translation as we may have switched the execution mode */
15949 ctx->bstate = BS_STOP;
15950 break;
15951 default: /* Invalid */
15952 MIPS_INVAL("mfmc0");
15953 generate_exception(ctx, EXCP_RI);
15954 break;
15955 }
6c5c1e20 15956 tcg_temp_free(t0);
7a387fff 15957 }
0eaef5aa 15958#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15959 break;
7a387fff 15960 case OPC_RDPGPR:
d75c135e 15961 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15962 gen_load_srsgpr(rt, rd);
ead9360e 15963 break;
7a387fff 15964 case OPC_WRPGPR:
d75c135e 15965 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 15966 gen_store_srsgpr(rt, rd);
38121543 15967 break;
6af0bf9c 15968 default:
923617a3 15969 MIPS_INVAL("cp0");
7a387fff 15970 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15971 break;
15972 }
15973 break;
324d9e32
AJ
15974 case OPC_ADDI: /* Arithmetic with immediate opcode */
15975 case OPC_ADDIU:
d75c135e 15976 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 15977 break;
324d9e32
AJ
15978 case OPC_SLTI: /* Set on less than with immediate opcode */
15979 case OPC_SLTIU:
d75c135e 15980 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
15981 break;
15982 case OPC_ANDI: /* Arithmetic with immediate opcode */
15983 case OPC_LUI:
15984 case OPC_ORI:
15985 case OPC_XORI:
d75c135e 15986 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 15987 break;
7a387fff
TS
15988 case OPC_J ... OPC_JAL: /* Jump */
15989 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15990 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061 15991 break;
fecd2646
LA
15992 case OPC_BEQL ... OPC_BGTZL: /* Branch */
15993 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15994 case OPC_BEQ ... OPC_BGTZ:
7dca4ad0 15995 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061 15996 break;
fecd2646
LA
15997 case OPC_LWL: /* Load and stores */
15998 case OPC_LWR:
4368b29a 15999 case OPC_LL:
fecd2646
LA
16000 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16001 case OPC_LB ... OPC_LH:
16002 case OPC_LW ... OPC_LHU:
d75c135e 16003 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 16004 break;
fecd2646 16005 case OPC_SWL:
7a387fff 16006 case OPC_SWR:
fecd2646
LA
16007 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16008 case OPC_SB ... OPC_SH:
16009 case OPC_SW:
5c13fdfd 16010 gen_st(ctx, op, rt, rs, imm);
7a387fff 16011 break;
d66c7132 16012 case OPC_SC:
4368b29a 16013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
16014 gen_st_cond(ctx, op, rt, rs, imm);
16015 break;
7a387fff 16016 case OPC_CACHE:
bf7910c6 16017 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 16018 check_cp0_enabled(ctx);
d75c135e 16019 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 16020 /* Treat as NOP. */
34ae7b51 16021 break;
7a387fff 16022 case OPC_PREF:
bf7910c6 16023 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 16024 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 16025 /* Treat as NOP. */
6af0bf9c 16026 break;
4ad40f36 16027
923617a3 16028 /* Floating point (COP1). */
7a387fff
TS
16029 case OPC_LWC1:
16030 case OPC_LDC1:
16031 case OPC_SWC1:
16032 case OPC_SDC1:
5ab5c041 16033 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
16034 break;
16035
7a387fff 16036 case OPC_CP1:
5ab5c041 16037 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 16038 check_cp1_enabled(ctx);
36d23958
TS
16039 op1 = MASK_CP1(ctx->opcode);
16040 switch (op1) {
3a95e3a7
TS
16041 case OPC_MFHC1:
16042 case OPC_MTHC1:
d75c135e 16043 check_insn(ctx, ISA_MIPS32R2);
36d23958
TS
16044 case OPC_MFC1:
16045 case OPC_CFC1:
16046 case OPC_MTC1:
16047 case OPC_CTC1:
e189e748
TS
16048 gen_cp1(ctx, op1, rt, rd);
16049 break;
d26bc211 16050#if defined(TARGET_MIPS64)
36d23958
TS
16051 case OPC_DMFC1:
16052 case OPC_DMTC1:
d75c135e 16053 check_insn(ctx, ISA_MIPS3);
36d23958
TS
16054 gen_cp1(ctx, op1, rt, rd);
16055 break;
e189e748 16056#endif
fbcc6828
TS
16057 case OPC_BC1ANY2:
16058 case OPC_BC1ANY4:
fecd2646 16059 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b8aa4598 16060 check_cop1x(ctx);
d75c135e 16061 check_insn(ctx, ASE_MIPS3D);
d8a5950a
TS
16062 /* fall through */
16063 case OPC_BC1:
fecd2646 16064 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 16065 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 16066 (rt >> 2) & 0x7, imm << 2);
c9602061 16067 break;
fecd2646
LA
16068 case OPC_PS_FMT:
16069 check_insn_opc_removed(ctx, ISA_MIPS32R6);
36d23958
TS
16070 case OPC_S_FMT:
16071 case OPC_D_FMT:
16072 case OPC_W_FMT:
16073 case OPC_L_FMT:
bf4120ad 16074 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 16075 (imm >> 8) & 0x7);
36d23958
TS
16076 break;
16077 default:
923617a3 16078 MIPS_INVAL("cp1");
e397ee33 16079 generate_exception (ctx, EXCP_RI);
36d23958
TS
16080 break;
16081 }
16082 } else {
16083 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 16084 }
4ad40f36
FB
16085 break;
16086
16087 /* COP2. */
7a387fff
TS
16088 case OPC_LWC2:
16089 case OPC_LDC2:
16090 case OPC_SWC2:
16091 case OPC_SDC2:
7a387fff 16092 /* COP2: Not implemented. */
4ad40f36
FB
16093 generate_exception_err(ctx, EXCP_CpU, 2);
16094 break;
bd277fa1 16095 case OPC_CP2:
d75c135e 16096 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
16097 /* Note that these instructions use different fields. */
16098 gen_loongson_multimedia(ctx, sa, rd, rt);
16099 break;
4ad40f36 16100
7a387fff 16101 case OPC_CP3:
fecd2646 16102 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 16103 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 16104 check_cp1_enabled(ctx);
36d23958
TS
16105 op1 = MASK_CP3(ctx->opcode);
16106 switch (op1) {
5a5012ec
TS
16107 case OPC_LWXC1:
16108 case OPC_LDXC1:
16109 case OPC_LUXC1:
16110 case OPC_SWXC1:
16111 case OPC_SDXC1:
16112 case OPC_SUXC1:
93b12ccc 16113 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 16114 break;
e0c84da7 16115 case OPC_PREFX:
ead9360e 16116 /* Treat as NOP. */
e0c84da7 16117 break;
5a5012ec
TS
16118 case OPC_ALNV_PS:
16119 case OPC_MADD_S:
16120 case OPC_MADD_D:
16121 case OPC_MADD_PS:
16122 case OPC_MSUB_S:
16123 case OPC_MSUB_D:
16124 case OPC_MSUB_PS:
16125 case OPC_NMADD_S:
16126 case OPC_NMADD_D:
16127 case OPC_NMADD_PS:
16128 case OPC_NMSUB_S:
16129 case OPC_NMSUB_D:
16130 case OPC_NMSUB_PS:
16131 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
16132 break;
36d23958 16133 default:
923617a3 16134 MIPS_INVAL("cp3");
e397ee33 16135 generate_exception (ctx, EXCP_RI);
36d23958
TS
16136 break;
16137 }
16138 } else {
e397ee33 16139 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 16140 }
4ad40f36
FB
16141 break;
16142
d26bc211 16143#if defined(TARGET_MIPS64)
7a387fff 16144 /* MIPS64 opcodes */
7a387fff 16145 case OPC_LDL ... OPC_LDR:
bf7910c6 16146 case OPC_LLD:
fecd2646
LA
16147 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16148 case OPC_LWU:
7a387fff 16149 case OPC_LD:
d75c135e 16150 check_insn(ctx, ISA_MIPS3);
5c13fdfd 16151 check_mips_64(ctx);
d75c135e 16152 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
16153 break;
16154 case OPC_SDL ... OPC_SDR:
fecd2646 16155 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff 16156 case OPC_SD:
d75c135e 16157 check_insn(ctx, ISA_MIPS3);
e189e748 16158 check_mips_64(ctx);
5c13fdfd 16159 gen_st(ctx, op, rt, rs, imm);
7a387fff 16160 break;
d66c7132 16161 case OPC_SCD:
bf7910c6 16162 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 16163 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
16164 check_mips_64(ctx);
16165 gen_st_cond(ctx, op, rt, rs, imm);
16166 break;
324d9e32
AJ
16167 case OPC_DADDI:
16168 case OPC_DADDIU:
d75c135e 16169 check_insn(ctx, ISA_MIPS3);
e189e748 16170 check_mips_64(ctx);
d75c135e 16171 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 16172 break;
6af0bf9c 16173#endif
7a387fff 16174 case OPC_JALX:
d75c135e 16175 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
16176 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16177 gen_compute_branch(ctx, op, 4, rs, rt, offset);
364d4831 16178 break;
7a387fff 16179 case OPC_MDMX:
d75c135e 16180 check_insn(ctx, ASE_MDMX);
7a387fff 16181 /* MDMX: Not implemented. */
6af0bf9c 16182 default: /* Invalid */
923617a3 16183 MIPS_INVAL("major opcode");
6af0bf9c
FB
16184 generate_exception(ctx, EXCP_RI);
16185 break;
16186 }
6af0bf9c
FB
16187}
16188
2cfc5f17 16189static inline void
6429db34
AF
16190gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
16191 bool search_pc)
6af0bf9c 16192{
ed2803da 16193 CPUState *cs = CPU(cpu);
6429db34 16194 CPUMIPSState *env = &cpu->env;
278d0702 16195 DisasContext ctx;
6af0bf9c
FB
16196 target_ulong pc_start;
16197 uint16_t *gen_opc_end;
a1d1bb31 16198 CPUBreakpoint *bp;
6af0bf9c 16199 int j, lj = -1;
2e70f6ef
PB
16200 int num_insns;
16201 int max_insns;
c9602061 16202 int insn_bytes;
240ce26a 16203 int is_delay;
6af0bf9c 16204
93fcfe39
AL
16205 if (search_pc)
16206 qemu_log("search pc %d\n", search_pc);
4ad40f36 16207
6af0bf9c 16208 pc_start = tb->pc;
92414b31 16209 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 16210 ctx.pc = pc_start;
4ad40f36 16211 ctx.saved_pc = -1;
ed2803da 16212 ctx.singlestep_enabled = cs->singlestep_enabled;
d75c135e 16213 ctx.insn_flags = env->insn_flags;
5ab5c041 16214 ctx.CP0_Config1 = env->CP0_Config1;
6af0bf9c
FB
16215 ctx.tb = tb;
16216 ctx.bstate = BS_NONE;
4ad40f36 16217 /* Restore delay slot state from the tb context. */
c068688b 16218 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
d279279e 16219 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
fd4a04eb 16220 restore_cpu_state(env, &ctx);
932e71cd 16221#ifdef CONFIG_USER_ONLY
0eaef5aa 16222 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 16223#else
0eaef5aa 16224 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 16225#endif
2e70f6ef
PB
16226 num_insns = 0;
16227 max_insns = tb->cflags & CF_COUNT_MASK;
16228 if (max_insns == 0)
16229 max_insns = CF_COUNT_MASK;
d12d51d5 16230 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
806f352d 16231 gen_tb_start();
faf7aaa9 16232 while (ctx.bstate == BS_NONE) {
f0c3c505
AF
16233 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
16234 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
a1d1bb31 16235 if (bp->pc == ctx.pc) {
278d0702 16236 save_cpu_state(&ctx, 1);
4ad40f36 16237 ctx.bstate = BS_BRANCH;
895c2d04 16238 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
16239 /* Include the breakpoint location or the tb won't
16240 * be flushed when it must be. */
16241 ctx.pc += 4;
4ad40f36
FB
16242 goto done_generating;
16243 }
16244 }
16245 }
16246
6af0bf9c 16247 if (search_pc) {
92414b31 16248 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
16249 if (lj < j) {
16250 lj++;
16251 while (lj < j)
ab1103de 16252 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c 16253 }
25983cad 16254 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
4ad40f36 16255 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 16256 gen_opc_btarget[lj] = ctx.btarget;
ab1103de 16257 tcg_ctx.gen_opc_instr_start[lj] = 1;
c9c99c22 16258 tcg_ctx.gen_opc_icount[lj] = num_insns;
6af0bf9c 16259 }
2e70f6ef
PB
16260 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
16261 gen_io_start();
c9602061 16262
240ce26a 16263 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 16264 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 16265 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061 16266 insn_bytes = 4;
240ce26a 16267 decode_opc(env, &ctx);
d75c135e 16268 } else if (ctx.insn_flags & ASE_MICROMIPS) {
895c2d04 16269 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 16270 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 16271 } else if (ctx.insn_flags & ASE_MIPS16) {
895c2d04 16272 ctx.opcode = cpu_lduw_code(env, ctx.pc);
240ce26a 16273 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061
NF
16274 } else {
16275 generate_exception(&ctx, EXCP_RI);
3c824109 16276 ctx.bstate = BS_STOP;
c9602061
NF
16277 break;
16278 }
240ce26a 16279 if (is_delay) {
d75c135e 16280 handle_delay_slot(&ctx, insn_bytes);
c9602061
NF
16281 }
16282 ctx.pc += insn_bytes;
16283
2e70f6ef 16284 num_insns++;
4ad40f36 16285
7b270ef2
NF
16286 /* Execute a branch and its delay slot as a single instruction.
16287 This is what GDB expects and is consistent with what the
16288 hardware does (e.g. if a delay slot instruction faults, the
16289 reported PC is the PC of the branch). */
ed2803da 16290 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 16291 break;
ed2803da 16292 }
4ad40f36 16293
6af0bf9c
FB
16294 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
16295 break;
4ad40f36 16296
efd7f486 16297 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
faf7aaa9 16298 break;
efd7f486 16299 }
faf7aaa9 16300
2e70f6ef
PB
16301 if (num_insns >= max_insns)
16302 break;
1b530a6d
AJ
16303
16304 if (singlestep)
16305 break;
6af0bf9c 16306 }
ed2803da 16307 if (tb->cflags & CF_LAST_IO) {
2e70f6ef 16308 gen_io_end();
ed2803da
AF
16309 }
16310 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 16311 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 16312 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 16313 } else {
6958549d 16314 switch (ctx.bstate) {
16c00cb2 16315 case BS_STOP:
df1561e2
TS
16316 gen_goto_tb(&ctx, 0, ctx.pc);
16317 break;
16c00cb2 16318 case BS_NONE:
278d0702 16319 save_cpu_state(&ctx, 0);
16c00cb2
TS
16320 gen_goto_tb(&ctx, 0, ctx.pc);
16321 break;
5a5012ec 16322 case BS_EXCP:
57fec1fe 16323 tcg_gen_exit_tb(0);
16c00cb2 16324 break;
5a5012ec
TS
16325 case BS_BRANCH:
16326 default:
16327 break;
6958549d 16328 }
6af0bf9c 16329 }
4ad40f36 16330done_generating:
806f352d 16331 gen_tb_end(tb, num_insns);
efd7f486 16332 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
6af0bf9c 16333 if (search_pc) {
92414b31 16334 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
6af0bf9c
FB
16335 lj++;
16336 while (lj <= j)
ab1103de 16337 tcg_ctx.gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
16338 } else {
16339 tb->size = ctx.pc - pc_start;
2e70f6ef 16340 tb->icount = num_insns;
6af0bf9c
FB
16341 }
16342#ifdef DEBUG_DISAS
d12d51d5 16343 LOG_DISAS("\n");
8fec2b8c 16344 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39 16345 qemu_log("IN: %s\n", lookup_symbol(pc_start));
f4359b9f 16346 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
93fcfe39 16347 qemu_log("\n");
6af0bf9c
FB
16348 }
16349#endif
6af0bf9c
FB
16350}
16351
7db13fae 16352void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 16353{
6429db34 16354 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
6af0bf9c
FB
16355}
16356
7db13fae 16357void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 16358{
6429db34 16359 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
6af0bf9c
FB
16360}
16361
7db13fae 16362static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 16363 int flags)
6ea83fed
FB
16364{
16365 int i;
5e755519 16366 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 16367
2a5612e6
SW
16368#define printfpr(fp) \
16369 do { \
16370 if (is_fpu64) \
16371 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
16372 " fd:%13g fs:%13g psu: %13g\n", \
16373 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
16374 (double)(fp)->fd, \
16375 (double)(fp)->fs[FP_ENDIAN_IDX], \
16376 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
16377 else { \
16378 fpr_t tmp; \
16379 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
16380 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
16381 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
16382 " fd:%13g fs:%13g psu:%13g\n", \
16383 tmp.w[FP_ENDIAN_IDX], tmp.d, \
16384 (double)tmp.fd, \
16385 (double)tmp.fs[FP_ENDIAN_IDX], \
16386 (double)tmp.fs[!FP_ENDIAN_IDX]); \
16387 } \
6ea83fed
FB
16388 } while(0)
16389
5a5012ec 16390
9a78eead
SW
16391 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
16392 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 16393 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
16394 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
16395 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 16396 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
16397 }
16398
16399#undef printfpr
16400}
16401
d26bc211 16402#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 16403/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 16404 sign-extended values on 64bit machines. */
c570fd16
TS
16405
16406#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
16407
8706c382 16408static void
7db13fae 16409cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 16410 fprintf_function cpu_fprintf,
8706c382 16411 int flags)
c570fd16
TS
16412{
16413 int i;
16414
b5dc7732
TS
16415 if (!SIGN_EXT_P(env->active_tc.PC))
16416 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
16417 if (!SIGN_EXT_P(env->active_tc.HI[0]))
16418 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
16419 if (!SIGN_EXT_P(env->active_tc.LO[0]))
16420 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 16421 if (!SIGN_EXT_P(env->btarget))
3594c774 16422 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
16423
16424 for (i = 0; i < 32; i++) {
b5dc7732
TS
16425 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
16426 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
16427 }
16428
16429 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 16430 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
16431 if (!SIGN_EXT_P(env->lladdr))
16432 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
16433}
16434#endif
16435
878096ee
AF
16436void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
16437 int flags)
6af0bf9c 16438{
878096ee
AF
16439 MIPSCPU *cpu = MIPS_CPU(cs);
16440 CPUMIPSState *env = &cpu->env;
6af0bf9c 16441 int i;
3b46e624 16442
a7200c9f
SW
16443 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
16444 " LO=0x" TARGET_FMT_lx " ds %04x "
16445 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
16446 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
16447 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
16448 for (i = 0; i < 32; i++) {
16449 if ((i & 3) == 0)
16450 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 16451 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
16452 if ((i & 3) == 3)
16453 cpu_fprintf(f, "\n");
16454 }
568b600d 16455
3594c774 16456 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 16457 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 16458 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 16459 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 16460 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 16461 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 16462#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
16463 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
16464#endif
6af0bf9c
FB
16465}
16466
78ce64f4 16467void mips_tcg_init(void)
39454628 16468{
f01be154 16469 int i;
39454628
TS
16470 static int inited;
16471
16472 /* Initialize various static tables. */
16473 if (inited)
6958549d 16474 return;
39454628 16475
a7812ae4 16476 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 16477 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 16478 for (i = 1; i < 32; i++)
a7812ae4 16479 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16480 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 16481 regnames[i]);
d73ee8a2
RH
16482
16483 for (i = 0; i < 32; i++) {
16484 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
16485 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
16486 }
16487
a7812ae4 16488 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 16489 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 16490 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 16491 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16492 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 16493 regnames_HI[i]);
a7812ae4 16494 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16495 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 16496 regnames_LO[i]);
a7812ae4 16497 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 16498 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
16499 regnames_ACX[i]);
16500 }
a7812ae4 16501 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 16502 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 16503 "DSPControl");
1ba74fb8 16504 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 16505 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 16506 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 16507 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 16508 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 16509 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 16510
a7812ae4 16511 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 16512 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
16513 "fcr0");
16514 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 16515 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 16516 "fcr31");
39454628
TS
16517
16518 inited = 1;
16519}
16520
aaed909a
FB
16521#include "translate_init.c"
16522
30bf942d 16523MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 16524{
0f71a709 16525 MIPSCPU *cpu;
6af0bf9c 16526 CPUMIPSState *env;
c227f099 16527 const mips_def_t *def;
6af0bf9c 16528
aaed909a
FB
16529 def = cpu_mips_find_by_name(cpu_model);
16530 if (!def)
16531 return NULL;
0f71a709
AF
16532 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
16533 env = &cpu->env;
aaed909a
FB
16534 env->cpu_model = def;
16535
51cc2e78
BS
16536#ifndef CONFIG_USER_ONLY
16537 mmu_init(env, def);
16538#endif
16539 fpu_init(env, def);
16540 mvp_init(env, def);
c1caf1d9
AF
16541
16542 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
16543
30bf942d 16544 return cpu;
6ae81775
TS
16545}
16546
1bba0dc9 16547void cpu_state_reset(CPUMIPSState *env)
6ae81775 16548{
55e5c285
AF
16549 MIPSCPU *cpu = mips_env_get_cpu(env);
16550 CPUState *cs = CPU(cpu);
6ae81775 16551
51cc2e78
BS
16552 /* Reset registers to their default values */
16553 env->CP0_PRid = env->cpu_model->CP0_PRid;
16554 env->CP0_Config0 = env->cpu_model->CP0_Config0;
16555#ifdef TARGET_WORDS_BIGENDIAN
16556 env->CP0_Config0 |= (1 << CP0C0_BE);
16557#endif
16558 env->CP0_Config1 = env->cpu_model->CP0_Config1;
16559 env->CP0_Config2 = env->cpu_model->CP0_Config2;
16560 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
16561 env->CP0_Config4 = env->cpu_model->CP0_Config4;
16562 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
16563 env->CP0_Config5 = env->cpu_model->CP0_Config5;
16564 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
16565 env->CP0_Config6 = env->cpu_model->CP0_Config6;
16566 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
16567 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
16568 << env->cpu_model->CP0_LLAddr_shift;
16569 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
16570 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
16571 env->CCRes = env->cpu_model->CCRes;
16572 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
16573 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
16574 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
16575 env->current_tc = 0;
16576 env->SEGBITS = env->cpu_model->SEGBITS;
16577 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
16578#if defined(TARGET_MIPS64)
16579 if (env->cpu_model->insn_flags & ISA_MIPS3) {
16580 env->SEGMask |= 3ULL << 62;
16581 }
16582#endif
16583 env->PABITS = env->cpu_model->PABITS;
16584 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
16585 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
16586 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
16587 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
16588 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
16589 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
16590 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
16591 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
16592 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
16593 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
16594 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 16595 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
16596 env->insn_flags = env->cpu_model->insn_flags;
16597
0eaef5aa 16598#if defined(CONFIG_USER_ONLY)
03e6e501 16599 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
16600# ifdef TARGET_MIPS64
16601 /* Enable 64-bit register mode. */
16602 env->CP0_Status |= (1 << CP0St_PX);
16603# endif
16604# ifdef TARGET_ABI_MIPSN64
16605 /* Enable 64-bit address mode. */
16606 env->CP0_Status |= (1 << CP0St_UX);
16607# endif
94159135
MI
16608 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16609 hardware registers. */
16610 env->CP0_HWREna |= 0x0000000F;
91a75935 16611 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 16612 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 16613 }
6f0af304
PJ
16614 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16615 env->CP0_Status |= (1 << CP0St_MX);
853c3240 16616 }
4d66261f
PJ
16617# if defined(TARGET_MIPS64)
16618 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16619 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16620 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
16621 env->CP0_Status |= (1 << CP0St_FR);
16622 }
4d66261f 16623# endif
932e71cd
AJ
16624#else
16625 if (env->hflags & MIPS_HFLAG_BMASK) {
16626 /* If the exception was raised from a delay slot,
16627 come back to the jump. */
16628 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 16629 } else {
932e71cd
AJ
16630 env->CP0_ErrorEPC = env->active_tc.PC;
16631 }
16632 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
16633 env->CP0_Random = env->tlb->nb_tlb - 1;
16634 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 16635 env->CP0_Wired = 0;
0a2672b7
JH
16636 env->CP0_EBase = (cs->cpu_index & 0x3FF);
16637 if (kvm_enabled()) {
16638 env->CP0_EBase |= 0x40000000;
16639 } else {
16640 env->CP0_EBase |= 0x80000000;
16641 }
932e71cd
AJ
16642 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16643 /* vectored interrupts not implemented, timer on int 7,
16644 no performance counters. */
16645 env->CP0_IntCtl = 0xe0000000;
16646 {
16647 int i;
16648
16649 for (i = 0; i < 7; i++) {
16650 env->CP0_WatchLo[i] = 0;
16651 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 16652 }
932e71cd
AJ
16653 env->CP0_WatchLo[7] = 0;
16654 env->CP0_WatchHi[7] = 0;
fd88b6ab 16655 }
932e71cd
AJ
16656 /* Count register increments in debug mode, EJTAG version 1 */
16657 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 16658
4b69c7e2
JH
16659 cpu_mips_store_count(env, 1);
16660
9e56e756
EI
16661 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16662 int i;
16663
16664 /* Only TC0 on VPE 0 starts as active. */
16665 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 16666 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
16667 env->tcs[i].CP0_TCHalt = 1;
16668 }
16669 env->active_tc.CP0_TCHalt = 1;
259186a7 16670 cs->halted = 1;
9e56e756 16671
55e5c285 16672 if (cs->cpu_index == 0) {
9e56e756
EI
16673 /* VPE0 starts up enabled. */
16674 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16675 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16676
16677 /* TC0 starts up unhalted. */
259186a7 16678 cs->halted = 0;
9e56e756
EI
16679 env->active_tc.CP0_TCHalt = 0;
16680 env->tcs[0].CP0_TCHalt = 0;
16681 /* With thread 0 active. */
16682 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16683 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16684 }
16685 }
51cc2e78 16686#endif
03e6e501 16687 compute_hflags(env);
27103424 16688 cs->exception_index = EXCP_NONE;
6af0bf9c 16689}
d2856f1a 16690
7db13fae 16691void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 16692{
25983cad 16693 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
d2856f1a
AJ
16694 env->hflags &= ~MIPS_HFLAG_BMASK;
16695 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
16696 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16697 case MIPS_HFLAG_BR:
16698 break;
16699 case MIPS_HFLAG_BC:
16700 case MIPS_HFLAG_BL:
16701 case MIPS_HFLAG_B:
16702 env->btarget = gen_opc_btarget[pc_pos];
16703 break;
16704 }
d2856f1a 16705}
This page took 3.584211 seconds and 4 git commands to generate.